diff options
Diffstat (limited to 'src/VBox/Additions/WINNT/Graphics/Video/disp')
40 files changed, 2120 insertions, 1005 deletions
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk index 53a32b0a..e11768aa 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk @@ -104,6 +104,9 @@ endif ifdef VBOX_WITH_CROGL VBoxDispD3D_DEFS += VBOX_WITH_CROGL endif +ifdef VBOX_WITH_NEW_WINE + VBoxDispD3D_DEFS += VBOX_WITH_NEW_WINE +endif VBoxDispD3D_INCS = \ ../../../include \ .. \ @@ -112,9 +115,7 @@ VBoxDispD3D_SOURCES = \ wddm/VBoxDispD3D.cpp \ wddm/VBoxDispD3DIf.cpp \ wddm/VBoxDispCm.cpp \ - wddm/VBoxDispMp.cpp \ wddm/VBoxScreen.cpp \ - wddm/VBoxDispMpTst.cpp \ wddm/VBoxDispKmt.cpp \ wddm/VBoxDispDbg.cpp \ wddm/VBoxD3DIf.cpp \ @@ -208,7 +209,7 @@ tstMvWnd_TEMPLATE = VBOXR3EXE tstMvWnd_DEFS = UNICODE _UNICODE tstMvWnd_SOURCES = \ wddm/dbg/tstMvWnd.cpp -tstMvWnd_LIBS = $(LIB_RUNTIME) +tstMvWnd_LIBS = $(VBOX_LIB_IPRT_GUEST_R3) tstMvWnd_LDFLAGS.win = /SUBSYSTEM:windows PROGRAMS += DumpD3DCaps9 @@ -217,7 +218,7 @@ DumpD3DCaps9_SDKS = ReorderCompilerIncs $(VBOX_WINDDK_GST_WLH) DumpD3DCaps9_DEFS = UNICODE _UNICODE DumpD3DCaps9_SOURCES = \ wddm/dbg/DumpD3DCaps9.cpp -DumpD3DCaps9_LIBS = $(LIB_RUNTIME) +DumpD3DCaps9_LIBS = $(VBOX_LIB_IPRT_GUEST_R3) d3d9.lib DumpD3DCaps9_LDFLAGS.win = /SUBSYSTEM:CONSOLE endif #VBOXVIDEOWINDBG diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp index f6aadbf0..e86375f7 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -61,11 +61,7 @@ VBOXCRHGSMI_DECL(PVBOXUHGSMI) VBoxCrHgsmiCreate() PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = (PVBOXUHGSMI_PRIVATE_KMT)RTMemAllocZ(sizeof (*pHgsmiGL)); if (pHgsmiGL) { -#if 0 HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/); -#else - HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/); -#endif Log(("CrHgsmi: faled to create KmtEsc VBOXUHGSMI instance, hr (0x%x)\n", hr)); if (hr == S_OK) { diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp index d8e0bf67..bf8d2259 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp @@ -482,7 +482,7 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc) else { hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateCubeTexture((IDirect3DDevice9Ex *)pDevice9If, - pAllocation->D3DWidth, + pAllocation->SurfDesc.d3dWidth, VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc), vboxDDI2D3DUsage(pRc->RcDesc.fFlags), vboxDDI2D3DFormat(pRc->RcDesc.enmFormat), @@ -502,7 +502,7 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc) else if (pRc->RcDesc.fFlags.Volume) { hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateVolumeTexture((IDirect3DDevice9Ex *)pDevice9If, - pAllocation->D3DWidth, + pAllocation->SurfDesc.d3dWidth, pAllocation->SurfDesc.height, pAllocation->SurfDesc.depth, pRc->cAllocations, @@ -523,7 +523,7 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc) else { hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If, - pAllocation->D3DWidth, + pAllocation->SurfDesc.d3dWidth, pAllocation->SurfDesc.height, pRc->cAllocations, vboxDDI2D3DUsage(pRc->RcDesc.fFlags), @@ -570,28 +570,26 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc) PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; HANDLE hSharedHandle = pAllocation->hSharedHandle; IDirect3DSurface9* pD3D9Surf; - switch (pAllocation->enmType) + if ((pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT) || pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC) { - case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC: - { - hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width, - pAllocation->SurfDesc.height, - vboxDDI2D3DFormat(pRc->RcDesc.enmFormat), - vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType), - pRc->RcDesc.MultisampleQuality, - !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */, - &pD3D9Surf, + hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width, + pAllocation->SurfDesc.height, + vboxDDI2D3DFormat(pRc->RcDesc.enmFormat), + vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType), + pRc->RcDesc.MultisampleQuality, + !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */, + &pD3D9Surf, #ifdef VBOXWDDMDISP_DEBUG_NOSHARED - NULL + NULL #else - pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL + pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL #endif - ); - Assert(hr == S_OK); - break; - } - case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE: - { + ); + Assert(hr == S_OK); + } + else if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE) + { + do { BOOL bNeedPresent; if (pRc->cAllocations != 1) { @@ -622,13 +620,12 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc) Assert(pAllocation->pD3DIf); pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf; break; - } - default: - { - WARN(("unexpected alloc type %d", pAllocation->enmType)); - hr = E_FAIL; - break; - } + } while (0); + } + else + { + WARN(("unexpected alloc type %d", pAllocation->enmType)); + hr = E_FAIL; } if (SUCCEEDED(hr)) @@ -709,7 +706,11 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc) PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; IDirect3DVertexBuffer9 *pD3D9VBuf; hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width, - vboxDDI2D3DUsage(pRc->RcDesc.fFlags), + vboxDDI2D3DUsage(pRc->RcDesc.fFlags) +#ifdef VBOX_WITH_NEW_WINE + & (~D3DUSAGE_DYNAMIC) /* <- avoid using dynamic to ensure wine does not switch do user buffer */ +#endif + , pRc->RcDesc.Fvf, vboxDDI2D3DPool(pRc->RcDesc.enmPool), &pD3D9VBuf, @@ -829,13 +830,156 @@ HRESULT VBoxD3DIfDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice) IDirect3DDevice9 * pDevice9If = NULL; HRESULT hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If); - if (!SUCCEEDED(hr)) + if (SUCCEEDED(hr)) { + int32_t hostId = 0; + hr = pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9GetHostId((IDirect3DDevice9Ex*)pDevice9If, &hostId); + if (SUCCEEDED(hr)) + { + Assert(hostId); + + VBOXDISPIFESCAPE Data; + Data.escapeCode = VBOXESC_SETCTXHOSTID; + Data.u32CmdSpecific = (uint32_t)hostId; + D3DDDICB_ESCAPE DdiEscape = {0}; + DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext; + DdiEscape.hDevice = pDevice->hDevice; + // DdiEscape.Flags.Value = 0; + DdiEscape.pPrivateDriverData = &Data; + DdiEscape.PrivateDriverDataSize = sizeof (Data); + hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape); + if (SUCCEEDED(hr)) + { + pDevice->pDevice9If = pDevice9If; + return S_OK; + } + else + WARN(("pfnEscapeCb VBOXESC_SETCTXHOSTID failed hr 0x%x", hr)); + } + else + WARN(("pfnVBoxWineExD3DDev9GetHostId failed hr 0x%x", hr)); + + pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Term((IDirect3DDevice9Ex *)pDevice9If); + } + else WARN(("CreateDevice failed hr 0x%x", hr)); - return hr; + + return hr; +} + +int vboxD3DIfSetHostId(PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t hostID, uint32_t *pHostID) +{ + struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc; + PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice; + + VBOXDISPIFESCAPE_SETALLOCHOSTID SetHostID = {0}; + SetHostID.EscapeHdr.escapeCode = VBOXESC_SETALLOCHOSTID; + SetHostID.hostID = hostID; + SetHostID.hAlloc = pAlloc->hAllocation; + + D3DDDICB_ESCAPE DdiEscape = {0}; + DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext; + DdiEscape.hDevice = pDevice->hDevice; +// DdiEscape.Flags.Value = 0; + DdiEscape.pPrivateDriverData = &SetHostID; + DdiEscape.PrivateDriverDataSize = sizeof (SetHostID); + HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape); + if (SUCCEEDED(hr)) + { + if (pHostID) + *pHostID = SetHostID.EscapeHdr.u32CmdSpecific; + + return SetHostID.rc; } + else + WARN(("pfnEscapeCb VBOXESC_SETALLOCHOSTID failed hr 0x%x", hr)); - pDevice->pDevice9If = pDevice9If; - return S_OK; + return VERR_GENERAL_FAILURE; } +IUnknown* vboxD3DIfCreateSharedPrimary(PVBOXWDDMDISP_ALLOCATION pAlloc) +{ + IDirect3DSurface9 *pSurfIf; + struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc; + PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice; + + HRESULT hr = VBoxD3DIfCreateForRc(pRc); + if (!SUCCEEDED(hr)) + { + WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr)); + return NULL; + } + + Assert(pAlloc->pD3DIf); + Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE); + Assert(pAlloc->pRc->RcDesc.fFlags.SharedResource); + + hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf); + if (!SUCCEEDED(hr)) + { + WARN(("VBoxD3DIfSurfGet failed hr %#x", hr)); + return NULL; + } + + uint32_t hostID, usedHostId; + hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9GetHostId(pSurfIf, &hostID); + if (SUCCEEDED(hr)) + { + Assert(hostID); + int rc = vboxD3DIfSetHostId(pAlloc, hostID, &usedHostId); + if (!RT_SUCCESS(rc)) + { + if (rc == VERR_NOT_EQUAL) + { + WARN(("another hostId % is in use, using it instead", usedHostId)); + Assert(hostID != usedHostId); + Assert(usedHostId); + pSurfIf->Release(); + pSurfIf = NULL; + for (UINT i = 0; i < pRc->cAllocations; ++i) + { + PVBOXWDDMDISP_ALLOCATION pCurAlloc = &pRc->aAllocations[i]; + if (pCurAlloc->pD3DIf) + { + pCurAlloc->pD3DIf->Release(); + pCurAlloc->pD3DIf = NULL; + } + } + + pAlloc->hSharedHandle = (HANDLE)usedHostId; + + hr = VBoxD3DIfCreateForRc(pRc); + if (!SUCCEEDED(hr)) + { + WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr)); + return NULL; + } + + hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf); + if (!SUCCEEDED(hr)) + { + WARN(("VBoxD3DIfSurfGet failed hr %#x", hr)); + return NULL; + } + } + else + { + WARN(("vboxD3DIfSetHostId failed %#x, ignoring", hr)); + hr = S_OK; + hostID = 0; + usedHostId = 0; + } + } + else + { + Assert(hostID == usedHostId); + } + } + else + WARN(("pfnVBoxWineExD3DSurf9GetHostId failed, hr 0x%x", hr)); + + pSurfIf->Release(); + pSurfIf = NULL; + + return pAlloc->pD3DIf; +} diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h index 31e39082..43520b65 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h @@ -40,8 +40,11 @@ HRESULT VBoxD3DIfLockRect(struct VBOXWDDMDISP_RESOURCE *pRc, UINT iAlloc, HRESULT VBoxD3DIfUnlockRect(struct VBOXWDDMDISP_RESOURCE *pRc, UINT iAlloc); void VBoxD3DIfLockUnlockMemSynch(struct VBOXWDDMDISP_ALLOCATION *pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo); +IUnknown* vboxD3DIfCreateSharedPrimary(PVBOXWDDMDISP_ALLOCATION pAlloc); + + /* NOTE: does NOT increment a ref counter! NO Release needed!! */ -DECLINLINE(IUnknown*) VBoxD3DIfGet(PVBOXWDDMDISP_ALLOCATION pAlloc) +DECLINLINE(IUnknown*) vboxD3DIfGet(PVBOXWDDMDISP_ALLOCATION pAlloc) { if (pAlloc->pD3DIf) return pAlloc->pD3DIf; @@ -52,17 +55,7 @@ DECLINLINE(IUnknown*) VBoxD3DIfGet(PVBOXWDDMDISP_ALLOCATION pAlloc) return NULL; } - HRESULT hr = VBoxD3DIfCreateForRc(pAlloc->pRc); - if (!SUCCEEDED(hr)) - { - WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr)); - return NULL; - } - - Assert(pAlloc->pD3DIf); - Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE); - - return pAlloc->pD3DIf; + return vboxD3DIfCreateSharedPrimary(pAlloc); } /* on success increments the surface ref counter, @@ -72,7 +65,7 @@ DECLINLINE(HRESULT) VBoxD3DIfSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, ID HRESULT hr = S_OK; Assert(pRc->cAllocations > iAlloc); *ppSurf = NULL; - IUnknown* pD3DIf = VBoxD3DIfGet(&pRc->aAllocations[iAlloc]); + IUnknown* pD3DIf = vboxD3DIfGet(&pRc->aAllocations[iAlloc]); switch (pRc->aAllocations[0].enmD3DIfType) { diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp index f4c6c528..39c465f5 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -164,7 +164,12 @@ HRESULT vboxDispCmCtxCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT vboxDispCmSessionCtxAdd(&g_pVBoxCmMgr.Session, pContext); pContext->pDevice = pDevice; if (fIsCrContext) - vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice); + { + if (pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_CMDVBVA) + vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice); + else + vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice); + } } else { @@ -206,10 +211,21 @@ static HRESULT vboxDispCmSessionCmdQueryData(PVBOXDISPCM_SESSION pSession, PVBOX DdiEscape.PrivateDriverDataSize = cbCmd; pCmd->EscapeHdr.escapeCode = VBOXESC_GETVBOXVIDEOCMCMD; + + PVBOXWDDMDISP_CONTEXT pContext = NULL, pCurCtx; + /* lock to ensure the context is not destroyed */ EnterCriticalSection(&pSession->CritSect); /* use any context for identifying the kernel CmSession. We're using the first one */ - PVBOXWDDMDISP_CONTEXT pContext = RTListGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode); + RTListForEach(&pSession->CtxList, pCurCtx, VBOXWDDMDISP_CONTEXT, ListNode) + { + PVBOXWDDMDISP_DEVICE pDevice = pCurCtx->pDevice; + if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) + { + pContext = pCurCtx; + break; + } + } if (pContext) { PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice; diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp index 6311a93d..d3946060 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -37,6 +37,9 @@ volatile uint32_t g_u32VBoxDispProfileFunctionLoggerIndex = 0; +/* the number of frames to collect data before doing dump/reset */ +#define VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT 0x20 + struct VBOXDISPPROFILE_GLOBAL { VBoxDispProfileFpsCounter ProfileDdiFps; VBoxDispProfileSet ProfileDdiFunc; @@ -50,10 +53,25 @@ struct VBOXDISPPROFILE_GLOBAL { # ifdef VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_ENABLE -extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; +class VBoxDispProfileDevicePostProcess +{ +public: + VBoxDispProfileDevicePostProcess(PVBOXWDDMDISP_DEVICE pDevice) : + m_pDevice(pDevice) + {} + + void postProcess() + { + if (m_pDevice->pDevice9If) + m_pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Finish((IDirect3DDevice9Ex *)m_pDevice->pDevice9If); + } +private: + PVBOXWDDMDISP_DEVICE m_pDevice; +}; //static VBoxDispProfileSet g_VBoxDispProfileDDI("D3D_DDI"); -# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc) +# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_DEV(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc, VBoxDispProfileDevicePostProcess, VBoxDispProfileDevicePostProcess(_pObj)) +# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_BASE(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc, VBoxDispProfileDummyPostProcess, VBoxDispProfileDummyPostProcess()) # define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj) do {\ (_pObj)->ProfileDdiFunc.dump(_pObj); \ } while (0) @@ -67,14 +85,15 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; # define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() # define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pObj) do { \ - if (!((_pObj)->ProfileDdiFunc.reportIteration() % 31) && !VBOXVDBG_IS_DWM()) {\ + if (!((_pObj)->ProfileDdiFunc.reportIteration() % VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT) /*&& !VBOXVDBG_IS_DWM()*/) {\ VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj); \ VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj); \ } \ } while (0) # else -# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj) do {} while(0) +# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_DEV(_pObj) do {} while(0) +# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_BASE(_pObj) do {} while(0) # define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj) do {} while(0) # define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj) do {} while(0) # define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {} while (0) @@ -84,7 +103,7 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; # ifdef VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE //static VBoxDispProfileFpsCounter g_VBoxDispFpsDDI(64); -# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&(_pObj)->ProfileDdiFps) +# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&(_pObj)->ProfileDdiFps, VBoxDispProfileDummyPostProcess, VBoxDispProfileDummyPostProcess()) # define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {\ VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT();\ } while (0) @@ -98,7 +117,7 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; # define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pObj) do { \ (_pObj)->ProfileDdiFps.ReportFrame(); \ - if(!((_pObj)->ProfileDdiFps.GetNumFrames() % 31)) \ + if(!((_pObj)->ProfileDdiFps.GetNumFrames() % VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT)) \ { \ VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj); \ } \ @@ -113,8 +132,12 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; # define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj) do {} while (0) # endif -# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(_pObj) \ - VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj); \ +# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_DEV(_pObj) \ + VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_DEV(_pObj); \ + VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj); + +# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE(_pObj) \ + VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_BASE(_pObj); \ VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj); # define VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT() \ @@ -127,11 +150,15 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev); \ } while (0) +#if 0 # define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {\ VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT(); \ VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev); \ VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev); \ } while (0) +#else +# define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {} while (0) +#endif # define VBOXDISPPROFILE_DDI_INIT_CMN(_pObj, _name, _cEntries) do { \ (_pObj)->ProfileDdiFps = VBoxDispProfileFpsCounter(); \ @@ -156,7 +183,8 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; # define VBOXDISPPROFILE_DDI_INIT_ADP(_pAdp) VBOXDISPPROFILE_DDI_INIT_CMN(_pAdp, "DDI_Adp", 64) # define VBOXDISPPROFILE_DDI_INIT_DEV(_pDev) VBOXDISPPROFILE_DDI_INIT_CMN(_pDev, "DDI_Dev", 64) #else -# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(_pObj) do {} while (0) +# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_DEV(_pObj) do {} while (0) +# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE(_pObj) do {} while (0) # define VBOXDISPPROFILE_DDI_REPORT_FRAME(_pDev) do {} while (0) # define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {} while (0) # define VBOXDISPPROFILE_DDI_INIT_GLBL() do {} while (0) @@ -174,15 +202,15 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0; #define VBOXDISP_DDI_PROLOGUE_DEV(_hDevice) \ VBOXDISP_DDI_PROLOGUE_CMN(); \ - VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE((PVBOXWDDMDISP_DEVICE)(_hDevice)); + VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_DEV((PVBOXWDDMDISP_DEVICE)(_hDevice)); #define VBOXDISP_DDI_PROLOGUE_ADP(_hAdapter) \ VBOXDISP_DDI_PROLOGUE_CMN(); \ - VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE((PVBOXWDDMDISP_ADAPTER)(_hAdapter)); + VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE((PVBOXWDDMDISP_ADAPTER)(_hAdapter)); #define VBOXDISP_DDI_PROLOGUE_GLBL() \ VBOXDISP_DDI_PROLOGUE_CMN(); \ - VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(&g_VBoxDispProfile); + VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE(&g_VBoxDispProfile); #ifdef VBOXDISPMP_TEST HRESULT vboxDispMpTstStart(); @@ -238,7 +266,8 @@ typedef struct VBOXWDDMDISP_NSCADD static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc) { HRESULT hr = S_OK; - if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4) + Assert(pAlloc->fEverWritten || pAlloc->pRc->RcDesc.fFlags.SharedResource); + if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer >= 4) { memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST)); pData->pAllocationList[0].hAllocation = pAlloc->hAllocation; @@ -265,24 +294,28 @@ static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALL return hr; } -static BOOLEAN vboxWddmDalCheckRemove(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc) +static VOID vboxWddmDalRemove(PVBOXWDDMDISP_ALLOCATION pAlloc) { - BOOLEAN fRemoved = FALSE; - - if (pAlloc->DirtyAllocListEntry.pNext) - { - RTListNodeRemove(&pAlloc->DirtyAllocListEntry); - pAlloc->fDirtyWrite = FALSE; - fRemoved = TRUE; - } - - return fRemoved; + RTListNodeRemove(&pAlloc->DirtyAllocListEntry); + pAlloc->fDirtyWrite = FALSE; } +#ifdef DEBUG_misha +typedef struct VBOXWDDM_DBG_ALLOC +{ + BOOLEAN fWrite; + PVBOXWDDMDISP_ALLOCATION pAlloc; +} VBOXWDDM_DBG_ALLOC; +#endif + static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice) { VBOXWDDMDISP_NSCADD NscAdd; BOOL bReinitRenderData = TRUE; +#ifdef DEBUG_misha + uint32_t cDbgAllocs = 0; + VBOXWDDM_DBG_ALLOC aDbgAllocs[128]; +#endif do { @@ -304,16 +337,38 @@ static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice) NscAdd.pvCommandBuffer = (VOID*)(((uint8_t*)NscAdd.pvCommandBuffer) + sizeof (*pHdr)); NscAdd.cbCommandBuffer -= sizeof (*pHdr); bReinitRenderData = FALSE; + +#ifdef DEBUG_misha + { + memset(aDbgAllocs, 0, sizeof (aDbgAllocs)); + PVBOXWDDMDISP_ALLOCATION pAlloc; + uint32_t cAllocs = 0; + RTListForEach(&pDevice->DirtyAllocList, pAlloc, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry) + { + Assert(pAlloc->fEverWritten || pAlloc->pRc->RcDesc.fFlags.SharedResource); + if (cAllocs < RT_ELEMENTS(aDbgAllocs)) + { + aDbgAllocs[cAllocs].pAlloc = pAlloc; + aDbgAllocs[cAllocs].fWrite = pAlloc->fDirtyWrite; + ++cDbgAllocs; + } + ++cAllocs; + } + } +#endif } PVBOXWDDMDISP_ALLOCATION pAlloc = RTListGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry); if (pAlloc) { HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc); +#ifdef DEBUG_misha + Assert(tmpHr == S_OK); +#endif Assert(tmpHr == S_OK || tmpHr == S_FALSE); if (tmpHr == S_OK) { - vboxWddmDalCheckRemove(pDevice, pAlloc); + vboxWddmDalRemove(pAlloc); continue; } } @@ -356,31 +411,122 @@ static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice) return S_OK; } -//#define VBOX_WDDM_SHRC_WO_NOTIFY +#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK +static HRESULT vboxWddmDalCheckUnlock(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc) +{ + if (!pAlloc->fAllocLocked || pAlloc->LockInfo.cLocks) + return S_OK; + + Assert(pAlloc->hAllocation); + + D3DDDICB_UNLOCK Unlock; + + Unlock.NumAllocations = 1; + Unlock.phAllocations = &pAlloc->hAllocation; + + HRESULT hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &Unlock); + if(hr != S_OK) + { + WARN(("pfnUnlockCb failed, hr %#x", hr)); + } + + return hr; +} + +static HRESULT vboxWddmDalCheckLock(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_LOCKFLAGS Flags) +{ + if (!pAlloc->hAllocation || pAlloc->fAllocLocked) + return S_OK; + + HRESULT hr; + + if (pAlloc->fDirtyWrite) + { + Assert(pAlloc->DirtyAllocListEntry.pNext); + hr = vboxWddmDalNotifyChange(pDevice); + if (hr == S_OK) + { + Assert(!pAlloc->DirtyAllocListEntry.pNext); + } + else + { + WARN(("vboxWddmDalNotifyChange failed %#x, ignoring", hr)); + } + } + + D3DDDICB_LOCK LockData; + LockData.hAllocation = pAlloc->hAllocation; + LockData.PrivateDriverData = 0; + LockData.NumPages = 0; + LockData.pPages = NULL; + LockData.pData = NULL; /* out */ + LockData.Flags.Value = 0; + LockData.Flags.Discard = Flags.Discard; + LockData.Flags.DonotWait = Flags.DoNotWait; + + hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData); + if (hr == S_OK) + { + if (!Flags.ReadOnly) + pAlloc->fEverWritten = TRUE; + pAlloc->fAllocLocked = TRUE; + return S_OK; + } + + WARN(("pfnLockCb failed %#x, Flags %#x", hr, Flags.Value)); + + return hr; +} +#endif + +static BOOLEAN vboxWddmDalCheckNotifyRemove(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc) +{ + if (pAlloc->DirtyAllocListEntry.pNext) + { + HRESULT hr = vboxWddmDalNotifyChange(pDevice); + if (hr == S_OK) + { + Assert(!pAlloc->DirtyAllocListEntry.pNext); + } + else + { + WARN(("vboxWddmDalNotifyChange failed %#x", hr)); + if (pAlloc->DirtyAllocListEntry.pNext) + vboxWddmDalRemove(pAlloc); + } + + return TRUE; + } + + return FALSE; +} + static BOOLEAN vboxWddmDalCheckAdd(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOLEAN fWrite) { if (!pAlloc->hAllocation /* only shared resources matter */ -#ifdef VBOX_WDDM_SHRC_WO_NOTIFY - || !fWrite /* only write op matter */ -#endif + || (/*!fWrite &&*/ !pAlloc->hSharedHandle) ) { -#ifdef VBOX_WDDM_SHRC_WO_NOTIFY - Assert(!pAlloc->DirtyAllocListEntry.pNext || (!fWrite && pAlloc->hSharedHandle && pAlloc->fDirtyWrite)); -#else - Assert(!pAlloc->DirtyAllocListEntry.pNext); -#endif + Assert(!pAlloc->DirtyAllocListEntry.pNext || pAlloc->hSharedHandle /*|| pAlloc->fDirtyWrite*/); + Assert(!pAlloc->hSharedHandle); return FALSE; } + Assert(fWrite || pAlloc->fEverWritten || pAlloc->pRc->RcDesc.fFlags.SharedResource); + if (!pAlloc->DirtyAllocListEntry.pNext) { Assert(!pAlloc->fDirtyWrite); RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry); } + else + { + Assert(pAlloc->fDirtyWrite == fWrite); + } pAlloc->fDirtyWrite |= fWrite; + pAlloc->fEverWritten |= fWrite; return TRUE; } @@ -396,7 +542,13 @@ static DECLINLINE(BOOLEAN) vboxWddmDalCheckAddRc(PVBOXWDDMDISP_DEVICE pDevice, P return fChanged; } -static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice) +static VOID vboxWddmDalCheckAddDepthStencil(PVBOXWDDMDISP_DEVICE pDevice) +{ + if (pDevice->pDepthStencilRc) + vboxWddmDalCheckAddRc(pDevice, pDevice->pDepthStencilRc, TRUE); +} + +static VOID vboxWddmDalCheckAddRTs(PVBOXWDDMDISP_DEVICE pDevice) { for (UINT i = 0; i < pDevice->cRTs; ++i) { @@ -405,7 +557,10 @@ static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice) vboxWddmDalCheckAdd(pDevice, pDevice->apRTs[i], TRUE); } } +} +static VOID vboxWddmDalCheckAddSamplers(PVBOXWDDMDISP_DEVICE pDevice) +{ for (UINT i = 0, iSampler = 0; iSampler < pDevice->cSamplerTextures; ++i) { Assert(i < RT_ELEMENTS(pDevice->aSamplerTextures)); @@ -415,6 +570,20 @@ static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice) } } +static VOID vboxWddmDalCheckAddOnDraw(PVBOXWDDMDISP_DEVICE pDevice) +{ + vboxWddmDalCheckAddRTs(pDevice); + + vboxWddmDalCheckAddDepthStencil(pDevice); + + vboxWddmDalCheckAddSamplers(pDevice); +} + +static BOOLEAN vboxWddmDalIsEmpty(PVBOXWDDMDISP_DEVICE pDevice) +{ + return RTListIsEmpty(&pDevice->DirtyAllocList); +} + #ifdef VBOX_WITH_VIDEOHWACCEL static bool vboxVhwaIsEnabled(PVBOXWDDMDISP_ADAPTER pAdapter) @@ -569,6 +738,13 @@ static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD Buf.SwapchainInfo.EscapeHdr.escapeCode = VBOXESC_SWAPCHAININFO; Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm; Buf.SwapchainInfo.SwapchainInfo.hSwapchainUm = (VBOXDISP_UMHANDLE)pSwapchain; + HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSwapchain9GetHostWinID(pSwapchain->pSwapChainIf, &Buf.SwapchainInfo.SwapchainInfo.winHostID); + if (FAILED(hr)) + { + WARN(("pfnVBoxWineExD3DSwapchain9GetHostWinID failed, hr 0x%x", hr)); + return hr; + } + Assert(Buf.SwapchainInfo.SwapchainInfo.winHostID); // Buf.SwapchainInfo.SwapchainInfo.Rect; // Buf.SwapchainInfo.SwapchainInfo.u32Reserved; Buf.SwapchainInfo.SwapchainInfo.cAllocs = pSwapchain->cRTs; @@ -582,7 +758,6 @@ static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD } Assert(cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs || !cAllocsKm); - HRESULT hr = S_OK; if (cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs) { D3DDDICB_ESCAPE DdiEscape = {0}; @@ -651,7 +826,6 @@ DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD /* first do a Km destroy to ensure all km->um region submissions are completed */ vboxWddmSwapchainKmDestroy(pDevice, pSwapchain); - vboxDispMpInternalCancel(&pDevice->DefaultContext, pSwapchain); vboxWddmSwapchainDestroyIf(pDevice, pSwapchain); vboxWddmSwapchainInit(pSwapchain); } @@ -1029,7 +1203,7 @@ static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD } else { - WARN(("GetFrontBufferData failed, hr (0x%x)", hr)); + WARN(("GetFrontBufferData failed, hr (0x%x)", tmpHr)); } } #endif @@ -1771,7 +1945,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, #ifdef VBOXWDDMDISP_DEBUG_VEHANDLER vboxVDbgVEHandlerRegister(); #endif - int rc = RTR3InitDll(0); + int rc = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE); AssertRC(rc); if (RT_SUCCESS(rc)) { @@ -1783,14 +1957,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, Assert(hr == S_OK); if (hr == S_OK) { - hr = vboxDispMpInternalInit(); - Assert(hr == S_OK); - if (hr == S_OK) - { - VBoxDispD3DGlobalInit(); - vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n")); - return TRUE; - } + VBoxDispD3DGlobalInit(); + vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n")); + return TRUE; } // VbglR3Term(); } @@ -1807,19 +1976,14 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, #ifdef VBOXWDDMDISP_DEBUG_VEHANDLER vboxVDbgVEHandlerUnregister(); #endif - HRESULT hr = vboxDispMpInternalTerm(); + HRESULT hr = vboxDispCmTerm(); Assert(hr == S_OK); if (hr == S_OK) { - hr = vboxDispCmTerm(); - Assert(hr == S_OK); - if (hr == S_OK) - { // VbglR3Term(); - /// @todo RTR3Term(); - VBoxDispD3DGlobalTerm(); - return TRUE; - } + /// @todo RTR3Term(); + VBoxDispD3DGlobalTerm(); + return TRUE; } break; @@ -1833,7 +1997,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData) { - VBOXDISP_DDI_PROLOGUE_ADP(hAdapter); + VBOXDISP_DDI_PROLOGUE_ADP(hAdapter); vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type)); @@ -2417,34 +2581,47 @@ static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIAR VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice); - if (!pDevice->cStreamSources) + if (pDevice->cStreamSourcesUm) { - if (pDevice->aStreamSourceUm[0].pvBuffer) - { #ifdef DEBUG - for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i) + uint32_t cStreams = 0; + for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i) + { + if(pDevice->aStreamSourceUm[i].pvBuffer) { - Assert(!pDevice->aStreamSourceUm[i].pvBuffer); + ++cStreams; } -#endif - hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, - pData->PrimitiveCount, - ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride, - pDevice->aStreamSourceUm[0].cbStride); - Assert(hr == S_OK); + } -// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitiveUP\n")); + Assert(cStreams); + Assert(cStreams == pDevice->cStreamSourcesUm); +#endif + if (pDevice->cStreamSourcesUm == 1) + { + for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i) + { + if(pDevice->aStreamSourceUm[i].pvBuffer) + { + hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, + pData->PrimitiveCount, + ((uint8_t*)pDevice->aStreamSourceUm[i].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[i].cbStride, + pDevice->aStreamSourceUm[i].cbStride); + Assert(hr == S_OK); + break; + } + } } else { /* todo: impl */ - Assert(0); + WARN(("multiple user stream sources (%d) not implemented!!", pDevice->cStreamSourcesUm)); } } else { #ifdef DEBUG + Assert(!pDevice->cStreamSourcesUm); for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i) { Assert(!pDevice->aStreamSourceUm[i].pvBuffer); @@ -2471,7 +2648,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIAR // vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitive\n")); } - vboxWddmDalCheckAddRtsSamplers(pDevice); + vboxWddmDalCheckAddOnDraw(pDevice); VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice); @@ -2602,7 +2779,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D } } - vboxWddmDalCheckAddRtsSamplers(pDevice); + vboxWddmDalCheckAddOnDraw(pDevice); VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice); @@ -2618,7 +2795,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIAR Assert(pDevice); VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice); Assert(0); - vboxWddmDalCheckAddRtsSamplers(pDevice); + vboxWddmDalCheckAddOnDraw(pDevice); vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice)); return E_FAIL; } @@ -2631,7 +2808,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG Assert(pDevice); VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice); Assert(0); - vboxWddmDalCheckAddRtsSamplers(pDevice); + vboxWddmDalCheckAddOnDraw(pDevice); vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice)); return E_FAIL; } @@ -2724,7 +2901,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIA #endif #endif - vboxWddmDalCheckAddRtsSamplers(pDevice); + vboxWddmDalCheckAddOnDraw(pDevice); VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice); @@ -2808,7 +2985,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST } } - vboxWddmDalCheckAddRtsSamplers(pDevice); + vboxWddmDalCheckAddOnDraw(pDevice); vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice)); return hr; } @@ -2895,7 +3072,7 @@ static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBL VBOXVDBG_CHECK_SMSYNC(pDstRc); VBOXVDBG_CHECK_SMSYNC(pSrcRc); - if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth + if (pSrcRc->aAllocations[0].SurfDesc.d3dWidth == pDstRc->aAllocations[0].SurfDesc.d3dWidth && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat &&pData->DstPoint.x == 0 && pData->DstPoint.y == 0 @@ -2998,7 +3175,17 @@ static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData->FillColor, pData->FillDepth, pData->FillStencil); - Assert(hr == S_OK); + if (SUCCEEDED(hr)) + { + if (pData->Flags & D3DCLEAR_TARGET) + vboxWddmDalCheckAddRTs(pDevice); + if ((pData->Flags & D3DCLEAR_STENCIL) + || (pData->Flags & D3DCLEAR_ZBUFFER)) + vboxWddmDalCheckAddDepthStencil(pDevice); + } + else + WARN(("Clear failed %#x", hr)); + vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr)); return hr; } @@ -3213,15 +3400,24 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) Assert(pDevice); VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice); PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource; - Assert(pData->SubResourceIndex < pRc->cAllocations); if (pData->SubResourceIndex >= pRc->cAllocations) return E_INVALIDARG; + PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; + Assert(pData->SubResourceIndex < pRc->cAllocations); HRESULT hr = S_OK; if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) { // Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex); +#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK + hr = vboxWddmDalCheckLock(pDevice, pAlloc, pData->Flags); + if (!SUCCEEDED(hr)) + { + WARN(("vboxWddmDalCheckLock failed %#x", hr)); + return hr; + } +#endif if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE @@ -3229,7 +3425,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) { PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0]; Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex]; IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf; IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pTexAlloc->pD3DIf; IDirect3DSurface9 *pD3DIfSurface = (IDirect3DSurface9*)pTexAlloc->pD3DIf; @@ -3245,20 +3440,20 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) /* else - we lock the entire texture, pRect == NULL */ - if (pLockAlloc->LockInfo.cLocks) + if (pAlloc->LockInfo.cLocks) { - Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid); - if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid) + Assert(pAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid); + if (pAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid) { - Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left); - Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top); - Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right); - Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom); + Assert(pAlloc->LockInfo.Area.left == pData->Area.left); + Assert(pAlloc->LockInfo.Area.top == pData->Area.top); + Assert(pAlloc->LockInfo.Area.right == pData->Area.right); + Assert(pAlloc->LockInfo.Area.bottom == pData->Area.bottom); } - Assert(pLockAlloc->LockInfo.LockedRect.pBits); - Assert((pLockAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */ + Assert(pAlloc->LockInfo.LockedRect.pBits); + Assert((pAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */ - if (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly) + if (pAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly) { switch (pTexAlloc->enmD3DIfType) { @@ -3288,34 +3483,34 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) { VBOXVDBG_CHECK_SMSYNC(pRc); - pLockAlloc->LockInfo.fFlags = pData->Flags; + pAlloc->LockInfo.fFlags = pData->Flags; if (pRect) { - pLockAlloc->LockInfo.Area = *pRect; - Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1); + pAlloc->LockInfo.Area = *pRect; + Assert(pAlloc->LockInfo.fFlags.AreaValid == 1); } else { - Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0); + Assert(pAlloc->LockInfo.fFlags.AreaValid == 0); } switch (pTexAlloc->enmD3DIfType) { case VBOXDISP_D3DIFTYPE_TEXTURE: hr = pD3DIfTex->LockRect(pData->SubResourceIndex, - &pLockAlloc->LockInfo.LockedRect, + &pAlloc->LockInfo.LockedRect, pRect, vboxDDI2D3DLockFlags(pData->Flags)); break; case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE: hr = pD3DIfCubeTex->LockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex), VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex), - &pLockAlloc->LockInfo.LockedRect, + &pAlloc->LockInfo.LockedRect, pRect, vboxDDI2D3DLockFlags(pData->Flags)); break; case VBOXDISP_D3DIFTYPE_SURFACE: - hr = pD3DIfSurface->LockRect(&pLockAlloc->LockInfo.LockedRect, + hr = pD3DIfSurface->LockRect(&pAlloc->LockInfo.LockedRect, pRect, vboxDDI2D3DLockFlags(pData->Flags)); break; @@ -3332,19 +3527,19 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) if (SUCCEEDED(hr)) { - ++pLockAlloc->LockInfo.cLocks; + ++pAlloc->LockInfo.cLocks; if (!pData->Flags.NotifyOnly) { - pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits; - pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch; + pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits; + pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch; pData->SlicePitch = 0; - Assert(pLockAlloc->SurfDesc.slicePitch == 0); - Assert(!pLockAlloc->pvMem); + Assert(pAlloc->SurfDesc.slicePitch == 0); + Assert(!pAlloc->pvMem); } else { - Assert(pLockAlloc->pvMem); + Assert(pAlloc->pvMem); Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM); } @@ -3357,7 +3552,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) { PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0]; Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex]; IDirect3DVolumeTexture9 *pD3DIfTex = (IDirect3DVolumeTexture9*)pTexAlloc->pD3DIf; Assert(pTexAlloc->pD3DIf); D3DDDIBOX *pBox = NULL; @@ -3371,22 +3565,22 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) /* else - we lock the entire texture, pBox == NULL */ - if (pLockAlloc->LockInfo.cLocks) + if (pAlloc->LockInfo.cLocks) { - Assert(pLockAlloc->LockInfo.fFlags.BoxValid == pData->Flags.BoxValid); - if (pLockAlloc->LockInfo.fFlags.BoxValid && pData->Flags.BoxValid) + Assert(pAlloc->LockInfo.fFlags.BoxValid == pData->Flags.BoxValid); + if (pAlloc->LockInfo.fFlags.BoxValid && pData->Flags.BoxValid) { - Assert(pLockAlloc->LockInfo.Box.Left == pData->Box.Left); - Assert(pLockAlloc->LockInfo.Box.Top == pData->Box.Top); - Assert(pLockAlloc->LockInfo.Box.Right == pData->Box.Right); - Assert(pLockAlloc->LockInfo.Box.Bottom == pData->Box.Bottom); - Assert(pLockAlloc->LockInfo.Box.Front == pData->Box.Front); - Assert(pLockAlloc->LockInfo.Box.Back == pData->Box.Back); + Assert(pAlloc->LockInfo.Box.Left == pData->Box.Left); + Assert(pAlloc->LockInfo.Box.Top == pData->Box.Top); + Assert(pAlloc->LockInfo.Box.Right == pData->Box.Right); + Assert(pAlloc->LockInfo.Box.Bottom == pData->Box.Bottom); + Assert(pAlloc->LockInfo.Box.Front == pData->Box.Front); + Assert(pAlloc->LockInfo.Box.Back == pData->Box.Back); } - Assert(pLockAlloc->LockInfo.LockedBox.pBits); - Assert((pLockAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */ + Assert(pAlloc->LockInfo.LockedBox.pBits); + Assert((pAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */ - if (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly) + if (pAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly) { hr = pD3DIfTex->UnlockBox(pData->SubResourceIndex); Assert(hr == S_OK); @@ -3401,19 +3595,19 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) { VBOXVDBG_CHECK_SMSYNC(pRc); - pLockAlloc->LockInfo.fFlags = pData->Flags; + pAlloc->LockInfo.fFlags = pData->Flags; if (pBox) { - pLockAlloc->LockInfo.Box = *pBox; - Assert(pLockAlloc->LockInfo.fFlags.BoxValid == 1); + pAlloc->LockInfo.Box = *pBox; + Assert(pAlloc->LockInfo.fFlags.BoxValid == 1); } else { - Assert(pLockAlloc->LockInfo.fFlags.BoxValid == 0); + Assert(pAlloc->LockInfo.fFlags.BoxValid == 0); } hr = pD3DIfTex->LockBox(pData->SubResourceIndex, - &pLockAlloc->LockInfo.LockedBox, + &pAlloc->LockInfo.LockedBox, (D3DBOX*)pBox, vboxDDI2D3DLockFlags(pData->Flags)); if (FAILED(hr)) @@ -3424,18 +3618,18 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) if (SUCCEEDED(hr)) { - ++pLockAlloc->LockInfo.cLocks; + ++pAlloc->LockInfo.cLocks; if (!pData->Flags.NotifyOnly) { - pData->pSurfData = pLockAlloc->LockInfo.LockedBox.pBits; - pData->Pitch = pLockAlloc->LockInfo.LockedBox.RowPitch; - pData->SlicePitch = pLockAlloc->LockInfo.LockedBox.SlicePitch; - Assert(!pLockAlloc->pvMem); + pData->pSurfData = pAlloc->LockInfo.LockedBox.pBits; + pData->Pitch = pAlloc->LockInfo.LockedBox.RowPitch; + pData->SlicePitch = pAlloc->LockInfo.LockedBox.SlicePitch; + Assert(!pAlloc->pvMem); } else { - Assert(pLockAlloc->pvMem); + Assert(pAlloc->pvMem); Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM); } @@ -3447,7 +3641,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER) { Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf; BOOL bLocked = false; Assert(pD3D9VBuf); @@ -3478,7 +3671,7 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) { Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width); pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch; -// Assert(pLockAlloc->LockInfo.fFlags.Value == 0); +// Assert(pAlloc->LockInfo.fFlags.Value == 0); pAlloc->LockInfo.fFlags = pData->Flags; if (pRange) { @@ -3541,7 +3734,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER) { Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf; BOOL bLocked = false; Assert(pD3D9IBuf); @@ -3572,7 +3764,7 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) { Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width); pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch; -// Assert(pLockAlloc->LockInfo.fFlags.Value == 0); +// Assert(pAlloc->LockInfo.fFlags.Value == 0); pAlloc->LockInfo.fFlags = pData->Flags; if (pRange) { @@ -3634,12 +3826,19 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData) } else { - Assert(0); + WARN(("not implemented %d", pRc->aAllocations[0].enmD3DIfType)); } + +#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK + if (!SUCCEEDED(hr)) + { + WARN(("lock failed %#x", hr)); + vboxWddmDalCheckUnlock(pDevice, pAlloc); + } +#endif } else /* if !VBOXDISPMODE_IS_3D(pDevice->pAdapter) */ { - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; if (pAlloc->hAllocation) { if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM) @@ -3736,6 +3935,8 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC if (pData->SubResourceIndex >= pRc->cAllocations) return E_INVALIDARG; + PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; + if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) { if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE @@ -3743,13 +3944,12 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE) { Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex]; VBOXVDBG_DUMP_UNLOCK_ST(pData); - --pLockAlloc->LockInfo.cLocks; - Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX); - if (!pLockAlloc->LockInfo.cLocks) + --pAlloc->LockInfo.cLocks; + Assert(pAlloc->LockInfo.cLocks < UINT32_MAX); + if (!pAlloc->LockInfo.cLocks) { PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0]; Assert(pTexAlloc->pD3DIf); @@ -3786,13 +3986,12 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE) { Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex]; VBOXVDBG_DUMP_UNLOCK_ST(pData); - --pLockAlloc->LockInfo.cLocks; - Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX); - if (!pLockAlloc->LockInfo.cLocks) + --pAlloc->LockInfo.cLocks; + Assert(pAlloc->LockInfo.cLocks < UINT32_MAX); + if (!pAlloc->LockInfo.cLocks) { PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0]; Assert(pTexAlloc->pD3DIf); @@ -3806,7 +4005,6 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER) { Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; --pAlloc->LockInfo.cLocks; Assert(pAlloc->LockInfo.cLocks < UINT32_MAX); @@ -3847,7 +4045,6 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER) { Assert(pData->SubResourceIndex < pRc->cAllocations); - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; --pAlloc->LockInfo.cLocks; Assert(pAlloc->LockInfo.cLocks < UINT32_MAX); @@ -3887,13 +4084,22 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC } else { - Assert(0); + WARN(("Unlock unsupported %d", pRc->aAllocations[0].enmD3DIfType)); + } + +#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK + if (SUCCEEDED(hr)) + { + hr = vboxWddmDalCheckUnlock(pDevice, pAlloc); + if (!SUCCEEDED(hr)) + WARN(("vboxWddmDalCheckUnlock failed %#x", hr)); } + else + WARN(("unlock failed %#x", hr)); +#endif } else { - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; - if (pAlloc->hAllocation) { BOOL fDoUnlock = FALSE; @@ -3938,18 +4144,12 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC if (fDoUnlock) { - struct - { - D3DDDICB_UNLOCK Unlock; - D3DKMT_HANDLE hAllocation; - } UnlockData; + D3DDDICB_UNLOCK Unlock; + Unlock.NumAllocations = 1; + Unlock.phAllocations = &pAlloc->hAllocation; - UnlockData.Unlock.NumAllocations = 1; - UnlockData.Unlock.phAllocations = &UnlockData.hAllocation; - UnlockData.hAllocation = pAlloc->hAllocation; - - hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock); + hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &Unlock); if(hr != S_OK) { WARN(("pfnUnlockCb failed, hr 0x%x", hr)); @@ -4062,6 +4262,7 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE } bool bIssueCreateResource = false; bool bCreateKMResource = false; + bool bSetHostID = false; pRc->hResource = pResource->hResource; pRc->hKMResource = NULL; @@ -4087,7 +4288,7 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC; pAllocation->iAlloc = i; pAllocation->pRc = pRc; - pAllocation->D3DWidth = pSurf->Width; + pAllocation->SurfDesc.d3dWidth = pSurf->Width; pAllocation->pvMem = (void*)pSurf->pSysMem; pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch; pAllocation->SurfDesc.depth = pSurf->Depth; @@ -4119,14 +4320,14 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE if (pAllocation->SurfDesc.pitch != minPitch) { Assert(pAllocation->SurfDesc.pitch > minPitch); - pAllocation->D3DWidth = vboxWddmCalcWidthForPitch(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.format); + pAllocation->SurfDesc.d3dWidth = vboxWddmCalcWidthForPitch(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.format); Assert(VBOXWDDMDISP_IS_TEXTURE(pRc->RcDesc.fFlags) && !pRc->RcDesc.fFlags.CubeMap); /* <- tested for textures only! */ } - Assert(pAllocation->D3DWidth >= pAllocation->SurfDesc.width); + Assert(pAllocation->SurfDesc.d3dWidth >= pAllocation->SurfDesc.width); } else { - Assert(pAllocation->D3DWidth == pAllocation->SurfDesc.width); + Assert(pAllocation->SurfDesc.d3dWidth == pAllocation->SurfDesc.width); } } @@ -4140,9 +4341,10 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE bCreateKMResource = true; } - if (pRc->RcDesc.fFlags.RenderTarget) + if (pRc->RcDesc.fFlags.RenderTarget || pRc->RcDesc.fFlags.Primary) { bIssueCreateResource = true; + bSetHostID = true; } hr = VBoxD3DIfCreateForRc(pRc); @@ -4194,92 +4396,121 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE pAllocInfo->fFlags = pResource->Flags; pAllocInfo->hSharedHandle = (uint64_t)pAllocation->hSharedHandle; pAllocInfo->SurfDesc = pAllocation->SurfDesc; + if (bSetHostID) + { + IDirect3DSurface9 *pSurfIf = NULL; + hr = VBoxD3DIfSurfGet(pRc, i, &pSurfIf); + if (SUCCEEDED(hr)) + { + hr = pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9GetHostId(pSurfIf, &pAllocInfo->hostID); + if (SUCCEEDED(hr)) + { + Assert(pAllocInfo->hostID); + } + else + { + WARN(("pfnVBoxWineExD3DSurf9GetHostId failed, hr 0x%x", hr)); + break; + } + pSurfIf->Release(); + } + else + { + WARN(("VBoxD3DIfSurfGet failed, hr 0x%x", hr)); + break; + } + } + else + pAllocInfo->hostID = 0; } Assert(!pRc->fFlags.Opened); // Assert(!pRc->fFlags.KmResource); Assert(pRc->fFlags.Generic); - if (bCreateKMResource) - { - Assert(pRc->fFlags.KmResource); - - hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate); - Assert(hr == S_OK); - Assert(pDdiAllocate->hKMResource - || pResource->Flags.SharedResource /* for some reason shared resources - * are created with zero km resource handle on Win7+ */ - ); - } - else + if (SUCCEEDED(hr)) { - Assert(!pRc->fFlags.KmResource); - - pDdiAllocate->hResource = NULL; - pDdiAllocate->NumAllocations = 1; - pDdiAllocate->PrivateDriverDataSize = 0; - pDdiAllocate->pPrivateDriverData = NULL; - D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo; - - for (UINT i = 0; i < pResource->SurfCount; ++i) + if (bCreateKMResource) { - pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i]; + Assert(pRc->fFlags.KmResource); + hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate); Assert(hr == S_OK); - Assert(!pDdiAllocate->hKMResource); - if (SUCCEEDED(hr)) - { - Assert(pDdiAllocate->pAllocationInfo->hAllocation); - } - else + Assert(pDdiAllocate->hKMResource + || pResource->Flags.SharedResource /* for some reason shared resources + * are created with zero km resource handle on Win7+ */ + ); + } + else + { + Assert(!pRc->fFlags.KmResource); + + pDdiAllocate->hResource = NULL; + pDdiAllocate->NumAllocations = 1; + pDdiAllocate->PrivateDriverDataSize = 0; + pDdiAllocate->pPrivateDriverData = NULL; + D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo; + + for (UINT i = 0; i < pResource->SurfCount; ++i) { - for (UINT j = 0; i < j; ++j) + pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i]; + hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate); + Assert(hr == S_OK); + Assert(!pDdiAllocate->hKMResource); + if (SUCCEEDED(hr)) { - D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i]; - D3DDDICB_DEALLOCATE Dealloc; - Dealloc.hResource = 0; - Dealloc.NumAllocations = 1; - Dealloc.HandleList = &pCur->hAllocation; - HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc); - Assert(tmpHr == S_OK); + Assert(pDdiAllocate->pAllocationInfo->hAllocation); + } + else + { + for (UINT j = 0; i < j; ++j) + { + D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i]; + D3DDDICB_DEALLOCATE Dealloc; + Dealloc.hResource = 0; + Dealloc.NumAllocations = 1; + Dealloc.HandleList = &pCur->hAllocation; + HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc); + Assert(tmpHr == S_OK); + } + break; } - break; } - } - - pDdiAllocate->pAllocationInfo = pDdiAllocIBase; - } - if (SUCCEEDED(hr)) - { - pRc->hKMResource = pDdiAllocate->hKMResource; + pDdiAllocate->pAllocationInfo = pDdiAllocIBase; + } - for (UINT i = 0; i < pResource->SurfCount; ++i) + if (SUCCEEDED(hr)) { - PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; - D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i]; - PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData; - CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i]; - pAllocation->hAllocation = pDdiAllocI->hAllocation; - pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC; - pAllocation->pvMem = (void*)pSurf->pSysMem; - pAllocation->SurfDesc = pAllocInfo->SurfDesc; - - if (pResource->Flags.SharedResource) + pRc->hKMResource = pDdiAllocate->hKMResource; + + for (UINT i = 0; i < pResource->SurfCount; ++i) { + PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; + D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i]; + PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData; + CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i]; + pAllocation->hAllocation = pDdiAllocI->hAllocation; + pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC; + pAllocation->pvMem = (void*)pSurf->pSysMem; + pAllocation->SurfDesc = pAllocInfo->SurfDesc; + + if (pResource->Flags.SharedResource) + { #ifdef VBOXWDDMDISP_DEBUG_PRINT_SHARED_CREATE - Assert(VBOXWDDMDISP_IS_TEXTURE(pResource->Flags)); - vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared CREATED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), " - "Handle(0x%x), (0n%d) \n***********\n\n", - GetCurrentProcessId(), GetCurrentProcessId(), - pAllocation, pRc->hKMResource, pAllocation->hAllocation, - pAllocation->hSharedHandle, pAllocation->hSharedHandle - )); + Assert(VBOXWDDMDISP_IS_TEXTURE(pResource->Flags)); + vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared CREATED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), " + "Handle(0x%x), (0n%d) \n***********\n\n", + GetCurrentProcessId(), GetCurrentProcessId(), + pAllocation, pRc->hKMResource, pAllocation->hAllocation, + pAllocation->hSharedHandle, pAllocation->hSharedHandle + )); #endif + } } - } - VBOXVDBG_CREATE_CHECK_SWAPCHAIN(); + VBOXVDBG_CREATE_CHECK_SWAPCHAIN(); + } } vboxWddmRequestAllocFree(pDdiAllocate); @@ -4349,7 +4580,7 @@ static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hReso vboxWddmSwapchainDestroy(pDevice, pSwapchain); } - vboxWddmDalCheckRemove(pDevice, pAlloc); + vboxWddmDalCheckNotifyRemove(pDevice, pAlloc); } } @@ -4426,7 +4657,29 @@ static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRES Assert(pDevice); VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice); HRESULT hr = S_OK; - if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) + PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter; + PVBOXWDDMDISP_RESOURCE pSrcRc = NULL, pDstRc = NULL; + PVBOXWDDMDISP_ALLOCATION pSrcAlloc = NULL, pDstAlloc = NULL; + + Assert(vboxWddmDalIsEmpty(pDevice)); + + if (pData->hSrcResource) + { + pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource; + Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex); + pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex]; + Assert(pSrcAlloc->hAllocation); + } + + if (pData->hDstResource) + { + pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource; + Assert(pDstRc->cAllocations > pData->DstSubResourceIndex); + pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex]; + Assert(pDstAlloc->hAllocation); + } + + if (VBOXDISPMODE_IS_3D(pAdapter)) { #ifdef VBOXWDDM_TEST_UHGSMI { @@ -4437,55 +4690,65 @@ static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRES uint32_t cCPS = (((uint64_t)cCals) * 1000ULL)/TimeMs; } #endif - PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource; - Assert(pRc); - Assert(pRc->cAllocations > pData->SrcSubResourceIndex); - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex]; - hr = vboxWddmSwapchainPresent(pDevice, pAlloc); - Assert(hr == S_OK); - } + if (pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT) + { + IDirect3DSurface9 *pSrcSurfIf = NULL; + hr = VBoxD3DIfSurfGet(pSrcRc, pData->DstSubResourceIndex, &pSrcSurfIf); + if (SUCCEEDED(hr)) + { + pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9SyncToHost(pSrcSurfIf); + pSrcSurfIf->Release(); + } + else + { + WARN(("VBoxD3DIfSurfGet failed, hr = 0x%x", hr)); + return hr; + } - { - D3DDDICB_PRESENT DdiPresent = {0}; - if (pData->hSrcResource) + pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9FlushToHost((IDirect3DDevice9Ex*)pDevice->pDevice9If); + } + else { + pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9FlushToHost((IDirect3DDevice9Ex*)pDevice->pDevice9If); PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource; + Assert(pRc); Assert(pRc->cAllocations > pData->SrcSubResourceIndex); PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex]; - Assert(pAlloc->hAllocation); - DdiPresent.hSrcAllocation = pAlloc->hAllocation; - } - if (pData->hDstResource) - { - PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource; - Assert(pRc->cAllocations > pData->DstSubResourceIndex); - PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex]; - Assert(pAlloc->hAllocation); - DdiPresent.hDstAllocation = pAlloc->hAllocation; + hr = vboxWddmSwapchainPresent(pDevice, pAlloc); + Assert(hr == S_OK); } - DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext; + } + + D3DDDICB_PRESENT DdiPresent = {0}; + if (pSrcAlloc) + DdiPresent.hSrcAllocation = pSrcAlloc->hAllocation; + + if (pDstAlloc) + DdiPresent.hDstAllocation = pDstAlloc->hAllocation; + + DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext; #if 0 //def VBOX_WDDMDISP_WITH_PROFILE - VBoxDispProfileScopeLogger<VBoxDispProfileEntry> profilePresentCbLogger(pDevice->ProfileDdiPresentCb.alloc("pfnPresentCb")); + VBoxDispProfileScopeLogger<VBoxDispProfileEntry> profilePresentCbLogger(pDevice->ProfileDdiPresentCb.alloc("pfnPresentCb")); #endif + #ifdef VBOXWDDMDISP_DEBUG_TIMER - HANDLE hTimer = NULL; - vboxVDbgTimerStart(pDevice->hTimerQueue, &hTimer, 1000); + HANDLE hTimer = NULL; + vboxVDbgTimerStart(pDevice->hTimerQueue, &hTimer, 1000); #endif - hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent); + hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent); #ifdef VBOXWDDMDISP_DEBUG_TIMER - vboxVDbgTimerStop(pDevice->hTimerQueue, hTimer); + vboxVDbgTimerStop(pDevice->hTimerQueue, hTimer); #endif #if 0 //def VBOX_WDDMDISP_WITH_PROFILE - profilePresentCbLogger.logAndDisable(); - if (pDevice->ProfileDdiPresentCb.getNumEntries() == 64) - { - pDevice->ProfileDdiPresentCb.dump(pDevice); - pDevice->ProfileDdiPresentCb.reset(); - } -#endif - Assert(hr == S_OK); + profilePresentCbLogger.logAndDisable(); + if (pDevice->ProfileDdiPresentCb.getNumEntries() == 64) + { + pDevice->ProfileDdiPresentCb.dump(pDevice); + pDevice->ProfileDdiPresentCb.reset(); } +#endif + Assert(hr == S_OK); vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr)); @@ -4749,13 +5012,23 @@ static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDI static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData) { VBOXDISP_DDI_PROLOGUE_DEV(hDevice); - vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice)); + vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice)); PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice; Assert(pDevice); VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice); + IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice); + HRESULT hr = pDevice9If->SetStreamSourceFreq(pData->Stream, pData->Divider); + if (SUCCEEDED(hr)) + hr = S_OK; + else + WARN(("SetStreamSourceFreq failed hr 0x%x", hr)); + +#ifdef DEBUG_misha + /* test it more */ Assert(0); - vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice)); - return E_FAIL; +#endif + vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice)); + return hr; } static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData) { @@ -5045,7 +5318,10 @@ static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDI { hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf); if (SUCCEEDED(hr)) + { + pDevice->pDepthStencilRc = pRc; hr = S_OK; + } else WARN(("VBoxD3DIfSurfGet failed, hr (0x%x)",hr)); @@ -5353,7 +5629,11 @@ static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice) HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext); Assert(hr == S_OK); if (hr == S_OK) + { + if (pDevice->hHgsmiTransportModule) + FreeLibrary(pDevice->hHgsmiTransportModule); RTMemFree(pDevice); + } vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice)); return hr; } @@ -5638,7 +5918,8 @@ static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENR pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE; pRc->RcDesc.MultisampleQuality = 0; pRc->RcDesc.MipLevels = 0; - pRc->RcDesc.Fvf; + /*pRc->RcDesc.Fvf;*/ + pRc->RcDesc.fFlags.SharedResource = 1; if (pData->NumAllocations != 1) { @@ -5903,7 +6184,7 @@ static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIA Assert(hr == S_OK); if (hr == S_OK) { - #ifdef VBOXDISP_EARLYCREATEDEVICE +#ifdef VBOXDISP_EARLYCREATEDEVICE PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2); Assert(pRc); if (pRc) @@ -5939,13 +6220,13 @@ static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIA { hr = E_OUTOFMEMORY; } - #else +#else //# define VBOXDISP_TEST_SWAPCHAIN # ifdef VBOXDISP_TEST_SWAPCHAIN VBOXDISP_D3DEV(pDevice); # endif break; - #endif +#endif HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext); Assert(tmpHr == S_OK); @@ -5969,6 +6250,22 @@ static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIA hr = E_OUTOFMEMORY; } + if (SUCCEEDED(hr)) + { + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (LPCWSTR)pDevice->RtCallbacks.pfnAllocateCb, + &pDevice->hHgsmiTransportModule)) + { + Assert(pDevice->hHgsmiTransportModule); + } + else + { + DWORD winEr = GetLastError(); + WARN(("GetModuleHandleEx failed winEr %d, ignoring", winEr)); + pDevice->hHgsmiTransportModule = 0; + } + } + vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter)); return hr; @@ -6102,8 +6399,9 @@ HRESULT APIENTRY OpenAdapter(__inout D3DDDIARG_OPENADAPTER* pOpenData) pAdapter->uRtVersion= pOpenData->Version; pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks; - pAdapter->cHeads = Query.cInfos; + pAdapter->u32VBox3DCaps = Query.u32VBox3DCaps; + pAdapter->cHeads = Query.cInfos; pOpenData->hAdapter = pAdapter; pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps; diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def index d4884561..2c69c887 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def @@ -3,7 +3,7 @@ ; ; VBoxDispD3D ; -; Copyright (C) 2011 Oracle Corporation +; Copyright (C) 2011-2012 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -16,4 +16,3 @@ EXPORTS OpenAdapter - VBoxDispMpGetCallbacks diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h index 8b8a4bfe..4b614e7e 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -20,7 +20,7 @@ #define ___VBoxDispD3D_h___ #include "VBoxDispD3DIf.h" -#include "common/wddm/VBoxMPIf.h" +#include "../../common/wddm/VBoxMPIf.h" #ifdef VBOX_WITH_CRHGSMI #include "VBoxUhgsmiDisp.h" #endif @@ -78,6 +78,7 @@ typedef struct VBOXWDDMDISP_ADAPTER D3DDDI_ADAPTERCALLBACKS RtCallbacks; VBOXWDDMDISP_D3D D3D; VBOXWDDMDISP_FORMATS Formats; + uint32_t u32VBox3DCaps; #ifdef VBOX_WDDMDISP_WITH_PROFILE VBoxDispProfileFpsCounter ProfileDdiFps; VBoxDispProfileSet ProfileDdiFunc; @@ -210,6 +211,10 @@ typedef struct VBOXWDDMDISP_DEVICE UINT cSamplerTextures; struct VBOXWDDMDISP_RESOURCE *aSamplerTextures[VBOXWDDMDISP_TOTAL_SAMPLERS]; + struct VBOXWDDMDISP_RESOURCE *pDepthStencilRc; + + HMODULE hHgsmiTransportModule; + #ifdef VBOX_WDDMDISP_WITH_PROFILE VBoxDispProfileFpsCounter ProfileDdiFps; VBoxDispProfileSet ProfileDdiFunc; @@ -261,13 +266,14 @@ typedef struct VBOXWDDMDISP_ALLOCATION UINT iAlloc; struct VBOXWDDMDISP_RESOURCE *pRc; void* pvMem; - UINT D3DWidth; /* object type is defined by enmD3DIfType enum */ IUnknown *pD3DIf; VBOXDISP_D3DIFTYPE enmD3DIfType; /* list entry used to add allocation to the dirty alloc list */ RTLISTNODE DirtyAllocListEntry; + BOOLEAN fEverWritten; BOOLEAN fDirtyWrite; + BOOLEAN fAllocLocked; HANDLE hSharedHandle; VBOXWDDMDISP_LOCKINFO LockInfo; VBOXWDDM_DIRTYREGION DirtyRegion; /* <- dirty region to notify host about */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def deleted file mode 100644 index ad901dc8..00000000 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def +++ /dev/null @@ -1,21 +0,0 @@ -; $Id: VBoxDispD3D64.def $ -; @file -; -; VBoxDispD3D 64bit -; -; Copyright (C) 2011 Oracle Corporation -; -; This file is part of VirtualBox Open Source Edition (OSE), as -; available from http://www.virtualbox.org. This file is free software; -; you can redistribute it and/or modify it under the terms of the GNU -; General Public License (GPL) as published by the Free Software -; Foundation, in version 2 as it comes in the "COPYING" file of the -; VirtualBox OSE distribution. VirtualBox OSE is distributed in the -; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. -; - -LIBRARY VBoxDispD3D64 - -EXPORTS - OpenAdapter - VBoxDispMpGetCallbacks diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h new file mode 100644 index 00000000..8599f75b --- /dev/null +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h @@ -0,0 +1,46 @@ +/* $Id: VBoxDispD3DBase.h $ */ +/** @file + * VBoxVideo Display D3D Base Include + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#ifndef __VBoxDispD3DBase_h_ +#define __VBoxDispD3DBase_h_ + +# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap +# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap +# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap +# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap +# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap +# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap +# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap +# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap +# pragma warning(disable : 4163) +#include <windows.h> +# pragma warning(default : 4163) +# undef _InterlockedExchange +# undef _InterlockedExchangeAdd +# undef _InterlockedCompareExchange +# undef _InterlockedAddLargeStatistic +# undef _interlockedbittestandset +# undef _interlockedbittestandreset +# undef _interlockedbittestandset64 +# undef _interlockedbittestandreset64 + +#include <d3d9types.h> +//#include <d3dtypes.h> +#include <D3dumddi.h> +#include <d3dhal.h> + + +#endif /* #ifndef __VBoxDispD3DBase_h_ */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h index 38609367..a71a108a 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -18,30 +18,7 @@ #ifndef ___VBoxDispD3DCmn_h___ #define ___VBoxDispD3DCmn_h___ -# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap -# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap -# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap -# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap -# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap -# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap -# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap -# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap -# pragma warning(disable : 4163) -#include <windows.h> -# pragma warning(default : 4163) -# undef _InterlockedExchange -# undef _InterlockedExchangeAdd -# undef _InterlockedCompareExchange -# undef _InterlockedAddLargeStatistic -# undef _interlockedbittestandset -# undef _interlockedbittestandreset -# undef _interlockedbittestandset64 -# undef _interlockedbittestandreset64 - -#include <d3d9types.h> -//#include <d3dtypes.h> -#include <D3dumddi.h> -#include <d3dhal.h> +#include "VBoxDispD3DBase.h" #include <iprt/initterm.h> #include <iprt/log.h> @@ -53,7 +30,7 @@ #include "VBoxDispDbg.h" #include "VBoxDispD3DIf.h" -#include "common/wddm/VBoxMPIf.h" +#include "../../common/wddm/VBoxMPIf.h" #include "VBoxDispCm.h" #include "VBoxDispMpInternal.h" #include "VBoxDispKmt.h" @@ -66,6 +43,7 @@ #ifndef IN_VBOXCRHGSMI #include "VBoxD3DIf.h" #endif +#include <cr_protocol.h> # ifdef VBOXWDDMDISP # define VBOXWDDMDISP_DECL(_type) DECLEXPORT(_type) diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp index 8ad6e5cb..a50780ca 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -27,18 +27,38 @@ void VBoxDispD3DClose(VBOXDISPD3D *pD3D) pD3D->hD3DLib = NULL; } +/** + * Loads a system DLL. + * + * @returns Module handle or NULL + * @param pszName The DLL name. + */ +static HMODULE loadSystemDll(const char *pszName) +{ + char szPath[MAX_PATH]; + UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath)); + size_t cbName = strlen(pszName) + 1; + if (cchPath + 1 + cbName > sizeof(szPath)) + { + SetLastError(ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + szPath[cchPath] = '\\'; + memcpy(&szPath[cchPath + 1], pszName, cbName); + return LoadLibraryA(szPath); +} HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D) { #ifdef VBOX_WDDM_WOW64 - pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm-x86.dll"); + pD3D->hD3DLib = loadSystemDll("VBoxD3D9wddm-x86.dll"); #else - pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm.dll"); + pD3D->hD3DLib = loadSystemDll("VBoxD3D9wddm.dll"); #endif if (!pD3D->hD3DLib) { DWORD winErr = GetLastError(); - WARN((__FUNCTION__": LoadLibraryW failed, winErr = (%d)", winErr)); + WARN((__FUNCTION__": LoadLibrary failed, winErr = (%d)", winErr)); return E_FAIL; } @@ -79,6 +99,20 @@ HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D) break; } + pD3D->pfnVBoxWineExD3DDev9FlushToHost = (PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9FlushToHost"); + if (!pD3D->pfnVBoxWineExD3DDev9FlushToHost) + { + WARN(("no VBoxWineExD3DDev9FlushToHost")); + break; + } + + pD3D->pfnVBoxWineExD3DDev9Finish = (PFNVBOXWINEEXD3DDEV9_FINISH)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Finish"); + if (!pD3D->pfnVBoxWineExD3DDev9Finish) + { + WARN(("no VBoxWineExD3DDev9Finish")); + break; + } + pD3D->pfnVBoxWineExD3DDev9VolBlt = (PFNVBOXWINEEXD3DDEV9_VOLBLT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9VolBlt"); if (!pD3D->pfnVBoxWineExD3DDev9VolBlt) { @@ -93,31 +127,45 @@ HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D) break; } - pD3D->pfnVBoxWineExD3DDev9Update = (PFNVBOXWINEEXD3DDEV9_UPDATE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Update"); - if (!pD3D->pfnVBoxWineExD3DDev9Update) + pD3D->pfnVBoxWineExD3DDev9Term = (PFNVBOXWINEEXD3DDEV9_TERM)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Term"); + if (!pD3D->pfnVBoxWineExD3DDev9Term) { - WARN(("no VBoxWineExD3DDev9Update")); + WARN(("no VBoxWineExD3DDev9Term")); break; } - pD3D->pfnVBoxWineExD3DDev9Term = (PFNVBOXWINEEXD3DDEV9_TERM)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Term"); - if (!pD3D->pfnVBoxWineExD3DDev9Term) + pD3D->pfnVBoxWineExD3DSwapchain9Present = (PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9Present"); + if (!pD3D->pfnVBoxWineExD3DSwapchain9Present) { - WARN(("no VBoxWineExD3DDev9Term")); + WARN(("no VBoxWineExD3DSwapchain9Present")); break; } - pD3D->pfnVBoxWineExD3DRc9SetShRcState = (PFNVBOXWINEEXD3DRC9_SETSHRCSTATE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DRc9SetShRcState"); - if (!pD3D->pfnVBoxWineExD3DRc9SetShRcState) + pD3D->pfnVBoxWineExD3DSurf9GetHostId = (PFNVBOXWINEEXD3DSURF9_GETHOSTID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9GetHostId"); + if (!pD3D->pfnVBoxWineExD3DSurf9GetHostId) { - WARN(("no VBoxWineExD3DRc9SetShRcState")); + WARN(("no VBoxWineExD3DSurf9GetHostId")); break; } - pD3D->pfnVBoxWineExD3DSwapchain9Present = (PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9Present"); - if (!pD3D->pfnVBoxWineExD3DSwapchain9Present) + pD3D->pfnVBoxWineExD3DSurf9SyncToHost = (PFNVBOXWINEEXD3DSURF9_SYNCTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9SyncToHost"); + if (!pD3D->pfnVBoxWineExD3DSurf9SyncToHost) { - WARN(("no VBoxWineExD3DSwapchain9Present")); + WARN(("no VBoxWineExD3DSurf9SyncToHost")); + break; + } + + pD3D->pfnVBoxWineExD3DSwapchain9GetHostWinID = (PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9GetHostWinID"); + if (!pD3D->pfnVBoxWineExD3DSwapchain9GetHostWinID) + { + WARN(("no VBoxWineExD3DSwapchain9GetHostWinID")); + break; + } + + pD3D->pfnVBoxWineExD3DDev9GetHostId = (PFNVBOXWINEEXD3DDEV9_GETHOSTID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9GetHostId"); + if (!pD3D->pfnVBoxWineExD3DDev9GetHostId) + { + WARN(("no VBoxWineExD3DDev9GetHostId")); break; } @@ -943,6 +991,56 @@ static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_D3D pD3D, D3DCAPS9 *pCaps) return hr; } + /* needed for Windows Media Player to work properly */ + pCaps->Caps |= D3DCAPS_READ_SCANLINE; + pCaps->Caps2 |= 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/; + pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE; + pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */ + /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */; + pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS + | D3DPMISCCAPS_FOGINFVF + | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS; + pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */; + pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE; + pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE; + pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE; + pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED; + pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4; + pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT; + pCaps->GuardBandLeft = -8192.; + pCaps->GuardBandTop = -8192.; + pCaps->GuardBandRight = 8192.; + pCaps->GuardBandBottom = 8192.; + pCaps->VS20Caps.DynamicFlowControlDepth = 24; + pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS; + pCaps->PS20Caps.DynamicFlowControlDepth = 24; + pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS; + + /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */ + if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300) + { + pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots); + pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots); + } +#if defined(DEBUG) + if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300) + { + Assert(pCaps->MaxVertexShader30InstructionSlots >= 512); + Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768); + Assert(pCaps->MaxPixelShader30InstructionSlots >= 512); + Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768); + } + else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200) + { + Assert(pCaps->MaxVertexShader30InstructionSlots == 0); + Assert(pCaps->MaxPixelShader30InstructionSlots == 0); + } + else + { + WARN(("incorect shader caps!")); + } +#endif + vboxDispDumpD3DCAPS9(pCaps); return S_OK; diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h index 9d534050..c112b26c 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -43,7 +43,11 @@ # undef _interlockedbittestandset64 # undef _interlockedbittestandreset64 +#ifdef VBOX_WITH_NEW_WINE +#include "../../../Wine_new/vbox/VBoxWineEx.h" +#else #include "../../../Wine/vbox/VBoxWineEx.h" +#endif /* D3D functionality the VBOXDISPD3D provides */ typedef HRESULT WINAPI FNVBOXDISPD3DCREATE9EX(UINT SDKVersion, IDirect3D9Ex **ppD3D); @@ -66,14 +70,22 @@ typedef struct VBOXDISPD3D PFNVBOXWINEEXD3DDEV9_VOLTEXBLT pfnVBoxWineExD3DDev9VolTexBlt; - PFNVBOXWINEEXD3DDEV9_UPDATE pfnVBoxWineExD3DDev9Update; - PFNVBOXWINEEXD3DDEV9_TERM pfnVBoxWineExD3DDev9Term; - PFNVBOXWINEEXD3DRC9_SETSHRCSTATE pfnVBoxWineExD3DRc9SetShRcState; - PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT pfnVBoxWineExD3DSwapchain9Present; + PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST pfnVBoxWineExD3DDev9FlushToHost; + + PFNVBOXWINEEXD3DDEV9_FINISH pfnVBoxWineExD3DDev9Finish; + + PFNVBOXWINEEXD3DSURF9_GETHOSTID pfnVBoxWineExD3DSurf9GetHostId; + + PFNVBOXWINEEXD3DSURF9_SYNCTOHOST pfnVBoxWineExD3DSurf9SyncToHost; + + PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID pfnVBoxWineExD3DSwapchain9GetHostWinID; + + PFNVBOXWINEEXD3DDEV9_GETHOSTID pfnVBoxWineExD3DDev9GetHostId; + /* module handle */ HMODULE hD3DLib; } VBOXDISPD3D; diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp index ad5fdf3f..da7af03c 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -84,14 +84,19 @@ static void vboxDispLogDbgFormatStringV(char * szBuffer, uint32_t cbBuffer, cons LONG g_VBoxVDbgFIsDwm = -1; DWORD g_VBoxVDbgPid = 0; -#endif - -#ifdef VBOXWDDMDISP_DEBUG DWORD g_VBoxVDbgFLogRel = 1; +# if !defined(VBOXWDDMDISP_DEBUG) +DWORD g_VBoxVDbgFLog = 0; +# else DWORD g_VBoxVDbgFLog = 1; +# endif DWORD g_VBoxVDbgFLogFlow = 0; +#endif + +#ifdef VBOXWDDMDISP_DEBUG + # ifndef IN_VBOXCRHGSMI #define VBOXWDDMDISP_DEBUG_DUMP_DEFAULT 0 DWORD g_VBoxVDbgFDumpSetTexture = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT; @@ -156,9 +161,9 @@ VOID vboxVDbgDoPrintLopLastCmd(const char* pszDesc) typedef struct VBOXVDBG_DUMP_INFO { DWORD fFlags; - PVBOXWDDMDISP_ALLOCATION pAlloc; + const VBOXWDDMDISP_ALLOCATION *pAlloc; IDirect3DResource9 *pD3DRc; - RECT *pRect; + const RECT *pRect; } VBOXVDBG_DUMP_INFO, *PVBOXVDBG_DUMP_INFO; typedef DECLCALLBACK(void) FNVBOXVDBG_CONTENTS_DUMPER(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper); @@ -166,7 +171,7 @@ typedef FNVBOXVDBG_CONTENTS_DUMPER *PFNVBOXVDBG_CONTENTS_DUMPER; static VOID vboxVDbgDoDumpSummary(const char * pPrefix, PVBOXVDBG_DUMP_INFO pInfo, const char * pSuffix) { - PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc; + const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc; IDirect3DResource9 *pD3DRc = pInfo->pD3DRc; char rectBuf[24]; if (pInfo->pRect) @@ -219,7 +224,7 @@ VOID vboxVDbgDoDumpPerform(const char * pPrefix, PVBOXVDBG_DUMP_INFO pInfo, cons static DECLCALLBACK(void) vboxVDbgAllocRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper) { - PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc; + const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc; const RECT *pRect = pInfo->pRect; Assert(pAlloc->hAllocation); @@ -241,7 +246,7 @@ static DECLCALLBACK(void) vboxVDbgAllocRectContentsDumperCb(PVBOXVDBG_DUMP_INFO if (hr == S_OK) { UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format); - vboxVDbgDoPrintDumpCmd("Surf Info", LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch); + vboxVDbgDoPrintDumpCmd("Surf Info", LockData.pData, pAlloc->SurfDesc.d3dWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch); if (pRect) { Assert(pRect->right > pRect->left); @@ -274,7 +279,7 @@ VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAll static DECLCALLBACK(void) vboxVDbgRcRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper) { - PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc; + const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc; IDirect3DResource9 *pD3DRc = pInfo->pD3DRc; const RECT *pRect = pInfo->pRect; IDirect3DSurface9 *pSurf; @@ -314,6 +319,8 @@ static DECLCALLBACK(void) vboxVDbgRcRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pIn Assert(hr == S_OK); } } + + pSurf->Release(); } VOID vboxVDbgDoDumpRcRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, @@ -417,8 +424,8 @@ VOID vboxVDbgDoDumpSamplers(const char * pPrefix, PVBOXWDDMDISP_DEVICE pDevice, static DECLCALLBACK(void) vboxVDbgLockUnlockSurfTexContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper) { - PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc; - PRECT pRect = pInfo->pRect; + const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc; + const RECT *pRect = pInfo->pRect; UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format); uint32_t width, height, pitch; void *pvData; @@ -451,11 +458,12 @@ static DECLCALLBACK(void) vboxVDbgLockUnlockSurfTexContentsDumperCb(PVBOXVDBG_DU } } -VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, const char * pSuffix, DWORD fFlags) +VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const VBOXWDDMDISP_ALLOCATION *pAlloc, const char * pSuffix, DWORD fFlags) { Assert(!pAlloc->hSharedHandle); - RECT Rect, *pRect; + RECT Rect; + const RECT *pRect; Assert(!pAlloc->LockInfo.fFlags.RangeValid); Assert(!pAlloc->LockInfo.fFlags.BoxValid); if (pAlloc->LockInfo.fFlags.AreaValid) @@ -481,16 +489,19 @@ VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_A VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, DWORD fFlags) { - const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource; - const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; - pAlloc->LockInfo.pvData = pData->pSurfData; + const VBOXWDDMDISP_RESOURCE *pRc = (const VBOXWDDMDISP_RESOURCE*)pData->hResource; + const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; +#ifdef VBOXWDDMDISP_DEBUG + VBOXWDDMDISP_ALLOCATION *pUnconstpAlloc = (VBOXWDDMDISP_ALLOCATION *)pAlloc; + pUnconstpAlloc->LockInfo.pvData = pData->pSurfData; +#endif vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fFlags); } VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, DWORD fFlags) { - const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource; - const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; + const VBOXWDDMDISP_RESOURCE *pRc = (const VBOXWDDMDISP_RESOURCE*)pData->hResource; + const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fFlags); } @@ -528,8 +539,8 @@ BOOL vboxVDbgDoCheckLRects(D3DLOCKED_RECT *pDstLRect, const RECT *pDstRect, D3DL return fMatch; } -BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDstAlloc, - const PVBOXWDDMDISP_RESOURCE pSrcRc, uint32_t iSrcAlloc, +BOOL vboxVDbgDoCheckRectsMatch(const VBOXWDDMDISP_RESOURCE *pDstRc, uint32_t iDstAlloc, + const VBOXWDDMDISP_RESOURCE *pSrcRc, uint32_t iSrcAlloc, const RECT *pDstRect, const RECT *pSrcRect, BOOL fBreakOnMismatch) @@ -592,46 +603,46 @@ BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDs } D3DLOCKED_RECT SrcLRect, DstLRect; - HRESULT hr = VBoxD3DIfLockRect(pDstRc, iDstAlloc, &DstLRect, pDstRect, D3DLOCK_READONLY); + HRESULT hr = VBoxD3DIfLockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc, &DstLRect, pDstRect, D3DLOCK_READONLY); if (FAILED(hr)) { WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr)); return FALSE; } - hr = VBoxD3DIfLockRect(pSrcRc, iSrcAlloc, &SrcLRect, pSrcRect, D3DLOCK_READONLY); + hr = VBoxD3DIfLockRect((VBOXWDDMDISP_RESOURCE *)pSrcRc, iSrcAlloc, &SrcLRect, pSrcRect, D3DLOCK_READONLY); if (FAILED(hr)) { WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr)); - hr = VBoxD3DIfUnlockRect(pDstRc, iDstAlloc); + hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc); return FALSE; } fMatch = vboxVDbgDoCheckLRects(&DstLRect, pDstRect, &SrcLRect, pSrcRect, bpp, fBreakOnMismatch); - hr = VBoxD3DIfUnlockRect(pDstRc, iDstAlloc); + hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc); Assert(hr == S_OK); - hr = VBoxD3DIfUnlockRect(pSrcRc, iSrcAlloc); + hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pSrcRc, iSrcAlloc); Assert(hr == S_OK); return fMatch; } -void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix) +void vboxVDbgDoPrintAlloc(const char * pPrefix, const VBOXWDDMDISP_RESOURCE *pRc, uint32_t iAlloc, const char * pSuffix) { Assert(pRc->cAllocations > iAlloc); - const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc]; + const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[iAlloc]; BOOL bPrimary = pRc->RcDesc.fFlags.Primary; BOOL bFrontBuf = FALSE; if (bPrimary) { - PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc); + PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc((VBOXWDDMDISP_ALLOCATION *)pAlloc); Assert(pSwapchain); bFrontBuf = (vboxWddmSwapchainGetFb(pSwapchain)->pAlloc == pAlloc); } - vboxVDbgPrint(("%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix, - pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format, + vboxVDbgPrint(("%s d3dWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix, + pAlloc->SurfDesc.d3dWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format, bPrimary ? (bFrontBuf ? "Front Buffer" : "Back Buffer") : "?Everage? Alloc", diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h index 9c5798b4..df5a14bb 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -49,11 +49,6 @@ //# define VBOXWDDMDISP_DEBUG_TIMER # endif -/* log enable flags */ -extern DWORD g_VBoxVDbgFLogRel; -extern DWORD g_VBoxVDbgFLog; -extern DWORD g_VBoxVDbgFLogFlow; - # ifndef IN_VBOXCRHGSMI /* debug config vars */ extern DWORD g_VBoxVDbgFDumpSetTexture; @@ -90,6 +85,13 @@ extern DWORD g_VBoxVDbgCfgCreateSwapchainOnDdiOnce; # endif /* #ifndef IN_VBOXCRHGSMI */ #endif +#if defined(VBOXWDDMDISP_DEBUG) || defined(VBOX_WDDMDISP_WITH_PROFILE) +/* log enable flags */ +extern DWORD g_VBoxVDbgFLogRel; +extern DWORD g_VBoxVDbgFLog; +extern DWORD g_VBoxVDbgFLogFlow; +#endif + #ifdef VBOXWDDMDISP_DEBUG_VEHANDLER void vboxVDbgVEHandlerRegister(); void vboxVDbgVEHandlerUnregister(); @@ -115,7 +117,7 @@ void vboxVDbgVEHandlerUnregister(); # define DbgPrintUsrFlow(_m) do { } while (0) #endif -#ifdef VBOXWDDMDISP_DEBUG +#if defined(VBOXWDDMDISP_DEBUG) || defined(VBOX_WDDMDISP_WITH_PROFILE) #define vboxVDbgInternalLog(_p) if (g_VBoxVDbgFLog) { _p } #define vboxVDbgInternalLogFlow(_p) if (g_VBoxVDbgFLogFlow) { _p } #define vboxVDbgInternalLogRel(_p) if (g_VBoxVDbgFLogRel) { _p } @@ -233,20 +235,20 @@ typedef struct VBOXWDDMDISP_RESOURCE *PVBOXWDDMDISP_RESOURCE; VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, RECT *pRect, const char* pSuffix, DWORD fFlags); VOID vboxVDbgDoDumpRcRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DResource9 *pD3DRc, RECT *pRect, const char * pSuffix, DWORD fFlags); -VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, const char * pSuffix, DWORD fFlags); +VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const VBOXWDDMDISP_ALLOCATION *pAlloc, const char * pSuffix, DWORD fFlags); VOID vboxVDbgDoDumpRt(const char * pPrefix, struct VBOXWDDMDISP_DEVICE *pDevice, const char * pSuffix, DWORD fFlags); VOID vboxVDbgDoDumpBb(const char * pPrefix, IDirect3DSwapChain9 *pSwapchainIf, const char * pSuffix, DWORD fFlags); VOID vboxVDbgDoDumpFb(const char * pPrefix, IDirect3DSwapChain9 *pSwapchainIf, const char * pSuffix, DWORD fFlags); VOID vboxVDbgDoDumpSamplers(const char * pPrefix, struct VBOXWDDMDISP_DEVICE *pDevice, const char * pSuffix, DWORD fFlags); void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix); -void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix); +void vboxVDbgDoPrintAlloc(const char * pPrefix, const VBOXWDDMDISP_RESOURCE *pRc, uint32_t iAlloc, const char * pSuffix); VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, DWORD fFlags); VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, DWORD fFlags); -BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDstAlloc, - const PVBOXWDDMDISP_RESOURCE pSrcRc, uint32_t iSrcAlloc, +BOOL vboxVDbgDoCheckRectsMatch(const VBOXWDDMDISP_RESOURCE *pDstRc, uint32_t iDstAlloc, + const VBOXWDDMDISP_RESOURCE *pSrcRc, uint32_t iSrcAlloc, const RECT *pDstRect, const RECT *pSrcRect, BOOL fBreakOnMismatch); diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp index 081088a4..200fa44c 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -16,19 +16,41 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -#include "VBoxDispD3DCmn.h" +#include "VBoxDispD3DBase.h" +#include "VBoxDispKmt.h" + +#include <iprt/assert.h> +#include <iprt/log.h> #ifndef NT_SUCCESS # define NT_SUCCESS(_Status) ((_Status) >= 0) #endif +/** + * Loads a system DLL. + * + * @returns Module handle or NULL + * @param pszName The DLL name. + */ +static HMODULE loadSystemDll(const char *pszName) +{ + char szPath[MAX_PATH]; + UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath)); + size_t cbName = strlen(pszName) + 1; + if (cchPath + 1 + cbName > sizeof(szPath)) + return NULL; + szPath[cchPath] = '\\'; + memcpy(&szPath[cchPath + 1], pszName, cbName); + return LoadLibraryA(szPath); +} + HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks) { HRESULT hr = S_OK; memset(pCallbacks, 0, sizeof (*pCallbacks)); - pCallbacks->hGdi32 = LoadLibraryW(L"gdi32.dll"); + pCallbacks->hGdi32 = loadSystemDll("gdi32.dll"); if (pCallbacks->hGdi32 != NULL) { bool bSupported = true; @@ -49,7 +71,11 @@ HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks) Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pCallbacks->pfnD3DKMTEscape)); bSupported &= !!(pCallbacks->pfnD3DKMTEscape); - pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice"); + pCallbacks->pfnD3DKMTQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress(pCallbacks->hGdi32, "D3DKMTQueryAdapterInfo"); + Log((__FUNCTION__": pfnD3DKMTQueryAdapterInfo = %p\n", pCallbacks->pfnD3DKMTQueryAdapterInfo)); + bSupported &= !!(pCallbacks->pfnD3DKMTQueryAdapterInfo); + + pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice"); Log((__FUNCTION__": pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice)); bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice); @@ -85,6 +111,14 @@ HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks) Log((__FUNCTION__": pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock)); bSupported &= !!(pCallbacks->pfnD3DKMTUnlock); + pCallbacks->pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTInvalidateActiveVidPn"); + Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pCallbacks->pfnD3DKMTInvalidateActiveVidPn)); + bSupported &= !!(pCallbacks->pfnD3DKMTInvalidateActiveVidPn); + + pCallbacks->pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTPollDisplayChildren"); + Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren = %p\n", pCallbacks->pfnD3DKMTPollDisplayChildren)); + bSupported &= !!(pCallbacks->pfnD3DKMTPollDisplayChildren); + pCallbacks->pfnD3DKMTEnumAdapters = (PFND3DKMT_ENUMADAPTERS)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEnumAdapters"); Log((__FUNCTION__": pfnD3DKMTEnumAdapters = %p\n", pCallbacks->pfnD3DKMTEnumAdapters)); /* this present starting win8 release preview only, so keep going if it is not available, @@ -185,7 +219,7 @@ HRESULT vboxDispKmtAdpHdcCreate(HDC *phDc) return hr; } -static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) +static HRESULT vboxDispKmtOpenAdapterViaHdc(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) { D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0}; HRESULT hr = vboxDispKmtAdpHdcCreate(&OpenAdapterData.hDc); @@ -194,10 +228,6 @@ static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, P Assert(OpenAdapterData.hDc); NTSTATUS Status = pCallbacks->pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData); -#ifdef DEBUG_misha - /* may fail with xpdm driver */ - Assert(NT_SUCCESS(Status)); -#endif if (NT_SUCCESS(Status)) { pAdapter->hAdapter = OpenAdapterData.hAdapter; @@ -217,7 +247,7 @@ static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, P return hr; } -static HRESULT vboxDispKmtOpenAdapterViaLuid(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) +static HRESULT vboxDispKmtOpenAdapterViaLuid(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) { if (pCallbacks->enmVersion < VBOXDISPKMT_CALLBACKS_VERSION_WIN8) return E_NOTIMPL; @@ -266,7 +296,7 @@ static HRESULT vboxDispKmtOpenAdapterViaLuid(PVBOXDISPKMT_CALLBACKS pCallbacks, return E_FAIL; } -HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) +HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) { HRESULT hr = vboxDispKmtOpenAdapterViaHdc(pCallbacks, pAdapter); if (SUCCEEDED(hr)) diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h index 54fe974b..6c481a72 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -21,6 +21,8 @@ #include <D3dkmthk.h> +#include "../../common/wddm/VBoxMPIf.h" + /* win8 release preview-specific stuff */ typedef struct _D3DKMT_ADAPTERINFO { @@ -68,6 +70,8 @@ typedef struct VBOXDISPKMT_CALLBACKS /* escape */ PFND3DKMT_ESCAPE pfnD3DKMTEscape; + PFND3DKMT_QUERYADAPTERINFO pfnD3DKMTQueryAdapterInfo; + PFND3DKMT_CREATEDEVICE pfnD3DKMTCreateDevice; PFND3DKMT_DESTROYDEVICE pfnD3DKMTDestroyDevice; PFND3DKMT_CREATECONTEXT pfnD3DKMTCreateContext; @@ -81,6 +85,11 @@ typedef struct VBOXDISPKMT_CALLBACKS PFND3DKMT_LOCK pfnD3DKMTLock; PFND3DKMT_UNLOCK pfnD3DKMTUnlock; + /* auto resize support */ + PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn; + PFND3DKMT_POLLDISPLAYCHILDREN pfnD3DKMTPollDisplayChildren; + + /* win8 specifics */ PFND3DKMT_ENUMADAPTERS pfnD3DKMTEnumAdapters; PFND3DKMT_OPENADAPTERFROMLUID pfnD3DKMTOpenAdapterFromLuid; } VBOXDISPKMT_CALLBACKS, *PVBOXDISPKMT_CALLBACKS; @@ -90,7 +99,7 @@ typedef struct VBOXDISPKMT_ADAPTER D3DKMT_HANDLE hAdapter; HDC hDc; LUID Luid; - PVBOXDISPKMT_CALLBACKS pCallbacks; + const VBOXDISPKMT_CALLBACKS *pCallbacks; }VBOXDISPKMT_ADAPTER, *PVBOXDISPKMT_ADAPTER; typedef struct VBOXDISPKMT_DEVICE @@ -120,7 +129,7 @@ typedef struct VBOXDISPKMT_CONTEXT HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks); HRESULT vboxDispKmtCallbacksTerm(PVBOXDISPKMT_CALLBACKS pCallbacks); -HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter); +HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter); HRESULT vboxDispKmtCloseAdapter(PVBOXDISPKMT_ADAPTER pAdapter); HRESULT vboxDispKmtCreateDevice(PVBOXDISPKMT_ADAPTER pAdapter, PVBOXDISPKMT_DEVICE pDevice); HRESULT vboxDispKmtDestroyDevice(PVBOXDISPKMT_DEVICE pDevice); diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp index 182354e2..e7e06e93 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -18,7 +18,7 @@ #include "VBoxDispD3DCmn.h" #include "VBoxDispMp.h" - +#if 0 #include <iprt/assert.h> typedef struct VBOXVIDEOCM_ITERATOR @@ -293,3 +293,4 @@ HRESULT vboxDispMpInternalCancel(VBOXWDDMDISP_CONTEXT *pContext, PVBOXWDDMDISP_S LeaveCriticalSection(&g_VBoxDispMp.CritSect); return hr; } +#endif /* 0 */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h index c91db2a2..c643f713 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -25,6 +25,7 @@ #include <d3dhal.h> #include "../../common/wddm/VBoxMPIf.h" +#if 0 typedef struct VBOXDISPMP_REGIONS { HWND hWnd; @@ -80,5 +81,5 @@ typedef struct VBOXDISPMP_CALLBACKS */ typedef VBOXDISPMP_DECL(HRESULT) FNVBOXDISPMP_GETCALLBACKS(uint32_t u32Version, PVBOXDISPMP_CALLBACKS pCallbacks); typedef FNVBOXDISPMP_GETCALLBACKS *PFNVBOXDISPMP_GETCALLBACKS; - +#endif /* 0 */ #endif /* #ifndef ___VBoxDispMp_h___ */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h index 0f159634..b0bd9718 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h @@ -21,8 +21,10 @@ #include <windows.h> +#if 0 HRESULT vboxDispMpInternalInit(); HRESULT vboxDispMpInternalTerm(); HRESULT vboxDispMpInternalCancel(struct VBOXWDDMDISP_CONTEXT *pContext, struct VBOXWDDMDISP_SWAPCHAIN *pSwapchain); +#endif #endif /* #ifndef ___VBoxDispMpInternal_h__ */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp deleted file mode 100644 index 679dc91e..00000000 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* $Id: VBoxDispMpTst.cpp $ */ - -/** @file - * VBoxVideo Display D3D User mode dll - */ - -/* - * Copyright (C) 2011 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ - -#include "VBoxDispD3DCmn.h" -#include "VBoxDispMp.h" - -#include <iprt/thread.h> -#include <iprt/err.h> - -#ifdef VBOXWDDM_TEST_UHGSMI -#include "VBoxDispProfile.h" -#endif - -static RTTHREAD g_VBoxDispMpTstThread; -static VBOXDISPMP_CALLBACKS g_VBoxDispMpTstCallbacks; -static HMODULE g_hVBoxDispMpModule; -static PFNVBOXDISPMP_GETCALLBACKS g_pfnVBoxDispMpGetCallbacks; - - -static void vboxDispMpTstLogRect(const char * pPrefix, RECT *pRect, const char * pSuffix) -{ - vboxVDbgPrint(("%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix)); -} - -static DECLCALLBACK(int) vboxDispMpTstThreadProc(RTTHREAD ThreadSelf, void *pvUser) -{ - VBOXDISPMP_REGIONS Regions; - - HRESULT hr = g_VBoxDispMpTstCallbacks.pfnEnableEvents(); - Assert(hr == S_OK); - if (hr != S_OK) - return VERR_GENERAL_FAILURE; - - do - { - hr = g_VBoxDispMpTstCallbacks.pfnGetRegions(&Regions, INFINITE); - Assert(hr == S_OK); - if (hr == S_OK) - { - vboxVDbgPrint(("\n>>>\n")); - HWND hWnd = Regions.hWnd; - if (Regions.pRegions->fFlags.bAddVisibleRects) - { - uint32_t iVisibleRects = 0; - uint32_t cVisibleRects = Regions.pRegions->RectsInfo.cRects; - if (Regions.pRegions->fFlags.bSetViewRect) - { - iVisibleRects = 1; - - vboxVDbgPrint(("hWnd (0x%p), position and/or size changed: ", hWnd)); - vboxDispMpTstLogRect("", Regions.pRegions->RectsInfo.aRects, "\n"); - } - - vboxVDbgPrint(("hWnd (0x%p), visibleRects: \n", hWnd)); - for (uint32_t i = iVisibleRects; i < cVisibleRects; ++i) - { - vboxDispMpTstLogRect("", &Regions.pRegions->RectsInfo.aRects[i], ""); - } - } - else if (Regions.pRegions->fFlags.bAddHiddenRects) - { - vboxVDbgPrint(("hWnd (0x%p), hiddenRects: \n", hWnd)); - for (uint32_t i = 0; i < Regions.pRegions->RectsInfo.cRects; ++i) - { - vboxDispMpTstLogRect("", &Regions.pRegions->RectsInfo.aRects[i], ""); - } - } - - vboxVDbgPrint(("\n<<<\n")); - } - } while (1); - - hr = g_VBoxDispMpTstCallbacks.pfnDisableEvents(); - Assert(hr == S_OK); - - return VINF_SUCCESS; -} - -HRESULT vboxDispMpTstStart() -{ - HRESULT hr = E_FAIL; - g_hVBoxDispMpModule = GetModuleHandleW(L"VBoxDispD3D.dll"); - Assert(g_hVBoxDispMpModule); - - if (g_hVBoxDispMpModule) - { - g_pfnVBoxDispMpGetCallbacks = (PFNVBOXDISPMP_GETCALLBACKS)GetProcAddress(g_hVBoxDispMpModule, "VBoxDispMpGetCallbacks"); - Assert(g_pfnVBoxDispMpGetCallbacks); - if (g_pfnVBoxDispMpGetCallbacks) - { - hr = g_pfnVBoxDispMpGetCallbacks(VBOXDISPMP_VERSION, &g_VBoxDispMpTstCallbacks); - Assert(hr == S_OK); - if (hr == S_OK) - { - int rc = RTThreadCreate(&g_VBoxDispMpTstThread, vboxDispMpTstThreadProc, NULL, 0, - RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxDispMpTst"); - AssertRC(rc); - if (RT_SUCCESS(rc)) - return S_OK; - - hr = E_FAIL; - } - } - FreeLibrary(g_hVBoxDispMpModule); - } - - return hr; -} - -HRESULT vboxDispMpTstStop() -{ - HRESULT hr = g_VBoxDispMpTstCallbacks.pfnDisableEvents(); - Assert(hr == S_OK); -#if 0 - if (hr == S_OK) - { - int rc = RTThreadWaitNoResume(g_VBoxDispMpTstThread, RT_INDEFINITE_WAIT, NULL); - AssertRC(rc); - if (RT_SUCCESS(rc)) - { - BOOL bResult = FreeLibrary(g_hVBoxDispMpModule); - Assert(bResult); -#ifdef DEBUG - if (!bResult) - { - DWORD winEr = GetLastError(); - hr = HRESULT_FROM_WIN32(winEr); - } -#endif - } - else - hr = E_FAIL; - } -#endif - return hr; -} - -#ifdef VBOXWDDM_TEST_UHGSMI -int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs) -{ - PVBOXUHGSMI_BUFFER pBuf; - int rc = pUhgsmi->pfnBufferCreate(pUhgsmi, cbBuf, VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT, NULL, &pBuf); - AssertRC(rc); - if (RT_SUCCESS(rc)) - { - uint64_t TimeMs = VBOXDISPPROFILE_GET_TIME_MILLI(); - do - { - VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags; - fFlags.Value = 0; - fFlags.bLockEntire = 1; - fFlags.bDiscard = 1; - - void *pvLock; - rc = pBuf->pfnLock(pBuf, 0, cbBuf, fFlags, &pvLock); - AssertRC(rc); - if (!RT_SUCCESS(rc)) - break; - - rc = pBuf->pfnUnlock(pBuf); - AssertRC(rc); - if (!RT_SUCCESS(rc)) - break; - - VBOXUHGSMI_BUFFER_SUBMIT SubmitData; - SubmitData.pBuf = pBuf; - SubmitData.fFlags.Value = 0; - SubmitData.fFlags.bDoNotRetire = 1; - SubmitData.fFlags.bEntireBuffer = 1; - - rc = pUhgsmi->pfnBufferSubmitAsynch(pUhgsmi, &SubmitData, 1); - AssertRC(rc); - if (!RT_SUCCESS(rc)) - break; - - DWORD dw = WaitForSingleObject(pBuf->hSynch, INFINITE); - Assert(dw == WAIT_OBJECT_0); - if (dw) - break; - } while (--cNumCals); - - TimeMs = VBOXDISPPROFILE_GET_TIME_MILLI() - TimeMs; - *pTimeMs = TimeMs; - - pBuf->pfnDestroy(pBuf); - } - return rc; -} -#endif diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h index a732762e..4e62c621 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -77,11 +77,19 @@ public: // VBOXDISPPROFILE_DUMP((pDevice, "Entry '%s': calls(%d), time: nanos(%I64u), micros(%I64u), millis(%I64u)\n", // m_pName, m_cCalls, // m_cTime, m_cTime/1000, m_cTime/1000000)); - VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%u\t%u\t%u\t%u", m_pName, pvObj, + +// VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%u\t%u\t%f\t%f", m_pName, pvObj, +// m_cCalls, +// (uint32_t)m_cTime, (uint32_t)(m_cTime/1000), (uint32_t)(m_cTime/1000000), +// (((double)m_cTime)/cTotalEntriesTime), +// (((double)m_cTime)/cTotalTime))); + + VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%f\t%f", m_pName, pvObj, m_cCalls, - (uint32_t)m_cTime, (uint32_t)(m_cTime/1000), (uint32_t)(m_cTime/1000000), - (uint32_t)(((double)m_cTime)/cTotalEntriesTime), - (uint32_t)(((double)m_cTime)/cTotalTime))); + (uint32_t)(m_cTime/1000000), + (((double)m_cTime)/cTotalEntriesTime), + (((double)m_cTime)/cTotalTime))); + } private: uint32_t m_cCalls; @@ -193,11 +201,18 @@ private: const char * m_pName; }; -template<typename T> class VBoxDispProfileScopeLogger +class VBoxDispProfileDummyPostProcess +{ +public: + void postProcess(){} +}; + +template<typename T, typename P> class VBoxDispProfileScopeLogger { public: - VBoxDispProfileScopeLogger(T *pEntry) : + VBoxDispProfileScopeLogger(T *pEntry, P PostProcess) : m_pEntry(pEntry), + m_PostProcess(PostProcess), m_bDisable(FALSE) { m_cTime = VBOXDISPPROFILE_GET_TIME_NANO(); @@ -225,10 +240,12 @@ public: private: void logStep() { + m_PostProcess.postProcess(); uint64_t cNewTime = VBOXDISPPROFILE_GET_TIME_NANO(); m_pEntry->step(cNewTime - m_cTime); } T *m_pEntry; + P m_PostProcess; uint64_t m_cTime; BOOL m_bDisable; }; @@ -372,18 +389,18 @@ private: } while (0) #ifdef VBOXDISPPROFILE_FUNCTION_LOGGER_GLOBAL_PROFILE -# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p) \ +# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \ static VBoxDispProfileEntry * __pVBoxDispProfileEntry = NULL; \ if (!__pVBoxDispProfileEntry) { __pVBoxDispProfileEntry = _p.alloc(__FUNCTION__); } \ - VBoxDispProfileScopeLogger<VBoxDispProfileEntry> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry); + VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v); #else # ifndef VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN # error "VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN should be fedined!" # endif -# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p) \ +# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \ static uint32_t __u32VBoxDispProfileIndex = VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN(); \ VBoxDispProfileEntry * __pVBoxDispProfileEntry = _p.get(__u32VBoxDispProfileIndex, __FUNCTION__); \ - VBoxDispProfileScopeLogger<VBoxDispProfileEntry> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry); + VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v); #endif #define VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT() do { \ @@ -395,8 +412,8 @@ private: } while (0) -#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p) \ - VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter> __vboxDispProfileStatisticLogger(_p); +#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p, _T, _v) \ + VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter, _T> __vboxDispProfileStatisticLogger(_p, _v); //#define VBOXDISPPROFILE_FUNCTION_PROLOGUE(_p) \ // VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p) diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp index 0345bbc9..d225e339 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp @@ -1,11 +1,10 @@ /* $Id: VBoxScreen.cpp $ */ - /** @file * VBoxVideo Display D3D User mode dll */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -340,6 +339,24 @@ static HRESULT vboxScreenMonWndDestroy(HWND hWnd) return HRESULT_FROM_WIN32(winErr); } +/** + * Loads a system DLL. + * + * @returns Module handle or NULL + * @param pszName The DLL name. + */ +static HMODULE loadSystemDll(const char *pszName) +{ + char szPath[MAX_PATH]; + UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath)); + size_t cbName = strlen(pszName) + 1; + if (cchPath + 1 + cbName > sizeof(szPath)) + return NULL; + szPath[cchPath] = '\\'; + memcpy(&szPath[cchPath + 1], pszName, cbName); + return LoadLibraryA(szPath); +} + //HRESULT vboxScreenMonInit(PVBOXSCREENMON pMon) HRESULT vboxScreenMonInit() { @@ -350,7 +367,7 @@ HRESULT vboxScreenMonInit() pMon->LoData.ScreenLayout.EscapeHdr.escapeCode = VBOXESC_SCREENLAYOUT; - pMon->hGdi32 = LoadLibraryW(L"gdi32.dll"); + pMon->hGdi32 = loadSystemDll("gdi32.dll"); if (pMon->hGdi32 != NULL) { bool bSupported = true; diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp index 939cba60..6ac9d7e7 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp @@ -32,7 +32,7 @@ DECLCALLBACK(int) vboxUhgsmiBaseEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf) int vboxUhgsmiBaseBufferTerm(PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer) { - PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pBuffer->PrivateBase.pHgsmi); + PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pBuffer->BasePrivate.pHgsmi); VBOXDISPIFESCAPE_UHGSMI_DEALLOCATE DeallocInfo = {0}; DeallocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_DEALLOCATE; DeallocInfo.hAlloc = pBuffer->Alloc.hAlloc; @@ -97,12 +97,12 @@ int vboxUhgsmiKmtEscBufferInit(PVBOXUHGSMI_PRIVATE_BASE pPrivate, PVBOXUHGSMI_BU pBuffer->Alloc = AllocInfo.Alloc; Assert(pBuffer->Alloc.pvData); - pBuffer->PrivateBase.pHgsmi = pPrivate; - pBuffer->PrivateBase.Base.pfnLock = vboxUhgsmiBaseEscBufferLock; - pBuffer->PrivateBase.Base.pfnUnlock = vboxUhgsmiBaseEscBufferUnlock; - pBuffer->PrivateBase.Base.pfnDestroy = pfnDestroy; - pBuffer->PrivateBase.Base.fType = fUhgsmiType; - pBuffer->PrivateBase.Base.cbBuffer = AllocInfo.Alloc.cbData; + pBuffer->BasePrivate.pHgsmi = pPrivate; + pBuffer->BasePrivate.Base.pfnLock = vboxUhgsmiBaseEscBufferLock; + pBuffer->BasePrivate.Base.pfnUnlock = vboxUhgsmiBaseEscBufferUnlock; + pBuffer->BasePrivate.Base.pfnDestroy = pfnDestroy; + pBuffer->BasePrivate.Base.fType = fUhgsmiType; + pBuffer->BasePrivate.Base.cbBuffer = AllocInfo.Alloc.cbData; pBuffer->hSynch = hSynch; return VINF_SUCCESS; } @@ -136,7 +136,7 @@ DECLCALLBACK(int) vboxUhgsmiBaseEscBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbB int rc = vboxUhgsmiKmtEscBufferInit(pPrivate, pBuffer, cbBuf, fUhgsmiType, vboxUhgsmiBaseEscBufferDestroy); if (RT_SUCCESS(rc)) { - *ppBuf = &pBuffer->PrivateBase.Base; + *ppBuf = &pBuffer->BasePrivate.Base; return VINF_SUCCESS; } @@ -177,11 +177,10 @@ DECLCALLBACK(int) vboxUhgsmiBaseEscBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_ PVBOXUHGSMI_BUFFER_SUBMIT pBufInfo = &aBuffers[i]; PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuf = VBOXUHGSMIESCBASE_GET_BUFFER(pBufInfo->pBuf); pSubmInfo->hAlloc = pBuf->Alloc.hAlloc; - pSubmInfo->Info.bDoNotSignalCompletion = 0; if (pBufInfo->fFlags.bEntireBuffer) { pSubmInfo->Info.offData = 0; - pSubmInfo->Info.cbData = pBuf->PrivateBase.Base.cbBuffer; + pSubmInfo->Info.cbData = pBuf->BasePrivate.Base.cbBuffer; } else { @@ -233,19 +232,24 @@ int vboxCrHgsmiPrivateCtlConCall(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, struct } pBuf->CallHdr.EscapeHdr.escapeCode = VBOXESC_CRHGSMICTLCON_CALL; - pBuf->CallHdr.EscapeHdr.u32CmdSpecific = 0; + pBuf->CallHdr.EscapeHdr.u32CmdSpecific = (uint32_t)VERR_GENERAL_FAILURE; memcpy(&pBuf->CallHdr.CallInfo, pCallInfo, cbCallInfo); int rc = vboxCrHgsmiPrivateEscape(pHgsmi, pBuf, cbBuffer, FALSE); if (RT_SUCCESS(rc)) { - memcpy(pCallInfo, &pBuf->CallHdr.CallInfo, cbCallInfo); - rc = VINF_SUCCESS; + rc = (int)pBuf->CallHdr.EscapeHdr.u32CmdSpecific; + if (RT_SUCCESS(rc)) + { + memcpy(pCallInfo, &pBuf->CallHdr.CallInfo, cbCallInfo); + rc = VINF_SUCCESS; + } + else + WARN(("vboxCrHgsmiPrivateEscape u32CmdSpecific failed, rc (%d)", rc)); } else - { WARN(("vboxCrHgsmiPrivateEscape failed, rc (%d)", rc)); - } + /* cleanup */ if (pBuf != &Buf) RTMemFree(pBuf); diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h index 07a09d8e..9aaafa0c 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -67,14 +67,14 @@ typedef struct VBOXUHGSMI_BUFFER_PRIVATE_BASE typedef struct VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE { - VBOXUHGSMI_BUFFER_PRIVATE_BASE PrivateBase; + VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate; VBOXVIDEOCM_UM_ALLOC Alloc; HANDLE hSynch; } VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE; typedef struct VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE { - VBOXUHGSMI_BUFFER_PRIVATE_BASE PrivateBase; + VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate; D3DKMT_HANDLE hAllocation; UINT aLockPageIndices[1]; } VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE; @@ -83,13 +83,14 @@ typedef struct VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE #define VBOXUHGSMIBASE_GET(_p) VBOXUHGSMIBASE_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_BASE) #define VBOXUHGSMIBASE_GET_BUFFER(_p) VBOXUHGSMIBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_BASE) -#define VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, PrivateBase.Base))) +#define VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base))) #define VBOXUHGSMIESCBASE_GET_BUFFER(_p) VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE) #define VBOXUHGSMDXALLOCBASE_GET_BUFFER(_p) VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE) -DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, - D3DDDICB_LOCKFLAGS *pfFlags, UINT *pNumPages, UINT* pPages) +DECLINLINE(int) vboxUhgsmiBaseDxLockData(PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pPrivate, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, + D3DDDICB_LOCKFLAGS *pfFlags, UINT *pNumPages) { + PVBOXUHGSMI_BUFFER pBuf = &pPrivate->BasePrivate.Base; D3DDDICB_LOCKFLAGS fLockFlags; fLockFlags.Value = 0; if (fFlags.bLockEntire) @@ -126,7 +127,7 @@ DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock *pNumPages = cPages; for (UINT i = 0, j = iFirstPage; i < cPages; ++i, ++j) { - pPages[i] = j; + pPrivate->aLockPageIndices[i] = j; } } @@ -140,8 +141,17 @@ DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock return VINF_SUCCESS; } -#if 0 -DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers, +DECLINLINE(void) vboxUhgsmiBaseDxAllocInfoFill(D3DDDI_ALLOCATIONINFO *pDdiAllocInfo, VBOXWDDM_ALLOCINFO *pAllocInfo, uint32_t cbBuffer, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType) +{ + pDdiAllocInfo->pPrivateDriverData = pAllocInfo; + pDdiAllocInfo->PrivateDriverDataSize = sizeof (*pAllocInfo); + pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER; + pAllocInfo->cbBuffer = cbBuffer; + pAllocInfo->fUhgsmiType = fUhgsmiType; + +} + +DECLINLINE(int) vboxUhgsmiBaseDxDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers, VOID* pCommandBuffer, UINT *pCommandBufferSize, D3DDDI_ALLOCATIONLIST *pAllocationList, UINT AllocationListSize, D3DDDI_PATCHLOCATIONLIST *pPatchLocationList, UINT PatchLocationListSize) @@ -162,25 +172,24 @@ DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32 PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pCommandBuffer; pHdr->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD; - pHdr->Base.u32CmdReserved = cBuffers; + pHdr->Base.u32CmdReserved = 0; PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pBufSubmInfo = pHdr->aBufInfos; for (uint32_t i = 0; i < cBuffers; ++i) { PVBOXUHGSMI_BUFFER_SUBMIT pBufInfo = &aBuffers[i]; - PVBOXUHGSMI_BUFFER_PRIVATE_BASE pBuffer = VBOXUHGSMIBASE_GET_BUFFER(pBufInfo->pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBufInfo->pBuf); memset(pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST)); pAllocationList->hAllocation = pBuffer->hAllocation; pAllocationList->Value = 0; pAllocationList->WriteOperation = !pBufInfo->fFlags.bHostReadOnly; pAllocationList->DoNotRetireInstance = pBufInfo->fFlags.bDoNotRetire; - pBufSubmInfo->bDoNotSignalCompletion = 0; if (pBufInfo->fFlags.bEntireBuffer) { pBufSubmInfo->offData = 0; - pBufSubmInfo->cbData = pBuffer->Base.cbBuffer; + pBufSubmInfo->cbData = pBuffer->BasePrivate.Base.cbBuffer; } else { @@ -194,7 +203,6 @@ DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32 return VINF_SUCCESS; } -#endif DECLCALLBACK(int) vboxUhgsmiBaseEscBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock); DECLCALLBACK(int) vboxUhgsmiBaseEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf); diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp index 12e26c12..c3fe710b 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -21,91 +21,83 @@ #define VBOXUHGSMID3D_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base))) #define VBOXUHGSMID3D_GET(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_D3D) -#if 0 -#define VBOXUHGSMID3D_GET_BUFFER(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_D3D) - #include <iprt/mem.h> #include <iprt/err.h> -typedef struct VBOXUHGSMI_BUFFER_PRIVATE_D3D -{ - VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate; - PVBOXWDDMDISP_DEVICE pDevice; - UINT aLockPageIndices[1]; -} VBOXUHGSMI_BUFFER_PRIVATE_D3D, *PVBOXUHGSMI_BUFFER_PRIVATE_D3D; - - - DECLCALLBACK(int) vboxUhgsmiD3DBufferDestroy(PVBOXUHGSMI_BUFFER pBuf) { - PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuffer = VBOXUHGSMID3D_GET_BUFFER(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf); + struct VBOXWDDMDISP_DEVICE *pDevice = VBOXUHGSMID3D_GET(pBuffer->BasePrivate.pHgsmi)->pDevice; D3DDDICB_DEALLOCATE DdiDealloc; DdiDealloc.hResource = 0; DdiDealloc.NumAllocations = 1; - DdiDealloc.HandleList = &pBuffer->BasePrivate.hAllocation; - HRESULT hr = pBuffer->pDevice->RtCallbacks.pfnDeallocateCb(pBuffer->pDevice->hDevice, &DdiDealloc); - Assert(hr == S_OK); + DdiDealloc.HandleList = &pBuffer->hAllocation; + HRESULT hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &DdiDealloc); if (hr == S_OK) { - if (pBuffer->BasePrivate.hSynch) - CloseHandle(pBuffer->BasePrivate.hSynch); RTMemFree(pBuffer); return VINF_SUCCESS; } + + WARN(("pfnDeallocateCb failed, hr %#x", hr)); return VERR_GENERAL_FAILURE; } +/* typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_LOCK(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock); */ DECLCALLBACK(int) vboxUhgsmiD3DBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock) { - PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuffer = VBOXUHGSMID3D_GET_BUFFER(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf); + struct VBOXWDDMDISP_DEVICE *pDevice = VBOXUHGSMID3D_GET(pBuffer->BasePrivate.pHgsmi)->pDevice; D3DDDICB_LOCK DdiLock = {0}; - DdiLock.hAllocation = pBuffer->BasePrivate.hAllocation; + DdiLock.hAllocation = pBuffer->hAllocation; DdiLock.PrivateDriverData = 0; - int rc = vboxUhgsmiBaseLockData(pBuf, offLock, cbLock, fFlags, - &DdiLock.Flags, &DdiLock.NumPages, pBuffer->aLockPageIndices); - AssertRC(rc); - if (RT_FAILURE(rc)) + int rc = vboxUhgsmiBaseDxLockData(pBuffer, offLock, cbLock, fFlags, + &DdiLock.Flags, &DdiLock.NumPages); + if (!RT_SUCCESS(rc)) + { + WARN(("vboxUhgsmiBaseDxLockData failed rc %d", rc)); return rc; + } if (DdiLock.NumPages) DdiLock.pPages = pBuffer->aLockPageIndices; else DdiLock.pPages = NULL; - HRESULT hr = pBuffer->pDevice->RtCallbacks.pfnLockCb(pBuffer->pDevice->hDevice, &DdiLock); - Assert(hr == S_OK); + HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &DdiLock); if (hr == S_OK) { *pvLock = (void*)(((uint8_t*)DdiLock.pData) + (offLock & 0xfff)); return VINF_SUCCESS; } + + WARN(("pfnLockCb failed, hr %#x", hr)); return VERR_GENERAL_FAILURE; } DECLCALLBACK(int) vboxUhgsmiD3DBufferUnlock(PVBOXUHGSMI_BUFFER pBuf) { - PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuffer = VBOXUHGSMID3D_GET_BUFFER(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf); + struct VBOXWDDMDISP_DEVICE *pDevice = VBOXUHGSMID3D_GET(pBuffer->BasePrivate.pHgsmi)->pDevice; D3DDDICB_UNLOCK DdiUnlock; DdiUnlock.NumAllocations = 1; - DdiUnlock.phAllocations = &pBuffer->BasePrivate.hAllocation; - HRESULT hr = pBuffer->pDevice->RtCallbacks.pfnUnlockCb(pBuffer->pDevice->hDevice, &DdiUnlock); - Assert(hr == S_OK); + DdiUnlock.phAllocations = &pBuffer->hAllocation; + HRESULT hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock); if (hr == S_OK) return VINF_SUCCESS; + + WARN(("pfnUnlockCb failed, hr %#x", hr)); return VERR_GENERAL_FAILURE; } -DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf) +/*typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_CREATE(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf);*/ +DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf) { - HANDLE hSynch = NULL; if (!cbBuf) return VERR_INVALID_PARAMETER; - int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch); - AssertRC(rc); - if (RT_FAILURE(rc)) - return rc; + int rc = VINF_SUCCESS; cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000); Assert(cbBuf); @@ -113,72 +105,69 @@ DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, Assert(cPages); PVBOXUHGSMI_PRIVATE_D3D pPrivate = VBOXUHGSMID3D_GET(pHgsmi); - PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_D3D)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_D3D, aLockPageIndices[cPages])); - Assert(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, aLockPageIndices[cPages])); if (pBuf) { - struct - { - D3DDDICB_ALLOCATE DdiAlloc; - D3DDDI_ALLOCATIONINFO DdiAllocInfo; - VBOXWDDM_ALLOCINFO AllocInfo; - } Buf; - memset(&Buf, 0, sizeof (Buf)); - Buf.DdiAlloc.hResource = NULL; - Buf.DdiAlloc.hKMResource = NULL; - Buf.DdiAlloc.NumAllocations = 1; - Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo; - Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo; - Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo); - Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER; - Buf.AllocInfo.cbBuffer = cbBuf; - Buf.AllocInfo.hSynch = hSynch; - Buf.AllocInfo.fUhgsmiType = fUhgsmiType; - - HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &Buf.DdiAlloc); - Assert(hr == S_OK); + D3DDDICB_ALLOCATE DdiAlloc; + D3DDDI_ALLOCATIONINFO DdiAllocInfo; + VBOXWDDM_ALLOCINFO AllocInfo; + + memset(&DdiAlloc, 0, sizeof (DdiAlloc)); + DdiAlloc.hResource = NULL; + DdiAlloc.hKMResource = NULL; + DdiAlloc.NumAllocations = 1; + DdiAlloc.pAllocationInfo = &DdiAllocInfo; + vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType); + + HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &DdiAlloc); if (hr == S_OK) { - Assert(Buf.DdiAllocInfo.hAllocation); + Assert(DdiAllocInfo.hAllocation); pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiD3DBufferLock; pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiD3DBufferUnlock; -// pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiD3DBufferAdjustValidDataRange; pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiD3DBufferDestroy; - pBuf->BasePrivate.Base.fType = fUhgsmiType; + pBuf->BasePrivate.Base.fType = fType; pBuf->BasePrivate.Base.cbBuffer = cbBuf; - pBuf->pDevice = pPrivate->pDevice; - pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation; + pBuf->hAllocation = DdiAllocInfo.hAllocation; *ppBuf = &pBuf->BasePrivate.Base; return VINF_SUCCESS; } + else + { + WARN(("pfnAllocateCb failed hr %#x")); + rc = VERR_GENERAL_FAILURE; + } RTMemFree(pBuf); } else + { + WARN(("RTMemAllocZ failed")); rc = VERR_NO_MEMORY; - - if (hSynch) - CloseHandle(hSynch); + } return rc; } +/* typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_SUBMIT(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers); */ DECLCALLBACK(int) vboxUhgsmiD3DBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers) { PVBOXUHGSMI_PRIVATE_D3D pHg = VBOXUHGSMID3D_GET(pHgsmi); PVBOXWDDMDISP_DEVICE pDevice = pHg->pDevice; UINT cbDmaCmd = pDevice->DefaultContext.ContextInfo.CommandBufferSize; - int rc = vboxUhgsmiBaseDmaFill(aBuffers, cBuffers, + int rc = vboxUhgsmiBaseDxDmaFill(aBuffers, cBuffers, pDevice->DefaultContext.ContextInfo.pCommandBuffer, &cbDmaCmd, pDevice->DefaultContext.ContextInfo.pAllocationList, pDevice->DefaultContext.ContextInfo.AllocationListSize, pDevice->DefaultContext.ContextInfo.pPatchLocationList, pDevice->DefaultContext.ContextInfo.PatchLocationListSize); - AssertRC(rc); if (RT_FAILURE(rc)) + { + WARN(("vboxUhgsmiBaseDxDmaFill failed, rc %d", rc)); return rc; + } D3DDDICB_RENDER DdiRender = {0}; DdiRender.CommandLength = cbDmaCmd; @@ -193,7 +182,6 @@ DECLCALLBACK(int) vboxUhgsmiD3DBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF DdiRender.hContext = pDevice->DefaultContext.ContextInfo.hContext; HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &DdiRender); - Assert(hr == S_OK); if (hr == S_OK) { pDevice->DefaultContext.ContextInfo.CommandBufferSize = DdiRender.NewCommandBufferSize; @@ -206,17 +194,18 @@ DECLCALLBACK(int) vboxUhgsmiD3DBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF return VINF_SUCCESS; } + WARN(("pfnRenderCb failed, hr %#x", hr)); return VERR_GENERAL_FAILURE; } -HRESULT vboxUhgsmiD3DInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, PVBOXWDDMDISP_DEVICE pDevice) +void vboxUhgsmiD3DInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, PVBOXWDDMDISP_DEVICE pDevice) { pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiD3DBufferCreate; pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiD3DBufferSubmit; + /* no escapes (for now) */ + pHgsmi->BasePrivate.pfnEscape = NULL; pHgsmi->pDevice = pDevice; - return S_OK; } -#endif static DECLCALLBACK(int) vboxCrHhgsmiDispEscape(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, void *pvData, uint32_t cbData, BOOL fHwAccess) { diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h index f85b0e0d..1c2e981f 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -28,9 +28,7 @@ typedef struct VBOXUHGSMI_PRIVATE_D3D struct VBOXWDDMDISP_DEVICE *pDevice; } VBOXUHGSMI_PRIVATE_D3D, *PVBOXUHGSMI_PRIVATE_D3D; -#if 0 void vboxUhgsmiD3DInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, struct VBOXWDDMDISP_DEVICE *pDevice); -#endif void vboxUhgsmiD3DEscInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, struct VBOXWDDMDISP_DEVICE *pDevice); diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp index 53325c6b..25573e21 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -27,29 +27,20 @@ # define NT_SUCCESS(_Status) (((NTSTATUS)(_Status)) >= 0) #endif -#if 0 -typedef struct VBOXUHGSMI_BUFFER_PRIVATE_KMT -{ - VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate; - CRITICAL_SECTION CritSect; -} VBOXUHGSMI_BUFFER_PRIVATE_KMT, *PVBOXUHGSMI_BUFFER_PRIVATE_KMT; - - -#define VBOXUHGSMIKMT_GET_BUFFER(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_KMT) DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf) { - PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf); + PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi); + D3DKMT_DESTROYALLOCATION DdiDealloc; - DdiDealloc.hDevice = pBuffer->pHgsmi->Device.hDevice; + DdiDealloc.hDevice = pPrivate->Device.hDevice; DdiDealloc.hResource = NULL; - DdiDealloc.phAllocationList = &pBuffer->BasePrivate.hAllocation; + DdiDealloc.phAllocationList = &pBuffer->hAllocation; DdiDealloc.AllocationCount = 1; - NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc); + NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc); if (NT_SUCCESS(Status)) { - if (pBuffer->BasePrivate.hSynch) - CloseHandle(pBuffer->BasePrivate.hSynch); RTMemFree(pBuffer); return VINF_SUCCESS; } @@ -62,27 +53,28 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf) DECLCALLBACK(int) vboxUhgsmiKmtBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock) { - PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf); + PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi); D3DKMT_LOCK DdiLock = {0}; - DdiLock.hDevice = pBuffer->pHgsmi->Device.hDevice; - DdiLock.hAllocation = pBuffer->BasePrivate.hAllocation; + DdiLock.hDevice = pPrivate->Device.hDevice; + DdiLock.hAllocation = pBuffer->hAllocation; DdiLock.PrivateDriverData = NULL; - EnterCriticalSection(&pBuffer->CritSect); - - int rc = vboxUhgsmiBaseLockData(pBuf, offLock, cbLock, fFlags, - &DdiLock.Flags, &DdiLock.NumPages, pBuffer->aLockPageIndices); - AssertRC(rc); - if (RT_FAILURE(rc)) + int rc = vboxUhgsmiBaseDxLockData(pBuffer, offLock, cbLock, fFlags, + &DdiLock.Flags, &DdiLock.NumPages); + if (!RT_SUCCESS(rc)) + { + WARN(("vboxUhgsmiBaseDxLockData failed rc %d", rc)); return rc; + } + if (DdiLock.NumPages) DdiLock.pPages = pBuffer->aLockPageIndices; else DdiLock.pPages = NULL; - NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTLock(&DdiLock); - LeaveCriticalSection(&pBuffer->CritSect); + NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTLock(&DdiLock); if (NT_SUCCESS(Status)) { *pvLock = (void*)(((uint8_t*)DdiLock.pData) + (offLock & 0xfff)); @@ -98,13 +90,14 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offL DECLCALLBACK(int) vboxUhgsmiKmtBufferUnlock(PVBOXUHGSMI_BUFFER pBuf) { - PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf); + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf); D3DKMT_UNLOCK DdiUnlock; - DdiUnlock.hDevice = pBuffer->pHgsmi->Device.hDevice; + PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi); + DdiUnlock.hDevice = pPrivate->Device.hDevice; DdiUnlock.NumAllocations = 1; - DdiUnlock.phAllocations = &pBuffer->BasePrivate.hAllocation; - NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTUnlock(&DdiUnlock); + DdiUnlock.phAllocations = &pBuffer->hAllocation; + NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTUnlock(&DdiUnlock); if (NT_SUCCESS(Status)) return VINF_SUCCESS; else @@ -113,16 +106,12 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferUnlock(PVBOXUHGSMI_BUFFER pBuf) return VERR_GENERAL_FAILURE; } -DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf) +DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf) { - HANDLE hSynch = NULL; if (!cbBuf) return VERR_INVALID_PARAMETER; - int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch); - AssertRC(rc); - if (RT_FAILURE(rc)) - return rc; + int rc = VINF_SUCCESS; cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000); Assert(cbBuf); @@ -130,61 +119,48 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, Assert(cPages); PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi); - PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_KMT, aLockPageIndices[cPages])); - Assert(pBuf); - if (pBuf) + PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, aLockPageIndices[cPages])); + if (!pBuf) { - struct - { - D3DKMT_CREATEALLOCATION DdiAlloc; - D3DDDI_ALLOCATIONINFO DdiAllocInfo; - VBOXWDDM_ALLOCINFO AllocInfo; - } Buf; - memset(&Buf, 0, sizeof (Buf)); - Buf.DdiAlloc.hDevice = pPrivate->Device.hDevice; - Buf.DdiAlloc.NumAllocations = 1; - Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo; - Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo; - Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo); - Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER; - Buf.AllocInfo.cbBuffer = cbBuf; - Buf.AllocInfo.hSynch = (uint64_t)hSynch; - Buf.AllocInfo.fUhgsmiType = fUhgsmiType; - - NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&Buf.DdiAlloc); - if (NT_SUCCESS(Status)) - { - InitializeCriticalSection(&pBuf->CritSect); + WARN(("RTMemAllocZ failed")); + return VERR_NO_MEMORY; + } - Assert(Buf.DdiAllocInfo.hAllocation); - pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock; - pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock; -// pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiKmtBufferAdjustValidDataRange; - pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy; + D3DKMT_CREATEALLOCATION DdiAlloc; + D3DDDI_ALLOCATIONINFO DdiAllocInfo; + VBOXWDDM_ALLOCINFO AllocInfo; - pBuf->BasePrivate.Base.fType = fUhgsmiType; - pBuf->BasePrivate.Base.cbBuffer = cbBuf; + memset(&DdiAlloc, 0, sizeof (DdiAlloc)); + DdiAlloc.hDevice = pPrivate->Device.hDevice; + DdiAlloc.NumAllocations = 1; + DdiAlloc.pAllocationInfo = &DdiAllocInfo; - pBuf->pHgsmi = pPrivate; - pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation; + vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType); - *ppBuf = &pBuf->BasePrivate.Base; + NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&DdiAlloc); + if (NT_SUCCESS(Status)) + { + Assert(DdiAllocInfo.hAllocation); + pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock; + pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock; + pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy; - return VINF_SUCCESS; - } - else - { - WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status)); - rc = VERR_OUT_OF_RESOURCES; - } + pBuf->BasePrivate.Base.fType = fType; + pBuf->BasePrivate.Base.cbBuffer = cbBuf; + + pBuf->hAllocation = DdiAllocInfo.hAllocation; - RTMemFree(pBuf); + *ppBuf = &pBuf->BasePrivate.Base; + + return VINF_SUCCESS; } else - rc = VERR_NO_MEMORY; + { + WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status)); + rc = VERR_OUT_OF_RESOURCES; + } - if (hSynch) - CloseHandle(hSynch); + RTMemFree(pBuf); return rc; } @@ -193,13 +169,15 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF { PVBOXUHGSMI_PRIVATE_KMT pHg = VBOXUHGSMIKMT_GET(pHgsmi); UINT cbDmaCmd = pHg->Context.CommandBufferSize; - int rc = vboxUhgsmiBaseDmaFill(aBuffers, cBuffers, + int rc = vboxUhgsmiBaseDxDmaFill(aBuffers, cBuffers, pHg->Context.pCommandBuffer, &cbDmaCmd, pHg->Context.pAllocationList, pHg->Context.AllocationListSize, pHg->Context.pPatchLocationList, pHg->Context.PatchLocationListSize); - AssertRC(rc); if (RT_FAILURE(rc)) + { + WARN(("vboxUhgsmiBaseDxDmaFill failed, rc %d", rc)); return rc; + } D3DKMT_RENDER DdiRender = {0}; DdiRender.hContext = pHg->Context.hContext; @@ -227,7 +205,7 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF return VERR_GENERAL_FAILURE; } -#endif + static HRESULT vboxUhgsmiKmtEngineCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D) { @@ -296,20 +274,81 @@ static DECLCALLBACK(int) vboxCrHhgsmiKmtEscape(struct VBOXUHGSMI_PRIVATE_BASE *p return VERR_GENERAL_FAILURE; } +static void vboxUhgsmiKmtSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi) +{ + pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtBufferCreate; + pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiKmtBufferSubmit; + /* no escapes (for now) */ + pHgsmi->BasePrivate.pfnEscape = NULL; +} + +static void vboxUhgsmiKmtEscSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi) +{ + vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape); +} + #if 0 HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D) { - vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape); -#error "port me!" + vboxUhgsmiKmtSetupCallbacks(pHgsmi); return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D); } -#endif HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D) { - vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape); + vboxUhgsmiKmtEscSetupCallbacks(pHgsmi); return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D); } +#endif + +static HRESULT vboxUhgsmiKmtQueryCaps(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t *pu32Caps) +{ + VBOXWDDM_QI Query; + D3DKMT_QUERYADAPTERINFO Info; + Info.hAdapter = pHgsmi->Adapter.hAdapter; + Info.Type = KMTQAITYPE_UMDRIVERPRIVATE; + Info.pPrivateDriverData = &Query; + Info.PrivateDriverDataSize = sizeof (Query); + + NTSTATUS Status = pHgsmi->Callbacks.pfnD3DKMTQueryAdapterInfo(&Info); + if (!NT_SUCCESS(Status)) + { + WARN(("pfnD3DKMTQueryAdapterInfo failed, Status %#x", Status)); + return Status; + } + + if (Query.u32Version != VBOXVIDEOIF_VERSION) + { + WARN(("Version mismatch")); + return E_FAIL; + } + + *pu32Caps = Query.u32VBox3DCaps; + + return S_OK; +} + +HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D) +{ + HRESULT hr = vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D); + if (!SUCCEEDED(hr)) + return hr; + + uint32_t u32Caps = 0; + hr = vboxUhgsmiKmtQueryCaps(pHgsmi, &u32Caps); + if (!SUCCEEDED(hr)) + { + WARN(("vboxUhgsmiKmtQueryCaps failed hr %#x", hr)); + return hr; + } + + if (u32Caps & CR_VBOX_CAP_CMDVBVA) + vboxUhgsmiKmtSetupCallbacks(pHgsmi); + else + vboxUhgsmiKmtEscSetupCallbacks(pHgsmi); + + return S_OK; +} HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi) { diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h index 511aec6b..357bc288 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -34,12 +34,8 @@ typedef struct VBOXUHGSMI_PRIVATE_KMT #define VBOXUHGSMIKMT_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base))) #define VBOXUHGSMIKMT_GET(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_KMT) -#if 0 -HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D); -#endif HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi); -HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D); - +HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D); #endif /* #ifndef ___VBoxUhgsmiKmt_h__ */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp index 44be1a7f..e92e4d66 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp @@ -14,8 +14,12 @@ #include <windows.h> #include <d3d9types.h> #include <d3d9caps.h> +#include <d3d9.h> #include <stdio.h> +#define MAX(_v1, _v2) ((_v1) > (_v2) ? (_v1) : (_v2)) +#define MIN(_v1, _v2) ((_v1) < (_v2) ? (_v1) : (_v2)) + #define MISSING_FLAGS(_dw1, _dw2) ((_dw2) & ((_dw1) ^ (_dw2))) #define Log(_m) do { printf _m ; } while (0) @@ -496,6 +500,14 @@ static void printXxxCaps(const char* pszPrefix, const char* pszSeparator, DWORD static void diffCaps(D3DCAPS9 *pCaps1, D3DCAPS9 *pCaps2) { + if (!memcmp(pCaps1, pCaps2, sizeof (D3DCAPS9))) + { + Log(("caps are identical!\n")); + return; + } + + Log(("caps differ, doing detailed diff..\n")); + if (pCaps1->DeviceType != pCaps2->DeviceType) { printDeviceType("pCaps->DeviceType = ", pCaps2->DeviceType, ";\n"); @@ -560,9 +572,9 @@ static void diffCaps(D3DCAPS9 *pCaps1, D3DCAPS9 *pCaps2) DUMP_DIFF_VAL(MaxVertexIndex, "%d"); DUMP_DIFF_VAL(MaxStreams, "%d"); DUMP_DIFF_VAL(MaxStreamStride, "%d"); - DUMP_DIFF_VAL(VertexShaderVersion, "%d"); + DUMP_DIFF_VAL(VertexShaderVersion, "0x%x"); DUMP_DIFF_VAL(MaxVertexShaderConst, "%d"); - DUMP_DIFF_VAL(PixelShaderVersion, "%d"); + DUMP_DIFF_VAL(PixelShaderVersion, "0x%x"); DUMP_DIFF_VAL(PixelShader1xMaxValue, "%f"); /* D3D9 */ @@ -605,19 +617,19 @@ static void diffCaps(D3DCAPS9 *pCaps1, D3DCAPS9 *pCaps2) } static DWORD g_aCaps1[] = { - 0x00000001, 0x00000000, 0x00000000, 0xe00a0000, - 0x00000320, 0x80000001, 0x00000003, 0x0059aff1, - 0x000e6ff2, 0x077363b1, 0x000000ff, 0x00003fff, - 0x000023ff, 0x000000ff, 0x00084208, 0x0007eccd, + 0x00000001, 0x00000000, 0x00020000, 0xe0000000, + 0x00000320, 0x80000001, 0x00000003, 0x0019aff0, + 0x000f4ff2, 0x07736191, 0x000000ff, 0x00003fff, + 0x000023ff, 0x000000ff, 0x00084208, 0x0001ecc5, 0x07030700, 0x07030700, 0x03030300, 0x0000003f, - 0x0000003f, 0x0000001f, 0x00002000, 0x00002000, - 0x00000800, 0x00008000, 0x00002000, 0x00000010, + 0x0000003f, 0x0000001f, 0x00001000, 0x00001000, + 0x00000100, 0x00008000, 0x00001000, 0x00000010, 0x3f800000, 0xc6000000, 0xc6000000, 0x46000000, 0x46000000, 0x00000000, 0x000001ff, 0x00100008, - 0x03feffff, 0x00000008, 0x00000008, 0x0000003b, - 0x00000008, 0x00000006, 0x00000001, 0x00000000, - 0x427c0000, 0x000fffff, 0x000fffff, 0x00000010, - 0x00000400, 0xfffe0200, 0x00000100, 0xffff0200, + 0x03feffff, 0x00000008, 0x00000008, 0x0000013b, + 0x00000008, 0x00000006, 0x00000000, 0x00000000, + 0x437f0000, 0x000fffff, 0x000fffff, 0x00000010, + 0x00000400, 0xfffe0200, 0x00000080, 0xffff0200, 0x41000000, 0x00000051, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x0000030f, 0x00000001, 0x03000300, 0x00000000, 0x00000018, @@ -628,41 +640,438 @@ static DWORD g_aCaps1[] = { static DWORD g_aCaps2[] = { - 0x00000001, 0x00000000, 0x00020000, 0xe00a0000, - 0x00000320, 0x80000001, 0x00000003, 0x0059aff1, - 0x000e6ff2, 0x077263b1, 0x000000ff, 0x00003fff, - 0x000023ff, 0x000000ff, 0x00084208, 0x0007eccd, - 0x07030700, 0x07030700, 0x03030300, 0x0000003f, - 0x0000003f, 0x0000001f, 0x00002000, 0x00002000, - 0x00002000, 0x00008000, 0x00002000, 0x00000010, - 0x3f800000, 0xc6000000, 0xc6000000, 0x46000000, - 0x46000000, 0x00000000, 0x000001ff, 0x00100008, - 0x03feffff, 0x00000008, 0x00000008, 0x0000003b, - 0x00000008, 0x00000008, 0x00000001, 0x00000000, - 0x46000000, 0x000fffff, 0x000fffff, 0x00000010, - 0x00000400, 0xfffe0300, 0x00000100, 0xffff0300, + 0x00000001, 0x00000000, 0x00000000, 0x60020000, + 0x00000320, 0x80000001, 0x00000003, 0x0019aff0, + 0x000a0ff2, 0x07332191, 0x000000ff, 0x00003fff, + 0x000023ff, 0x000000ff, 0x00084208, 0x0001ec85, + 0x07030700, 0x07030700, 0x03030300, 0x0000001f, + 0x0000001f, 0x0000001f, 0x00001000, 0x00001000, + 0x00000100, 0x00008000, 0x00001000, 0x00000010, + 0x3f800000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x000001ff, 0x00100008, + 0x03feffff, 0x00000008, 0x00000008, 0x0000013b, + 0x00000008, 0x00000006, 0x00000000, 0x00000000, + 0x437f0000, 0x000fffff, 0x000fffff, 0x00000010, + 0x00000400, 0xfffe0200, 0x00000080, 0xffff0200, 0x41000000, 0x00000051, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0x0000030f, - 0x00000001, 0x03000300, 0x00000001, 0x00000018, - 0x00000020, 0x00000004, 0x0000001f, 0x00000018, - 0x00000020, 0x00000004, 0x00000200, 0x01000100, - 0x0000ffff, 0x0000ffff, 0x00008000, 0x00008000 + 0x00000000, 0x00000000, 0x00000001, 0x0000000f, + 0x00000001, 0x03000300, 0x00000000, 0x00000000, + 0x0000001f, 0x00000001, 0x00000000, 0x00000000, + 0x00000100, 0x00000000, 0x00000060, 0x00000000, + 0x0000ffff, 0x00000200, 0x00000000, 0x00000000 }; + +/* ogl stuff */ +static const char * strNext(const char * pcszStr) +{ + pcszStr = strchr(pcszStr, ' '); + if (!pcszStr) + return NULL; + + do + { + ++pcszStr; + if (*pcszStr == '\0') + return NULL; + else if (*pcszStr != ' ') + return pcszStr; + } while (1); + + Log(("WARNING: should NOT be here!\n")); + return NULL; +} + +static int strLength(const char * pcszStr, char sep) +{ + if (sep == '\0') + return (int)strlen(pcszStr); + const char * pcszNext = strchr(pcszStr, sep); + if (pcszNext) + return (int)(pcszNext - pcszStr); + return (int)strlen(pcszStr); +} + +static int strCmp(const char * pcszStr1, const char * pcszStr2, char sep) +{ + if (sep == '\0') + return strcmp(pcszStr1, pcszStr2); + + int cStr1 = strLength(pcszStr1, sep); + int cStr2 = strLength(pcszStr2, sep); + int iCmp = strncmp(pcszStr1, pcszStr2, MIN(cStr1, cStr2)); + if (iCmp) + return iCmp; + return cStr1 - cStr2; +} + +static char * strDupCur(const char * pcszStr, char sep) +{ + int cStr = strLength(pcszStr, sep); + char * newStr = (char *)malloc(cStr+1); + if (!newStr) + { + Log(("malloc failed!\n")); + return NULL; + } + memcpy(newStr, pcszStr, cStr); + newStr[cStr] = '\0'; + return newStr; +} + +static char * strDupTotal(const char * pcszStr) +{ + int cStr = (int)strlen(pcszStr); + char * newStr = (char *)malloc(cStr+1+1); + if (!newStr) + { + Log(("malloc failed!\n")); + return NULL; + } + memcpy(newStr, pcszStr, cStr); + newStr[cStr] = '\0'; + newStr[cStr+1] = '\0'; + return newStr; +} + +static char * strDupSort(const char * pcszStr) +{ + int cStr = (int)strlen(pcszStr); + char * pNewStr = (char *)malloc(cStr+1+1+1); + if (!pNewStr) + { + Log(("malloc failed!\n")); + return NULL; + } + char *pCurNew = pNewStr; + const char *pPrevCmp = NULL; + const char * pCmp = "\001"; + const char * pCur; + int cLength, cPrevLength; + + do + { + cLength = 0; + for (pCur = pcszStr; pCur; pCur = strNext(pCur)) + { + int cCur = strLength(pCur, ' '); + int cCmp = strLength(pCmp, ' '); + int iCmp = strncmp(pCur, pCmp, MIN(cCur, cCmp)); + if (!iCmp) + iCmp = cCur - cCmp; + if (iCmp > 0) + { + if (!cLength) + { + pCmp = pCur; + cLength = cCur; + } + } + else if (iCmp < 0) + { + if (cLength) + { + if (pPrevCmp) + { + int iCmp = strncmp(pCur, pPrevCmp, MIN(cCur, cPrevLength)); + if (!iCmp) + iCmp = cCur - cPrevLength; + if (iCmp > 0) + { + pCmp = pCur; + cLength = cCur; + } + } + else + { + pCmp = pCur; + cLength = cCur; + } + } + } + } + + if (!cLength) + break; + + pPrevCmp = pCmp; + cPrevLength = cLength; + memcpy(pCurNew, pCmp, cLength); + pCurNew += cLength; + *pCurNew = ' '; + ++pCurNew; + } while (1); + + *pCurNew = '\0'; + ++pCurNew; + + return pNewStr; +} + + +#define DUMP_DIFF_STR_ADDED(_pStr) do { \ + char * pszCopy = strDupCur(_pStr, ' '); \ + Log(("+ %s\n", pszCopy)); \ + if (pszCopy) free(pszCopy); \ + } while (0) + +#define DUMP_DIFF_STR_REMOVED(_pStr) do { \ + char * pszCopy = strDupCur(_pStr, ' '); \ + Log(("- %s\n", pszCopy)); \ + if (pszCopy) free(pszCopy); \ + } while (0) + +#define DIFF_STR_ADDED(_ppStr) do { \ + DUMP_DIFF_STR_ADDED(*(_ppStr)); \ + *(_ppStr) = strNext(*(_ppStr)); \ + } while (0) + +#define DIFF_STR_REMOVED(_ppStr) do { \ + DUMP_DIFF_STR_REMOVED(*(_ppStr)); \ + *(_ppStr) = strNext(*(_ppStr)); \ + } while (0) + +#define DIFF_STR_MATCHED(_ppStr1, _ppStr2) do { \ + *(_ppStr1) = strNext(*(_ppStr1)); \ + *(_ppStr2) = strNext(*(_ppStr2)); \ + } while (0) + +static void diffStrOrderedLists(const char * pcszStr1, const char * pcszStr2) +{ + while (pcszStr1 || pcszStr2) + { + if (pcszStr1 && pcszStr2) + { + int iCmp = strCmp(pcszStr1, pcszStr2, ' '); +// int cStr1 = strLength(pcszStr1, ' '); +// int cStr2 = strLength(pcszStr2, ' '); +// int iCmp = strncmp(pcszStr1, pcszStr2, MAX(cStr1, cStr2)); + if (iCmp > 0) + DIFF_STR_ADDED(&pcszStr2); + else if (iCmp < 0) + DIFF_STR_REMOVED(&pcszStr1); + else + DIFF_STR_MATCHED(&pcszStr1, &pcszStr2); + } + else if (pcszStr1) + DIFF_STR_REMOVED(&pcszStr1); + else + DIFF_STR_ADDED(&pcszStr2); + } +} + +static void diffGlExts(const char * pcszExts1, const char * pcszExts2) +{ + pcszExts1 = strDupSort(pcszExts1); + pcszExts2 = strDupSort(pcszExts2); + + if (!strcmp(pcszExts1, pcszExts2)) + { + Log(("GL Exts identical!\n")); + Log(("%s\n", pcszExts1)); + return; + } + + Log(("%s\n", pcszExts1)); + + Log(("Diffing GL Exts..\n")); + diffStrOrderedLists(pcszExts1, pcszExts2); +} + +static char *g_GlExts1 = + "GL_ARB_multisample GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_color GL_EXT_blend_logic_op GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_copy_texture " + "GL_EXT_polygon_offset GL_EXT_subtexture GL_EXT_texture_object GL_EXT_vertex_array GL_EXT_compiled_vertex_array GL_EXT_texture GL_EXT_texture3D " + "GL_IBM_rasterpos_clip GL_ARB_point_parameters GL_EXT_draw_range_elements GL_EXT_packed_pixels GL_EXT_point_parameters GL_EXT_rescale_normal " + "GL_EXT_separate_specular_color GL_EXT_texture_edge_clamp GL_SGIS_generate_mipmap GL_SGIS_texture_border_clamp GL_SGIS_texture_edge_clamp " + "GL_SGIS_texture_lod GL_ARB_framebuffer_sRGB GL_ARB_multitexture GL_EXT_framebuffer_sRGB GL_IBM_multimode_draw_arrays GL_IBM_texture_mirrored_repeat " + "GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_transpose_matrix GL_EXT_blend_func_separate GL_EXT_fog_coord GL_EXT_multi_draw_arrays " + "GL_EXT_secondary_color GL_EXT_texture_env_add GL_EXT_texture_filter_anisotropic GL_EXT_texture_lod_bias GL_INGR_blend_func_separate GL_NV_blend_square " + "GL_NV_light_max_exponent GL_NV_texgen_reflection GL_NV_texture_env_combine4 GL_SUN_multi_draw_arrays GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_EXT_framebuffer_object " + "GL_EXT_texture_env_dot3 GL_MESA_window_pos GL_NV_packed_depth_stencil GL_NV_texture_rectangle GL_ARB_depth_texture GL_ARB_occlusion_query GL_ARB_shadow GL_ARB_texture_env_combine " + "GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_mirrored_repeat GL_ARB_window_pos GL_EXT_stencil_two_side GL_EXT_texture_cube_map GL_NV_depth_clamp GL_APPLE_packed_pixels " + "GL_APPLE_vertex_array_object GL_ARB_draw_buffers GL_ARB_fragment_program GL_ARB_fragment_shader GL_ARB_shader_objects GL_ARB_vertex_program GL_ARB_vertex_shader GL_ATI_draw_buffers GL_ATI_texture_env_combine3 " + "GL_EXT_shadow_funcs GL_EXT_stencil_wrap GL_MESA_pack_invert GL_NV_primitive_restart GL_ARB_depth_clamp GL_ARB_fragment_program_shadow GL_ARB_half_float_pixel GL_ARB_occlusion_query2 GL_ARB_point_sprite " + "GL_ARB_shading_language_100 GL_ARB_sync GL_ARB_texture_non_power_of_two GL_ARB_vertex_buffer_object GL_ATI_blend_equation_separate GL_EXT_blend_equation_separate GL_OES_read_format GL_ARB_color_buffer_float " + "GL_ARB_pixel_buffer_object GL_ARB_texture_compression_rgtc GL_ARB_texture_rectangle GL_EXT_packed_float GL_EXT_pixel_buffer_object GL_EXT_texture_compression_rgtc GL_EXT_texture_mirror_clamp GL_EXT_texture_rectangle " + "GL_EXT_texture_sRGB GL_EXT_texture_shared_exponent GL_ARB_framebuffer_object GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_packed_depth_stencil GL_ARB_vertex_array_object GL_ATI_separate_stencil " + "GL_ATI_texture_mirror_once GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_gpu_program_parameters GL_EXT_texture_env_combine GL_EXT_texture_sRGB_decode GL_EXT_timer_query GL_OES_EGL_image GL_ARB_copy_buffer " + "GL_ARB_draw_instanced GL_ARB_half_float_vertex GL_ARB_instanced_arrays GL_ARB_map_buffer_range GL_ARB_texture_rg GL_ARB_texture_swizzle GL_ARB_vertex_array_bgra GL_EXT_separate_shader_objects GL_EXT_texture_swizzle " + "GL_EXT_vertex_array_bgra GL_NV_conditional_render GL_ARB_ES2_compatibility GL_ARB_draw_elements_base_vertex GL_ARB_explicit_attrib_location GL_ARB_fragment_coord_conventions GL_ARB_provoking_vertex " + "GL_ARB_sampler_objects GL_ARB_shader_texture_lod GL_EXT_provoking_vertex GL_EXT_texture_snorm GL_MESA_texture_signed_rgba GL_NV_texture_barrier GL_ARB_robustness" + ; +static char *g_GlExts2 = "GL_ARB_blend_func_extended GL_ARB_color_buffer_float GL_ARB_compatibility GL_ARB_copy_buffer GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_draw_buffers " + "GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_ES2_compatibility GL_ARB_explicit_attrib_location GL_ARB_fragment_coord_conventions GL_ARB_fragment_program GL_ARB_fragment_program_shadow " + "GL_ARB_fragment_shader GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_get_program_binary GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging GL_ARB_instanced_arrays " + "GL_ARB_map_buffer_range GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_occlusion_query2 GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_provoking_vertex " + "GL_ARB_robustness GL_ARB_sampler_objects GL_ARB_seamless_cube_map GL_ARB_separate_shader_objects GL_ARB_shader_bit_encoding GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_shading_language_include " + "GL_ARB_shadow GL_ARB_sync GL_ARB_texture_border_clamp GL_ARB_texture_buffer_object GL_ARB_texture_compression GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine " + "GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_float GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample GL_ARB_texture_non_power_of_two GL_ARB_texture_rectangle GL_ARB_texture_rg " + "GL_ARB_texture_rgb10_a2ui GL_ARB_texture_swizzle GL_ARB_timer_query GL_ARB_transpose_matrix GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra GL_ARB_vertex_array_object GL_ARB_vertex_buffer_object GL_ARB_vertex_program " + "GL_ARB_vertex_shader GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_viewport_array GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float GL_ATI_texture_mirror_once GL_S3_s3tc GL_EXT_texture_env_add GL_EXT_abgr GL_EXT_bgra " + "GL_EXT_bindable_uniform GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_compiled_vertex_array GL_EXT_Cg_shader GL_EXT_depth_bounds_test " + "GL_EXT_direct_state_access GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXTX_framebuffer_mixed_formats " + "GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_packed_pixels " + "GL_EXT_pixel_buffer_object GL_EXT_point_parameters GL_EXT_provoking_vertex GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_shader_objects GL_EXT_separate_specular_color GL_EXT_shadow_funcs " + "GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_array GL_EXT_texture_buffer_object GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_latc GL_EXT_texture_compression_rgtc " + "GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map GL_EXT_texture_edge_clamp GL_EXT_texture_env_combine GL_EXT_texture_env_dot3 GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_texture_integer " + "GL_EXT_texture_lod GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_object GL_EXT_texture_shared_exponent GL_EXT_texture_sRGB GL_EXT_texture_swizzle GL_EXT_texture_type_2_10_10_10_REV GL_EXT_timer_query " + "GL_EXT_vertex_array GL_EXT_vertex_array_bgra GL_EXT_x11_sync_object GL_EXT_import_sync_object GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat GL_KTX_buffer_region GL_NV_alpha_test GL_NV_blend_minmax GL_NV_blend_square " + "GL_NV_complex_primitives GL_NV_conditional_render GL_NV_copy_depth_to_color GL_NV_copy_image GL_NV_depth_buffer_float GL_NV_depth_clamp GL_NV_explicit_multisample GL_NV_fbo_color_attachments " + "GL_NV_fence GL_NV_float_buffer GL_NV_fog_distance GL_NV_fragdepth GL_NV_fragment_program GL_NV_fragment_program_option GL_NV_fragment_program2 GL_NV_framebuffer_multisample_coverage GL_NV_geometry_shader4 " + "GL_NV_gpu_program4 GL_NV_half_float GL_NV_light_max_exponent GL_NV_multisample_coverage GL_NV_multisample_filter_hint GL_NV_occlusion_query GL_NV_packed_depth_stencil GL_NV_parameter_buffer_object " + "GL_NV_parameter_buffer_object2 GL_NV_path_rendering GL_NV_pixel_data_range GL_NV_point_sprite GL_NV_primitive_restart GL_NV_register_combiners GL_NV_register_combiners2 GL_NV_shader_buffer_load GL_NV_texgen_reflection " + "GL_NV_texture_barrier GL_NV_texture_compression_vtc GL_NV_texture_env_combine4 GL_NV_texture_expand_normal GL_NV_texture_lod_clamp GL_NV_texture_multisample GL_NV_texture_rectangle GL_NV_texture_shader GL_NV_texture_shader2 " + "GL_NV_texture_shader3 GL_NV_transform_feedback GL_NV_vdpau_interop GL_NV_vertex_array_range GL_NV_vertex_array_range2 GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program GL_NV_vertex_program1_1 GL_NV_vertex_program2 " + "GL_NV_vertex_program2_option GL_NV_vertex_program3 GL_NVX_conditional_render GL_NVX_gpu_memory_info GL_OES_depth24 GL_OES_depth32 GL_OES_depth_texture GL_OES_element_index_uint GL_OES_fbo_render_mipmap " + "GL_OES_get_program_binary GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_texture_3D GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float " + "GL_OES_texture_half_float_linear GL_OES_texture_npot GL_OES_vertex_array_object GL_OES_vertex_half_float GL_SGIS_generate_mipmap GL_SGIS_texture_lod GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum"; + +typedef enum +{ + D3DCAPSSOURCE_TYPE_UNDEFINED = 0, + D3DCAPSSOURCE_TYPE_EMBEDDED1, + D3DCAPSSOURCE_TYPE_EMBEDDED2, + D3DCAPSSOURCE_TYPE_NULL, + D3DCAPSSOURCE_TYPE_LOCAL, + D3DCAPSSOURCE_TYPE_FILE, + D3DCAPSSOURCE_TYPE_NONE +} D3DCAPSSOURCE_TYPE; + +static D3DCAPS9* selectCaps(D3DCAPS9 *pLocalStorage, D3DCAPS9 *pLocalEmbedded1, D3DCAPS9 *pLocalEmbedded2, D3DCAPSSOURCE_TYPE enmCapsType) +{ + switch (enmCapsType) + { + case D3DCAPSSOURCE_TYPE_EMBEDDED1: + return pLocalEmbedded1; + case D3DCAPSSOURCE_TYPE_EMBEDDED2: + return pLocalEmbedded2; + case D3DCAPSSOURCE_TYPE_NULL: + memset (pLocalStorage, 0, sizeof (*pLocalStorage)); + return pLocalStorage; + case D3DCAPSSOURCE_TYPE_LOCAL: + { + LPDIRECT3D9EX pD3D = NULL; + HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); + if (FAILED(hr)) + { + Log(("Direct3DCreate9Ex failed hr 0x%x\n", hr)); + return NULL; + } + + memset (pLocalStorage, 0, sizeof (*pLocalStorage)); + + hr = pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pLocalStorage); + + pD3D->Release(); + + if (FAILED(hr)) + { + Log(("GetDeviceCaps failed hr 0x%x\n", hr)); + return NULL; + } + + return pLocalStorage; + } + case D3DCAPSSOURCE_TYPE_FILE: + { + Log(("Loading caps from file not implemented yet!")); + return NULL; + } + case D3DCAPSSOURCE_TYPE_NONE: + return NULL; + default: + { + Log(("Unsupported type %d", enmCapsType)); + return NULL; + } + } + + Log(("Should not be here!")); + return NULL; +} + +static void vboxUmdDumpDword(DWORD *pvData, DWORD cData) +{ + char aBuf[16*4]; + DWORD dw1, dw2, dw3, dw4; + for (UINT i = 0; i < (cData & (~3)); i+=4) + { + dw1 = *pvData++; + dw2 = *pvData++; + dw3 = *pvData++; + dw4 = *pvData++; + sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", dw1, dw2, dw3, dw4); + Log(("%s", aBuf)); + } + + cData = cData % 4; + switch (cData) + { + case 3: + dw1 = *pvData++; + dw2 = *pvData++; + dw3 = *pvData++; + sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x\n", dw1, dw2, dw3); + Log(("%s", aBuf)); + break; + case 2: + dw1 = *pvData++; + dw2 = *pvData++; + sprintf(aBuf, "0x%08x, 0x%08x\n", dw1, dw2); + Log(("%s", aBuf)); + break; + case 1: + dw1 = *pvData++; + sprintf(aBuf, "0x%8x\n", dw1); + Log(("%s", aBuf)); + break; + default: + break; + } +} + int main() { + diffGlExts(g_GlExts1, g_GlExts2); + if (sizeof (g_aCaps1) != sizeof (D3DCAPS9)) { - Log(("incorrect caps 1 size (%d), expected(%d)", sizeof (g_aCaps1), sizeof (D3DCAPS9))); + Log(("incorrect caps 1 size (%d), expected(%d)\n", sizeof (g_aCaps1), sizeof (D3DCAPS9))); return 1; } if (sizeof (g_aCaps2) != sizeof (D3DCAPS9)) { - Log(("incorrect caps 2 size (%d), expected(%d)", sizeof (g_aCaps2), sizeof (D3DCAPS9))); + Log(("incorrect caps 2 size (%d), expected(%d)\n", sizeof (g_aCaps2), sizeof (D3DCAPS9))); + return 1; + } + + D3DCAPS9 Caps1, Caps2; + D3DCAPS9 *pCaps1, *pCaps2; + D3DCAPSSOURCE_TYPE enmCaps1 = D3DCAPSSOURCE_TYPE_EMBEDDED1; + D3DCAPSSOURCE_TYPE enmCaps2 = D3DCAPSSOURCE_TYPE_EMBEDDED2; + + pCaps1 = selectCaps(&Caps1, (D3DCAPS9*)g_aCaps1, (D3DCAPS9*)g_aCaps2, enmCaps1); + if (!pCaps1) + { + Log(("Failed to select Caps1")); return 1; } - diffCaps((D3DCAPS9*)g_aCaps1, (D3DCAPS9*)g_aCaps2); + if (D3DCAPSSOURCE_TYPE_NONE != enmCaps2) + { + pCaps2 = selectCaps(&Caps2, (D3DCAPS9*)g_aCaps1, (D3DCAPS9*)g_aCaps2, enmCaps2); + if (!pCaps2) + { + Log(("Failed to select Caps2")); + return 1; + } + + diffCaps((D3DCAPS9*)pCaps1, (D3DCAPS9*)pCaps2); + } + else + { + vboxUmdDumpDword((DWORD*)pCaps1, sizeof (*pCaps1) / sizeof (DWORD)); + } return 0; } diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp index 221e45e7..432d9bf0 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp @@ -1,6 +1,6 @@ /* $Id: tstMvWnd.cpp $ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h index d727e4ef..af369986 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -134,6 +134,8 @@ typedef struct _VBOXDISPDEV #ifdef VBOX_WITH_VIDEOHWACCEL VBOXDISPVHWAINFO vhwa; /* VHWA Info */ #endif + + BOOL bBitmapCacheDisabled; } VBOXDISPDEV, *PVBOXDISPDEV; /* -------------------- Driver callbacks -------------------- */ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp index bfb3b9d3..855aca55 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp @@ -66,11 +66,11 @@ DWORD APIENTRY VBoxDispDDCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSu { if(pBody->u.out.ErrInfo) { + WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo)); lpCanCreateSurface->ddRVal = DDERR_GENERIC; } else { - WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo)); lpCanCreateSurface->ddRVal = DD_OK; } } @@ -274,8 +274,9 @@ DWORD APIENTRY VBoxDispDDDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface) memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY)); pBody->u.in.hSurf = pDesc->hHostHandle; - /* we're not interested in completion, just send the command */ - VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); + VBoxDispVHWACommandSubmit(pDev, pCmd); + + VBoxDispVHWACommandRelease(pDev, pCmd); VBoxDispVHWASurfDescFree(pDesc); diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp index a1b61f85..a0a17ee6 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -518,6 +518,14 @@ VBoxDispDrvEnablePDEV(DEVMODEW *pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF *p } pDev->hDriver = hDriver; + ULONG ulRegistryFlags = 0; + rc = VBoxDispMPQueryRegistryFlags(hDriver, &ulRegistryFlags); + if (RT_SUCCESS(rc)) + { + pDev->bBitmapCacheDisabled = (ulRegistryFlags & VBOXVIDEO_REGISTRY_FLAGS_DISABLE_BITMAP_CACHE) != 0; + LOG(("Bitmap cache %s", pDev->bBitmapCacheDisabled? "disabled": "enabled")); + } + /* Initialize device structure and query miniport to fill device and gdi infos */ rc = VBoxDispInitDevice(pDev, pdm, &gdiInfo, &devInfo); if (RT_FAILURE(rc)) diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp index 018d9b77..466acd71 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp @@ -406,3 +406,24 @@ int VBoxDispMPUnshareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem) LOGF_LEAVE(); return VINF_SUCCESS; } + +int VBoxDispMPQueryRegistryFlags(HANDLE hDriver, ULONG *pulFlags) +{ + DWORD dwrc; + ULONG cbReturned; + ULONG ulInfoLevel; + LOGF_ENTER(); + + *pulFlags = 0; + ulInfoLevel = VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS; + dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO, &ulInfoLevel, sizeof(DWORD), + pulFlags, sizeof(DWORD), &cbReturned); + VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); + VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_QUERY_INFO", cbReturned, sizeof(DWORD), VERR_DEV_IO_ERROR); + + if (*pulFlags != 0) + LogRel(("VBoxDisp: video flags 0x%08X\n", *pulFlags)); + + LOGF_LEAVE(); + return VINF_SUCCESS; +} diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h index 9df90c16..35cf5cf9 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h @@ -38,5 +38,6 @@ int VBoxDispMPSetVisibleRegion(HANDLE hDriver, PRTRECT pRects, DWORD cRects); int VBoxDispMPResetDevice(HANDLE hDriver); int VBoxDispMPShareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem, PVIDEO_SHARE_MEMORY_INFORMATION pSMemInfo); int VBoxDispMPUnshareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem); +int VBoxDispMPQueryRegistryFlags(HANDLE hDriver, ULONG *pulFlags); #endif /*VBOXDISPMINI_H*/ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp index da9c3fdc..741bdae9 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -1460,8 +1460,9 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ * VRDPBCHASH hashDeleted; int cacheResult; - LOG(("MEMBLT.")); - if ( (psoSrc->fjBitmap & BMF_DONTCACHE) != 0 + LOG(("MEMBLT: bitmap %dx%d.", psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy)); + if ( pDev->bBitmapCacheDisabled + || (psoSrc->fjBitmap & BMF_DONTCACHE) != 0 || psoSrc->iUniq == 0 /* Bitmaps with hdev == 0 seems to have different RGB layout for 16BPP modes. * Just do not cache these bitmaps and report the dirty display area instead. @@ -1469,6 +1470,10 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ * || ( psoSrc->hdev == 0 && !(psoSrc->iBitmapFormat == BMF_24BPP || psoSrc->iBitmapFormat == BMF_32BPP) ) + /* Do not try to cache large bitmaps. The cache should be mostly used for icons, etc. + * Computing a bitmap hash increases CPU load. Up to 384K pixels (~620x620) + */ + || psoSrc->sizlBitmap.cx * psoSrc->sizlBitmap.cy > 384 * _1K ) { LOG(("MEMBLT: non cacheable bitmap.")); @@ -1476,17 +1481,11 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ * } else { - LOG(("going to cache.")); - cacheResult = vrdpbmpCacheSurface(&pDev->vrdpCache, psoSrc, &hash, &hashDeleted); + LOG(("MEMBLT: going to cache.")); + cacheResult = vrdpbmpCacheSurface(&pDev->vrdpCache, psoSrc, &hash, &hashDeleted, FALSE); } - LOG(("MEMBLT: cacheResult 0x%08X. trg %d,%d %dx%d src %dx%d from %d,%d", - cacheResult, - rclTrg.left, rclTrg.top, - rclTrg.right - rclTrg.left, - rclTrg.bottom - rclTrg.top, - psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy, - pptlSrc->x, pptlSrc->y)); + LOG(("MEMBLT: cacheResult 0x%08X", cacheResult)); if (cacheResult & VRDPBMP_RC_F_DELETED) { @@ -1499,10 +1498,17 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ * { case VRDPBMP_RC_CACHED: vrdpReportCachedBitmap(pDev, psoSrc, &hash); + LOG(("MEMBLT: cached add %dx%d", + psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy)); /* Continue and report MEMBLT order. */ case VRDPBMP_RC_ALREADY_CACHED: vrdpReportMemBlt(pDev, &clipRects, pptlSrc, (uint8_t)rop4, &hash); + LOG(("MEMBLT: cached use %dx%d from %d,%d %dx%d", + psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy, + pptlSrc->x, pptlSrc->y, + rclTrg.right - rclTrg.left, + rclTrg.bottom - rclTrg.top)); LOG((" %08X %08X %08X %08X", *(uint32_t *)&((uint8_t *)&hash)[0], *(uint32_t *)&((uint8_t *)&hash)[4], @@ -1513,7 +1519,11 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ * default: /* The surface was not cached. Fallback to dirty rects. */ - LOG(("MEMBLT: bitmap not cached.")); + LOG(("MEMBLT: not cached %dx%d from %d,%d %dx%d", + psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy, + pptlSrc->x, pptlSrc->y, + rclTrg.right - rclTrg.left, + rclTrg.bottom - rclTrg.top)); VBoxDispDumpPSO(psoSrc, "psoSrc"); vrdpReportDirtyRects(pDev, &clipRects); } diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp index d9ac9960..9f64770c 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -21,9 +21,16 @@ #include <VBox/RemoteDesktop/VRDEOrders.h> /* - * Cache has a fixed number of preallocated entries. Entries are linked in the MRU - * list. The list contains both used and free entries. Free entries are at the end. - * The most recently used entry is in the head. + * Cache has a fixed number of preallocated entries. Entries are linked in the MRU lists. + * + * A new bitmap hash is added to the "temporary" list, and the caller is told that the + * bitmap was not cached. If the hash is used again, then it is moved to the "cached" list. + * This protects against "cache, memblt, cache, memblt, ..." sequences. + * + * "Temporary" list contains free and temporary entries. Temporary entries are at the head, + * free entries are at the tail. New temporary entries are inserted in the head. + * + * "Cached" list contains cached entries. When a entry is used, it is moved to the head. * * The purpose of the cache is to answer whether the bitmap was already encountered * before. @@ -74,127 +81,286 @@ static BOOL bcComputeHash (const SURFOBJ *pso, VRDPBCHASH *phash) return TRUE; } -/* Meves an entry to the head of MRU list. */ -static void bcMoveToHead (VRDPBC *pCache, VRDPBCENTRY *pEntry) +static void bcRemoveFromCached(VRDPBC *pCache, VRDPBCENTRY *pEntry) { if (pEntry->prev) { - /* The entry is not yet in the head. Exclude from list. */ pEntry->prev->next = pEntry->next; + } + else + { + pCache->headCached = pEntry->next; + } - if (pEntry->next) - { - pEntry->next->prev = pEntry->prev; - } - else - { - pCache->tail = pEntry->prev; - } + if (pEntry->next) + { + pEntry->next->prev = pEntry->prev; + } + else + { + pCache->tailCached = pEntry->prev; + } +} + +static void bcRemoveFromTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + if (pEntry->prev) + { + pEntry->prev->next = pEntry->next; + } + else + { + pCache->headTmp = pEntry->next; + } + + if (pEntry->next) + { + pEntry->next->prev = pEntry->prev; + } + else + { + pCache->tailTmp = pEntry->prev; + } +} + +static void bcInsertHeadCached(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + pEntry->prev = NULL; + pEntry->next = pCache->headCached; + + if (pCache->headCached) + { + pCache->headCached->prev = pEntry; + } + else + { + pCache->tailCached = pEntry; + } + + pCache->headCached = pEntry; +} + +static void bcInsertHeadTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + pEntry->prev = NULL; + pEntry->next = pCache->headTmp; + + if (pCache->headTmp) + { + pCache->headTmp->prev = pEntry; + } + else + { + pCache->tailTmp = pEntry; + } + + pCache->headTmp = pEntry; +} + +/* Moves an entry to the head of MRU list. */ +static void bcMoveToHeadCached(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + if (pEntry->prev) + { + /* The entry is not yet in the head. Exclude from list. */ + bcRemoveFromCached(pCache, pEntry); /* Insert the entry at the head of MRU list. */ - pEntry->prev = NULL; - pEntry->next = pCache->head; + bcInsertHeadCached(pCache, pEntry); + } +} - Assert(pCache->head); +static void bcMoveToHeadTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + if (pEntry->prev) + { + /* The entry is not yet in the head. Exclude from list. */ + bcRemoveFromTmp(pCache, pEntry); - pCache->head->prev = pEntry; - pCache->head = pEntry; + /* Insert the entry at the head of MRU list. */ + bcInsertHeadTmp(pCache, pEntry); } } -/* Returns TRUE if the hash already presents in the cache. - * Moves the found entry to the head of MRU list. +static void bcMoveTmpToCached(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + /* Remove from Tmp list. */ + bcRemoveFromTmp(pCache, pEntry); + + /* Insert the entry at the head of Cached list. */ + bcInsertHeadCached(pCache, pEntry); +} + +static void bcMoveCachedToTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry) +{ + /* Remove from cached list. */ + bcRemoveFromCached(pCache, pEntry); + + /* Insert the entry at the head of Tmp list. */ + bcInsertHeadTmp(pCache, pEntry); +} + + +/* Returns pointer to the entry if the hash already presents in the cache. + * Moves the found entry to the head of cached MRU list. */ -static BOOL bcFindHash (VRDPBC *pCache, const VRDPBCHASH *phash) +static VRDPBCENTRY *bcFindHash (VRDPBC *pCache, const VRDPBCHASH *phash) { - /* Search the MRU list. */ - VRDPBCENTRY *pEntry = pCache->head; + /* Search the "Cached" MRU list. */ + VRDPBCENTRY *pEntry = pCache->headCached; - while (pEntry && pEntry->fUsed) + while (pEntry) { if (memcmp (&pEntry->hash, phash, sizeof (VRDPBCHASH)) == 0) { - /* Found the entry. Move it to the head of MRU list. */ - bcMoveToHead (pCache, pEntry); + /* Found the entry. Move it to the head of Cached MRU list. */ + bcMoveToHeadCached(pCache, pEntry); - return TRUE; + return pEntry; } pEntry = pEntry->next; } - return FALSE; + /* Search the "Temporary" MRU list. */ + pEntry = pCache->headTmp; + + while ( pEntry + && pEntry->u32Status != VRDP_BC_ENTRY_STATUS_EMPTY) + { + if (memcmp (&pEntry->hash, phash, sizeof (VRDPBCHASH)) == 0) + { + /* Found the entry. It will be removed from the list by the caller. */ + return pEntry; + } + + pEntry = pEntry->next; + } + + return NULL; } -/* Returns TRUE is a entry was also deleted to nake room for new entry. */ -static BOOL bcInsertHash (VRDPBC *pCache, const VRDPBCHASH *phash, VRDPBCHASH *phashDeleted) +/* Returns TRUE is a entry was also deleted to make room for new entry. */ +static int bcInsertHash (VRDPBC *pCache, const VRDPBCHASH *phash, VRDPBCHASH *phashDeleted, BOOL bForce) { - BOOL bRc = FALSE; - VRDPBCENTRY *pEntry; + LOG(("bcInsertHash %p, tmp tail %p, cached tail %p.", pCache, pCache->tailTmp, pCache->tailCached)); - LOG(("insert hash cache %p, tail %p.", pCache, pCache->tail)); + /* Get the free entry to be used. Try Tmp list, then the tail of the Cached list. */ + VRDPBCENTRY *pEntry = pCache->tailTmp; + + if (pEntry != NULL) + { + /* Insert to the head of Tmp list. */ + bcMoveToHeadTmp(pCache, pEntry); + LOG(("bcInsertHash %p, use tmp tail %p.", pCache, pEntry)); + } + else + { + pEntry = pCache->tailCached; + LOG(("bcInsertHash %p, reuse cached tail %p.", pCache, pEntry, pEntry? pEntry->u32Status: 0)); - /* Get the free entry to be used. Try tail, that should be */ - pEntry = pCache->tail; + if (pEntry != NULL) + { + bcMoveCachedToTmp(pCache, pEntry); + } + } - if (pEntry == NULL) + if (!pEntry) { - return bRc; + LOG(("bcInsertHash %p, failed to find an entry!!!", pCache)); + return VRDPBMP_RC_NOT_CACHED; } - if (pEntry->fUsed) + BOOL bHashDeleted; + if (pEntry->u32Status == VRDP_BC_ENTRY_STATUS_CACHED) { - /* The cache is full. Remove the tail. */ + /* The cache is full. Remove the tail hash. */ memcpy (phashDeleted, &pEntry->hash, sizeof (VRDPBCHASH)); - bRc = TRUE; + bHashDeleted = TRUE; + } + else + { + bHashDeleted = FALSE; } - bcMoveToHead (pCache, pEntry); - + /* The just inserted entry is at the head of Tmp list, so the temporary + * entries will be deleted when there is no room in the cache. + */ memcpy (&pEntry->hash, phash, sizeof (VRDPBCHASH)); - pEntry->fUsed = TRUE; - return bRc; + int rc; + if (bForce) + { + LOG(("Force cache")); + bcMoveTmpToCached(pCache, pEntry); + pEntry->u32Status = VRDP_BC_ENTRY_STATUS_CACHED; + rc = VRDPBMP_RC_CACHED; + } + else + { + pEntry->u32Status = VRDP_BC_ENTRY_STATUS_TEMPORARY; + rc = VRDPBMP_RC_NOT_CACHED; + } + + if (bHashDeleted) + { + rc |= VRDPBMP_RC_F_DELETED; + } + + return rc; } /* Find out whether the surface already in the cache. * Insert in the cache if not. + * Protection against "cache, memblt, cache, memblt, ..." sequence: + * first time just append the bitmap hash and mark it as "temporary"; + * if the hash is used again, mark as cached and tell the caller to cache the bitmap; + * remove "temporary" entries before any other. + * */ -int vrdpbmpCacheSurface(VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted) +int vrdpbmpCacheSurface(VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted, BOOL bForce) { - int rc; - VRDPBCHASH hash; BOOL bResult = bcComputeHash (pso, &hash); - LOG(("vrdpbmpCacheSurface: compute hash %d.", bResult)); + if (!bResult) { WARN(("MEMBLT: vrdpbmpCacheSurface: could not compute hash.")); return VRDPBMP_RC_NOT_CACHED; } - bResult = bcFindHash (pCache, &hash); - - LOG(("vrdpbmpCacheSurface: find hash %d.", bResult)); *phash = hash; - if (bResult) + VRDPBCENTRY *pEntry = bcFindHash (pCache, &hash); + LOG(("vrdpbmpCacheSurface: find hash %d.", pEntry? pEntry->u32Status: 0)); + + if (pEntry) { - return VRDPBMP_RC_ALREADY_CACHED; - } + if (pEntry->u32Status == VRDP_BC_ENTRY_STATUS_CACHED) + { + return VRDPBMP_RC_ALREADY_CACHED; + } - rc = VRDPBMP_RC_CACHED; + /* The status must be VRDP_BC_ENTRY_STATUS_TEMPORARY here. + * Update it to *_CACHED. + */ + if (pEntry->u32Status != VRDP_BC_ENTRY_STATUS_TEMPORARY) + { + LOG(("MEMBLT: vrdpbmpCacheSurface: unexpected status %d.", pEntry->u32Status)); + return VRDPBMP_RC_NOT_CACHED; + } - bResult = bcInsertHash (pCache, &hash, phashDeleted); + bcMoveTmpToCached(pCache, pEntry); - LOG(("vrdpbmpCacheSurface: insert hash %d.", bResult)); - if (bResult) - { - rc |= VRDPBMP_RC_F_DELETED; + pEntry->u32Status = VRDP_BC_ENTRY_STATUS_CACHED; + return VRDPBMP_RC_CACHED; } + int rc = bcInsertHash (pCache, &hash, phashDeleted, bForce); + LOG(("vrdpbmpCacheSurface: insert hash %x.", rc)); + return rc; } @@ -205,24 +371,29 @@ void vrdpbmpReset(VRDPBC *pCache) Assert(sizeof (VRDPBCHASH) == sizeof (VRDEBITMAPHASH)); + LOG(("vrdpbmpReset: %p.", pCache)); + /* Reinitialize the cache structure. */ memset(pCache, 0, sizeof (VRDPBC)); - pCache->head = &pCache->aEntries[0]; - pCache->tail = &pCache->aEntries[RT_ELEMENTS(pCache->aEntries) - 1]; + pCache->headTmp = &pCache->aEntries[0]; + pCache->tailTmp = &pCache->aEntries[RT_ELEMENTS(pCache->aEntries) - 1]; for (i = 0; i < RT_ELEMENTS(pCache->aEntries); i++) { VRDPBCENTRY *pEntry = &pCache->aEntries[i]; - if (pEntry != pCache->tail) + if (pEntry != pCache->tailTmp) { pEntry->next = &pCache->aEntries[i + 1]; } - if (pEntry != pCache->head) + if (pEntry != pCache->headTmp) { pEntry->prev = &pCache->aEntries[i - 1]; } } + + pCache->headCached = NULL; + pCache->tailCached = NULL; } diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h index f1e93fb4..483adf5d 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -55,22 +55,28 @@ typedef struct _VRDPBCHASH } VRDPBCHASH; #pragma pack () +#define VRDP_BC_ENTRY_STATUS_EMPTY 0 +#define VRDP_BC_ENTRY_STATUS_TEMPORARY 1 +#define VRDP_BC_ENTRY_STATUS_CACHED 2 + typedef struct _VRDPBCENTRY { - bool fUsed; struct _VRDPBCENTRY *next; struct _VRDPBCENTRY *prev; VRDPBCHASH hash; + uint32_t u32Status; } VRDPBCENTRY; typedef struct _VRDPBC { - VRDPBCENTRY *head; - VRDPBCENTRY *tail; + VRDPBCENTRY *headTmp; + VRDPBCENTRY *tailTmp; + VRDPBCENTRY *headCached; + VRDPBCENTRY *tailCached; VRDPBCENTRY aEntries[VRDPBMP_N_CACHED_BITMAPS]; } VRDPBC; void vrdpbmpReset (VRDPBC *pCache); -int vrdpbmpCacheSurface (VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted); +int vrdpbmpCacheSurface (VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted, BOOL bForce); #endif /*VBOXDISPVRDPBMP_H*/ diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp index b7cbe084..16f10b60 100644 --- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp +++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; |
