VirtualBox

Changeset 40716 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
Mar 29, 2012 5:14:19 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
77175
Message:

wddm/display: fix 3d-off rendering, miniport changes still pending; more correct ddraw detection

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk

    r40483 r40716  
    121121VBoxDispD3D_LIBS     = \
    122122        $(VBOX_LIB_IPRT_GUEST_R3) \
    123         $(VBOX_LIB_VBGL_R3)
     123        $(VBOX_LIB_VBGL_R3) \
     124        Psapi.lib
    124125
    125126#
     
    131132VBoxDispD3D-x86_LIBS = \
    132133        $(VBOX_LIB_IPRT_GUEST_R3_X86) \
    133         $(VBOX_LIB_VBGL_R3_X86)
     134        $(VBOX_LIB_VBGL_R3_X86) \
     135        Psapi.lib
    134136VBoxDispD3D-x86_DEFS = $(VBoxDispD3D_DEFS) VBOX_WDDM_WOW64
    135137
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp

    r40388 r40716  
    3131#include "VBoxScreen.h"
    3232#include <VBox/VBoxCrHgsmi.h>
     33
     34#include <Psapi.h>
    3335
    3436#ifdef VBOX_WDDMDISP_WITH_PROFILE
     
    11891191    pAdapter->paSurfDescs = NULL;
    11901192
    1191     if (pAdapter->uIfVersion > 7)
    1192     {
    1193         if (pAdapter->pD3D9If)
    1194         {
    1195             pAdapter->paFormstOps = (FORMATOP*)RTMemAllocZ(sizeof (gVBoxFormatOps3D));
    1196             Assert(pAdapter->paFormstOps);
    1197             if (pAdapter->paFormstOps)
    1198             {
    1199                 memcpy (pAdapter->paFormstOps , gVBoxFormatOps3D, sizeof (gVBoxFormatOps3D));
    1200                 pAdapter->cFormstOps = RT_ELEMENTS(gVBoxFormatOps3D);
    1201             }
    1202             else
    1203                 return VERR_OUT_OF_RESOURCES;
    1204 
    1205             /* @todo: do we need surface caps here ? */
    1206         }
     1193    if (VBOXDISPMODE_IS_3D(pAdapter))
     1194    {
     1195        pAdapter->paFormstOps = (FORMATOP*)RTMemAllocZ(sizeof (gVBoxFormatOps3D));
     1196        Assert(pAdapter->paFormstOps);
     1197        if (pAdapter->paFormstOps)
     1198        {
     1199            memcpy (pAdapter->paFormstOps , gVBoxFormatOps3D, sizeof (gVBoxFormatOps3D));
     1200            pAdapter->cFormstOps = RT_ELEMENTS(gVBoxFormatOps3D);
     1201        }
     1202        else
     1203            return VERR_OUT_OF_RESOURCES;
    12071204    }
    12081205#ifdef VBOX_WITH_VIDEOHWACCEL
     
    32193216                memset(pData->pData, 0, sizeof (DDRAW_CAPS));
    32203217#ifdef VBOX_WITH_VIDEOHWACCEL
    3221                 if (vboxVhwaHasCKeying(pAdapter))
    3222                 {
    3223                     DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
    3224                     pCaps->Caps |= DDRAW_CAPS_COLORKEY;
    3225 //                    pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
     3218                if (!VBOXDISPMODE_IS_3D(pAdapter))
     3219                {
     3220                    if (vboxVhwaHasCKeying(pAdapter))
     3221                    {
     3222                        DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
     3223                        pCaps->Caps |= DDRAW_CAPS_COLORKEY;
     3224    //                    pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
     3225                    }
     3226                }
     3227                else
     3228                {
     3229                    WARN(("D3DDDICAPS_DDRAW query for D3D mode!"));
    32263230                }
    32273231#endif
     
    32423246                        0, sizeof (DDRAW_MODE_SPECIFIC_CAPS) - RT_OFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
    32433247#ifdef VBOX_WITH_VIDEOHWACCEL
    3244                 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
    3245                 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
    3246                 {
    3247                     pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
    3248 
    3249                     if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
     3248                if (!VBOXDISPMODE_IS_3D(pAdapter))
     3249                {
     3250                    VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
     3251                    if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
    32503252                    {
    3251                         pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
    3252                                 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
    3253                                 ;
     3253                        pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
     3254
     3255                        if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
     3256                        {
     3257                            pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
     3258                                    | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
     3259                                    ;
     3260                        }
     3261
     3262                        if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
     3263                        {
     3264                            pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
     3265                                    | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
     3266                                    | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
     3267                                    | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
     3268                                    ;
     3269                        }
     3270
     3271                        pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
     3272                                | MODE_FXCAPS_OVERLAYSHRINKY
     3273                                | MODE_FXCAPS_OVERLAYSTRETCHX
     3274                                | MODE_FXCAPS_OVERLAYSTRETCHY;
     3275
     3276
     3277                        pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
     3278                        pCaps->MinOverlayStretch = 1;
     3279                        pCaps->MaxOverlayStretch = 32000;
    32543280                    }
    3255 
    3256                     if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
    3257                     {
    3258                         pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
    3259                                 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
    3260                                 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
    3261                                 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
    3262                                 ;
    3263                     }
    3264 
    3265                     pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
    3266                             | MODE_FXCAPS_OVERLAYSHRINKY
    3267                             | MODE_FXCAPS_OVERLAYSTRETCHX
    3268                             | MODE_FXCAPS_OVERLAYSTRETCHY;
    3269 
    3270 
    3271                     pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
    3272                     pCaps->MinOverlayStretch = 1;
    3273                     pCaps->MaxOverlayStretch = 32000;
     3281                }
     3282                else
     3283                {
     3284                    WARN(("D3DDDICAPS_DDRAW_MODE_SPECIFIC query for D3D mode!"));
    32743285                }
    32753286#endif
     
    47244735    else /* if !VBOXDISPMODE_IS_3D(pDevice->pAdapter) */
    47254736    {
    4726 #ifdef DEBUG_misha
    4727         Assert(0);
    4728 #endif
    47294737        PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
    4730         D3DDDICB_LOCK LockData;
    4731         LockData.hAllocation = pAlloc->hAllocation;
    4732         LockData.PrivateDriverData = 0;
    4733         LockData.NumPages = 0;
    4734         LockData.pPages = NULL;
    4735         LockData.pData = NULL; /* out */
    4736         LockData.Flags.Value = 0;
    4737         LockData.Flags.Discard = pData->Flags.Discard;
    4738         LockData.Flags.DonotWait = pData->Flags.DoNotWait;
    4739 
    4740 
    4741         hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
    4742         Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
    4743         if (hr == S_OK)
    4744         {
    4745             Assert(!pAlloc->LockInfo.cLocks);
    4746 
    4747             uintptr_t offset;
    4748             if (pData->Flags.AreaValid)
    4749             {
    4750                 offset = vboxWddmCalcOffXYrd(pData->Area.left, pData->Area.top, pAlloc->SurfDesc.pitch, pAlloc->SurfDesc.format);
    4751             }
    4752             else if (pData->Flags.RangeValid)
    4753             {
    4754                 offset = pData->Range.Offset;
    4755             }
    4756             else if (pData->Flags.BoxValid)
    4757             {
    4758                 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
    4759                 Assert(0);
    4760             }
    4761             else
    4762             {
    4763                 offset = 0;
    4764             }
    4765 
    4766             if (!pData->Flags.ReadOnly)
    4767             {
     4738        if (pAlloc->hAllocation)
     4739        {
     4740            if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
     4741            {
     4742                D3DDDICB_LOCK LockData;
     4743                LockData.hAllocation = pAlloc->hAllocation;
     4744                LockData.PrivateDriverData = 0;
     4745                LockData.NumPages = 0;
     4746                LockData.pPages = NULL;
     4747                LockData.pData = NULL; /* out */
     4748                LockData.Flags.Value = 0;
     4749                LockData.Flags.Discard = pData->Flags.Discard;
     4750                LockData.Flags.DonotWait = pData->Flags.DoNotWait;
     4751
     4752                uintptr_t offset;
    47684753                if (pData->Flags.AreaValid)
    4769                     vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
     4754                {
     4755                    offset = vboxWddmCalcOffXYrd(pData->Area.left, pData->Area.top, pAlloc->SurfDesc.pitch, pAlloc->SurfDesc.format);
     4756                }
     4757                else if (pData->Flags.RangeValid)
     4758                {
     4759                    offset = pData->Range.Offset;
     4760                }
     4761                else if (pData->Flags.BoxValid)
     4762                {
     4763                    vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
     4764                    Assert(0);
     4765                }
    47704766                else
    47714767                {
    4772                     Assert(!pData->Flags.RangeValid);
    4773                     Assert(!pData->Flags.BoxValid);
    4774                     vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
    4775                 }
    4776             }
    4777 
    4778             if (pData->Flags.Discard)
    4779             {
    4780                 /* check if the surface was renamed */
    4781                 if (LockData.hAllocation)
    4782                     pAlloc->hAllocation = LockData.hAllocation;
    4783             }
    4784 
    4785             pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
    4786             pData->Pitch = pAlloc->SurfDesc.pitch;
    4787             pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
    4788 
    4789             Assert(hr == S_OK);
    4790             ++pAlloc->LockInfo.cLocks;
     4768                    offset = 0;
     4769                }
     4770
     4771                hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
     4772                Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
     4773                if (hr == S_OK)
     4774                {
     4775                    pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
     4776                    pData->Pitch = pAlloc->SurfDesc.pitch;
     4777                    pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
     4778
     4779                    if (pData->Flags.Discard)
     4780                    {
     4781                        /* check if the surface was renamed */
     4782                        if (LockData.hAllocation)
     4783                            pAlloc->hAllocation = LockData.hAllocation;
     4784                    }
     4785                }
     4786            }
     4787            /* else - d3d may create sysmem render targets and call our Present callbacks for those
     4788             * to make it work properly we need to create a VRAM surface corresponding to sysmem one
     4789             * and copy stuff to VRAM on lock/unlock
     4790             *
     4791             * so we don't do any locking here, but still track the lock info here
     4792             * and do lock-memcopy-unlock to VRAM surface on sysmem surface unlock
     4793             * */
     4794
     4795            if (hr == S_OK)
     4796            {
     4797                Assert(!pAlloc->LockInfo.cLocks);
     4798
     4799                if (!pData->Flags.ReadOnly)
     4800                {
     4801                    if (pData->Flags.AreaValid)
     4802                        vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
     4803                    else
     4804                    {
     4805                        Assert(!pData->Flags.RangeValid);
     4806                        Assert(!pData->Flags.BoxValid);
     4807                        vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
     4808                    }
     4809                }
     4810
     4811                ++pAlloc->LockInfo.cLocks;
     4812            }
    47914813        }
    47924814    }
     
    47954817    return hr;
    47964818}
     4819
    47974820static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
    47984821{
     
    49484971    else
    49494972    {
    4950         struct
    4951         {
    4952             D3DDDICB_UNLOCK Unlock;
    4953             D3DKMT_HANDLE hAllocation;
    4954         } UnlockData;
    4955 
    49564973        PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
    49574974
    4958         UnlockData.Unlock.NumAllocations = 1;
    4959         UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
    4960         UnlockData.hAllocation = pAlloc->hAllocation;
    4961 
    4962         hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
    4963         Assert(hr == S_OK);
    4964         if (hr == S_OK)
    4965         {
     4975        if (pAlloc->hAllocation)
     4976        {
     4977            BOOL fDoUnlock = FALSE;
     4978
    49664979            Assert(pAlloc->LockInfo.cLocks);
    49674980            --pAlloc->LockInfo.cLocks;
    49684981            Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
     4982
     4983            if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
     4984            {
     4985                fDoUnlock = TRUE;
     4986            }
     4987            else
     4988            {
     4989                if (!pAlloc->LockInfo.cLocks)
     4990                {
     4991                    D3DDDICB_LOCK LockData;
     4992                    LockData.hAllocation = pAlloc->hAllocation;
     4993                    LockData.PrivateDriverData = 0;
     4994                    LockData.NumPages = 0;
     4995                    LockData.pPages = NULL;
     4996                    LockData.pData = NULL; /* out */
     4997                    LockData.Flags.Value = 0;
     4998
     4999                    hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
     5000                    if (hr == S_OK)
     5001                    {
     5002                        D3DLOCKED_RECT LRect;
     5003                        LRect.pBits = LockData.pData;
     5004                        LRect.Pitch = ((pAlloc->SurfDesc.bpp * pAlloc->SurfDesc.width) + 7) >> 3;
     5005                        Assert(pAlloc->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID);
     5006                        vboxWddmLockUnlockMemSynch(pAlloc, &LRect, &pAlloc->DirtyRegion.Rect, TRUE /* bool bToLockInfo*/);
     5007                        vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
     5008                        fDoUnlock = TRUE;
     5009                    }
     5010                    else
     5011                    {
     5012                        WARN(("pfnLockCb failed, hr 0x%x", hr));
     5013                    }
     5014                }
     5015            }
     5016
     5017            if (fDoUnlock)
     5018            {
     5019                struct
     5020                {
     5021                    D3DDDICB_UNLOCK Unlock;
     5022                    D3DKMT_HANDLE hAllocation;
     5023                } UnlockData;
     5024
     5025
     5026                UnlockData.Unlock.NumAllocations = 1;
     5027                UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
     5028                UnlockData.hAllocation = pAlloc->hAllocation;
     5029
     5030                hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
     5031                if(hr != S_OK)
     5032                {
     5033                    WARN(("pfnUnlockCb failed, hr 0x%x", hr));
     5034                }
     5035            }
     5036
     5037            if (!SUCCEEDED(hr))
     5038            {
     5039                WARN(("unlock failure!"));
     5040                ++pAlloc->LockInfo.cLocks;
     5041            }
    49695042        }
    49705043    }
     
    54935566    else
    54945567    {
    5495         bIssueCreateResource = true;
    5496         bCreateKMResource = true;
     5568        bIssueCreateResource = (pResource->Pool != D3DDDIPOOL_SYSTEMMEM) || pResource->Flags.RenderTarget;
     5569        bCreateKMResource = bIssueCreateResource;
    54975570    }
    54985571
     
    57255798    }
    57265799
    5727     Assert(pRc->hKMResource || VBOXDISPMODE_IS_3D(pAdapter));
    57285800    if (pRc->fFlags.KmResource)
    57295801    {
     
    74197491}
    74207492
     7493#define VBOXDISP_IS_MODULE_FUNC(_pvModule, _cbModule, _pfn) ( \
     7494           (((uintptr_t)(_pfn)) >= ((uintptr_t)(_pvModule))) \
     7495        && (((uintptr_t)(_pfn)) < (((uintptr_t)(_pvModule)) + ((DWORD)(_cbModule)))) \
     7496        )
     7497
     7498static BOOL vboxDispIsDDraw(__inout D3DDDIARG_OPENADAPTER*  pOpenData)
     7499{
     7500    /*if we are loaded by ddraw module, the Interface version should be 7
     7501     * and pAdapterCallbacks should be ddraw-supplied, i.e. reside in ddraw module */
     7502    if (pOpenData->Interface != 7)
     7503        return FALSE;
     7504
     7505    HMODULE hDDraw = GetModuleHandleA("ddraw.dll");
     7506    if (!hDDraw)
     7507        return FALSE;
     7508
     7509    HANDLE hProcess = GetCurrentProcess();
     7510    MODULEINFO ModuleInfo = {0};
     7511
     7512    if (!GetModuleInformation(hProcess, hDDraw, &ModuleInfo, sizeof (ModuleInfo)))
     7513    {
     7514        DWORD winEr = GetLastError();
     7515        WARN(("GetModuleInformation failed, %d", winEr));
     7516        return FALSE;
     7517    }
     7518
     7519    if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage, pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb))
     7520        return TRUE;
     7521    if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage, pOpenData->pAdapterCallbacks->pfnGetMultisampleMethodListCb))
     7522        return TRUE;
     7523
     7524    return FALSE;
     7525}
     7526
    74217527HRESULT APIENTRY OpenAdapter(__inout D3DDDIARG_OPENADAPTER*  pOpenData)
    74227528{
     
    74947600        pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
    74957601        pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
    7496         /*
    7497          * here we detect whether we are called by the d3d or ddraw.
    7498          * in the d3d case we init our d3d environment
    7499          * in the ddraw case we init 2D acceleration
    7500          * if interface version is > 7, this is D3D, treat it as so
    7501          * otherwise treat it as ddraw
    7502          * @todo: need a more clean way of doing this */
    7503 
    7504         if (pAdapter->uIfVersion > 7)
     7602        if (!vboxDispIsDDraw(pOpenData))
    75057603        {
    75067604            do
     
    75507648        }
    75517649#ifdef VBOX_WITH_VIDEOHWACCEL
    7552         else
     7650        if (!VBOXDISPMODE_IS_3D(pAdapter))
    75537651        {
    75547652            for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette