add multi-monitor support in QXL mode

This commit is contained in:
Vadim Rozenfeld 2014-12-06 15:44:28 +11:00
parent 2885958174
commit 861b2d2d44
2 changed files with 33 additions and 18 deletions

View File

@ -132,18 +132,6 @@ NTSTATUS QxlDod::StartDevice(_In_ DXGK_START_INFO* pDxgkStartInfo,
return Status;
}
// This sample driver only uses the frame buffer of the POST device. DxgkCbAcquirePostDisplayOwnership
// gives you the frame buffer address and ensures that no one else is drawing to it. Be sure to give it back!
Status = m_DxgkInterface.DxgkCbAcquirePostDisplayOwnership(m_DxgkInterface.DeviceHandle, &(m_CurrentModes[0].DispInfo));
if (!NT_SUCCESS(Status) || m_CurrentModes[0].DispInfo.Width == 0)
{
// The most likely cause of failure is that the driver is simply not running on a POST device, or we are running
// after a pre-WDDM 1.2 driver. Since we can't draw anything, we should fail to start.
DbgPrint(TRACE_LEVEL_ERROR, ("DxgkCbAcquirePostDisplayOwnership failed with status 0x%X Width = %d\n",
Status, m_CurrentModes[0].DispInfo.Width));
return STATUS_UNSUCCESSFUL;
}
Status = CheckHardware();
if (NT_SUCCESS(Status))
{
@ -169,6 +157,27 @@ NTSTATUS QxlDod::StartDevice(_In_ DXGK_START_INFO* pDxgkStartInfo,
return Status;
}
if (m_pHWDevice->GetId() == 0)
{
Status = m_DxgkInterface.DxgkCbAcquirePostDisplayOwnership(m_DxgkInterface.DeviceHandle, &(m_CurrentModes[0].DispInfo));
}
if (!NT_SUCCESS(Status) )
{
DbgPrint(TRACE_LEVEL_ERROR, ("DxgkCbAcquirePostDisplayOwnership failed with status 0x%X Width = %d\n",
Status, m_CurrentModes[0].DispInfo.Width));
return STATUS_UNSUCCESSFUL;
}
if (m_CurrentModes[0].DispInfo.Width == 0)
{
m_CurrentModes[0].DispInfo.Width = MIN_WIDTH_SIZE;
m_CurrentModes[0].DispInfo.Height = MIN_HEIGHT_SIZE;
m_CurrentModes[0].DispInfo.Pitch = BPPFromPixelFormat(D3DDDIFMT_R8G8B8) / 8;
m_CurrentModes[0].DispInfo.ColorFormat = D3DDDIFMT_R8G8B8;
m_CurrentModes[0].DispInfo.TargetId = 0;
}
*pNumberOfViews = MAX_VIEWS;
*pNumberOfChildren = MAX_CHILDREN;
m_Flags.DriverStarted = TRUE;
@ -307,13 +316,14 @@ NTSTATUS QxlDod::QueryChildRelations(_Out_writes_bytes_(ChildRelationsSize) DXGK
// The last DXGK_CHILD_DESCRIPTOR in the array of pChildRelations must remain zeroed out, so we subtract this from the count
ULONG ChildRelationsCount = (ChildRelationsSize / sizeof(DXGK_CHILD_DESCRIPTOR)) - 1;
ULONG DeviceId = m_pHWDevice->GetId();
QXL_ASSERT(ChildRelationsCount <= MAX_CHILDREN);
for (UINT ChildIndex = 0; ChildIndex < ChildRelationsCount; ++ChildIndex)
{
pChildRelations[ChildIndex].ChildDeviceType = TypeVideoOutput;
pChildRelations[ChildIndex].ChildCapabilities.HpdAwareness = HpdAwarenessAlwaysConnected;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_INTERNAL;
pChildRelations[ChildIndex].ChildCapabilities.HpdAwareness = (DeviceId == 0) ? HpdAwarenessAlwaysConnected : HpdAwarenessInterruptible;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = (DeviceId == 0) ? D3DKMDT_VOT_INTERNAL : D3DKMDT_VOT_HD15;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
// TODO: Replace 0 with the actual ACPI ID of the child device, if available
@ -2443,8 +2453,8 @@ NTSTATUS VgaDevice::GetModeList(DXGK_DISPLAY_INFORMATION* pDispInfo)
{
m_ModeNumbers[SuitableModeCount] = ModeTemp;
SetVideoModeInfo(SuitableModeCount, &tmpModeInfo);
if (tmpModeInfo.XResolution == 1024 &&
tmpModeInfo.YResolution == 768)
if (tmpModeInfo.XResolution == MIN_WIDTH_SIZE &&
tmpModeInfo.YResolution == MIN_HEIGHT_SIZE)
{
m_CurrentMode = (USHORT)SuitableModeCount;
}
@ -2947,8 +2957,8 @@ NTSTATUS QxlDevice::GetModeList(DXGK_DISPLAY_INFORMATION* pDispInfo)
{
m_ModeNumbers[SuitableModeCount] = CurrentMode;
SetVideoModeInfo(SuitableModeCount, tmpModeInfo);
if (tmpModeInfo->x_res == 1024 &&
tmpModeInfo->y_res == 768)
if (tmpModeInfo->x_res == MIN_WIDTH_SIZE &&
tmpModeInfo->y_res == MIN_HEIGHT_SIZE)
{
m_CurrentMode = (USHORT)SuitableModeCount;
}
@ -3111,6 +3121,9 @@ NTSTATUS QxlDevice::HWInit(PCM_RESOURCE_LIST pResList, DXGK_DISPLAY_INFORMATION*
m_RamPA = pResDescriptor->u.Memory.Start;
m_RamStart = (UINT8*)MemBase;
m_RamSize = MemLength;
if (pDispInfo->PhysicAddress.QuadPart == 0L) {
pDispInfo->PhysicAddress.QuadPart = m_RamPA.QuadPart;
}
pci_range = QXL_VRAM_RANGE_INDEX;
break;
case QXL_VRAM_RANGE_INDEX:

View File

@ -8,6 +8,8 @@
#define BITS_PER_BYTE 8
#define POINTER_SIZE 64
#define MIN_WIDTH_SIZE 1024
#define MIN_HEIGHT_SIZE 768
typedef struct _QXL_FLAGS
{