static VOID vboxWddmAddVideoModes(PVBOXMP_DEVEXT pExt, PVBOXWDDM_VIDEOMODES_INFO pDstInfo, PVBOXWDDM_VIDEOMODES_INFO pSrcInfo) { for (int i = 0; i < (int)pSrcInfo->cModes; ++i) { int foundIdx = VBoxMPFindVideoMode(pDstInfo->aModes, pDstInfo->cModes, &pSrcInfo->aModes[i]); if (foundIdx >= 0) continue; Assert(0); pDstInfo->aModes[pDstInfo->cModes] = pSrcInfo->aModes[i]; ++pDstInfo->cModes; } VBoxWddmBuildResolutionTableForModes(pDstInfo); }
static void VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, PVBOXWDDM_VIDEOMODES_INFO pModes, VIDEO_MODE_INFORMATION *paAddlModes, UINT cAddlModes) { pModes->cResolutions = RT_ELEMENTS(pModes->aResolutions); /* Add default modes and ones read from registry. */ pModes->cModes = VBoxMPFillModesTable(pExt, VidPnTargetId, pModes->aModes, RT_ELEMENTS(pModes->aModes), &pModes->iPreferredMode); Assert(pModes->cModes<=RT_ELEMENTS(pModes->aModes)); if (!VBoxMPIsStartingUp(pExt, VidPnTargetId)) { /* make sure we keep the current mode to avoid mode flickering */ PVBOXWDDM_ALLOC_DATA pAllocData = pExt->aSources[VidPnTargetId].pPrimaryAllocation ? &pExt->aSources[VidPnTargetId].pPrimaryAllocation->AllocData : &pExt->aSources[VidPnTargetId].AllocData; if (pModes->cModes < RT_ELEMENTS(pModes->aModes)) { /* VBox WDDM driver does not allow 24 modes since OS could choose the 24bit mode as default in that case, * the pExt->aSources[iDisplay].AllocData.SurfDesc.bpp could be initially 24 though, * i.e. when driver occurs the current mode on driver load via DxgkCbAcquirePostDisplayOwnership * and until driver reports the supported modes * This is true for Win8 Display-Only driver currently since DxgkCbAcquirePostDisplayOwnership is only used by it * * This is why we check the bpp to be supported here and add the current mode to the list only in that case */ if (VBoxMPIsSupportedBpp(pAllocData->SurfDesc.bpp)) { int foundIdx; VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes], pAllocData->SurfDesc.width, pAllocData->SurfDesc.height, pAllocData->SurfDesc.bpp, 1/*index*/, 0); if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]))>=0) { pModes->iPreferredMode = foundIdx; } else { pModes->iPreferredMode = pModes->cModes; ++pModes->cModes; } #ifdef VBOX_WITH_8BPP_MODES int bytesPerPixel=1; #else int bytesPerPixel=2; #endif for (; bytesPerPixel<=4; bytesPerPixel++) { int bpp = 8*bytesPerPixel; if (bpp == pAllocData->SurfDesc.bpp) continue; if (!VBoxMPValidateVideoModeParamsGuest(pExt, VidPnTargetId, pAllocData->SurfDesc.width, pAllocData->SurfDesc.height, bpp)) continue; if (pModes->cModes >= RT_ELEMENTS(pModes->aModes)) { WARN(("ran out of video modes 2")); break; } VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes], pAllocData->SurfDesc.width, pAllocData->SurfDesc.height, bpp, pModes->cModes, 0); if (VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]) < 0) { ++pModes->cModes; } } } } else { WARN(("ran out of video modes 1")); } } /* Check if there's a pending display change request for this adapter */ VIDEO_MODE_INFORMATION specialMode; if (VBoxMPCheckPendingVideoMode(pExt, &specialMode) && (specialMode.ModeIndex==VidPnTargetId)) { /*Minor hack, ModeIndex!=0 Means this mode has been validated already and not just read from registry */ specialMode.ModeIndex = 1; memcpy(&g_CustomVideoModes[VidPnTargetId], &specialMode, sizeof(VIDEO_MODE_INFORMATION)); /* Save mode to registry */ VBoxMPRegSaveModeInfo(pExt, VidPnTargetId, &specialMode); } /* Validate the mode which has been read from registry */ if (!g_CustomVideoModes[VidPnTargetId].ModeIndex) { uint32_t xres, yres, bpp; xres = g_CustomVideoModes[VidPnTargetId].VisScreenWidth; yres = g_CustomVideoModes[VidPnTargetId].VisScreenHeight; bpp = g_CustomVideoModes[VidPnTargetId].BitsPerPlane; if (VBoxMPValidateVideoModeParams(pExt, VidPnTargetId, xres, yres, bpp)) { VBoxFillVidModeInfo(&g_CustomVideoModes[VidPnTargetId], xres, yres, bpp, 1/*index*/, 0); Assert(g_CustomVideoModes[VidPnTargetId].ModeIndex == 1); } } /* Add custom mode to the table */ if (g_CustomVideoModes[VidPnTargetId].ModeIndex) { if (RT_ELEMENTS(pModes->aModes) > pModes->cModes) { g_CustomVideoModes[VidPnTargetId].ModeIndex = pModes->cModes; pModes->aModes[pModes->cModes] = g_CustomVideoModes[VidPnTargetId]; /* Check if we already have this mode in the table */ int foundIdx; if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]))>=0) { pModes->iPreferredMode = foundIdx; } else { pModes->iPreferredMode = pModes->cModes; ++pModes->cModes; } /* Add other bpp modes for this custom resolution */ #ifdef VBOX_WITH_8BPP_MODES UINT bpp=8; #else UINT bpp=16; #endif for (; bpp<=32; bpp+=8) { if (RT_ELEMENTS(pModes->aModes) == pModes->cModes) { WARN(("table full, can't add other bpp for specail mode!")); #ifdef DEBUG_misha /* this is definitely something we do not expect */ AssertFailed(); #endif break; } AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */ if (pModes->aModes[pModes->iPreferredMode].BitsPerPlane == bpp) continue; if (!VBoxMPValidateVideoModeParamsGuest(pExt, VidPnTargetId, pModes->aModes[pModes->iPreferredMode].VisScreenWidth, pModes->aModes[pModes->iPreferredMode].VisScreenHeight, bpp)) continue; VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes], pModes->aModes[pModes->iPreferredMode].VisScreenWidth, pModes->aModes[pModes->iPreferredMode].VisScreenHeight, bpp, pModes->cModes, 0); if (VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]) < 0) { ++pModes->cModes; } } } else { AssertRelease(RT_ELEMENTS(pModes->aModes) == pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */ WARN(("table full, can't add video mode for a host request!")); #ifdef DEBUG_misha /* this is definitely something we do not expect */ AssertFailed(); #endif } } /* Check and Add additional modes passed in paAddlModes */ for (UINT i=0; i<cAddlModes; ++i) { if (RT_ELEMENTS(pModes->aModes) == pModes->cModes) { WARN(("table full, can't add addl modes!")); #ifdef DEBUG_misha /* this is definitely something we do not expect */ AssertFailed(); #endif break; } AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */ if (!pExt->fAnyX) { paAddlModes[i].VisScreenWidth &= 0xFFF8; } if (VBoxLikesVideoMode(VidPnTargetId, paAddlModes[i].VisScreenWidth, paAddlModes[i].VisScreenHeight, paAddlModes[i].BitsPerPlane)) { int foundIdx; if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &paAddlModes[i]))>=0) { pModes->iPreferredMode = foundIdx; } else { memcpy(&pModes->aModes[pModes->cModes], &paAddlModes[i], sizeof(VIDEO_MODE_INFORMATION)); pModes->aModes[pModes->cModes].ModeIndex = pModes->cModes; ++pModes->cModes; } } } /* Build resolution table */ VBoxWddmBuildResolutionTableForModes(pModes); }
static void VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, PVBOXWDDM_VIDEOMODES_INFO pModes, VIDEO_MODE_INFORMATION *paAddlModes, UINT cAddlModes) { pModes->cResolutions = RT_ELEMENTS(pModes->aResolutions); /* Add default modes and ones read from registry. */ pModes->cModes = VBoxMPFillModesTable(pExt, VidPnTargetId, pModes->aModes, RT_ELEMENTS(pModes->aModes), &pModes->iPreferredMode); Assert(pModes->cModes<=RT_ELEMENTS(pModes->aModes)); /* Check if there's a pending display change request for this adapter */ VIDEO_MODE_INFORMATION specialMode; if (VBoxMPCheckPendingVideoMode(pExt, &specialMode) && (specialMode.ModeIndex==VidPnTargetId)) { /*Minor hack, ModeIndex!=0 Means this mode has been validated already and not just read from registry */ specialMode.ModeIndex = 1; memcpy(&g_CustomVideoModes[VidPnTargetId], &specialMode, sizeof(VIDEO_MODE_INFORMATION)); /* Save mode to registry */ VBoxMPRegSaveModeInfo(pExt, VidPnTargetId, &specialMode); } /* Validate the mode which has been read from registry */ if (!g_CustomVideoModes[VidPnTargetId].ModeIndex) { uint32_t xres, yres, bpp; xres = g_CustomVideoModes[VidPnTargetId].VisScreenWidth; yres = g_CustomVideoModes[VidPnTargetId].VisScreenHeight; bpp = g_CustomVideoModes[VidPnTargetId].BitsPerPlane; if (VBoxMPValidateVideoModeParams(pExt, VidPnTargetId, xres, yres, bpp)) { VBoxFillVidModeInfo(&g_CustomVideoModes[VidPnTargetId], xres, yres, bpp, 1/*index*/, 0); Assert(g_CustomVideoModes[VidPnTargetId].ModeIndex == 1); } } /* Add custom mode to the table */ if (g_CustomVideoModes[VidPnTargetId].ModeIndex) { if (RT_ELEMENTS(pModes->aModes) > pModes->cModes) { g_CustomVideoModes[VidPnTargetId].ModeIndex = pModes->cModes; pModes->aModes[pModes->cModes] = g_CustomVideoModes[VidPnTargetId]; /* Check if we already have this mode in the table */ int foundIdx; if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]))>=0) { pModes->iPreferredMode = foundIdx; } else { pModes->iPreferredMode = pModes->cModes; ++pModes->cModes; } /* Add other bpp modes for this custom resolution */ #ifdef VBOX_WITH_8BPP_MODES UINT bpp=8; #else UINT bpp=16; #endif for (; bpp<=32; bpp+=8) { if (RT_ELEMENTS(pModes->aModes) == pModes->cModes) { WARN(("table full, can't add other bpp for specail mode!")); #ifdef DEBUG_misha /* this is definitely something we do not expect */ AssertFailed(); #endif break; } AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */ if (pModes->aModes[pModes->iPreferredMode].BitsPerPlane == bpp) continue; if (!VBoxMPValidateVideoModeParamsGuest(pExt, VidPnTargetId, pModes->aModes[pModes->iPreferredMode].VisScreenWidth, pModes->aModes[pModes->iPreferredMode].VisScreenHeight, bpp)) continue; VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes], pModes->aModes[pModes->iPreferredMode].VisScreenWidth, pModes->aModes[pModes->iPreferredMode].VisScreenHeight, bpp, pModes->cModes, 0); if (VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]) < 0) { ++pModes->cModes; } } } else { AssertRelease(RT_ELEMENTS(pModes->aModes) == pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */ WARN(("table full, can't add video mode for a host request!")); #ifdef DEBUG_misha /* this is definitely something we do not expect */ AssertFailed(); #endif } } /* Check and Add additional modes passed in paAddlModes */ for (UINT i=0; i<cAddlModes; ++i) { if (RT_ELEMENTS(pModes->aModes) == pModes->cModes) { WARN(("table full, can't add addl modes!")); #ifdef DEBUG_misha /* this is definitely something we do not expect */ AssertFailed(); #endif break; } AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */ if (!pExt->fAnyX) { paAddlModes[i].VisScreenWidth &= 0xFFF8; } if (VBoxLikesVideoMode(VidPnTargetId, paAddlModes[i].VisScreenWidth, paAddlModes[i].VisScreenHeight, paAddlModes[i].BitsPerPlane)) { int foundIdx; if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &paAddlModes[i]))>=0) { pModes->iPreferredMode = foundIdx; } else { memcpy(&pModes->aModes[pModes->cModes], &paAddlModes[i], sizeof(VIDEO_MODE_INFORMATION)); pModes->aModes[pModes->cModes].ModeIndex = pModes->cModes; ++pModes->cModes; } } } /* Build resolution table */ VBoxWddmBuildResolutionTableForModes(pModes); }