VBoxDispD3D.cpp revision 46737b2c6b2da473108a7670c3682d88474bd8b9
af062818b47340eef15700d2f0211576ba3506eevboxsync * VBoxVideo Display D3D User mode dll
af062818b47340eef15700d2f0211576ba3506eevboxsync * Copyright (C) 2011-2012 Oracle Corporation
af062818b47340eef15700d2f0211576ba3506eevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
af062818b47340eef15700d2f0211576ba3506eevboxsync * available from http://www.virtualbox.org. This file is free software;
af062818b47340eef15700d2f0211576ba3506eevboxsync * you can redistribute it and/or modify it under the terms of the GNU
af062818b47340eef15700d2f0211576ba3506eevboxsync * General Public License (GPL) as published by the Free Software
af062818b47340eef15700d2f0211576ba3506eevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
af062818b47340eef15700d2f0211576ba3506eevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
af062818b47340eef15700d2f0211576ba3506eevboxsyncvolatile uint32_t g_u32VBoxDispProfileFunctionLoggerIndex = 0;
af062818b47340eef15700d2f0211576ba3506eevboxsync/* the number of frames to collect data before doing dump/reset */
af062818b47340eef15700d2f0211576ba3506eevboxsync/* uncomment to enable particular logging */
af062818b47340eef15700d2f0211576ba3506eevboxsync/* allows dumping fps + how much time is spent in ddi functions in comparison with the rest time */
af062818b47340eef15700d2f0211576ba3506eevboxsync//# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE
af062818b47340eef15700d2f0211576ba3506eevboxsync/* allows dumping time spent in each function and the number of calls made for any given function */
void postProcess()
m_pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Finish((IDirect3DDevice9Ex *)m_pDevice->pDevice9If);
# 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_DISABLE_CURRENT() do {\
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT()
if (!((_pObj)->ProfileDdiFunc.reportIteration() % VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT) /*&& !VBOXVDBG_IS_DWM()*/) {\
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {} while (0)
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() do {} while (0)
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&(_pObj)->ProfileDdiFps, VBoxDispProfileDummyPostProcess, VBoxDispProfileDummyPostProcess())
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {\
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() VBOXDISPPROFILE_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT()
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {} while (0)
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() do {} while (0)
# define VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT() \
# define VBOXDISPPROFILE_DDI_INIT_GLBL() VBOXDISPPROFILE_DDI_INIT_CMN(&g_VBoxDispProfile, "DDI_Adp", 64)
# define VBOXDISPPROFILE_DDI_INIT_GLBL() do {} while (0)
#define VBOXDISP_DDI_PROLOGUE_CMN() \
VBOXVDBG_BREAK_DDI(); \
#define VBOXDISP_DDI_PROLOGUE_GLBL() \
#ifdef VBOXDISPMP_TEST
#define VBOXDISP_WITH_WINE_BB_WORKAROUND
void vboxDispLock()
void vboxDispUnlock()
void vboxDispLockInit()
#define VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL() do {} while(0)
typedef struct VBOXWDDMDISP_NSCADD
return hr;
#ifdef DEBUG_misha
typedef struct VBOXWDDM_DBG_ALLOC
#ifdef DEBUG_misha
if (bReinitRenderData)
return E_FAIL;
#ifdef DEBUG_misha
++cDbgAllocs;
++cAllocs;
PVBOXWDDMDISP_ALLOCATION pAlloc = RTListGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
if (pAlloc)
#ifdef DEBUG_misha
RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
return S_OK;
#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
static HRESULT vboxWddmDalCheckUnlock(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc)
return S_OK;
return hr;
static HRESULT vboxWddmDalCheckLock(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_LOCKFLAGS Flags)
return S_OK;
return S_OK;
return hr;
static BOOLEAN vboxWddmDalCheckNotifyRemove(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc)
return TRUE;
return FALSE;
static BOOLEAN vboxWddmDalCheckAdd(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOLEAN fWrite)
return FALSE;
return TRUE;
static DECLINLINE(BOOLEAN) vboxWddmDalCheckAddRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, BOOLEAN fWrite)
return fChanged;
++iSampler;
#ifdef VBOX_WITH_VIDEOHWACCEL
PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAlloc(RT_OFFSETOF(VBOXWDDMDISP_RESOURCE, aAllocations[cAllocs]));
if (pRc)
return pRc;
return NULL;
#ifdef VBOXWDDMDISP_DEBUG
int iRc = 0;
static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch);
static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
} Buf;
HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSwapchain9GetHostWinID(pSwapchain->pSwapChainIf, &Buf.SwapchainInfo.SwapchainInfo.winHostID);
return hr;
++cAllocsKm;
DdiEscape.PrivateDriverDataSize = RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[Buf.SwapchainInfo.SwapchainInfo.cAllocs]);
#ifdef DEBUG_misha
return S_OK;
static HRESULT vboxWddmSwapchainKmDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
return hr;
static HRESULT vboxWddmSwapchainDestroyIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
#ifndef VBOXWDDM_WITH_VISIBLE_FB
return S_OK;
return S_OK;
DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
PVBOXWDDMDISP_SWAPCHAIN pCur = RTListGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
while (pCur)
PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)RTMemAllocZ(sizeof (VBOXWDDMDISP_SWAPCHAIN));
if (pSwapchain)
return pSwapchain;
return NULL;
DECLINLINE(VOID) vboxWddmSwapchainRtInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRt, PVBOXWDDMDISP_ALLOCATION pAlloc)
DECLINLINE(VOID) vboxWddmSwapchainBbAddTail(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bAssignAsBb)
else if (bAssignAsBb)
DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainRtForAlloc(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc)
return NULL;
Assert(0);
return NULL;
DECLINLINE(UINT) vboxWddmSwapchainRtIndex(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
return iRt;
DECLINLINE(VOID) vboxWddmSwapchainRtRemove(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
DECLINLINE(VOID) vboxWddmSwapchainSetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainFindCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc, BOOL *pbNeedPresent)
if (pSwapchain)
return pSwapchain;
if (!pSwapchain)
PVBOXWDDMDISP_SWAPCHAIN pCur = RTListGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
while (pCur)
&& vboxWddmSwapchainRtIndex(pCur, pRt) == 0) /* <- in case we add a rt to the swapchain on present this would mean
&& vboxWddmFmtNoAlphaFormat(pBbAlloc->SurfDesc.format) == vboxWddmFmtNoAlphaFormat(pRt->pAlloc->SurfDesc.format)
if (!pSwapchain)
if (pSwapchain)
return pSwapchain;
static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainCreateForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc)
if (pSwapchain)
return pSwapchain;
return NULL;
return iBb != (~0) ? (iBb + pSwapchain->iBB) % pSwapchain->cRTs : vboxWddmSwapchainIdxFb(pSwapchain);
static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
return S_OK;
iBb = 0;
return hr;
return hr;
#ifdef DEBUG_misha
VBOXVDBG_CHECK_SWAPCHAIN_SYNC(hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE); Assert(hr == S_OK),
if (pD3D9OldSurf)
VBOXVDBG_CHECK_SWAPCHAIN_SYNC(tmpHr = pDevice->pDevice9If->StretchRect(pD3D9Bb, NULL, (IDirect3DSurface9*)vboxWddmSwapchainGetBb(pSwapchain)->pAlloc->pD3DIf, NULL, D3DTEXF_NONE); Assert(tmpHr == S_OK),
pAlloc, pD3D9Bb, NULL, pAlloc, (IDirect3DSurface9*)vboxWddmSwapchainGetBb(pSwapchain)->pAlloc->pD3DIf, NULL);
return hr;
static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
return hr;
static VOID vboxWddmSwapchainFillPresentParams(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, D3DPRESENT_PARAMETERS *pParams)
#ifdef DEBUG_misha
/* not supported by wine properly, need to use offscreen render targets and blit their data to swapchain RTs*/
static HRESULT vboxWddmSwapchainSwtichOffscreenRt(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, BOOL fForceCreate)
if (pOldIf)
return hr;
if (fHasSurf)
if (pD3D9OldSurf)
if (pD3D9OldSurf)
VBOXVDBG_CHECK_SWAPCHAIN_SYNC(hr = pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9NewSurf, NULL, D3DTEXF_NONE); Assert(hr == S_OK),
if (pD3D9OldSurf)
if (pD3D9OldSurf)
return hr;
static HRESULT vboxWddmSwapchainSwtichRtPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
return S_OK;
return hr;
return hr;
HRESULT vboxWddmSwapchainChkCreateIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
return S_OK;
if (pOldIf)
if (fNeedRtPresentSwitch)
if (!bReuseSwapchain)
hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If);
if (pOldIf)
return hr;
if (fNeedRtPresentSwitch)
#ifndef VBOXWDDM_WITH_VISIBLE_FB
#ifdef DEBUG
if (pOldIf)
return S_OK;
static HRESULT vboxWddmSwapchainCreateIfForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_SWAPCHAIN *ppSwapchain)
if (pSwapchain)
return hr;
return E_OUTOFMEMORY;
static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain);
static HRESULT vboxWddmSwapchainBbUpdate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
return S_OK;
return hr;
return E_FAIL;
static HRESULT vboxWddmSwapchainSurfGet(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DSurface9 **ppSurf)
#ifndef VBOXWDDM_WITH_VISIBLE_FB
# ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
&& vboxWddmSwapchainNumRTs(pSwapchain) != 1 /* for swapchains w/o a backbuffer the alloc will contain the back-buffer actually */
return hr;
return S_OK;
static HRESULT vboxWddmSwapchainRtSurfGet(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch, IDirect3DSurface9 **ppSurf)
if (!bOnSwapchainSynch)
if (iRt == 0)
return hr;
return hr;
return hr;
return S_OK;
static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
return hr;
return hr;
return hr;
return hr;
static HRESULT vboxWddmSwapchainPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
/* we currently *assume* that presenting shared resource is only possible when 3d app is rendering with composited desktop on,
HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
return S_OK;
if (!bNeedPresent)
return S_OK;
if (pSwapchain)
return hr;
return E_OUTOFMEMORY;
static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
#ifdef VBOXWDDM_WITH_VISIBLE_FB
if (iNewRTFB == i)
# define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))
static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch)
if (pSwapchain)
return hr;
return hr;
return hr;
switch (dwReason)
case DLL_PROCESS_ATTACH:
#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
return TRUE;
#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
case DLL_PROCESS_DETACH:
#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
return TRUE;
return TRUE;
return FALSE;
case D3DDDICAPS_DDRAW:
#ifdef VBOX_WITH_VIDEOHWACCEL
#ifdef VBOX_WITH_VIDEOHWACCEL
case D3DDDICAPS_GETFORMATDATA:
memcpy(pData->pData, pAdapter->Formats.paFormstOps, pAdapter->Formats.cFormstOps * sizeof (FORMATOP));
Assert(0);
case D3DDDICAPS_GETD3D3CAPS:
case D3DDDICAPS_GETD3D7CAPS:
case D3DDDICAPS_GETD3D9CAPS:
case D3DDDICAPS_GETD3D8CAPS:
case D3DDDICAPS_GETD3D5CAPS:
case D3DDDICAPS_GETD3D6CAPS:
Assert(0);
Assert(0);
return S_OK;
static HRESULT APIENTRY vboxWddmDDevSetRenderState(HANDLE hDevice, CONST D3DDDIARG_RENDERSTATE* pData)
return hr;
return S_OK;
static HRESULT APIENTRY vboxWddmDDevValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE* pData)
#ifdef DEBUG_misha
Assert(0);
return S_OK;
static HRESULT APIENTRY vboxWddmDDevSetTextureStageState(HANDLE hDevice, CONST D3DDDIARG_TEXTURESTAGESTATE* pData)
hr = pDevice9If->SetTextureStageState(pData->Stage, D3DTEXTURESTAGESTATETYPE(lookup.dType), pData->Value);
return hr;
if (pRc)
Assert(0);
if (idx >= 0)
#ifdef DEBUG_misha
if (idx >= 0)
return hr;
return hr;
static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONST* pData, CONST FLOAT* pRegisters)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetStreamSourceUm(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEUM* pData, CONST VOID* pUMBuffer )
return hr;
if (pRc)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
return hr;
static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
#ifdef DEBUG
++cStreams;
((uint8_t*)pDevice->aStreamSourceUm[i].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[i].cbStride,
#ifdef DEBUG
++cStreams;
return hr;
static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
#ifdef DEBUG
++cStreams;
cStreams = 0;
++cStreams;
if (!pvIndexBuffer)
HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
return hr;
static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
int stream;
IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
RECT r;
r.top = 0;
VBoxD3DIfLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
#ifdef DEBUG
int stream;
#ifdef DEBUG
++cStreams;
(void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
hr = pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
#ifdef DEBUG
return hr;
static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
HRESULT tmpHr = pDevice9If->SetStreamSource(0, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[0]->pD3DIf, pDevice->StreamSourceInfo[0].uiOffset, pDevice->StreamSourceInfo[0].uiStride);
HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
return hr;
HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9VolTexBlt((IDirect3DDevice9Ex*)pDevice9If, pSrcTex, pDstTex,
return hr;;
Assert(0);
return E_FAIL;
#ifdef DEBUG
RECT tstRect = {0,0, pDstRc->aAllocations[0].SurfDesc.width, pDstRc->aAllocations[0].SurfDesc.height};
hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &DstRect, D3DTEXF_NONE); Assert(hr == S_OK),
return hr;
Assert(0);
return E_FAIL;
return S_OK;
static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
return hr;
static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
return hr;
static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
return hr;
return hr;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
return hr;
static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
switch (DevInfoID)
case D3DDDIDEVINFOID_VCACHE:
Assert(0);
return hr;
return E_INVALIDARG;
// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
return hr;
Assert((pAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
Assert(0);
if (pRect)
Assert(0);
Assert((pAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
if (pBox)
bLocked = true;
if (pRange)
if (pRange)
r.top = 0;
pr = &r;
bLocked = true;
if (pRange)
if (pRange)
r.top = 0;
pr = &r;
#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
offset = vboxWddmCalcOffXYrd(pData->Area.left, pData->Area.top, pAlloc->SurfDesc.pitch, pAlloc->SurfDesc.format);
Assert(0);
offset = 0;
return hr;
return E_INVALIDARG;
Assert(0);
// Assert(!pAlloc->LockInfo.cLocks);
r.top = 0;
pr = &r;
pr,
// Assert(!pAlloc->LockInfo.cLocks);
r.top = 0;
pr = &r;
pr,
#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
if (fDoUnlock)
return hr;
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
/* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
if (pvBuf)
return pAlloc;
return NULL;
static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
if (!pRc)
return E_OUTOFMEMORY;
bool bIssueCreateResource = false;
bool bCreateKMResource = false;
bool bSetHostID = false;
pAllocation->SurfDesc.cbSize = vboxWddmCalcSize(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.height, pAllocation->SurfDesc.format);
if (minPitch)
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! */
bIssueCreateResource = true;
bCreateKMResource = true;
bIssueCreateResource = true;
bSetHostID = true;
if (pDdiAllocate)
if (bSetHostID)
if (bCreateKMResource)
for (UINT j = 0; i < j; ++j)
return hr;
if (pSwapchain)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
return hr;
#ifdef VBOXWDDM_TEST_UHGSMI
#ifdef VBOXWDDM_TEST_UHGSMI
return hr;
if (pSrcAlloc)
if (pDstAlloc)
VBoxDispProfileScopeLogger<VBoxDispProfileEntry> profilePresentCbLogger(pDevice->ProfileDdiPresentCb.alloc("pfnPresentCb"));
#ifdef VBOXWDDMDISP_DEBUG_TIMER
#ifdef VBOXWDDMDISP_DEBUG_TIMER
return hr;
hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
return hr;
AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
bool bFreeVe = false;
if (pVe)
bFreeVe = true;
pVe,
if (bFreeVe)
return hr;
return hr;
return hr;
static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
return hr;
return hr;
return hr;
static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
return hr;
return hr;
static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
if (pRc)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
#ifdef DEBUG_misha
Assert(0);
return hr;
static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
Assert(0);
return E_FAIL;
Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc || vboxWddmSwapchainNumRTs(pDstSwapchain) == 1);
if (pSrcSwapchain)
Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
VBOXVDBG_CHECK_BLT(hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &pData->DstRect, vboxDDI2D3DBltFlags(pData->Flags)); Assert(hr == S_OK),
Assert(0);
return hr;
return hr;
Assert(0);
return E_FAIL;
if (!pQuery)
return E_OUTOFMEMORY;
return hr;
return hr;
return hr;
return hr;
static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
#ifdef DEBUG
case D3DDDIQUERYTYPE_EVENT:
Assert(0);
return hr;
static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
if (pRc)
if (pD3D9Surf)
return hr;
static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
return hr;
static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
return hr;
static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
return hr;
return hr;
static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
Assert(0);
return E_FAIL;
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
Assert(0);
return E_FAIL;
#ifdef VBOXWDDMDISP_DEBUG_TIMER
* Release may not work in case of some leaking, which will leave the crOgl context refering the destroyed VBOXUHGSMI */
return hr;
if (pOverlay)
#ifndef VBOXWDDMOVERLAY_TEST
return hr;
static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
#ifndef VBOXWDDMOVERLAY_TEST
return hr;
#ifndef VBOXWDDMOVERLAY_TEST
return hr;
static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
#ifndef VBOXWDDMOVERLAY_TEST
return hr;
static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
return hr;
if (pRc)
#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
Assert(!pAllocation->hSharedHandle == (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE));
if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
Assert(0);
vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
return hr;
static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
Assert(0);
return E_FAIL;
static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->D3D.cMaxSimRTs]));
if (pDevice)
pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
#ifdef VBOX_WDDMDISP_WITH_PROFILE
#ifdef VBOXWDDMDISP_DEBUG_TIMER
#ifdef VBOXDISP_EARLYCREATEDEVICE
if (pRc)
// params.hDeviceWindow = hWnd;
# ifdef VBOXDISP_TEST_SWAPCHAIN
vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
return hr;
#ifdef VBOX_WITH_VIDEOHWACCEL
return S_OK;
return FALSE;
if (!hDDraw)
return FALSE;
return FALSE;
if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage, pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb))
return TRUE;
if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage, pOpenData->pAdapterCallbacks->pfnGetMultisampleMethodListCb))
return TRUE;
return FALSE;
exit(0);
return E_FAIL;
#ifdef VBOX_WITH_VIDEOHWACCEL
PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
if (pAdapter)
#ifdef VBOX_WITH_VIDEOHWACCEL
return hr;