Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h	(revision 46783)
@@ -35,5 +35,5 @@
 
 /* One would increase this whenever definitions in this file are changed */
-#define VBOXVIDEOIF_VERSION 17
+#define VBOXVIDEOIF_VERSION 18
 
 #define VBOXWDDM_NODE_ID_SYSTEM           0
@@ -485,4 +485,5 @@
 {
     uint32_t u32Version;
+    uint32_t u32VBox3DCaps;
     uint32_t cInfos;
     VBOXVHWA_INFO aInfos[VBOX_VIDEO_MAX_SCREENS];
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp	(revision 46783)
@@ -571,26 +571,24 @@
             HANDLE hSharedHandle = pAllocation->hSharedHandle;
             IDirect3DSurface9* pD3D9Surf;
-            switch (pAllocation->enmType)
-            {
-                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,
+            if ((pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT) || pAllocation->enmType == 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,
 #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)
@@ -623,11 +621,10 @@
                     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;
             }
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp	(revision 46783)
@@ -4493,5 +4493,25 @@
     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;
+
+    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
@@ -4504,54 +4524,62 @@
         }
 #endif
-        pDevice->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];
-        hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
-        Assert(hr == S_OK);
-    }
-
-    {
-        D3DDDICB_PRESENT DdiPresent = {0};
-        if (pData->hSrcResource)
-        {
+        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);
+            }
+            else
+            {
+                WARN(("VBoxD3DIfSurfGet failed, hr = 0x%x", hr));
+                return hr;
+            }
+
+            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;
-        }
-        DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+            hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
+            Assert(hr == S_OK);
+        }
+    }
+
+    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();
-        }
+    profilePresentCbLogger.logAndDisable();
+    if (pDevice->ProfileDdiPresentCb.getNumEntries() == 64)
+    {
+        pDevice->ProfileDdiPresentCb.dump(pDevice);
+        pDevice->ProfileDdiPresentCb.reset();
+    }
 #endif
-        Assert(hr == S_OK);
-    }
+    Assert(hr == S_OK);
 
     vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
@@ -6180,6 +6208,7 @@
         pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
 
+        pAdapter->u32VBox3DCaps = Query.u32VBox3DCaps;
+
         pAdapter->cHeads = Query.cInfos;
-
 
         pOpenData->hAdapter = pAdapter;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h	(revision 46783)
@@ -79,4 +79,5 @@
     VBOXWDDMDISP_D3D D3D;
     VBOXWDDMDISP_FORMATS Formats;
+    uint32_t u32VBox3DCaps;
 #ifdef VBOX_WDDMDISP_WITH_PROFILE
     VBoxDispProfileFpsCounter ProfileDdiFps;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h	(revision 46783)
@@ -67,4 +67,5 @@
 #include "VBoxD3DIf.h"
 #endif
+#include <cr_protocol.h>
 
 # ifdef VBOXWDDMDISP
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp	(revision 46783)
@@ -146,4 +146,11 @@
         {
             WARN(("no VBoxWineExD3DSurf9GetHostId"));
+            break;
+        }
+
+        pD3D->pfnVBoxWineExD3DSurf9SyncToHost = (PFNVBOXWINEEXD3DSURF9_SYNCTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9SyncToHost");
+        if (!pD3D->pfnVBoxWineExD3DSurf9SyncToHost)
+        {
+            WARN(("no VBoxWineExD3DSurf9SyncToHost"));
             break;
         }
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h	(revision 46783)
@@ -81,4 +81,6 @@
     PFNVBOXWINEEXD3DSURF9_GETHOSTID pfnVBoxWineExD3DSurf9GetHostId;
 
+    PFNVBOXWINEEXD3DSURF9_SYNCTOHOST pfnVBoxWineExD3DSurf9SyncToHost;
+
     PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID pfnVBoxWineExD3DSwapchain9GetHostWinID;
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 46783)
@@ -24,4 +24,11 @@
 #ifdef VBOX_WITH_CROGL
 #include <cr_protocol.h>
+
+static uint32_t g_VBoxMpCrHostCaps = 0;
+
+uint32_t VBoxMpCrGetHostCaps()
+{
+    return g_VBoxMpCrHostCaps;
+}
 
 static void* vboxMpCrShgsmiBufferAlloc(PVBOXMP_DEVEXT pDevExt, HGSMISIZE cbData)
@@ -527,8 +534,9 @@
     CRVBOXHGSMIWRITEREAD *pCmd = &pWrData->Cmd;
 
-    pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET;
+    pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
     pDr->cbBuf = cbCmd;
     pDr->rc = VERR_NOT_IMPLEMENTED;
-    pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
+//    pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
+
 
     pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
@@ -546,5 +554,5 @@
 
     VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
-    pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
+    pBufCmd->offBuffer = vboxVdmaCBufDrPtrOffset(&pDevExt->u.primary.Vdma, pCmd);
     pBufCmd->cbBuffer = sizeof (*pCmd);
     pBufCmd->u32GuestData = 0;
@@ -569,5 +577,4 @@
         PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
 {
-
     const uint32_t cBuffers = 2;
     const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), cbContextData);
@@ -708,4 +715,37 @@
         return parms.hdr.result;
     }
+    return VINF_SUCCESS;
+}
+
+static int vboxMpCrCtlConGetCaps(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID, uint32_t *pu32Caps)
+{
+    CRVBOXHGCMGETCAPS parms;
+    int rc;
+
+    parms.hdr.result      = VERR_WRONG_ORDER;
+    parms.hdr.u32ClientID = u32ClientID;
+    parms.hdr.u32Function = SHCRGL_GUEST_FN_GET_CAPS;
+    parms.hdr.cParms      = SHCRGL_CPARMS_GET_CAPS;
+
+    parms.Caps.type      = VMMDevHGCMParmType_32bit;
+    parms.Caps.u.value32 = 0;
+
+    *pu32Caps = 0;
+
+    rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, &parms.hdr, sizeof (parms));
+    if (RT_FAILURE(rc))
+    {
+        WARN(("vboxCrCtlConCall failed, rc (%d)", rc));
+        return rc;
+    }
+
+    if (RT_FAILURE(parms.hdr.result))
+    {
+        WARN(("SHCRGL_GUEST_FN_GET_CAPS failed, rc (%d)", parms.hdr.result));
+        return parms.hdr.result;
+    }
+
+    *pu32Caps = parms.Caps.u.value32;
+
     return VINF_SUCCESS;
 }
@@ -835,7 +875,14 @@
     }
 
+    rc = vboxMpCrCtlConGetCaps(&CrCtlCon, u32ClientID, &g_VBoxMpCrHostCaps);
+    if (RT_FAILURE(rc))
+    {
+        WARN(("vboxMpCrCtlConGetCaps failed rc (%d), ignoring..", rc));
+        g_VBoxMpCrHostCaps = 0;
+    }
+
     rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
     if (RT_FAILURE(rc))
-        WARN(("VBoxMpCrCtlConDisconnect failed, ignoring.."));
+        WARN(("VBoxMpCrCtlConDisconnect failed rc (%d), ignoring..", rc));
 
     return true;
@@ -844,2 +891,35 @@
 #endif
 }
+
+int VBoxMpCrCmdRxReadbackHandler(CRMessageReadback *pRx, uint32_t cbRx)
+{
+    if (cbRx < sizeof (*pRx))
+    {
+        WARN(("invalid rx size %d", cbRx));
+        return VERR_INVALID_PARAMETER;
+    }
+    void* pvData = VBoxMpCrCmdRxReadbackData(pRx);
+    uint32_t cbData = VBoxMpCrCmdRxReadbackDataSize(pRx, cbRx);
+    void *pvDataPtr = *((void**)&pRx->readback_ptr);
+    memcpy(pvDataPtr, pvData, cbData);
+    return VINF_SUCCESS;
+}
+
+int VBoxMpCrCmdRxHandler(CRMessageHeader *pRx, uint32_t cbRx)
+{
+    if (cbRx < sizeof (*pRx))
+    {
+        WARN(("invalid rx size %d", cbRx));
+        return VERR_INVALID_PARAMETER;
+    }
+    CRMessageHeader *pHdr = (CRMessageHeader*)pRx;
+    switch (pHdr->type)
+    {
+        case CR_MESSAGE_READBACK:
+            return VBoxMpCrCmdRxReadbackHandler((CRMessageReadback*)pRx, cbRx);
+        default:
+            WARN(("unsupported rx message type: %d", pHdr->type));
+            return VERR_INVALID_PARAMETER;
+    }
+}
+
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h	(revision 46783)
@@ -217,4 +217,20 @@
     }
 }
+
+DECLINLINE(void*) VBoxMpCrCmdRxReadbackData(CRMessageReadback *pRx)
+{
+    return (void*)(pRx+1);
+}
+
+DECLINLINE(uint32_t) VBoxMpCrCmdRxReadbackDataSize(CRMessageReadback *pRx, uint32_t cbRx)
+{
+    return cbRx - sizeof (*pRx);
+}
+int VBoxMpCrCmdRxReadbackHandler(CRMessageReadback *pRx, uint32_t cbRx);
+int VBoxMpCrCmdRxHandler(CRMessageHeader *pRx, uint32_t cbRx);
+
+/* must be called after calling VBoxMpCrCtlConIs3DSupported only */
+uint32_t VBoxMpCrGetHostCaps();
+
 #define VBOXMP_CRCMD_HEADER_SIZE sizeof (CRMessageOpcodes)
 /* last +4 below is 4-aligned comand opcode size (i.e. ((1 + 3) & ~3)) */
@@ -224,4 +240,5 @@
 #define VBOXMP_CRCMD_SIZE_WINDOWSHOW (16 + 4)
 #define VBOXMP_CRCMD_SIZE_WINDOWSIZE (20 + 4)
+#define VBOXMP_CRCMD_SIZE_GETCHROMIUMPARAMETERVCR (36 + 4)
 
 #endif /* #ifndef ___VBoxMPCr_h__ */
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp	(revision 46783)
@@ -322,5 +322,21 @@
 }
 
-NTSTATUS vboxVdmaCrSubmitWriteAsync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID)
+typedef struct VBOXMP_VDMACR_WRITEREADCOMPLETION
+{
+    void *pvBufferToFree;
+    void *pvContext;
+} VBOXMP_VDMACR_WRITEREADCOMPLETION, *PVBOXMP_VDMACR_WRITEREADCOMPLETION;
+
+void vboxVdmaCrSubmitWriteReadAsyncGenericCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvCtx)
+{
+    PVBOXMP_VDMACR_WRITEREADCOMPLETION pData = (PVBOXMP_VDMACR_WRITEREADCOMPLETION)pvCtx;
+    void* pvBufferToFree = pData->pvBufferToFree;
+    if (pvBufferToFree)
+        VBoxMpCrShgsmiTransportBufFree(pCon, pvBufferToFree);
+
+    VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(pCon, pvCtx);
+}
+
+NTSTATUS vboxVdmaCrSubmitWriteReadAsync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID, PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion, void *pvCompletion)
 {
     Assert(u32CrConClientID);
@@ -331,4 +347,38 @@
     if (pvBuffer)
     {
+        PVBOXMP_VDMACR_WRITEREADCOMPLETION pvCompletionData = (PVBOXMP_VDMACR_WRITEREADCOMPLETION)VBoxMpCrShgsmiTransportCmdCreateWriteReadAsync(&pDevExt->CrHgsmiTransport, u32CrConClientID, pvBuffer, cbBuffer,
+                pfnCompletion, sizeof (*pvCompletionData));
+        if (pvCompletionData)
+        {
+            pvCompletionData->pvBufferToFree = pvPackBuffer;
+            pvCompletionData->pvContext = pvCompletion;
+            int rc = VBoxMpCrShgsmiTransportCmdSubmitWriteReadAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
+            if (RT_SUCCESS(rc))
+            {
+                return STATUS_SUCCESS;
+            }
+            WARN(("VBoxMpCrShgsmiTransportCmdSubmitWriteAsync failed, rc %d", rc));
+            Status = STATUS_UNSUCCESSFUL;
+            VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
+        }
+        else
+        {
+            WARN(("VBoxMpCrShgsmiTransportCmdCreateWriteAsync failed"));
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+        }
+    }
+
+    return Status;
+}
+
+NTSTATUS vboxVdmaCrSubmitWriteAsync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID)
+{
+    Assert(u32CrConClientID);
+    NTSTATUS Status = STATUS_SUCCESS;
+    uint32_t cbBuffer;
+    void * pvPackBuffer;
+    void * pvBuffer = VBoxMpCrPackerTxBufferComplete(pCrPacker, &cbBuffer, &pvPackBuffer);
+    if (pvBuffer)
+    {
         PVBOXMP_VDMACR_WRITECOMPLETION pvCompletionData = (PVBOXMP_VDMACR_WRITECOMPLETION)VBoxMpCrShgsmiTransportCmdCreateWriteAsync(&pDevExt->CrHgsmiTransport, u32CrConClientID, pvBuffer, cbBuffer,
                 vboxVdmaCrWriteCompletion, sizeof (*pvCompletionData));
@@ -337,14 +387,16 @@
             pvCompletionData->pvBufferToFree = pvPackBuffer;
             int rc = VBoxMpCrShgsmiTransportCmdSubmitWriteAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
-            if (!RT_SUCCESS(rc))
+            if (RT_SUCCESS(rc))
             {
-                WARN(("VBoxMpCrShgsmiTransportCmdSubmitWriteAsync failed, rc %d", rc));
-                Status = STATUS_UNSUCCESSFUL;
+                return STATUS_SUCCESS;
             }
+            WARN(("VBoxMpCrShgsmiTransportCmdSubmitWriteAsync failed, rc %d", rc));
+            Status = STATUS_UNSUCCESSFUL;
+            VBoxMpCrShgsmiTransportCmdTermWriteAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
         }
         else
         {
             WARN(("VBoxMpCrShgsmiTransportCmdCreateWriteAsync failed"));
-            Status = STATUS_NO_MEMORY;
+            Status = STATUS_INSUFFICIENT_RESOURCES;
         }
     }
@@ -550,5 +602,5 @@
     {
         WARN(("VBoxMpCrShgsmiTransportBufAlloc failed!"));
-        Status = STATUS_NO_MEMORY;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
         goto done;
     }
@@ -793,4 +845,91 @@
 }
 
+typedef struct VBOXVDMA_CRRXGENERICSYNC
+{
+    int rc;
+    KEVENT Event;
+} VBOXVDMA_CRRXGENERICSYNC, *PVBOXVDMA_CRRXGENERICSYNC;
+
+static DECLCALLBACK(void) vboxVdmaCrRxGenericSyncCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx)
+{
+    PVBOXMP_VDMACR_WRITEREADCOMPLETION pvCompletionData = (PVBOXMP_VDMACR_WRITEREADCOMPLETION)pvCtx;
+    PVBOXVDMA_CRRXGENERICSYNC pData = (PVBOXVDMA_CRRXGENERICSYNC)pvCompletionData->pvContext;
+    if (RT_SUCCESS(rc))
+    {
+        rc = VBoxMpCrCmdRxHandler((CRMessageHeader*)pvRx, cbRx);
+        if (!RT_SUCCESS(rc))
+        {
+            WARN(("VBoxMpCrCmdRxHandler failed %d", rc));
+        }
+    }
+    else
+    {
+        WARN(("rx failure %d", rc));
+    }
+
+    pData->rc = rc;
+
+    KeSetEvent(&pData->Event, 0, FALSE);
+
+    vboxVdmaCrSubmitWriteReadAsyncGenericCompletion(pCon, pvCtx);
+}
+
+NTSTATUS vboxVdmaCrRxGenericSync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID)
+{
+    VBOXVDMA_CRRXGENERICSYNC Data;
+    Data.rc = VERR_NOT_SUPPORTED;
+    KeInitializeEvent(&Data.Event, SynchronizationEvent, FALSE);
+    NTSTATUS Status = vboxVdmaCrSubmitWriteReadAsync(pDevExt, pCrPacker, u32CrConClientID, vboxVdmaCrRxGenericSyncCompletion, &Data);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("vboxVdmaCrSubmitWriteAsync failed Status 0x%x", Status));
+        return Status;
+    }
+
+     Status = KeWaitForSingleObject(&Data.Event, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */);
+     if (!NT_SUCCESS(Status))
+     {
+         WARN(("KeWaitForSingleObject failed Status 0x%x", Status));
+         return Status;
+     }
+
+     return STATUS_SUCCESS;
+}
+
+#if 0
+NTSTATUS vboxVdmaCrCmdGetChromiumParametervCR(PVBOXMP_DEVEXT pDevExt, uint32_t u32CrConClientID, GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid * values)
+{
+    uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE + VBOXMP_CRCMD_SIZE_GETCHROMIUMPARAMETERVCR;
+    uint32_t cCommands = 1;
+    void *pvCommandBuffer = VBoxMpCrShgsmiTransportBufAlloc(&pDevExt->CrHgsmiTransport, cbCommandBuffer);
+    if (!pvCommandBuffer)
+    {
+        WARN(("VBoxMpCrShgsmiTransportBufAlloc failed!"));
+        return VERR_OUT_OF_RESOURCES;
+    }
+
+    VBOXMP_CRPACKER CrPacker;
+    VBoxMpCrPackerInit(&CrPacker);
+
+    VBoxMpCrPackerTxBufferInit(&CrPacker, pvCommandBuffer, cbCommandBuffer, cCommands);
+
+    int dummy = 1;
+
+    crPackGetChromiumParametervCR(&CrPacker.CrPacker, target, index, type, count, values, &dummy);
+
+
+    NTSTATUS Status = vboxVdmaCrRxGenericSync(pDevExt, &CrPacker, u32CrConClientID);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("vboxVdmaCrRxGenericSync failed Status 0x%x", Status));
+        VBoxMpCrShgsmiTransportBufFree(&pDevExt->CrHgsmiTransport, pvCommandBuffer);
+        return Status;
+    }
+
+
+    return STATUS_SUCCESS;
+}
+#endif
+
 static NTSTATUS vboxVdmaSubitVBoxTexPresent(PVBOXMP_DEVEXT pDevExt,
         VBOXMP_CRPACKER *pCrPacker,
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 46783)
@@ -1166,6 +1166,6 @@
 
                     VBoxMpCrShgsmiTransportCreate(&pDevExt->CrHgsmiTransport, pDevExt);
-                    /* @todo: implement detection */
-                    pDevExt->fTexPresentEnabled = FALSE;
+
+                    pDevExt->fTexPresentEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_TEX_PRESENT);
 
                     for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
@@ -1988,6 +1988,5 @@
 #endif
             {
-                Assert (pQueryAdapterInfo->OutputDataSize >= sizeof (VBOXWDDM_QI));
-                if (pQueryAdapterInfo->OutputDataSize >= sizeof (VBOXWDDM_QI))
+                if (pQueryAdapterInfo->OutputDataSize == sizeof (VBOXWDDM_QI))
                 {
                     VBOXWDDM_QI * pQi = (VBOXWDDM_QI*)pQueryAdapterInfo->pOutputData;
@@ -2004,5 +2003,5 @@
                 else
                 {
-                    LOGREL(("buffer too small"));
+                    WARN(("incorrect buffer size %d, expected %d", pQueryAdapterInfo->OutputDataSize, sizeof (VBOXWDDM_QI)));
                     Status = STATUS_BUFFER_TOO_SMALL;
                 }
@@ -6077,4 +6076,15 @@
                 Assert(tmpStatus == STATUS_SUCCESS);
             }
+
+            int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pContext->u32CrConClientID);
+            if (RT_SUCCESS(rc))
+            {
+                VBoxMpCrPackerInit(&pContext->CrPacker);
+            }
+            else
+            {
+                WARN(("VBoxMpCrCtlConConnect failed rc (%d)", rc));
+                Status = STATUS_UNSUCCESSFUL;
+            }
         }
         else
@@ -6103,8 +6113,7 @@
                                 if (Status == STATUS_SUCCESS)
                                 {
-                                    int rc = VINF_SUCCESS;
                                     if (pInfo->crVersionMajor || pInfo->crVersionMinor)
                                     {
-                                        rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
+                                        int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
                                             pInfo->crVersionMajor, pInfo->crVersionMinor,
                                             &pContext->u32CrConClientID);
@@ -6120,5 +6129,5 @@
                                     }
 
-                                    if (RT_SUCCESS(rc))
+                                    if (NT_SUCCESS(Status))
                                     {
                                         ASMAtomicIncU32(&pDevExt->cContexts3D);
@@ -6141,8 +6150,7 @@
                         if (Status == STATUS_SUCCESS)
                         {
-                            int rc = VINF_SUCCESS;
                             if (pInfo->crVersionMajor || pInfo->crVersionMinor)
                             {
-                                rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
+                                int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
                                     pInfo->crVersionMajor, pInfo->crVersionMinor,
                                     &pContext->u32CrConClientID);
@@ -6154,5 +6162,5 @@
                             }
 
-                            if (RT_SUCCESS(rc))
+                            if (NT_SUCCESS(Status))
                             {
                                 ASMAtomicIncU32(&pDevExt->cContexts3D);
@@ -6220,8 +6228,4 @@
             uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContexts3D);
             Assert(cContexts < UINT32_MAX/2);
-            if (pContext->u32CrConClientID)
-            {
-                VBoxMpCrCtlConDisconnect(&pDevExt->CrCtlCon, pContext->u32CrConClientID);
-            }
             break;
         }
@@ -6234,4 +6238,9 @@
         default:
             break;
+    }
+
+    if (pContext->u32CrConClientID)
+    {
+        VBoxMpCrCtlConDisconnect(&pDevExt->CrCtlCon, pContext->u32CrConClientID);
     }
 
@@ -6674,5 +6683,5 @@
     ULONG major, minor, build;
     BOOLEAN checkedBuild = PsGetVersion(&major, &minor, &build, NULL);
-    BOOLEAN f3DCheckRequired = FALSE;
+    BOOLEAN f3DRequired = FALSE;
 
     LOGREL(("OsVersion( %d, %d, %d )", major, minor, build));
@@ -6686,5 +6695,5 @@
         {
             WARN(("Unknow win version, newer major release, assuming 3D check is required"));
-            f3DCheckRequired = TRUE;
+            f3DRequired = TRUE;
         }
         else if (major == 6)
@@ -6693,15 +6702,15 @@
             {
                 WARN(("Unknow win version, newer minor release, assuming 3D check is required"));
-                f3DCheckRequired = TRUE;
+                f3DRequired = TRUE;
             }
             else if (minor == 2)
             {
                 LOG(("3D check is required!"));
-                f3DCheckRequired = TRUE;
+                f3DRequired = TRUE;
             }
             else
             {
                 LOG(("3D is NOT required!"));
-                f3DCheckRequired = FALSE;
+                f3DRequired = FALSE;
             }
         }
@@ -6709,22 +6718,26 @@
         {
             WARN(("Unsupported OLDER win version, ignore and assume 3D is NOT required"));
-            f3DCheckRequired = FALSE;
+            f3DRequired = FALSE;
         }
 
         Status = STATUS_SUCCESS;
 
-        if (f3DCheckRequired)
-        {
-            LOG(("3D check is required, doing the 3D check.."));
-            if (!VBoxMpCrCtlConIs3DSupported())
-            {
+        /* always need to do the check to request host caps */
+        LOG(("Doing the 3D check.."));
+        if (!VBoxMpCrCtlConIs3DSupported())
+        {
 #ifdef VBOX_WDDM_WIN8
-                LOGREL(("3D is NOT supported by the host, falling back to display-only mode.."));
-                g_VBoxDisplayOnly = 1;
+            Assert(f3DRequired);
+            LOGREL(("3D is NOT supported by the host, falling back to display-only mode.."));
+            g_VBoxDisplayOnly = 1;
 #else
+            if (f3DRequired)
+            {
                 LOGREL(("3D is NOT supported by the host, but is required for the current guest version using this driver.."));
                 Status = STATUS_UNSUCCESSFUL;
-#endif
-            }
+            }
+            else
+                LOGREL(("3D is NOT supported by the host, but is NOT required for the current guest version using this driver, continuing with Disabled 3D.."));
+#endif
         }
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 46783)
@@ -3818,5 +3818,5 @@
 #define GL_RCUSAGE_TEXTURE_CLEAR_CR   0x8B2A
 /*configures host to create windows initially hidden*/
-#define GL_HOST_WND_CREATED_HIDDEN    0x8B2B
+#define GL_HOST_WND_CREATED_HIDDEN_CR    0x8B2B
 
 typedef void (WINE_GLAPI *PGLFNCHROMIUMPARAMETERUCR)(GLenum param, GLint value);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def	(revision 46783)
@@ -24,2 +24,3 @@
   VBoxWineExD3DSurf9GetHostId
   VBoxWineExD3DSwapchain9GetHostWinID
+  VBoxWineExD3DSurf9SyncToHost
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c	(revision 46783)
@@ -469,3 +469,13 @@
     return hr;
 }
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9SyncToHost(IDirect3DSurface9 *iface)
+{
+    struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    HRESULT hr;
+    wined3d_mutex_lock();
+    hr = wined3d_surface_sync_to_host(surface->wined3d_surface);
+    wined3d_mutex_unlock();
+    return hr;
+}
 #endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h	(revision 46783)
@@ -81,4 +81,7 @@
 typedef FNVBOXWINEEXD3DSURF9_GETHOSTID *PFNVBOXWINEEXD3DSURF9_GETHOSTID;
 
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DSURF9_SYNCTOHOST(IDirect3DSurface9 *iface);
+typedef FNVBOXWINEEXD3DSURF9_SYNCTOHOST *PFNVBOXWINEEXD3DSURF9_SYNCTOHOST;
+
 typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DSWAPCHAIN9_PRESENT(IDirect3DSwapChain9 *iface, IDirect3DSurface9 *surf);
 typedef FNVBOXWINEEXD3DSWAPCHAIN9_PRESENT *PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT;
@@ -128,4 +131,8 @@
 VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9GetHostId(IDirect3DSurface9 *iface, uint32_t *pu32Id);
 
+/* makes the surface contents to be synched with host,
+ * i.e. typically in case wine surface's location is in sysmem, puts it to texture*/
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9SyncToHost(IDirect3DSurface9 *iface);
+
 /* used for backwards compatibility purposes only with older host versions not supportgin new present mechanism */
 VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSwapchain9Present(IDirect3DSwapChain9 *iface,
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h	(revision 46783)
@@ -2480,4 +2480,5 @@
 HRESULT __cdecl wined3d_device_blt_voltex(struct wined3d_device *device, struct wined3d_texture *src, struct wined3d_texture *dst, const struct wined3d_box *pSrcBoxArg, const struct VBOXPOINT3D *pDstPoin3D);
 HRESULT __cdecl wined3d_surface_get_host_id(struct wined3d_surface *surface, uint32_t *id);
+HRESULT __cdecl wined3d_surface_sync_to_host(struct wined3d_surface *surface);
 
 HRESULT __cdecl wined3d_swapchain_present_rt(struct wined3d_swapchain *swapchain, struct wined3d_surface *rt);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c	(revision 46783)
@@ -1928,5 +1928,5 @@
 # endif
 # if defined(VBOX_WITH_WDDM)
-    pglChromiumParameteriCR(GL_HOST_WND_CREATED_HIDDEN,  GL_TRUE);
+    pglChromiumParameteriCR(GL_HOST_WND_CREATED_HIDDEN_CR,  GL_TRUE);
 # endif
 #endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c	(revision 46783)
@@ -7789,3 +7789,15 @@
     return S_OK;
 }
+
+HRESULT CDECL wined3d_surface_sync_to_host(struct wined3d_surface *surface)
+{
+    HRESULT hr = surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+    if (!SUCCEEDED(hr))
+    {
+        ERR("surface_load_location failed hr 0x%x", hr);
+        return hr;
+    }
+
+    return S_OK;
+}
 #endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h	(revision 46783)
@@ -177,5 +177,5 @@
 #define GL_RCUSAGE_TEXTURE_CLEAR_CR   0x8B2A
 /*configures host to create windows initially hidden*/
-#define GL_HOST_WND_CREATED_HIDDEN    0x8B2B
+#define GL_HOST_WND_CREATED_HIDDEN_CR 0x8B2B
 
 typedef void (WINE_GLAPI *PGLFNCHROMIUMPARAMETERUCR)(GLenum param, GLint value);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def	(revision 46768)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def	(revision 46783)
@@ -259,3 +259,4 @@
   wined3d_swapchain_present_rt
   wined3d_surface_get_host_id
+  wined3d_surface_sync_to_host
   wined3d_swapchain_get_host_win_id
