Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 30037)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 30038)
@@ -854,4 +854,24 @@
     }
     return NULL;
+}
+
+static D3DFORMAT vboxFormatDDI2D3D(D3DDDIFORMAT format)
+{
+    /* @todo: check they are all equal */
+    return (D3DFORMAT)format;
+}
+
+static void vboxResourcePopulateRcDesc(VBOXWDDM_RC_DESC *pDesc, D3DDDIARG_CREATERESOURCE* pResource)
+{
+    pDesc->fFlags = pResource->Flags;
+    pDesc->enmFormat = pResource->Format;
+    pDesc->enmPool = pResource->Pool;
+    pDesc->enmMultisampleType = pResource->MultisampleType;
+    pDesc->MultisampleQuality = pResource->MultisampleQuality;
+    pDesc->MipLevels = pResource->MipLevels;
+    pDesc->Fvf = pResource->Fvf;
+    pDesc->VidPnSourceId = pResource->VidPnSourceId;
+    pDesc->RefreshRate = pResource->RefreshRate;
+    pDesc->enmRotation = pResource->Rotation;
 }
 
@@ -1071,5 +1091,5 @@
             if (pData->DataSize >= sizeof (D3DCAPS9))
             {
-                if (pAdapter->pD3D9If)
+                if (VBOXDISPMODE_IS_3D(pAdapter))
                 {
                     D3DCAPS9* pCaps = (D3DCAPS9*)pData->pData;
@@ -1566,106 +1586,86 @@
     Assert(pDevice);
     Assert(pResource);
-
-    /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
-    uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
-    uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
-    uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
-    cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
-    uint32_t offRcInfo = (cbBuf + 7) & ~3;
-    uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
-    cbBuf = offRcInfo + cbRcInfo;
-    uint32_t offAllocInfos = (cbBuf + 7) & ~3;
-    uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
-    cbBuf = offAllocInfos + cbAllocInfos;
-    uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
-    if (pvBuf)
-    {
-        D3DDDICB_ALLOCATE *pAllocate = (D3DDDICB_ALLOCATE*)pvBuf;
-        D3DDDI_ALLOCATIONINFO* pDdiAllocInfos = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
-        PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
-        PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
-        pAllocate->pPrivateDriverData = pRcInfo;
-        pAllocate->PrivateDriverDataSize = cbRcInfo;
-        pAllocate->hResource = pResource->hResource;
-        pAllocate->hKMResource = NULL;
-        pAllocate->NumAllocations = pResource->SurfCount;
-        pAllocate->pAllocationInfo = pDdiAllocInfos;
-
-        pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
-        pRcInfo->RcDesc.fFlags = pResource->Flags;
-        pRcInfo->RcDesc.enmFormat = pResource->Format;
-        pRcInfo->RcDesc.enmPool = pResource->Pool;
-        pRcInfo->RcDesc.enmMultisampleType = pResource->MultisampleType;
-        pRcInfo->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
-        pRcInfo->RcDesc.MipLevels = pResource->MipLevels;
-        pRcInfo->RcDesc.Fvf = pResource->Fvf;
-        pRcInfo->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
-        pRcInfo->RcDesc.RefreshRate = pResource->RefreshRate;
-        pRcInfo->RcDesc.enmRotation = pResource->Rotation;
-        pRcInfo->cAllocInfos = pResource->SurfCount;
-
-        for (UINT i = 0; i < pResource->SurfCount; ++i)
-        {
-            PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
-            D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pDdiAllocInfos[i];
-            CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
-            pDdiAllocInfo->hAllocation = NULL;
-            pDdiAllocInfo->pSystemMem = pSurf->pSysMem;
-            Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
-            pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
-            pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
-            pDdiAllocInfo->VidPnSourceId = pResource->VidPnSourceId;
-            pDdiAllocInfo->Flags.Value = 0;
-            if (pResource->Flags.Primary)
-                pDdiAllocInfo->Flags.Primary = 1;
-
-            pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
-            pAllocInfo->SurfDesc.width = pSurf->Width;
-            pAllocInfo->SurfDesc.height = pSurf->Height;
-            pAllocInfo->SurfDesc.format = pResource->Format;
-            pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
-
-            if (pSurf->SysMemPitch)
-            {
-                pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
-#ifdef DEBUG
-                UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
-                Assert(tst == pSurf->SysMemPitch);
-#endif
+    PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
+
+    Assert(0);
+
+    if (VBOXDISPMODE_IS_3D(pAdapter))
+    {
+        if (pResource->Flags.RenderTarget)
+        {
+            HWND hWnd = NULL;
+            Assert(pResource->SurfCount);
+            Assert(!pDevice->pDevice9If);
+            Assert(!pDevice->hWnd);
+            hr = VBoxDispWndCreate(pAdapter, pResource->pSurfList[0].Width, pResource->pSurfList[0].Height, &hWnd);
+            Assert(hr == S_OK);
+            if (hr == S_OK)
+            {
+                DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
+                if (pDevice->fFlags.AllowMultithreading)
+                    fFlags |= D3DCREATE_MULTITHREADED;
+
+                IDirect3DDevice9 *pDevice9If = NULL;
+                D3DPRESENT_PARAMETERS params;
+                memset(&params, 0, sizeof (params));
+    //            params.BackBufferWidth = 0;
+    //            params.BackBufferHeight = 0;
+                params.BackBufferFormat = vboxFormatDDI2D3D(pResource->Format);
+                Assert(pResource->SurfCount);
+                params.BackBufferCount = pResource->SurfCount - 1;
+                params.MultiSampleType = D3DMULTISAMPLE_NONE;
+                if (pResource->Flags.DiscardRenderTarget)
+                    params.SwapEffect = D3DSWAPEFFECT_DISCARD;
+                params.hDeviceWindow = hWnd;
+                /* @todo: it seems there should be a way to detect this correctly since
+                 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
+                params.Windowed = TRUE;
+    //            params.EnableAutoDepthStencil = FALSE;
+    //            params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
+    //            params.Flags;
+    //            params.FullScreen_RefreshRateInHz;
+    //            params.FullScreen_PresentationInterval;
+                hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, &params, &pDevice9If);
+                Assert(hr == S_OK);
+                if (hr == S_OK)
+                {
+                    pDevice->pDevice9If = pDevice9If;
+                    pDevice->hWnd = hWnd;
+                }
+                else
+                {
+                    VBoxDispWndDestroy(pAdapter, hWnd);
+                }
             }
-            else
-                pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
-
-            pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
-            pAllocInfo->SurfDesc.depth = pSurf->Depth;
-            pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
-            pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
-            pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
         }
-
-        hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pAllocate);
-        Assert(hr == S_OK);
+        else
+        {
+            Assert(pDevice->pDevice9If);
+        }
+
         if (hr == S_OK)
         {
-            Assert(pAllocate->hKMResource);
             PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
+            Assert(pRc);
             if (pRc)
             {
                 pRc->hResource = pResource->hResource;
-                pRc->hKMResource = pAllocate->hKMResource;
                 pRc->pDevice = pDevice;
-                pRc->fFlags = pRcInfo->fFlags;
-                pRc->RcDesc = pRcInfo->RcDesc;
-                pRc->cAllocations = pRcInfo->cAllocInfos;
-                for (UINT i = 0; i < pRcInfo->cAllocInfos; ++i)
+                pRc->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
+                vboxResourcePopulateRcDesc(&pRc->RcDesc, pResource);
+                pRc->cAllocations = pResource->SurfCount;
+                for (UINT i = 0; i < pResource->SurfCount; ++i)
                 {
                     PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
-                    D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pDdiAllocInfos[i];
-                    PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
                     CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
-                    pAllocation->hAllocation = pDdiAllocInfo->hAllocation;
+                    pAllocation->hAllocation = NULL;
                     pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
                     pAllocation->pvMem = pSurf->pSysMem;
-                    pAllocation->SurfDesc = pAllocInfo->SurfDesc;
+                    pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
+                    pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
+                    pAllocation->SurfDesc.depth = pSurf->Depth;
+                    pAllocation->SurfDesc.width = pSurf->Width;
+                    pAllocation->SurfDesc.height = pSurf->Height;
+                    pAllocation->SurfDesc.format = pResource->Format;
                 }
 
@@ -1678,10 +1678,126 @@
             }
         }
-
-        RTMemFree(pvBuf);
     }
     else
     {
-        hr = E_OUTOFMEMORY;
+        /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
+        uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
+        uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
+        uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
+        cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
+        uint32_t offRcInfo = (cbBuf + 7) & ~3;
+        uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
+        cbBuf = offRcInfo + cbRcInfo;
+        uint32_t offAllocInfos = (cbBuf + 7) & ~3;
+        uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
+        cbBuf = offAllocInfos + cbAllocInfos;
+        uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
+        if (pvBuf)
+        {
+            D3DDDICB_ALLOCATE *pAllocate = (D3DDDICB_ALLOCATE*)pvBuf;
+            D3DDDI_ALLOCATIONINFO* pDdiAllocInfos = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
+            PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
+            PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
+            pAllocate->pPrivateDriverData = pRcInfo;
+            pAllocate->PrivateDriverDataSize = cbRcInfo;
+            pAllocate->hResource = pResource->hResource;
+            pAllocate->hKMResource = NULL;
+            pAllocate->NumAllocations = pResource->SurfCount;
+            pAllocate->pAllocationInfo = pDdiAllocInfos;
+
+            pRcInfo->fFlags = VBOXWDDM_RESOURCE_F_TYPE_GENERIC;
+            pRcInfo->RcDesc.fFlags = pResource->Flags;
+            pRcInfo->RcDesc.enmFormat = pResource->Format;
+            pRcInfo->RcDesc.enmPool = pResource->Pool;
+            pRcInfo->RcDesc.enmMultisampleType = pResource->MultisampleType;
+            pRcInfo->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
+            pRcInfo->RcDesc.MipLevels = pResource->MipLevels;
+            pRcInfo->RcDesc.Fvf = pResource->Fvf;
+            pRcInfo->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
+            pRcInfo->RcDesc.RefreshRate = pResource->RefreshRate;
+            pRcInfo->RcDesc.enmRotation = pResource->Rotation;
+            pRcInfo->cAllocInfos = pResource->SurfCount;
+
+            for (UINT i = 0; i < pResource->SurfCount; ++i)
+            {
+                PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
+                D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pDdiAllocInfos[i];
+                CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
+                pDdiAllocInfo->hAllocation = NULL;
+                pDdiAllocInfo->pSystemMem = pSurf->pSysMem;
+                Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
+                pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
+                pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
+                pDdiAllocInfo->VidPnSourceId = pResource->VidPnSourceId;
+                pDdiAllocInfo->Flags.Value = 0;
+                if (pResource->Flags.Primary)
+                    pDdiAllocInfo->Flags.Primary = 1;
+
+                pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
+                pAllocInfo->SurfDesc.width = pSurf->Width;
+                pAllocInfo->SurfDesc.height = pSurf->Height;
+                pAllocInfo->SurfDesc.format = pResource->Format;
+                pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
+
+                if (pSurf->SysMemPitch)
+                {
+                    pAllocInfo->SurfDesc.pitch = pSurf->SysMemPitch;
+#ifdef DEBUG
+                    UINT tst = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
+                    Assert(tst == pSurf->SysMemPitch);
+#endif
+                }
+                else
+                    pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
+
+                pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
+                pAllocInfo->SurfDesc.depth = pSurf->Depth;
+                pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
+                pAllocInfo->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
+                pAllocInfo->SurfDesc.RefreshRate = pResource->RefreshRate;
+            }
+
+            hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pAllocate);
+            Assert(hr == S_OK);
+            if (hr == S_OK)
+            {
+                Assert(pAllocate->hKMResource);
+                PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
+                Assert(pRc);
+                if (pRc)
+                {
+                    pRc->hResource = pResource->hResource;
+                    pRc->hKMResource = pAllocate->hKMResource;
+                    pRc->pDevice = pDevice;
+                    pRc->fFlags = pRcInfo->fFlags;
+                    pRc->RcDesc = pRcInfo->RcDesc;
+                    pRc->cAllocations = pRcInfo->cAllocInfos;
+                    for (UINT i = 0; i < pRcInfo->cAllocInfos; ++i)
+                    {
+                        PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
+                        D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pDdiAllocInfos[i];
+                        PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
+                        CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
+                        pAllocation->hAllocation = pDdiAllocInfo->hAllocation;
+                        pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
+                        pAllocation->pvMem = pSurf->pSysMem;
+                        pAllocation->SurfDesc = pAllocInfo->SurfDesc;
+                    }
+
+                    pResource->hResource = pRc;
+    //                vboxResourceFree(pRc);
+                }
+                else
+                {
+                    hr = E_OUTOFMEMORY;
+                }
+            }
+
+            RTMemFree(pvBuf);
+        }
+        else
+        {
+            hr = E_OUTOFMEMORY;
+        }
     }
 
@@ -1694,19 +1810,36 @@
     vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
     PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
+    PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
+    PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
+
     HRESULT hr = S_OK;
 
     Assert(pDevice);
     Assert(hResource);
-    PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
-    if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
-    {
-        D3DDDICB_DEALLOCATE Dealloc;
-        Dealloc.hResource = pRc->hResource;
-        Assert(pRc->hResource);
-        /* according to the docs the below two are ignored in case we set the hResource */
-        Dealloc.NumAllocations = 0;
-        Dealloc.HandleList = NULL;
-        hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
-        Assert(hr == S_OK);
+
+    if (VBOXDISPMODE_IS_3D(pAdapter))
+    {
+        if (pRc->RcDesc.fFlags.RenderTarget)
+        {
+            Assert(pDevice->hWnd);
+            Assert(pDevice->pDevice9If);
+            pDevice->pDevice9If->Release();
+            HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pDevice->hWnd);
+            Assert(tmpHr == S_OK);
+        }
+    }
+    else
+    {
+        if (!(pRc->fFlags & VBOXWDDM_RESOURCE_F_OPENNED))
+        {
+            D3DDDICB_DEALLOCATE Dealloc;
+            Dealloc.hResource = pRc->hResource;
+            Assert(pRc->hResource);
+            /* according to the docs the below two are ignored in case we set the hResource */
+            Dealloc.NumAllocations = 0;
+            Dealloc.HandleList = NULL;
+            hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
+            Assert(hr == S_OK);
+        }
     }
 
@@ -2391,19 +2524,11 @@
                 if (hr == S_OK)
                 {
-                    if (pDevice->u32IfVersion > 7)
+                    if (VBOXDISPMODE_IS_3D(pAdapter))
                     {
-                        /* D3D */
-                        if (pAdapter->pD3D9If)
-                        {
-                            /* */
-                            vboxVDbgPrint((__FUNCTION__": TODO: Implement D3D Device Creation\n"));
-                            break;
-                        }
-                        else
-                        {
-                            /* ballback */
-                            vboxVDbgPrint((__FUNCTION__": D3D Device Being Created, but D3D is unavailable\n"));
-                            break;
-                        }
+                        /* we postpone IDirect3DDevice device creation to CreateResource,
+                         * where resource render target gets created,
+                         * which is actually done as part of d3dx.dll Direct3DDevice creation */
+                        vboxVDbgPrint((__FUNCTION__": D3D Device Created\n"));
+                        break;
                     }
                     else
@@ -2452,7 +2577,9 @@
 
     PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
-    if (pAdapter->pD3D9If)
-    {
-        HRESULT hr = pAdapter->pD3D9If->Release();
+    if (VBOXDISPMODE_IS_3D(pAdapter))
+    {
+        HRESULT hr = VBoxDispWorkerDestroy(&pAdapter->WndWorker);
+        Assert(hr == S_OK);
+        hr = pAdapter->pD3D9If->Release();
         Assert(hr == S_OK);
         VBoxDispD3DClose(&pAdapter->D3D);
@@ -2536,6 +2663,12 @@
                     if (hr == S_OK)
                     {
-                        vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
-                        break;
+                        hr = VBoxDispWorkerCreate(&pAdapter->WndWorker);
+                        Assert(hr == S_OK);
+                        if (hr == S_OK)
+                        {
+                            vboxVDbgPrint((__FUNCTION__": SUCCESS 3D Enabled, pAdapter (0x%p)\n", pAdapter));
+                            break;
+                        }
+                        pAdapter->pD3D9If->Release();
                     }
                     else
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h	(revision 30037)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h	(revision 30038)
@@ -43,4 +43,5 @@
     UINT uRtVersion;
     VBOXDISPD3D D3D;
+    VBOXDISPWORKER WndWorker;
     IDirect3D9Ex * pD3D9If;
     D3DDDI_ADAPTERCALLBACKS RtCallbacks;
@@ -71,4 +72,6 @@
     UINT cbCmdBuffer;
     D3DDDI_CREATEDEVICEFLAGS fFlags;
+    HWND hWnd;
+    IDirect3DDevice9 *pDevice9If;
     VBOXWDDMDISP_CONTEXT DefaultContext;
 } VBOXWDDMDISP_DEVICE, *PVBOXWDDMDISP_DEVICE;
@@ -93,8 +96,5 @@
 } VBOXWDDMDISP_RESOURCE, *PVBOXWDDMDISP_RESOURCE;
 
-DECLINLINE(bool) vboxDispD3DIs3DEnabled(VBOXWDDMDISP_ADAPTER * pAdapter)
-{
-    return !!(pAdapter->pD3D9If);
-}
+#define VBOXDISPMODE_IS_3D(_p) (!!((_p)->pD3D9If))
 
 #endif /* #ifndef ___VBoxDispD3D_h___ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DCmn.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DCmn.h	(revision 30037)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DCmn.h	(revision 30038)
@@ -15,4 +15,23 @@
 #ifndef ___VBoxDispD3DCmn_h___
 #define ___VBoxDispD3DCmn_h___
+
+#include <windows.h>
+#include <d3d9types.h>
+//#include <d3dtypes.h>
+#include <D3dumddi.h>
+#include <d3dhal.h>
+
+
+#include <iprt/initterm.h>
+#include <iprt/log.h>
+#include <iprt/mem.h>
+
+#include <VBox/Log.h>
+
+#include <VBox/VBoxGuestLib.h>
+
+#include "VBoxDispD3DIf.h"
+#include "../../Miniport/wddm/VBoxVideoIf.h"
+#include "VBoxDispD3D.h"
 
 #ifdef DEBUG
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.cpp	(revision 30037)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.cpp	(revision 30038)
@@ -51,2 +51,311 @@
     return E_FAIL;
 }
+
+#define WM_VBOXDISP_CALLPROC (WM_APP+1)
+
+typedef struct VBOXDISP_CALLPROC
+{
+    PFNVBOXDISPWORKERCB pfnCb;
+    void *pvCb;
+} VBOXDISP_CALLPROC;
+
+static DWORD WINAPI vboxDispWorkerThread(void *pvUser)
+{
+    VBOXDISPWORKER *pWorker = (VBOXDISPWORKER*)pvUser;
+    MSG Msg;
+
+    PeekMessage(&Msg,
+        NULL /* HWND hWnd */,
+        WM_USER /* UINT wMsgFilterMin */,
+        WM_USER /* UINT wMsgFilterMax */,
+        PM_NOREMOVE);
+    RTSemEventSignal(pWorker->hEvent);
+
+    do
+    {
+        BOOL bResult = GetMessage(&Msg,
+            0 /*HWND hWnd*/,
+            0 /*UINT wMsgFilterMin*/,
+            0 /*UINT wMsgFilterMax*/
+            );
+
+        Assert(0);
+
+        if(!bResult) /* WM_QUIT was posted */
+            break;
+
+        Assert(bResult != -1);
+        if(bResult == -1) /* error occured */
+            break;
+
+        switch (Msg.message)
+        {
+            case WM_VBOXDISP_CALLPROC:
+            {
+                VBOXDISP_CALLPROC* pData = (VBOXDISP_CALLPROC*)Msg.lParam;
+                pData->pfnCb(pData->pvCb);
+                RTSemEventSignal(pWorker->hEvent);
+                break;
+            }
+            default:
+                TranslateMessage(&Msg);
+                DispatchMessage(&Msg);
+        }
+    } while (1);
+    return 0;
+}
+
+static int vboxDispWorkerSubmit(VBOXDISPWORKER *pWorker, UINT Msg, LPARAM lParam)
+{
+    /* need to serialize since vboxDispWorkerThread is using one pWorker->hEvent
+     * to signal job completion */
+    int rc = RTCritSectEnter(&pWorker->CritSect);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        BOOL bResult = PostThreadMessage(pWorker->idThread, Msg, 0, lParam);
+        Assert(bResult);
+        if (bResult)
+        {
+            rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
+            AssertRC(rc);
+        }
+        else
+            rc = VERR_GENERAL_FAILURE;
+
+        int tmpRc = RTCritSectLeave(&pWorker->CritSect);
+        AssertRC(tmpRc);
+    }
+    return rc;
+}
+
+HRESULT VBoxDispWorkerSubmitProc(VBOXDISPWORKER *pWorker, PFNVBOXDISPWORKERCB pfnCb, void *pvCb)
+{
+    VBOXDISP_CALLPROC Ctx;
+    Ctx.pfnCb = pfnCb;
+    Ctx.pvCb = pvCb;
+    int rc =  vboxDispWorkerSubmit(pWorker, WM_VBOXDISP_CALLPROC, (LPARAM)&Ctx);
+    AssertRC(rc);
+    return RT_SUCCESS(rc) ? S_OK : E_FAIL;
+}
+
+HRESULT VBoxDispWorkerCreate(VBOXDISPWORKER *pWorker)
+{
+    int rc = RTCritSectInit(&pWorker->CritSect);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTSemEventCreate(&pWorker->hEvent);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            pWorker->hThread = CreateThread(
+                                  NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,
+                                  0 /* SIZE_T dwStackSize */,
+                                  vboxDispWorkerThread,
+                                  pWorker,
+                                  0 /* DWORD dwCreationFlags */,
+                                  &pWorker->idThread);
+            Assert(pWorker->hThread);
+            if (pWorker->hThread)
+            {
+                Assert(0);
+                rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
+                AssertRC(rc);
+                if (RT_SUCCESS(rc))
+                    return S_OK;
+                /* destroy thread ? */
+            }
+            else
+            {
+                DWORD winErr = GetLastError();
+                vboxVDbgPrintR((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));
+                rc = VERR_GENERAL_FAILURE;
+            }
+            int tmpRc = RTSemEventDestroy(pWorker->hEvent);
+            AssertRC(tmpRc);
+        }
+        int tmpRc = RTCritSectDelete(&pWorker->CritSect);
+        AssertRC(tmpRc);
+    }
+    return E_FAIL;
+}
+
+HRESULT VBoxDispWorkerDestroy(VBOXDISPWORKER *pWorker)
+{
+    int rc = VINF_SUCCESS;
+    BOOL bResult = PostThreadMessage(pWorker->idThread, WM_QUIT, 0, 0);
+    Assert(bResult);
+    if (bResult)
+    {
+        DWORD dwErr = WaitForSingleObject(pWorker->hThread, INFINITE);
+        Assert(dwErr == WAIT_OBJECT_0);
+        if (dwErr == WAIT_OBJECT_0)
+        {
+            rc = RTSemEventDestroy(pWorker->hEvent);
+            AssertRC(rc);
+            if (RT_SUCCESS(rc))
+            {
+                rc = RTCritSectDelete(&pWorker->CritSect);
+                AssertRC(rc);
+            }
+        }
+        else
+            rc = VERR_GENERAL_FAILURE;
+    }
+    else
+        rc = VERR_GENERAL_FAILURE;
+
+    return RT_SUCCESS(rc) ? S_OK : E_FAIL;
+}
+
+static LRESULT CALLBACK WindowProc(HWND hwnd,
+    UINT uMsg,
+    WPARAM wParam,
+    LPARAM lParam
+)
+{
+    switch(uMsg)
+    {
+        case WM_CLOSE:
+            vboxVDbgPrint((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd));
+            return 0;
+        case WM_DESTROY:
+            vboxVDbgPrint((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd));
+            return 0;
+        case WM_NCHITTEST:
+            vboxVDbgPrint((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd));
+            return HTNOWHERE;
+    }
+
+    return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+#define VBOXDISPWND_NAME L"VboxDispD3DWindow"
+
+HRESULT vboxDispWndDoCreate(DWORD w, DWORD h, HWND *phWnd)
+{
+    HRESULT hr = S_OK;
+    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
+    /* Register the Window Class. */
+    WNDCLASS wc;
+    if (!GetClassInfo(hInstance, VBOXDISPWND_NAME, &wc))
+    {
+        wc.style = CS_OWNDC;
+        wc.lpfnWndProc = WindowProc;
+        wc.cbClsExtra = 0;
+        wc.cbWndExtra = 0;
+        wc.hInstance = hInstance;
+        wc.hIcon = NULL;
+        wc.hCursor = NULL;
+        wc.hbrBackground = NULL;
+        wc.lpszMenuName = NULL;
+        wc.lpszClassName = VBOXDISPWND_NAME;
+        if (!RegisterClass(&wc))
+        {
+            DWORD winErr = GetLastError();
+            vboxVDbgPrint((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));
+            hr = E_FAIL;
+        }
+    }
+
+    if (hr == S_OK)
+    {
+        HWND hWnd = CreateWindowEx (WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY,
+                                        VBOXDISPWND_NAME, VBOXDISPWND_NAME,
+                                        WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
+                                        0, 0, w, h,
+                                        GetDesktopWindow() /* hWndParent */,
+                                        NULL /* hMenu */,
+                                        hInstance,
+                                        NULL /* lpParam */);
+        Assert(hWnd);
+        if (hWnd)
+        {
+            *phWnd = hWnd;
+        }
+        else
+        {
+            DWORD winErr = GetLastError();
+            vboxVDbgPrint((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));
+            hr = E_FAIL;
+        }
+    }
+
+    return hr;
+}
+
+static HRESULT vboxDispWndDoDestroy(HWND hWnd)
+{
+    BOOL bResult = DestroyWindow(hWnd);
+    Assert(bResult);
+    if (bResult)
+        return S_OK;
+
+    DWORD winErr = GetLastError();
+    vboxVDbgPrint((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));
+
+    return E_FAIL;
+}
+
+typedef struct VBOXDISPWND_CREATE_INFO
+{
+    int hr;
+    HWND hWnd;
+    DWORD width;
+    DWORD height;
+} VBOXDISPWND_CREATE_INFO;
+
+typedef struct VBOXDISPWND_DESTROY_INFO
+{
+    int hr;
+    HWND hWnd;
+} VBOXDISPWND_DESTROY_INFO;
+
+DECLCALLBACK(void) vboxDispWndDestroyWorker(void *pvUser)
+{
+    VBOXDISPWND_DESTROY_INFO *pInfo = (VBOXDISPWND_DESTROY_INFO*)pvUser;
+    pInfo->hr = vboxDispWndDoDestroy(pInfo->hWnd);
+    Assert(pInfo->hr == S_OK);
+}
+
+DECLCALLBACK(void) vboxDispWndCreateWorker(void *pvUser)
+{
+    VBOXDISPWND_CREATE_INFO *pInfo = (VBOXDISPWND_CREATE_INFO*)pvUser;
+    pInfo->hr = vboxDispWndDoCreate(pInfo->width, pInfo->height, &pInfo->hWnd);
+    Assert(pInfo->hr == S_OK);
+}
+
+
+HRESULT VBoxDispWndDestroy(PVBOXWDDMDISP_ADAPTER pAdapter, HWND hWnd)
+{
+    VBOXDISPWND_DESTROY_INFO Info;
+    Info.hr = E_FAIL;
+    Info.hWnd = hWnd;
+    HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndDestroyWorker, &Info);
+    Assert(hr == S_OK);
+    if (hr == S_OK)
+    {
+        Assert(Info.hr == S_OK);
+        return Info.hr;
+    }
+    return hr;
+}
+
+HRESULT VBoxDispWndCreate(PVBOXWDDMDISP_ADAPTER pAdapter, DWORD width, DWORD height, HWND *phWnd)
+{
+    VBOXDISPWND_CREATE_INFO Info;
+    Info.hr = E_FAIL;
+    Info.width = width;
+    Info.height = height;
+    HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndCreateWorker, &Info);
+    Assert(hr == S_OK);
+    if (hr == S_OK)
+    {
+        Assert(Info.hr == S_OK);
+        if (Info.hr == S_OK)
+            *phWnd = Info.hWnd;
+        return Info.hr;
+    }
+    return hr;
+}
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.h	(revision 30037)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.h	(revision 30038)
@@ -17,4 +17,7 @@
 
 /* D3D headers */
+#include <iprt/critsect.h>
+#include <iprt/semaphore.h>
+
 #include <D3D9.h>
 
@@ -35,3 +38,27 @@
 void VBoxDispD3DClose(VBOXDISPD3D *pD3D);
 
+
+typedef struct VBOXDISPWORKER
+{
+    RTCRITSECT CritSect;
+
+    RTSEMEVENT hEvent;
+
+    HANDLE hThread;
+    DWORD  idThread;
+} VBOXDISPWORKER;
+
+HRESULT VBoxDispWorkerCreate(VBOXDISPWORKER *pWorker);
+HRESULT VBoxDispWorkerDestroy(VBOXDISPWORKER *pWorker);
+
+typedef DECLCALLBACK(void) FNVBOXDISPWORKERCB(void *pvUser);
+typedef FNVBOXDISPWORKERCB *PFNVBOXDISPWORKERCB;
+
+HRESULT VBoxDispWorkerSubmitProc(VBOXDISPWORKER *pWorker, PFNVBOXDISPWORKERCB pfnCb, void *pvCb);
+
+typedef struct VBOXWDDMDISP_ADAPTER *PVBOXWDDMDISP_ADAPTER;
+
+HRESULT VBoxDispWndDestroy(PVBOXWDDMDISP_ADAPTER pAdapter, HWND hWnd);
+HRESULT VBoxDispWndCreate(PVBOXWDDMDISP_ADAPTER pAdapter, DWORD width, DWORD height, HWND *phWnd);
+
 #endif /* ifndef ___VBoxDispD3DIf_h___ */
