コード例 #1
0
ファイル: VBoxMPVidModes.cpp プロジェクト: bayasist/vbox
DECLINLINE(uint32_t) VBoxMPAdjustBpp(uint32_t bpp)
{
    if (VBoxMPIsSupportedBpp(bpp))
        return bpp;
    Assert(g_aVBoxVidModesSupportedBpps[0] == 32);
    return g_aVBoxVidModesSupportedBpps[0];
}
コード例 #2
0
ファイル: VBoxMPVidModes.cpp プロジェクト: ryenus/vbox
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);
}