VirtualBox

Ignore:
Timestamp:
Sep 13, 2010 11:37:11 AM (14 years ago)
Author:
vboxsync
Message:

wddm/3d: multi-swapchain fixes

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp

    r32425 r32444  
    1313 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1414 */
     15#define INITGUID
     16
    1517#include <iprt/initterm.h>
    1618#include <iprt/log.h>
     
    870872        for (UINT i = 0; i < cAllocs; ++i)
    871873        {
     874            pRc->aAllocations[i].iAlloc = i;
    872875            pRc->aAllocations[i].pRc = pRc;
    873876        }
     
    13291332}
    13301333
     1334/* on success increments the surface ref counter,
     1335 * i.e. one must call pSurf->Release() once the surface is not needed*/
     1336static HRESULT vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
     1337{
     1338    HRESULT hr = S_OK;
     1339    Assert(pRc->cAllocations > iAlloc);
     1340    switch (pRc->aAllocations[0].enmD3DIfType)
     1341    {
     1342        case VBOXDISP_D3DIFTYPE_SURFACE:
     1343        {
     1344            IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
     1345            Assert(pD3DIfSurf);
     1346            pD3DIfSurf->AddRef();
     1347            *ppSurf = pD3DIfSurf;
     1348            break;
     1349        }
     1350        case VBOXDISP_D3DIFTYPE_TEXTURE:
     1351        {
     1352            Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
     1353                                             * in this case, if texture is used as a destination,
     1354                                             * we should update sub-layers as well which is not done currently
     1355                                             * so for now check vboxWddmSurfGet is used for one-level textures */
     1356            IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
     1357            IDirect3DSurface9 *pSurfaceLevel;
     1358            Assert(pD3DIfTex);
     1359            hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
     1360            Assert(hr == S_OK);
     1361            if (hr == S_OK)
     1362            {
     1363                *ppSurf = pSurfaceLevel;
     1364            }
     1365            break;
     1366        }
     1367        default:
     1368            Assert(0);
     1369            hr = E_FAIL;
     1370            break;
     1371    }
     1372    return hr;
     1373}
    13311374
    13321375/******/
     1376static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch);
     1377
    13331378DECLINLINE(VOID) vboxWddmSwapchainInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
    13341379{
     
    17111756}
    17121757
    1713 static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb, BOOL bSynchContents)
     1758static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
    17141759{
    17151760    IDirect3DSurface9 *pD3D9Surf;
     
    17251770        if (pAlloc->pD3DIf)
    17261771        {
    1727             if (bSynchContents)
     1772            if (pSwapchain->fFlags.bChanged)
    17281773            {
    17291774                IDirect3DSurface9 *pD3D9OldSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
    1730                 hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE);
    1731                 Assert(hr == S_OK);
     1775                if (pD3D9OldSurf)
     1776                {
     1777                    VOID *pvSwapchain = NULL;
     1778                    HRESULT tmpHr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
     1779                    if (tmpHr != S_OK || pvSwapchain != ((IDirect3DSwapChain9 *)pSwapchain->pSwapChainIf))
     1780                    {
     1781                        hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE);
     1782                        Assert(hr == S_OK);
     1783                    }
     1784                }
    17321785            }
    17331786            pAlloc->pD3DIf->Release();
     
    17351788        pAlloc->pD3DIf = pD3D9Surf;
    17361789        pRt->fFlags.Value = 0;
     1790
     1791        if (pSwapchain->fFlags.bChanged)
     1792        {
     1793            for (UINT i = 0; i < pDevice->cRTs; ++i)
     1794            {
     1795                if (pDevice->apRTs[i] == pAlloc)
     1796                {
     1797                    hr = vboxWddmRenderTargetSet(pDevice, i, pAlloc, TRUE);
     1798                    Assert(hr == S_OK);
     1799                }
     1800            }
     1801        }
    17371802    }
    17381803    return hr;
     
    17401805static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
    17411806{
    1742     BOOL bSynchContents = pSwapchain->fFlags.bChanged && pSwapchain->fFlags.bInited;
    17431807    for (int iBb = -1; iBb < int(pSwapchain->cRTs - 1); ++iBb)
    17441808    {
    1745         HRESULT hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb, bSynchContents);
     1809        HRESULT hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb);
    17461810        Assert(hr == S_OK);
    17471811    }
    17481812    pSwapchain->fFlags.bChanged = 0;
    1749     pSwapchain->fFlags.bInited = 1;
    17501813    return S_OK;
    17511814}
     
    18831946                    if (hr == S_OK)
    18841947                    {
    1885                         Assert(pSwapchain->fFlags.Value == 2); /* bInited */
     1948                        Assert(pSwapchain->fFlags.Value == 0);
    18861949                        if (pOldIf)
    18871950                        {
     
    19372000    {
    19382001        vboxWddmSwapchainFlip(pSwapchain);
    1939         Assert(pSwapchain->fFlags.Value == 2); /* bInited */
     2002        Assert(pSwapchain->fFlags.Value == 0);
    19402003        hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
    19412004        Assert(hr == S_OK);
     
    23112374#endif
    23122375/******/
     2376
     2377static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch)
     2378{
     2379    IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
     2380    PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
     2381    if (pSwapchain)
     2382    {
     2383        /* backbuffer */
     2384        Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
     2385    }
     2386
     2387    HRESULT hr = S_OK;
     2388    IDirect3DSurface9 *pD3D9Surf;
     2389    if (pSwapchain && vboxWddmSwapchainNumRTs(pSwapchain) == 1 && iRt == 0)
     2390    {
     2391        /* work-around wine double-buffering for the case we have no backbuffers */
     2392        Assert((!pSwapchain->fFlags.bChanged || bOnSwapchainSynch) && pSwapchain->pSwapChainIf);
     2393        if (!bOnSwapchainSynch)
     2394        {
     2395            vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
     2396        }
     2397        hr = pSwapchain->pSwapChainIf->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
     2398        Assert(hr == S_OK);
     2399        Assert(pD3D9Surf);
     2400    }
     2401    else
     2402    {
     2403        hr = vboxWddmSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
     2404        Assert(hr == S_OK);
     2405        Assert(pD3D9Surf);
     2406    }
     2407
     2408    if (hr == S_OK)
     2409    {
     2410        Assert(pD3D9Surf);
     2411        hr = pDevice9If->SetRenderTarget(iRt, pD3D9Surf);
     2412        Assert(hr == S_OK);
     2413        if (hr == S_OK)
     2414        {
     2415            Assert(iRt < pDevice->cRTs);
     2416            pDevice->apRTs[iRt] = pAlloc;
     2417        }
     2418        pD3D9Surf->Release();
     2419    }
     2420
     2421    return hr;
     2422}
    23132423
    23142424
     
    42864396            pAllocation->hAllocation = NULL;
    42874397            pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
     4398            pAllocation->iAlloc = i;
    42884399            pAllocation->pRc = pRc;
    42894400            pAllocation->pvMem = (void*)pSurf->pSysMem;
     
    54055516}
    54065517
    5407 /* on success increments the surface ref counter,
    5408  * i.e. one must call pSurf->Release() once the surface is not needed*/
    5409 static HRESULT vboxWddmSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, IDirect3DSurface9 **ppSurf)
    5410 {
    5411     HRESULT hr = S_OK;
    5412     Assert(pRc->cAllocations > iAlloc);
    5413     switch (pRc->aAllocations[0].enmD3DIfType)
    5414     {
    5415         case VBOXDISP_D3DIFTYPE_SURFACE:
    5416         {
    5417             IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
    5418             Assert(pD3DIfSurf);
    5419             pD3DIfSurf->AddRef();
    5420             *ppSurf = pD3DIfSurf;
    5421             break;
    5422         }
    5423         case VBOXDISP_D3DIFTYPE_TEXTURE:
    5424         {
    5425             Assert(pRc->cAllocations == 1); /* <- vboxWddmSurfGet is typically used in Blt & ColorFill functions
    5426                                              * in this case, if texture is used as a destination,
    5427                                              * we should update sub-layers as well which is not done currently
    5428                                              * so for now check vboxWddmSurfGet is used for one-level textures */
    5429             IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
    5430             IDirect3DSurface9 *pSurfaceLevel;
    5431             Assert(pD3DIfTex);
    5432             hr = pD3DIfTex->GetSurfaceLevel(iAlloc, &pSurfaceLevel);
    5433             Assert(hr == S_OK);
    5434             if (hr == S_OK)
    5435             {
    5436                 *ppSurf = pSurfaceLevel;
    5437             }
    5438             break;
    5439         }
    5440         default:
    5441             Assert(0);
    5442             hr = E_FAIL;
    5443             break;
    5444     }
    5445     return hr;
    5446 }
    5447 
    54485518static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
    54495519{
     
    57795849    PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
    57805850    Assert(pDevice);
    5781 //    PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
    57825851    IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
    57835852    PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
     
    57855854    Assert(pData->SubResourceIndex < pRc->cAllocations);
    57865855    PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
    5787     PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
    5788 //    PVBOXWDDMDISP_SCREEN pVisibleScreen = pRc->RcDesc.fFlags.Primary ? &pDevice->aScreens[pRc->RcDesc.VidPnSourceId] : pScreen;
    5789     if (pSwapchain)
    5790     {
    5791         /* backbuffer */
    5792         Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc);
    5793     }
    5794 
    5795     HRESULT hr = S_OK;
    5796     IDirect3DSurface9 *pD3D9Surf;
    5797     if (pSwapchain && vboxWddmSwapchainNumRTs(pSwapchain) == 1 && pData->RenderTargetIndex == 0)
    5798     {
    5799         /* work-around wine double-buffering for the case we have no backbuffers */
    5800         hr = pDevice9If->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
    5801         Assert(hr == S_OK);
    5802         Assert(pD3D9Surf);
    5803     }
    5804     else
    5805     {
    5806         hr = vboxWddmSurfGet(pRc, pData->SubResourceIndex, &pD3D9Surf);
    5807         Assert(hr == S_OK);
    5808         Assert(pD3D9Surf);
    5809     }
    5810     if (hr == S_OK)
    5811     {
    5812         Assert(pD3D9Surf);
    5813         hr = pDevice9If->SetRenderTarget(pData->RenderTargetIndex, pD3D9Surf);
    5814         Assert(hr == S_OK);
    5815         pD3D9Surf->Release();
    5816     }
     5856    HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
     5857    Assert(hr == S_OK);
    58175858    vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
    58185859    return hr;
     
    64306471
    64316472//    Assert(0);
    6432 
    6433     PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(sizeof (VBOXWDDMDISP_DEVICE));
     6473    PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
     6474
     6475    PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->cMaxSimRTs]));
    64346476    if (pDevice)
    64356477    {
    6436         PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
    6437 
     6478        pDevice->cRTs = pAdapter->cMaxSimRTs;
    64386479        pDevice->hDevice = pCreateData->hDevice;
    64396480        pDevice->pAdapter = pAdapter;
     
    66106651                    }
    66116652#else
     6653//# define VBOXDISP_TEST_SWAPCHAIN
     6654# ifdef VBOXDISP_TEST_SWAPCHAIN
     6655                    VBOXDISP_D3DEV(pDevice);
     6656# endif
    66126657                    break;
    66136658#endif
     
    67416786                    if (hr == S_OK)
    67426787                    {
    6743                         hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
     6788                        D3DCAPS9 Caps;
     6789                        memset(&Caps, 0, sizeof (Caps));
     6790                        hr = vboxWddmGetD3D9Caps(pAdapter, &Caps);
    67446791                        Assert(hr == S_OK);
    67456792                        if (hr == S_OK)
    67466793                        {
    6747                             vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
    6748                             break;
     6794                            pAdapter->cMaxSimRTs = Caps.NumSimultaneousRTs;
     6795                            Assert(pAdapter->cMaxSimRTs);
     6796                            Assert(pAdapter->cMaxSimRTs < UINT32_MAX/2);
     6797                            hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
     6798                            Assert(hr == S_OK);
     6799                            if (hr == S_OK)
     6800                            {
     6801                                vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
     6802                                break;
     6803                            }
    67496804                        }
    67506805                        pAdapter->pD3D9If->Release();
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h

    r32425 r32444  
    5454    uint32_t cSurfDescs;
    5555    DDSURFACEDESC *paSurfDescs;
     56    UINT cMaxSimRTs;
    5657#ifdef VBOX_WITH_VIDEOHWACCEL
    5758    uint32_t cHeads;
     
    121122        {
    122123            UINT bChanged : 1;
    123             UINT bInited  : 1;
    124             UINT Reserved : 30;
     124            UINT Reserved : 31;
    125125        };
    126126        uint32_t Value;
     
    167167    UINT cStreamSources;
    168168    VBOXWDDMDISP_STREAMSOURCEUM aStreamSourceUm[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
    169     VBOXWDDMDISP_ALLOCATION *aStreamSource[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
     169    struct VBOXWDDMDISP_ALLOCATION *aStreamSource[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
    170170    VBOXWDDMDISP_STREAM_SOURCE_INFO StreamSourceInfo[VBOXWDDMDISP_MAX_VERTEX_STREAMS];
    171171    VBOXWDDMDISP_INDICIESUM IndiciesUm;
    172     VBOXWDDMDISP_ALLOCATION *pIndicesAlloc;
     172    struct VBOXWDDMDISP_ALLOCATION *pIndicesAlloc;
    173173    VBOXWDDMDISP_INDICES_INFO IndiciesInfo;
    174174    /* need to cache the ViewPort data because IDirect3DDevice9::SetViewport
     
    179179    CRITICAL_SECTION DirtyAllocListLock;
    180180    RTLISTNODE DirtyAllocList;
     181    UINT cRTs;
     182    struct VBOXWDDMDISP_ALLOCATION * apRTs[1];
    181183} VBOXWDDMDISP_DEVICE, *PVBOXWDDMDISP_DEVICE;
    182184
     
    206208    D3DKMT_HANDLE hAllocation;
    207209    VBOXWDDM_ALLOC_TYPE enmType;
     210    UINT iAlloc;
    208211    struct VBOXWDDMDISP_RESOURCE *pRc;
    209212    void* pvMem;
Note: See TracChangeset for help on using the changeset viewer.

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