Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 49590)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 49591)
@@ -1569,15 +1569,17 @@
 /* CrHgsmi command */
 #define VBOXCMDVBVA_OPTYPE_CRCMD                        1
-/* special case for blitting to primary */
-#define VBOXCMDVBVA_OPTYPE_BLT_TOPRIMARY                2
 /* blit command that does blitting of allocations identified by VRAM offset or host id
  * for VRAM-offset ones the size and format are same as primary */
-#define VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID       3
+#define VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID       2
+/* flip */
+#define VBOXCMDVBVA_OPTYPE_FLIP                         3
+/* ColorFill */
+#define VBOXCMDVBVA_OPTYPE_CLRFILL                      4
 /* allocation paging transfer request */
-#define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER              4
+#define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER              5
 /* allocation paging fill request */
-#define VBOXCMDVBVA_OPTYPE_PAGING_FILL                  5
+#define VBOXCMDVBVA_OPTYPE_PAGING_FILL                  6
 /* same as VBOXCMDVBVA_OPTYPE_NOP, but contains VBOXCMDVBVA_HDR data */
-#define VBOXCMDVBVA_OPTYPE_NOPCMD                       6
+#define VBOXCMDVBVA_OPTYPE_NOPCMD                       7
 
 /* nop - is a one-bit command. The buffer size to skip is determined by VBVA buffer size */
@@ -1593,4 +1595,10 @@
 #define VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN              0x20
 
+/* VBOXCMDVBVA_OPTYPE_BLT_PRIMARY specific flags*/
+/* if set - src is a primary id */
+#define VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY               0x20
+/* if set - dst is a primary id */
+#define VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY               0x10
+
 
 /* trying to make the header as small as possible,
@@ -1599,11 +1607,14 @@
 typedef struct VBOXCMDVBVA_HDR
 {
-    /* one VBOXCMDVBVA_OPTYPE_XXX, ecxept NOP, see comments above */
+    /* one VBOXCMDVBVA_OPTYPE_XXX, except NOP, see comments above */
     uint8_t u8OpCode;
     /* command-specific
-     * VBOXCMDVBVA_OPTYPE_CRCMD - must be null
-     * VBOXCMDVBVA_OPTYPE_BLT_TOPRIMARY - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
-     * VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
-     * VBOXCMDVBVA_OPTYPE_NOP - must be null */
+     * VBOXCMDVBVA_OPTYPE_CRCMD                     - must be null
+     * VBOXCMDVBVA_OPTYPE_BLT_PRIMARY             - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
+     * VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID    - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
+     * VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER           - must be null
+     * VBOXCMDVBVA_OPTYPE_PAGING_FILL               - must be null
+     * VBOXCMDVBVA_OPTYPE_NOPCMD                    - must be null
+     * VBOXCMDVBVA_OPTYPE_NOP                       - not applicable (as the entire VBOXCMDVBVA_HDR is not valid) */
     uint8_t u8Flags;
     /* one of VBOXCMDVBVA_STATE_XXX*/
@@ -1616,5 +1627,5 @@
     };
     /* DXGK DDI fence ID */
-    uint32_t u32FenceID;
+    volatile uint32_t u32FenceID;
 } VBOXCMDVBVA_HDR;
 
@@ -1622,8 +1633,20 @@
 typedef uint64_t VBOXCMDVBVAPHADDR;
 
+typedef struct VBOXCMDVBVA_CRCMD_BUFFER
+{
+    uint32_t cbBuffer;
+    VBOXCMDVBVAOFFSET offBuffer;
+} VBOXCMDVBVA_CRCMD_BUFFER;
+
+typedef struct VBOXCMDVBVA_CRCMD_CMD
+{
+    uint32_t cBuffers;
+    VBOXCMDVBVA_CRCMD_BUFFER aBuffers[1];
+} VBOXCMDVBVA_CRCMD_CMD;
+
 typedef struct VBOXCMDVBVA_CRCMD
 {
     VBOXCMDVBVA_HDR Hdr;
-    VBOXCMDVBVAOFFSET offCmd;
+    VBOXCMDVBVA_CRCMD_CMD Cmd;
 } VBOXCMDVBVA_CRCMD;
 
@@ -1640,17 +1663,17 @@
 {
    /** Coordinates of affected rectangle. */
-   int16_t x;
-   int16_t y;
-   uint16_t w;
-   uint16_t h;
+   int16_t xLeft;
+   int16_t yTop;
+   int16_t xRight;
+   int16_t yBottom;
 } VBOXCMDVBVA_RECT;
 
-typedef struct VBOXCMDVBVA_BLT_TOPRIMARY
+typedef struct VBOXCMDVBVA_BLT_PRIMARY
 {
     VBOXCMDVBVA_HDR Hdr;
-    VBOXCMDVBVA_ALLOCINFO src;
+    VBOXCMDVBVA_ALLOCINFO alloc;
     /* the rects count is determined from the command size */
     VBOXCMDVBVA_RECT aRects[1];
-} VBOXCMDVBVA_BLT_TOPRIMARY;
+} VBOXCMDVBVA_BLT_PRIMARY;
 
 typedef struct VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID
@@ -1663,11 +1686,33 @@
 } VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID;
 
+typedef struct VBOXCMDVBVA_FLIP
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVA_ALLOCINFO src;
+} VBOXCMDVBVA_FLIP;
+
+typedef struct VBOXCMDVBVA_CLRFILL
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVA_ALLOCINFO dst;
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_CLRFILL;
+
+#define VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX  0x1000
+
+typedef struct VBOXCMDVBVA_SYSMEMEL
+{
+    uint32_t cPagesAfterFirst  : 12;
+    VBOXCMDVBVAPHADDR iPage    : 52;
+} VBOXCMDVBVA_SYSMEMEL;
+
 typedef struct VBOXCMDVBVA_PAGING_TRANSFER
 {
     VBOXCMDVBVA_HDR Hdr;
-    VBOXCMDVBVAPHADDR Addr;
     /* for now can only contain offVRAM.
      * paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */
     VBOXCMDVBVA_ALLOCINFO Alloc;
+    uint32_t cSysMem;
+    VBOXCMDVBVA_SYSMEMEL aSysMem[1];
 } VBOXCMDVBVA_PAGING_TRANSFER;
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h	(revision 49591)
@@ -35,5 +35,5 @@
 
 /* One would increase this whenever definitions in this file are changed */
-#define VBOXVIDEOIF_VERSION 19
+#define VBOXVIDEOIF_VERSION 20
 
 #define VBOXWDDM_NODE_ID_SYSTEM           0
@@ -115,5 +115,4 @@
         {
             uint32_t cbBuffer;
-            uint64_t hSynch;
             VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
         };
@@ -183,5 +182,4 @@
 typedef struct VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO
 {
-    uint32_t bDoNotSignalCompletion;
     uint32_t offData;
     uint32_t cbData;
@@ -193,4 +191,5 @@
     VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO aBufInfos[1];
 } VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, *PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD;
+
 
 #define VBOXVHWA_F_ENABLED  0x00000001
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp	(revision 49591)
@@ -62,9 +62,5 @@
     if (pHgsmiGL)
     {
-#if 0
         HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
-#else
-        HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
-#endif
         Log(("CrHgsmi: faled to create KmtEsc VBOXUHGSMI instance, hr (0x%x)\n", hr));
         if (hr == S_OK)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp	(revision 49591)
@@ -165,5 +165,10 @@
         pContext->pDevice = pDevice;
         if (fIsCrContext)
-            vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
+        {
+            if (pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_CMDVBVA)
+                vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice);
+            else
+                vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
+        }
     }
     else
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp	(revision 49591)
@@ -72,5 +72,9 @@
         bSupported &= !!(pCallbacks->pfnD3DKMTEscape);
 
-        pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
+        pCallbacks->pfnD3DKMTQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress(pCallbacks->hGdi32, "D3DKMTQueryAdapterInfo");
+        Log((__FUNCTION__": pfnD3DKMTQueryAdapterInfo = %p\n", pCallbacks->pfnD3DKMTQueryAdapterInfo));
+        bSupported &= !!(pCallbacks->pfnD3DKMTQueryAdapterInfo);
+
+                pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
         Log((__FUNCTION__": pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice));
         bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h	(revision 49591)
@@ -71,4 +71,6 @@
     PFND3DKMT_ESCAPE pfnD3DKMTEscape;
 
+    PFND3DKMT_QUERYADAPTERINFO pfnD3DKMTQueryAdapterInfo;
+
     PFND3DKMT_CREATEDEVICE pfnD3DKMTCreateDevice;
     PFND3DKMT_DESTROYDEVICE pfnD3DKMTDestroyDevice;
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp	(revision 49591)
@@ -178,5 +178,4 @@
         PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuf = VBOXUHGSMIESCBASE_GET_BUFFER(pBufInfo->pBuf);
         pSubmInfo->hAlloc = pBuf->Alloc.hAlloc;
-        pSubmInfo->Info.bDoNotSignalCompletion = 0;
         if (pBufInfo->fFlags.bEntireBuffer)
         {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h	(revision 49591)
@@ -142,4 +142,14 @@
 }
 
+DECLINLINE(void) vboxUhgsmiBaseDxAllocInfoFill(D3DDDI_ALLOCATIONINFO *pDdiAllocInfo, VBOXWDDM_ALLOCINFO *pAllocInfo, uint32_t cbBuffer, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType)
+{
+    pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
+    pDdiAllocInfo->PrivateDriverDataSize = sizeof (*pAllocInfo);
+    pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
+    pAllocInfo->cbBuffer = cbBuffer;
+    pAllocInfo->fUhgsmiType = fUhgsmiType;
+
+}
+
 DECLINLINE(int) vboxUhgsmiBaseDxDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers,
         VOID* pCommandBuffer, UINT *pCommandBufferSize,
@@ -163,5 +173,5 @@
     PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pCommandBuffer;
     pHdr->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
-    pHdr->Base.u32CmdReserved = cBuffers;
+    pHdr->Base.u32CmdReserved = 0;
 
     PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pBufSubmInfo = pHdr->aBufInfos;
@@ -177,5 +187,4 @@
         pAllocationList->WriteOperation = !pBufInfo->fFlags.bHostReadOnly;
         pAllocationList->DoNotRetireInstance = pBufInfo->fFlags.bDoNotRetire;
-        pBufSubmInfo->bDoNotSignalCompletion = 0;
         if (pBufInfo->fFlags.bEntireBuffer)
         {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp	(revision 49591)
@@ -118,10 +118,5 @@
         DdiAlloc.NumAllocations = 1;
         DdiAlloc.pAllocationInfo = &DdiAllocInfo;
-        DdiAllocInfo.pPrivateDriverData = &AllocInfo;
-        DdiAllocInfo.PrivateDriverDataSize = sizeof (AllocInfo);
-        AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
-        AllocInfo.cbBuffer = cbBuf;
-        AllocInfo.hSynch = 0;
-        AllocInfo.fUhgsmiType = fType;
+        vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType);
 
         HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &DdiAlloc);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp	(revision 49591)
@@ -28,27 +28,18 @@
 #endif
 
-#if 0
-typedef struct VBOXUHGSMI_BUFFER_PRIVATE_KMT
-{
-    VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
-    CRITICAL_SECTION CritSect;
-} VBOXUHGSMI_BUFFER_PRIVATE_KMT, *PVBOXUHGSMI_BUFFER_PRIVATE_KMT;
-
-
-#define VBOXUHGSMIKMT_GET_BUFFER(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_KMT)
 
 DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
 {
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
+    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
+
     D3DKMT_DESTROYALLOCATION DdiDealloc;
-    DdiDealloc.hDevice = pBuffer->pHgsmi->Device.hDevice;
+    DdiDealloc.hDevice = pPrivate->Device.hDevice;
     DdiDealloc.hResource = NULL;
-    DdiDealloc.phAllocationList = &pBuffer->BasePrivate.hAllocation;
+    DdiDealloc.phAllocationList = &pBuffer->hAllocation;
     DdiDealloc.AllocationCount = 1;
-    NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc);
-    if (NT_SUCCESS(Status))
-    {
-        if (pBuffer->BasePrivate.hSynch)
-            CloseHandle(pBuffer->BasePrivate.hSynch);
+    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc);
+    if (NT_SUCCESS(Status))
+    {
         RTMemFree(pBuffer);
         return VINF_SUCCESS;
@@ -63,17 +54,19 @@
 DECLCALLBACK(int) vboxUhgsmiKmtBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock)
 {
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
+    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
     D3DKMT_LOCK DdiLock = {0};
-    DdiLock.hDevice = pBuffer->pHgsmi->Device.hDevice;
-    DdiLock.hAllocation = pBuffer->BasePrivate.hAllocation;
+    DdiLock.hDevice = pPrivate->Device.hDevice;
+    DdiLock.hAllocation = pBuffer->hAllocation;
     DdiLock.PrivateDriverData = NULL;
 
-    EnterCriticalSection(&pBuffer->CritSect);
-
-    int rc = vboxUhgsmiBaseDxLockData(&pBuffer->BasePrivate, offLock, cbLock, fFlags,
+    int rc = vboxUhgsmiBaseDxLockData(pBuffer, offLock, cbLock, fFlags,
                                          &DdiLock.Flags, &DdiLock.NumPages);
-    AssertRC(rc);
-    if (RT_FAILURE(rc))
+    if (!RT_SUCCESS(rc))
+    {
+        WARN(("vboxUhgsmiBaseDxLockData failed rc %d", rc));
         return rc;
+    }
+
 
     if (DdiLock.NumPages)
@@ -82,6 +75,5 @@
         DdiLock.pPages = NULL;
 
-    NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTLock(&DdiLock);
-    LeaveCriticalSection(&pBuffer->CritSect);
+    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTLock(&DdiLock);
     if (NT_SUCCESS(Status))
     {
@@ -99,11 +91,12 @@
 DECLCALLBACK(int) vboxUhgsmiKmtBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
 {
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
+    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
     D3DKMT_UNLOCK DdiUnlock;
 
-    DdiUnlock.hDevice = pBuffer->pHgsmi->Device.hDevice;
+    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
+    DdiUnlock.hDevice = pPrivate->Device.hDevice;
     DdiUnlock.NumAllocations = 1;
-    DdiUnlock.phAllocations = &pBuffer->BasePrivate.hAllocation;
-    NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTUnlock(&DdiUnlock);
+    DdiUnlock.phAllocations = &pBuffer->hAllocation;
+    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTUnlock(&DdiUnlock);
     if (NT_SUCCESS(Status))
         return VINF_SUCCESS;
@@ -114,14 +107,10 @@
 }
 
-DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf)
-{
-    HANDLE hSynch = NULL;
+DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf)
+{
     if (!cbBuf)
         return VERR_INVALID_PARAMETER;
 
-    int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch);
-    AssertRC(rc);
-    if (RT_FAILURE(rc))
-        return rc;
+    int rc = VINF_SUCCESS;
 
     cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
@@ -131,59 +120,46 @@
 
     PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_KMT, aLockPageIndices[cPages]));
-    Assert(pBuf);
-    if (pBuf)
-    {
-        struct
-        {
-            D3DKMT_CREATEALLOCATION DdiAlloc;
-            D3DDDI_ALLOCATIONINFO DdiAllocInfo;
-            VBOXWDDM_ALLOCINFO AllocInfo;
-        } Buf;
-        memset(&Buf, 0, sizeof (Buf));
-        Buf.DdiAlloc.hDevice = pPrivate->Device.hDevice;
-        Buf.DdiAlloc.NumAllocations = 1;
-        Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo;
-        Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo;
-        Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo);
-        Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
-        Buf.AllocInfo.cbBuffer = cbBuf;
-        Buf.AllocInfo.hSynch = (uint64_t)hSynch;
-        Buf.AllocInfo.fUhgsmiType = fUhgsmiType;
-
-        NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&Buf.DdiAlloc);
-        if (NT_SUCCESS(Status))
-        {
-            InitializeCriticalSection(&pBuf->CritSect);
-
-            Assert(Buf.DdiAllocInfo.hAllocation);
-            pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock;
-            pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock;
-//            pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiKmtBufferAdjustValidDataRange;
-            pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy;
-
-            pBuf->BasePrivate.Base.fType = fUhgsmiType;
-            pBuf->BasePrivate.Base.cbBuffer = cbBuf;
-
-            pBuf->pHgsmi = pPrivate;
-            pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation;
-
-            *ppBuf = &pBuf->BasePrivate.Base;
-
-            return VINF_SUCCESS;
-        }
-        else
-        {
-            WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status));
-            rc = VERR_OUT_OF_RESOURCES;
-        }
-
-        RTMemFree(pBuf);
-    }
-    else
-        rc = VERR_NO_MEMORY;
-
-    if (hSynch)
-        CloseHandle(hSynch);
+    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, aLockPageIndices[cPages]));
+    if (!pBuf)
+    {
+        WARN(("RTMemAllocZ failed"));
+        return VERR_NO_MEMORY;
+    }
+
+    D3DKMT_CREATEALLOCATION DdiAlloc;
+    D3DDDI_ALLOCATIONINFO DdiAllocInfo;
+    VBOXWDDM_ALLOCINFO AllocInfo;
+
+    memset(&DdiAlloc, 0, sizeof (DdiAlloc));
+    DdiAlloc.hDevice = pPrivate->Device.hDevice;
+    DdiAlloc.NumAllocations = 1;
+    DdiAlloc.pAllocationInfo = &DdiAllocInfo;
+
+    vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType);
+
+    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&DdiAlloc);
+    if (NT_SUCCESS(Status))
+    {
+        Assert(DdiAllocInfo.hAllocation);
+        pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock;
+        pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock;
+        pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy;
+
+        pBuf->BasePrivate.Base.fType = fType;
+        pBuf->BasePrivate.Base.cbBuffer = cbBuf;
+
+        pBuf->hAllocation = DdiAllocInfo.hAllocation;
+
+        *ppBuf = &pBuf->BasePrivate.Base;
+
+        return VINF_SUCCESS;
+    }
+    else
+    {
+        WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status));
+        rc = VERR_OUT_OF_RESOURCES;
+    }
+
+    RTMemFree(pBuf);
 
     return rc;
@@ -198,7 +174,9 @@
             pHg->Context.pAllocationList, pHg->Context.AllocationListSize,
             pHg->Context.pPatchLocationList, pHg->Context.PatchLocationListSize);
-    AssertRC(rc);
     if (RT_FAILURE(rc))
+    {
+        WARN(("vboxUhgsmiBaseDxDmaFill failed, rc %d", rc));
         return rc;
+    }
 
     D3DKMT_RENDER DdiRender = {0};
@@ -228,5 +206,5 @@
     return VERR_GENERAL_FAILURE;
 }
-#endif
+
 
 static HRESULT vboxUhgsmiKmtEngineCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
@@ -297,17 +275,78 @@
 }
 
+static void vboxUhgsmiKmtSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
+{
+    pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtBufferCreate;
+    pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiKmtBufferSubmit;
+     /* no escapes (for now) */
+    pHgsmi->BasePrivate.pfnEscape = NULL;
+}
+
+static void vboxUhgsmiKmtEscSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
+{
+    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
+}
+
 #if 0
 HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
 {
-    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
-#error "port me!"
+    vboxUhgsmiKmtSetupCallbacks(pHgsmi);
     return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
 }
+
+HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
+{
+    vboxUhgsmiKmtEscSetupCallbacks(pHgsmi);
+    return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
+}
 #endif
 
-HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
-{
-    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
-    return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
+static HRESULT vboxUhgsmiKmtQueryCaps(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t *pu32Caps)
+{
+    VBOXWDDM_QI Query;
+    D3DKMT_QUERYADAPTERINFO Info;
+    Info.hAdapter = pHgsmi->Adapter.hAdapter;
+    Info.Type = KMTQAITYPE_UMDRIVERPRIVATE;
+    Info.pPrivateDriverData = &Query;
+    Info.PrivateDriverDataSize = sizeof (Query);
+
+    NTSTATUS Status = pHgsmi->Callbacks.pfnD3DKMTQueryAdapterInfo(&Info);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("pfnD3DKMTQueryAdapterInfo failed, Status %#x", Status));
+        return Status;
+    }
+
+    if (Query.u32Version != VBOXVIDEOIF_VERSION)
+    {
+        WARN(("Version mismatch"));
+        return E_FAIL;
+    }
+
+    *pu32Caps = Query.u32VBox3DCaps;
+
+    return S_OK;
+}
+
+HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
+{
+    HRESULT hr = vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
+    if (!SUCCEEDED(hr))
+        return hr;
+
+    uint32_t u32Caps = 0;
+    hr = vboxUhgsmiKmtQueryCaps(pHgsmi, &u32Caps);
+    if (!SUCCEEDED(hr))
+    {
+        WARN(("vboxUhgsmiKmtQueryCaps failed hr %#x", hr));
+        return hr;
+    }
+
+    if (u32Caps & CR_VBOX_CAP_CMDVBVA)
+        vboxUhgsmiKmtSetupCallbacks(pHgsmi);
+    else
+        vboxUhgsmiKmtEscSetupCallbacks(pHgsmi);
+
+    return S_OK;
 }
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h	(revision 49591)
@@ -35,11 +35,7 @@
 #define VBOXUHGSMIKMT_GET(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_KMT)
 
-#if 0
-HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
-#endif
 HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi);
 
-HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
-
+HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
 
 #endif /* #ifndef ___VBoxUhgsmiKmt_h__ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h	(revision 49591)
@@ -128,6 +128,9 @@
    BOOLEAN f3DEnabled;
    BOOLEAN fTexPresentEnabled;
+   BOOLEAN fCmdVbvaEnabled;
 
    uint32_t u32CrConDefaultClientID;
+
+   VBOXCMDVBVA CmdVbva;
 
    VBOXMP_CRCTLCON CrCtlCon;
@@ -213,5 +216,13 @@
 DECLINLINE(ULONG) vboxWddmVramCpuVisibleSize(PVBOXMP_DEVEXT pDevExt)
 {
-#ifdef VBOXWDDM_RENDER_FROM_SHADOW
+    if (pDevExt->fCmdVbvaEnabled)
+    {
+        /* all memory layout info should be initialized */
+        Assert(pDevExt->CmdVbva.Vbva.offVRAMBuffer);
+        /* page aligned */
+        Assert(!(pDevExt->CmdVbva.Vbva.offVRAMBuffer & 0xfff));
+
+        return (ULONG)(pDevExt->CmdVbva.Vbva.offVRAMBuffer & ~0xfffULL);
+    }
     /* all memory layout info should be initialized */
     Assert(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer);
@@ -220,12 +231,4 @@
 
     return (ULONG)(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer & ~0xfffULL);
-#else
-    /* all memory layout info should be initialized */
-    Assert(pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase);
-    /* page aligned */
-    Assert(!(pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase & 0xfff));
-
-    return pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase & ~0xfffUL;
-#endif
 }
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 49591)
@@ -893,4 +893,8 @@
     }
 
+#if 1 /*def DEBUG_misha*/
+    g_VBoxMpCrHostCaps &= ~CR_VBOX_CAP_CMDVBVA;
+#endif
+
     rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
     if (RT_FAILURE(rc))
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp	(revision 49591)
@@ -1375,5 +1375,5 @@
                 pBufCmd->offBuffer = pRef->pAlloc->offData + pBufInfo->Info.offData;
                 pBufCmd->cbBuffer = pBufInfo->Info.cbData;
-                pBufCmd->u32GuestData = pBufInfo->Info.bDoNotSignalCompletion;
+                pBufCmd->u32GuestData = 0;
                 pBufCmd->u64GuestData = (uint64_t)pRef;
             }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h	(revision 49591)
@@ -183,5 +183,4 @@
 #endif
     VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
-    PKEVENT pSynchEvent;
 } VBOXWDDM_ALLOCATION, *PVBOXWDDM_ALLOCATION;
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp	(revision 49591)
@@ -702,5 +702,5 @@
     PVBOXMP_DEVEXT pDevExt;
     VBOXCMDVBVA *pVbva;
-    UINT u32FenceId;
+    volatile UINT *pu32FenceId;
     DXGK_INTERRUPT_TYPE enmComplType;
 } VBOXCMDVBVA_NOTIFYCOMPLETED_CB, *PVBOXCMDVBVA_NOTIFYCOMPLETED_CB;
@@ -709,16 +709,25 @@
 {
     PVBOXCMDVBVA_NOTIFYCOMPLETED_CB pData = (PVBOXCMDVBVA_NOTIFYCOMPLETED_CB)pvContext;
-    vboxCmdVbvaDdiNotifyCompleteIrq(pData->pDevExt, pData->pVbva, pData->u32FenceId, pData->enmComplType);
-
-    pData->pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pData->pDevExt->u.primary.DxgkInterface.DeviceHandle);
-    return TRUE;
-}
-
-static int vboxCmdVbvaDdiNotifyComplete(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, UINT u32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
+    if (*pData->pu32FenceId)
+    {
+        UINT u32FenceId = *pData->pu32FenceId;
+        *pData->pu32FenceId = 0;
+
+        vboxCmdVbvaDdiNotifyCompleteIrq(pData->pDevExt, pData->pVbva, u32FenceId, pData->enmComplType);
+
+        pData->pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pData->pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static int vboxCmdVbvaDdiNotifyComplete(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, volatile UINT *pu32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
 {
     VBOXCMDVBVA_NOTIFYCOMPLETED_CB Data;
     Data.pDevExt = pDevExt;
     Data.pVbva = pVbva;
-    Data.u32FenceId = u32FenceId;
+    Data.pu32FenceId = pu32FenceId;
     Data.enmComplType = enmComplType;
     BOOLEAN bDummy;
@@ -759,10 +768,40 @@
 }
 
-static void vboxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, bool fPingHost, HGSMIGUESTCOMMANDCONTEXT *pCtx, bool fBufferOverflow)
+typedef struct VBOXCMDVBVA_CHECK_COMPLETED_CB
+{
+    PVBOXMP_DEVEXT pDevExt;
+    VBOXCMDVBVA *pVbva;
+    uint32_t u32FenceID;
+} VBOXCMDVBVA_CHECK_COMPLETED_CB;
+
+static BOOLEAN vboxCmdVbvaCheckCompletedIrqCb(PVOID pContext)
+{
+    VBOXCMDVBVA_CHECK_COMPLETED_CB *pCompleted = (VBOXCMDVBVA_CHECK_COMPLETED_CB*)pContext;
+    BOOLEAN bRc = DxgkDdiInterruptRoutineNew(pCompleted->pDevExt, 0);
+    if (pCompleted->pVbva)
+        pCompleted->u32FenceID = pCompleted->pVbva->u32FenceCompleted;
+    return bRc;
+}
+
+
+static uint32_t vboxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost, HGSMIGUESTCOMMANDCONTEXT *pCtx, bool fBufferOverflow)
 {
     if (fPingHost)
         vboxCmdVbvaFlush(pDevExt, pCtx, fBufferOverflow);
 
-    vboxWddmCallIsr(pDevExt);
+    VBOXCMDVBVA_CHECK_COMPLETED_CB context;
+    context.pDevExt = pDevExt;
+    context.pVbva = pVbva;
+    context.u32FenceID = 0;
+    BOOLEAN bRet;
+    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+                            pDevExt->u.primary.DxgkInterface.DeviceHandle,
+                            vboxCmdVbvaCheckCompletedIrqCb,
+                            &context,
+                            0, /* IN ULONG MessageNumber */
+                            &bRet);
+    Assert(Status == STATUS_SUCCESS);
+
+    return context.u32FenceID;
 }
 
@@ -771,5 +810,5 @@
     PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvFlush;
 
-    vboxCmdVbvaCheckCompleted(pDevExt, true /*fPingHost*/, pHGSMICtx, true /*fBufferOverflow*/);
+    vboxCmdVbvaCheckCompleted(pDevExt, NULL,  true /*fPingHost*/, pHGSMICtx, true /*fBufferOverflow*/);
 }
 
@@ -899,8 +938,11 @@
 
         if (!ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_CANCELLED, VBOXCMDVBVA_STATE_SUBMITTED))
+        {
             Assert(pCmd->u8State == VBOXCMDVBVA_STATE_IN_PROGRESS);
-
-        /* we have cancelled the command successfully */
-        vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
+            break;
+        }
+
+        /* we have canceled the command successfully */
+        vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, &pCmd->u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
         return true;
     }
@@ -939,11 +981,18 @@
         if (u8State == VBOXCMDVBVA_STATE_IN_PROGRESS)
         {
-            pVbva->u32FenceCompleted = u32FenceID;
+            if (u32FenceID)
+                pVbva->u32FenceCompleted = u32FenceID;
             enmDdiNotify = DXGK_INTERRUPT_DMA_COMPLETED;
         }
         else
+        {
+            Assert(u8State == VBOXCMDVBVA_STATE_CANCELLED);
             enmDdiNotify = DXGK_INTERRUPT_DMA_PREEMPTED;
-
-        vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, pCmd->u32FenceID, enmDdiNotify);
+            /* to prevent concurrent notifications from DdiPreemptCommand */
+            pCmd->u32FenceID = 0;
+        }
+
+        if (u32FenceID)
+            vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, u32FenceID, enmDdiNotify);
 
         fHasCommandsCompletedPreempted = true;
@@ -953,6 +1002,60 @@
 }
 
-void VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, bool fPingHost)
-{
-    vboxCmdVbvaCheckCompleted(pDevExt, fPingHost, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, false /* fBufferOverflow */);
-}
+uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost)
+{
+    return vboxCmdVbvaCheckCompleted(pDevExt, pVbva, fPingHost, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, false /* fBufferOverflow */);
+}
+
+
+static uint32_t vboxCVDdiSysMemElBuild(VBOXCMDVBVA_SYSMEMEL *pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages)
+{
+    PFN_NUMBER cur = MmGetMdlPfnArray(pMdl)[iPfn];
+    uint32_t cbEl = sizeof (*pEl);
+    uint32_t cStoredPages = 1;
+    pEl->iPage = cur;
+    --cPages;
+    for ( ; cPages && cStoredPages < VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX; --cPages, ++cStoredPages)
+    {
+        PFN_NUMBER next = MmGetMdlPfnArray(pMdl)[iPfn+cStoredPages];
+        if (next != cur+1)
+            break;
+
+        cur = next;
+        ++cStoredPages;
+        --cPages;
+    }
+
+    Assert(cStoredPages);
+    pEl->cPagesAfterFirst = cStoredPages - 1;
+
+    return cPages;
+}
+
+uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten)
+{
+    uint32_t cInitPages = cPages;
+    uint32_t cbInitBuffer = cbBuffer;
+    uint32_t cEls = 0;
+    VBOXCMDVBVA_SYSMEMEL *pEl = pCmd->aSysMem;
+
+    if (cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
+    {
+        WARN(("cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER)"));
+        goto done;
+    }
+
+    cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
+    uint32_t i = 0;
+
+    for (; cPages && cbBuffer >= sizeof (VBOXCMDVBVA_PAGING_TRANSFER); ++cEls, cbBuffer-=sizeof (VBOXCMDVBVA_SYSMEMEL), ++pEl, ++i)
+    {
+        cPages = vboxCVDdiSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages);
+    }
+
+    pCmd->cSysMem = i;
+
+done:
+    *pcPagesWritten = cInitPages - cPages;
+    return cbInitBuffer - cbBuffer;
+}
+
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h	(revision 49591)
@@ -115,4 +115,5 @@
 } VBVAEXBUFFERBACKWARDITER, *PVBVAEXBUFFERBACKWARDITER;
 
+#define VBOXCMDVBVA_BUFFERSIZE(_cbCmdApprox) (RT_OFFSETOF(VBVABUFFER, au8Data) + ((RT_SIZEOFMEMB(VBVABUFFER, aRecords)/RT_SIZEOFMEMB(VBVABUFFER, aRecords[0])) * (_cbCmdApprox)))
 
 typedef struct VBOXCMDVBVA
@@ -203,6 +204,26 @@
 int VBoxCmdVbvaSubmit(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, struct VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd);
 bool VBoxCmdVbvaPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t u32FenceID);
-void VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, bool fPingHost);
+uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost);
 bool VBoxCmdVbvaCheckCompletedIrq(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
 
+/*helper functions for filling vbva commands */
+DECLINLINE(void) VBoxCVDdiPackRect(VBOXCMDVBVA_RECT *pVbvaRect, const RECT *pRect)
+{
+    pVbvaRect->xLeft = (int16_t)pRect->left;
+    pVbvaRect->yTop = (int16_t)pRect->top;
+    pVbvaRect->xRight = (int16_t)pRect->right;
+    pVbvaRect->yBottom = (int16_t)pRect->bottom;
+}
+
+DECLINLINE(void) VBoxCVDdiPackRects(VBOXCMDVBVA_RECT *paVbvaRects, const RECT *paRects, uint32_t cRects)
+{
+    for (uint32_t i = 0; i < cRects; ++i)
+    {
+        VBoxCVDdiPackRect(&paVbvaRects[i], &paRects[i]);
+    }
+
+}
+
+uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten);
+
 #endif /* #ifndef ___VBoxMPVbva_h___ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 49591)
@@ -32,4 +32,6 @@
 
 #include <stdio.h>
+
+#define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof (RECT)
 
 DWORD g_VBoxLogUm = 0;
@@ -660,5 +662,5 @@
 }
 
-static void vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
+static void vboxWddmSetupDisplaysLegacy(PVBOXMP_DEVEXT pDevExt)
 {
     /* For WDDM, we simply store the number of monitors as we will deal with
@@ -770,4 +772,72 @@
             VBoxCommonFromDeviceExt(pDevExt)->bHGSMI = FALSE;
     }
+}
+
+static NTSTATUS vboxWddmSetupDisplaysNew(PVBOXMP_DEVEXT pDevExt)
+{
+    if (!VBoxCommonFromDeviceExt(pDevExt)->bHGSMI)
+        return STATUS_UNSUCCESSFUL;
+
+    ULONG cbAvailable = VBoxCommonFromDeviceExt(pDevExt)->cbVRAM
+                            - VBoxCommonFromDeviceExt(pDevExt)->cbMiniportHeap
+                            - VBVA_ADAPTER_INFORMATION_SIZE;
+
+    ULONG cbCmdVbva = cbAvailable / 2;
+    ULONG cbCmdVbvaApprox = VBOXCMDVBVA_BUFFERSIZE(4096);
+    if (cbCmdVbvaApprox > cbCmdVbva)
+    {
+        WARN(("too few VRAM memory %d, cmdVbva %d, while approximately needed %d, trying to adjust", cbAvailable, cbCmdVbva, cbCmdVbvaApprox));
+        cbCmdVbva = cbCmdVbvaApprox;
+    }
+
+    cbCmdVbva = VBOXWDDM_ROUNDBOUND(cbCmdVbva, 0x1000);
+    if (cbCmdVbva > cbAvailable - 0x1000)
+    {
+        WARN(("too few VRAM memory fatal, %d, requested for CmdVbva %d", cbAvailable, cbCmdVbva));
+        return STATUS_UNSUCCESSFUL;
+    }
+
+
+    ULONG offCmdVbva = cbAvailable - cbCmdVbva;
+
+    int rc = VBoxCmdVbvaCreate(pDevExt, &pDevExt->CmdVbva, offCmdVbva, cbCmdVbva);
+    if (RT_SUCCESS(rc))
+    {
+        rc = VBoxCmdVbvaEnable(pDevExt, &pDevExt->CmdVbva);
+        if (RT_SUCCESS(rc))
+        {
+            rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pDevExt->pvVisibleVram,
+                                           0, vboxWddmVramCpuVisibleSize(pDevExt));
+            if (RT_SUCCESS(rc))
+                return STATUS_SUCCESS;
+            else
+                WARN(("VBoxMPCmnMapAdapterMemory failed, rc %d", rc));
+
+            VBoxCmdVbvaDisable(pDevExt, &pDevExt->CmdVbva);
+        }
+        else
+            WARN(("VBoxCmdVbvaEnable failed, rc %d", rc));
+
+        VBoxCmdVbvaDestroy(pDevExt, &pDevExt->CmdVbva);
+    }
+    else
+        WARN(("VBoxCmdVbvaCreate failed, rc %d", rc));
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
+{
+    if (pDevExt->fCmdVbvaEnabled)
+    {
+        NTSTATUS Status = vboxWddmSetupDisplaysNew(pDevExt);
+        if (!NT_SUCCESS(Status))
+            VBoxCommonFromDeviceExt(pDevExt)->bHGSMI = FALSE;
+        return Status;
+    }
+
+    vboxWddmSetupDisplaysLegacy(pDevExt);
+    return VBoxCommonFromDeviceExt(pDevExt)->bHGSMI ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+        return STATUS_UNSUCCESSFUL;
 }
 
@@ -899,4 +969,17 @@
             if (Status == STATUS_SUCCESS)
             {
+                pDevExt->f3DEnabled = VBoxMpCrCtlConIs3DSupported();
+
+                if (pDevExt->f3DEnabled)
+                {
+                    pDevExt->fTexPresentEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_TEX_PRESENT);
+                    pDevExt->fCmdVbvaEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_CMDVBVA);
+                }
+                else
+                {
+                    pDevExt->fTexPresentEnabled = FALSE;
+                    pDevExt->fCmdVbvaEnabled = FALSE;
+                }
+
                 /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported.
                  * The host will however support both old and new interface to keep compatibility
@@ -944,12 +1027,4 @@
                     VBoxMpCrShgsmiTransportCreate(&pDevExt->CrHgsmiTransport, pDevExt);
 
-                    pDevExt->f3DEnabled = VBoxMpCrCtlConIs3DSupported();
-
-                    if (pDevExt->f3DEnabled)
-                    {
-                        pDevExt->fTexPresentEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_TEX_PRESENT);
-                    }
-                    else
-                        pDevExt->fTexPresentEnabled = FALSE;
 
                     for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
@@ -1227,5 +1302,41 @@
 }
 
-BOOLEAN DxgkDdiInterruptRoutine(
+
+BOOLEAN DxgkDdiInterruptRoutineNew(
+    IN CONST PVOID MiniportDeviceContext,
+    IN ULONG MessageNumber
+    )
+{
+//    LOGF(("ENTER, context(0x%p), msg(0x%x)", MiniportDeviceContext, MessageNumber));
+
+    vboxVDbgBreakFv();
+
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
+    BOOLEAN bOur = FALSE;
+    bool bNeedDpc = FALSE;
+    if (!VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags) /* If HGSMI is enabled at all. */
+    {
+        WARN(("ISR called with hgsmi disabled!"));
+        return FALSE;
+    }
+
+    uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
+    bOur = (flags & HGSMIHOSTFLAGS_IRQ);
+
+    if (bOur)
+        VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
+
+    bNeedDpc |= VBoxCmdVbvaCheckCompletedIrq(pDevExt, &pDevExt->CmdVbva);
+
+    if (bNeedDpc)
+        pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+//    LOGF(("LEAVE, context(0x%p), bOur(0x%x)", MiniportDeviceContext, (ULONG)bOur));
+
+    return bOur;
+}
+
+
+static BOOLEAN DxgkDdiInterruptRoutineLegacy(
     IN CONST PVOID MiniportDeviceContext,
     IN ULONG MessageNumber
@@ -1450,5 +1561,21 @@
 }
 
-VOID DxgkDdiDpcRoutine(
+static VOID DxgkDdiDpcRoutineNew(
+    IN CONST PVOID  MiniportDeviceContext
+    )
+{
+//    LOGF(("ENTER, context(0x%p)", MiniportDeviceContext));
+
+    vboxVDbgBreakFv();
+
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
+
+    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+//    LOGF(("LEAVE, context(0x%p)", MiniportDeviceContext));
+}
+
+
+static VOID DxgkDdiDpcRoutineLegacy(
     IN CONST PVOID  MiniportDeviceContext
     )
@@ -2020,6 +2147,4 @@
         case VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER:
         {
-            if (pAllocation->pSynchEvent)
-                ObDereferenceObject(pAllocation->pSynchEvent);
             break;
         }
@@ -2215,11 +2340,4 @@
 //                    pAllocationInfo->Flags.SynchronousPaging = 1;
                     pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_MAXIMUM;
-                    if (pAllocInfo->hSynch)
-                    {
-                        Status = ObReferenceObjectByHandle((HANDLE)pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
-                                (PVOID*)&pAllocation->pSynchEvent,
-                                NULL);
-                        Assert(Status == STATUS_SUCCESS);
-                    }
                     break;
                 }
@@ -2561,7 +2679,57 @@
 }
 
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiPatch(
+DxgkDdiPatchNew(
+    CONST HANDLE  hAdapter,
+    CONST DXGKARG_PATCH*  pPatch)
+{
+    /* DxgkDdiPatch should be made pageable. */
+    PAGED_CODE();
+
+    LOGF(("ENTER, context(0x%x)", hAdapter));
+
+    vboxVDbgBreakFv();
+
+    uint8_t * pPrivateBuf = (uint8_t*)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset);
+    UINT cbPatchBuff = pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset;
+
+    for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
+    {
+        const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[i];
+        Assert(pPatchList->AllocationIndex < pPatch->AllocationListSize);
+        const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
+        if (!pAllocationList->SegmentId)
+        {
+            WARN(("no segment id specified"));
+            continue;
+        }
+
+        if (pPatchList->PatchOffset == ~0UL)
+        {
+            /* this is a dummy patch request, ignore */
+            continue;
+        }
+
+        if (pPatchList->PatchOffset >= cbPatchBuff)
+        {
+            WARN(("pPatchList->PatchOffset(%d) >= cbPatchBuff(%d)", pPatchList->PatchOffset, cbPatchBuff));
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        VBOXCMDVBVAOFFSET *poffVram = (VBOXCMDVBVAOFFSET*)(pPrivateBuf + pPatchList->PatchOffset);
+        Assert(pAllocationList->SegmentId);
+        Assert(!pAllocationList->PhysicalAddress.HighPart);
+        Assert(!(pAllocationList->PhysicalAddress.QuadPart & 0xfffUL)); /* <- just a check to ensure allocation offset does not go here */
+        *poffVram = pAllocationList->PhysicalAddress.LowPart + pPatchList->AllocationOffset;;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+APIENTRY
+DxgkDdiPatchLegacy(
     CONST HANDLE  hAdapter,
     CONST DXGKARG_PATCH*  pPatch)
@@ -2729,5 +2897,7 @@
 {
     PVBOXWDDM_CALL_ISR pdc = (PVBOXWDDM_CALL_ISR)Context;
-    return DxgkDdiInterruptRoutine(pdc->pDevExt, pdc->MessageNumber);
+    if (pdc->pDevExt->fCmdVbvaEnabled)
+        return DxgkDdiInterruptRoutineNew(pdc->pDevExt, pdc->MessageNumber);
+    return DxgkDdiInterruptRoutineLegacy(pdc->pDevExt, pdc->MessageNumber);
 }
 
@@ -2755,23 +2925,54 @@
     VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
     UINT cBufs = pBody->cBuffers;
-    for (UINT i = 0; i < cBufs; ++i)
-    {
-        VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
-        if (!pBufCmd->u32GuestData)
-        {
-            /* signal completion */
-            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBufCmd->u64GuestData;
-            if (pAlloc->pSynchEvent)
-                KeSetEvent(pAlloc->pSynchEvent, 3, FALSE);
-        }
-    }
-
     vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
 }
 #endif
 
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiSubmitCommand(
+DxgkDdiSubmitCommandNew(
+    CONST HANDLE  hAdapter,
+    CONST DXGKARG_SUBMITCOMMAND*  pSubmitCommand)
+{
+    /* DxgkDdiSubmitCommand runs at dispatch, should not be pageable. */
+
+//    LOGF(("ENTER, context(0x%x)", hAdapter));
+
+    vboxVDbgBreakFv();
+
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+#ifdef DEBUG
+    PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
+    Assert(pContext);
+    Assert(pContext->pDevice);
+    Assert(pContext->pDevice->pAdapter == pDevExt);
+    Assert(!pSubmitCommand->DmaBufferSegmentId);
+#endif
+
+    /* the DMA command buffer is located in system RAM, the host will need to pick it from there */
+    //BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */
+    uint32_t cbCmd = pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset;
+    if (cbCmd < sizeof (VBOXCMDVBVA_HDR))
+    {
+        WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXCMDVBVA_HDR) (%d)",
+                pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset,
+                pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset,
+                sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    VBOXCMDVBVA_HDR *pHdr = (VBOXCMDVBVA_HDR*)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
+    pHdr->u32FenceID = pSubmitCommand->SubmissionFenceId;
+    int rc = VBoxCmdVbvaSubmit(pDevExt, &pDevExt->CmdVbva, pHdr, cbCmd);
+    if (RT_SUCCESS(rc))
+        return STATUS_SUCCESS;
+
+    WARN(("VBoxCmdVbvaSubmit failed rc %d", rc));
+    return STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS
+APIENTRY
+DxgkDdiSubmitCommandLegacy(
     CONST HANDLE  hAdapter,
     CONST DXGKARG_SUBMITCOMMAND*  pSubmitCommand)
@@ -2887,57 +3088,4 @@
             break;
         }
-        case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
-        {
-#ifdef VBOX_WITH_CRHGSMI
-            VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD *pChromiumCmd = (VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD*)pPrivateDataBase;
-            UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[pChromiumCmd->Base.u32CmdReserved]));
-
-            PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate (&pDevExt->u.primary.Vdma, cbCmd);
-            if (!pDr)
-            {
-                /* @todo: try flushing.. */
-                LOGREL(("vboxVdmaCBufDrCreate returned NULL"));
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-            // vboxVdmaCBufDrCreate zero initializes the pDr
-            pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
-            pDr->cbBuf = cbCmd;
-            pDr->rc = VERR_NOT_IMPLEMENTED;
-
-            PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
-            pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
-            pHdr->u32CmdSpecific = 0;
-            VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
-            pBody->cBuffers = pChromiumCmd->Base.u32CmdReserved;
-            for (UINT i = 0; i < pChromiumCmd->Base.u32CmdReserved; ++i)
-            {
-                VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
-                VBOXWDDM_UHGSMI_BUFFER_SUBMIT_INFO *pBufInfo = &pChromiumCmd->aBufInfos[i];
-
-                pBufCmd->offBuffer = pBufInfo->Alloc.offAlloc;
-                pBufCmd->cbBuffer = pBufInfo->cbData;
-                pBufCmd->u32GuestData = pBufInfo->bDoNotSignalCompletion;
-                pBufCmd->u64GuestData = (uint64_t)pBufInfo->Alloc.pAlloc;
-            }
-
-            PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
-            vboxVdmaDdiCmdInit(pDdiCmd, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, vboxWddmDmaCompleteChromiumCmd, pDr);
-            NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, pDdiCmd);
-            Assert(Status == STATUS_SUCCESS);
-            if (Status == STATUS_SUCCESS)
-            {
-                int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
-                Assert(rc == VINF_SUCCESS);
-            }
-            else
-            {
-                vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
-            }
-#else
-            Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
-            Assert(Status == STATUS_SUCCESS);
-#endif
-            break;
-        }
         case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
         {
@@ -3005,7 +3153,7 @@
 }
 
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiPreemptCommand(
+DxgkDdiPreemptCommandNew(
     CONST HANDLE  hAdapter,
     CONST DXGKARG_PREEMPTCOMMAND*  pPreemptCommand)
@@ -3013,4 +3161,22 @@
     LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
 
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+
+    VBoxCmdVbvaPreempt(pDevExt, &pDevExt->CmdVbva, pPreemptCommand->PreemptionFenceId);
+
+    LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+APIENTRY
+DxgkDdiPreemptCommandLegacy(
+    CONST HANDLE  hAdapter,
+    CONST DXGKARG_PREEMPTCOMMAND*  pPreemptCommand)
+{
+    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
+
     AssertFailed();
     /* @todo: fixme: implement */
@@ -3021,101 +3187,156 @@
 }
 
-#if 0
-static uint32_t vboxWddmSysMemElBuild(PVBOXVDMACMD_SYSMEMEL pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
-{
-    uint32_t cbInitialBuffer = cbBuffer;
-    if (cbBuf >= sizeof (*pEl))
-    {
-        PFN_NUMBER cur = MmGetMdlPfnArray(pMdl)[iPfn];
-        uint32_t cbEl = sizeof (*pEl);
-        uint32_t cBufs = 1;
-        pEl->phBuf[0] = (cur << 12);
-        --cPages;
-        cbBuffer -= sizeof (*pEl);
-        bool bArrayMode = false;
-        while (cPages)
-        {
-            PFN_NUMBER next = MmGetMdlPfnArray(pMdl)[iPfn+cBufs];
-            if (!bArrayMode)
-            {
-                if (next == cur+1)
-                {
-                    cur = next;
-                    ++cBufs;
-                    --cPages;
-                }
-                else if (cBufs > 1)
-                {
-                    break;
-                }
-                else
-                {
-                    bArrayMode = true;
-                }
-            }
-
-            /* array mode */
-            if (cbBuffer < sizeof (pEl->phBuf[0]))
-            {
-                break;
-            }
-
-            pEl->phBuf[cBufs] = (next << 12);
-            cbBuffer -= sizeof (pEl->phBuf[0]);
-            ++cBufs;
-            --cPages;
-        }
-
-        pEl->cPages = cPages;
-        if (bArrayMode)
-            pEl->fFlags = VBOXVDMACMD_SYSMEMEL_F_PAGELIST;
-        else
-            pEl->fFlags = 0;
-    }
-    else
-    {
-        Assert(0);
-    }
-
-    *pcPagesRemaining = cPages;
-    return cbInitialBuffer - cbBuffer;
-}
-
-static uint32_t vboxWddmBpbTransferVRamSysBuildEls(PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
-{
-    uint32_t cInitPages = cPages;
-    uint32_t cbBufferUsed = vboxWddmSysMemElBuild(&pCmd->FirstEl, pMdl, iPfn, cPages, cbBuffer, &cPages);
-    if (cbBufferUsed)
-    {
-        uint32_t cEls = 1;
-        PVBOXVDMACMD_SYSMEMEL pEl = &pCmd->FirstEl;
-        while (cPages)
-        {
-            PVBOXVDMACMD_SYSMEMEL pEl = VBOXVDMACMD_SYSMEMEL_NEXT(pEl);
-            cbBufferUsed = vboxWddmSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages, cbBuffer - cbBufferUsed, &cPages);
-            if (cbBufferUsed)
-            {
-                ++cEls;
-            }
-            else
-                break;
-        }
-    }
-    else
-    {
-        Assert(0);
-    }
-
-    pCmd->cTransferPages = (cInitPages - cPages);
-    *pcPagesRemaining = cPages;
-    return cbBufferUsed;
-}
-#endif
 /*
  * DxgkDdiBuildPagingBuffer
  */
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiBuildPagingBuffer(
+DxgkDdiBuildPagingBufferNew(
+    CONST HANDLE  hAdapter,
+    DXGKARG_BUILDPAGINGBUFFER*  pBuildPagingBuffer)
+{
+    /* DxgkDdiBuildPagingBuffer should be made pageable. */
+    PAGED_CODE();
+
+    vboxVDbgBreakFv();
+
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+    uint32_t cbBuffer = 0, cbPrivateData = 0;
+
+    LOGF(("ENTER, context(0x%x)", hAdapter));
+
+    /* paging buffer transfer is nop for hostID allocations */
+    if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
+    {
+        WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
+        /* @todo: can this actually happen? what status to return? */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    switch (pBuildPagingBuffer->Operation)
+    {
+        case DXGK_OPERATION_TRANSFER:
+        {
+            VBOXCMDVBVA_HDR *pHdr = (VBOXCMDVBVA_HDR*)pBuildPagingBuffer->pDmaBuffer;
+            pHdr->u8Flags = 0;
+            pHdr->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+            /* sanity */
+            pHdr->u32FenceID = 0;
+
+            if ((!pBuildPagingBuffer->Transfer.Source.SegmentId) == (!pBuildPagingBuffer->Transfer.Destination.SegmentId))
+            {
+                WARN(("we only support RAM <-> VRAM moves, Src Seg(%d), Dst Seg(%d)", pBuildPagingBuffer->Transfer.Source.SegmentId, pBuildPagingBuffer->Transfer.Destination.SegmentId));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Transfer.hAllocation;
+            if (!pAlloc)
+            {
+                WARN(("allocation is null"));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            if (pAlloc->AllocData.hostID)
+            {
+                pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
+                cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+                cbPrivateData = sizeof (*pHdr);
+                break;
+            }
+
+            if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
+            {
+                WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_PAGING_TRANSFER (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_PAGING_TRANSFER)));
+                /* @todo: can this actually happen? what status to return? */
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            VBOXCMDVBVA_PAGING_TRANSFER *pPaging = (VBOXCMDVBVA_PAGING_TRANSFER*)pBuildPagingBuffer->pDmaBuffer;
+            pPaging->Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER;
+
+            PMDL pMdl;
+            uint32_t offVRAM;
+            BOOLEAN fIn;
+
+            if (pBuildPagingBuffer->Transfer.Source.SegmentId)
+            {
+                Assert(!pBuildPagingBuffer->Transfer.Destination.SegmentId);
+                Assert(!pBuildPagingBuffer->Transfer.Source.SegmentAddress.HighPart);
+                offVRAM = pBuildPagingBuffer->Transfer.Source.SegmentAddress.LowPart;
+                pMdl = pBuildPagingBuffer->Transfer.Destination.pMdl;
+                fIn = FALSE;
+            }
+            else
+            {
+                Assert(pBuildPagingBuffer->Transfer.Destination.SegmentId);
+                Assert(!pBuildPagingBuffer->Transfer.Source.SegmentId);
+                Assert(!pBuildPagingBuffer->Transfer.Destination.SegmentAddress.HighPart);
+                offVRAM = pBuildPagingBuffer->Transfer.Destination.SegmentAddress.LowPart;
+                pMdl = pBuildPagingBuffer->Transfer.Source.pMdl;
+                fIn = TRUE;
+            }
+
+            uint32_t cPages = (uint32_t)((pBuildPagingBuffer->Transfer.TransferSize + 0xfff) >> PAGE_SHIFT);
+            uint32_t cTotalPages = cPages;
+            cPages -= pBuildPagingBuffer->MultipassOffset;
+            uint32_t iFirstPage = pBuildPagingBuffer->Transfer.MdlOffset + pBuildPagingBuffer->MultipassOffset;
+            uint32_t cPagesWritten;
+            offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + pBuildPagingBuffer->MultipassOffset;
+
+            pPaging->Alloc.offVRAM = offVRAM;
+            if (fIn)
+                pPaging->Hdr.u8Flags |= VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN;
+            cbPrivateData = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaBufferPrivateDataSize, &cPagesWritten);
+            if (cPagesWritten != cPages)
+                pBuildPagingBuffer->MultipassOffset += cPagesWritten;
+            else
+                pBuildPagingBuffer->MultipassOffset = 0;
+
+            cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+            break;
+        }
+        case DXGK_OPERATION_FILL:
+        {
+            Assert(pBuildPagingBuffer->Fill.FillPattern == 0);
+            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation;
+            if (!pAlloc)
+            {
+                WARN(("allocation is null"));
+                return STATUS_INVALID_PARAMETER;
+            }
+            /** @todo: add necessary bits */
+            break;
+        }
+        case DXGK_OPERATION_DISCARD_CONTENT:
+        {
+            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->DiscardContent.hAllocation;
+            if (!pAlloc)
+            {
+                WARN(("allocation is null"));
+                return STATUS_INVALID_PARAMETER;
+            }
+            break;
+        }
+        default:
+        {
+            WARN(("unsupported op (%d)", pBuildPagingBuffer->Operation));
+            break;
+        }
+    }
+
+    pBuildPagingBuffer->pDmaBuffer = ((uint8_t*)pBuildPagingBuffer->pDmaBuffer) + cbBuffer;
+    pBuildPagingBuffer->pDmaBufferPrivateData = ((uint8_t*)pBuildPagingBuffer->pDmaBufferPrivateData) + cbPrivateData;
+
+    LOGF(("LEAVE, context(0x%x)", hAdapter));
+
+    if (pBuildPagingBuffer->MultipassOffset)
+        return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+APIENTRY
+DxgkDdiBuildPagingBufferLegacy(
     CONST HANDLE  hAdapter,
     DXGKARG_BUILDPAGINGBUFFER*  pBuildPagingBuffer)
@@ -3632,4 +3853,10 @@
             case VBOXESC_UHGSMI_SUBMIT:
             {
+                if (pDevExt->fCmdVbvaEnabled)
+                {
+                    WARN(("VBOXESC_UHGSMI_SUBMIT not supported for CmdVbva mode"));
+                    Status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
                 /* submit VBOXUHGSMI command */
                 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
@@ -3652,4 +3879,11 @@
             {
                 /* allocate VBOXUHGSMI buffer */
+                if (pDevExt->fCmdVbvaEnabled)
+                {
+                    WARN(("VBOXESC_UHGSMI_ALLOCATE not supported for CmdVbva mode"));
+                    Status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
+
                 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
                 PVBOXDISPIFESCAPE_UHGSMI_ALLOCATE pAlocate = (PVBOXDISPIFESCAPE_UHGSMI_ALLOCATE)pEscapeHdr;
@@ -3668,4 +3902,10 @@
             case VBOXESC_UHGSMI_DEALLOCATE:
             {
+                if (pDevExt->fCmdVbvaEnabled)
+                {
+                    WARN(("VBOXESC_UHGSMI_DEALLOCATE not supported for CmdVbva mode"));
+                    Status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
                 /* deallocate VBOXUHGSMI buffer */
                 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
@@ -3685,4 +3925,11 @@
             case VBOXESC_GETVBOXVIDEOCMCMD:
             {
+                if (pDevExt->fCmdVbvaEnabled || pDevExt->fTexPresentEnabled)
+                {
+                    WARN(("VBOXESC_GETVBOXVIDEOCMCMD not supported for CmdVbva or TexPresent mode"));
+                    Status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
+
                 /* get the list of r0->r3 commands (d3d window visible regions reporting )*/
                 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
@@ -3710,4 +3957,11 @@
             case VBOXESC_CRHGSMICTLCON_CALL:
             {
+                if (pDevExt->fCmdVbvaEnabled)
+                {
+                    WARN(("VBOXESC_CRHGSMICTLCON_CALL not supported for CmdVbva mode"));
+                    Status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
+
                 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
                 PVBOXDISPIFESCAPE_CRHGSMICTLCON_CALL pCall = (PVBOXDISPIFESCAPE_CRHGSMICTLCON_CALL)pEscapeHdr;
@@ -4288,12 +4542,31 @@
 {
     PVBOXWDDM_QUERYCURFENCE_CB pdc = (PVBOXWDDM_QUERYCURFENCE_CB)Context;
-    BOOL bRc = DxgkDdiInterruptRoutine(pdc->pDevExt, pdc->MessageNumber);
+    BOOL bRc = DxgkDdiInterruptRoutineLegacy(pdc->pDevExt, pdc->MessageNumber);
     pdc->uLastCompletedCmdFenceId = pdc->pDevExt->u.primary.Vdma.uLastCompletedPagingBufferCmdFenceId;
     return bRc;
 }
 
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiQueryCurrentFence(
+DxgkDdiQueryCurrentFenceNew(
+    CONST HANDLE  hAdapter,
+    DXGKARG_QUERYCURRENTFENCE*  pCurrentFence)
+{
+    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
+
+    vboxVDbgBreakF();
+
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+    pCurrentFence->CurrentFence = VBoxCmdVbvaCheckCompleted(pDevExt, &pDevExt->CmdVbva, false);
+
+    LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+APIENTRY
+DxgkDdiQueryCurrentFenceLegacy(
     CONST HANDLE  hAdapter,
     DXGKARG_QUERYCURRENTFENCE*  pCurrentFence)
@@ -5254,7 +5527,182 @@
 }
 
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiRender(
+DxgkDdiRenderNew(
+    CONST HANDLE  hContext,
+    DXGKARG_RENDER  *pRender)
+{
+//    LOGF(("ENTER, hContext(0x%x)", hContext));
+
+    if (pRender->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
+    {
+        WARN(("pRender->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)",
+                pRender->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
+        /* @todo: can this actually happen? what status to return? */
+        return STATUS_INVALID_PARAMETER;
+    }
+    if (pRender->CommandLength < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
+    {
+        WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
+                pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+        /* @todo: can this actually happen? what status to return? */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pInputHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pCommand;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    uint32_t cbBuffer = 0;
+    uint32_t cbCmdDma = 0;
+    VBOXCMDVBVA_HDR* pCmd = (VBOXCMDVBVA_HDR*)pRender->pDmaBufferPrivateData;
+
+    switch (pInputHdr->enmCmd)
+    {
+        case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
+        {
+            if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos))/ RT_SIZEOFMEMB(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[0]))
+            {
+                WARN(("Invalid AllocationListSize %d", pRender->AllocationListSize));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize]))
+            {
+                WARN(("pRender->CommandLength (%d) != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize](%d)",
+                        pRender->CommandLength, RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize])));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers))/ RT_SIZEOFMEMB(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[0]))
+            {
+                WARN(("Invalid AllocationListSize %d", pRender->AllocationListSize));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            cbBuffer = RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[pRender->AllocationListSize]);
+            if (cbBuffer > 4096)
+            {
+                /* this should not be bigger actually */
+                WARN(("too big command buffer %d", cbBuffer));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+
+            if (pRender->DmaBufferPrivateDataSize < cbBuffer)
+            {
+                WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbBuffer));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            if (pRender->DmaSize < cbCmdDma)
+            {
+                WARN(("dma buffer %d too small", pRender->DmaSize));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            Assert(pRender->PatchLocationListOutSize == pRender->AllocationListSize);
+
+            if (pRender->PatchLocationListOutSize < pRender->AllocationListSize)
+            {
+                WARN(("pRender->PatchLocationListOutSize too small %d, requested %d", pRender->PatchLocationListOutSize, pRender->AllocationListSize));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
+            VBOXCMDVBVA_CRCMD* pChromiumCmd = (VBOXCMDVBVA_CRCMD*)pRender->pDmaBufferPrivateData;
+
+            PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
+            PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
+            PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
+
+            pChromiumCmd->Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_CRCMD;
+            pChromiumCmd->Hdr.u8Flags = 0;
+            pChromiumCmd->Cmd.cBuffers = pRender->AllocationListSize;
+
+            DXGK_ALLOCATIONLIST *pAllocationList = pRender->pAllocationList;
+            VBOXCMDVBVA_CRCMD_BUFFER *pSubmInfo = pChromiumCmd->Cmd.aBuffers;
+            PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pSubmUmInfo = pUmCmd->aBufInfos;
+
+            for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut, ++pAllocationList, ++pSubmInfo, ++pSubmUmInfo)
+            {
+                D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
+                PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pAllocationList);
+                if (pSubmUmInfo->offData >= pAlloc->AllocData.SurfDesc.cbSize
+                        || pSubmUmInfo->cbData > pAlloc->AllocData.SurfDesc.cbSize
+                        || pSubmUmInfo->offData + pSubmUmInfo->cbData > pAlloc->AllocData.SurfDesc.cbSize)
+                {
+                    WARN(("invalid data"));
+                    return STATUS_INVALID_PARAMETER;
+                }
+
+                memset(pPLL, 0, sizeof (*pPLL));
+
+                if (pAllocationList->SegmentId)
+                    pSubmInfo->offBuffer = pAllocationList->PhysicalAddress.LowPart + pSubmUmInfo->offData;
+
+                pSubmInfo->cbBuffer = pSubmUmInfo->cbData;
+
+                pPLL->AllocationIndex = i;
+                pPLL->PatchOffset = RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[i].offBuffer);
+                pPLL->AllocationOffset = pSubmUmInfo->offData;
+            }
+
+            break;
+        }
+        case VBOXVDMACMD_TYPE_DMA_NOP:
+        {
+            cbBuffer = sizeof (VBOXCMDVBVA_HDR);
+            cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+
+            if (pRender->DmaBufferPrivateDataSize < cbBuffer)
+            {
+                WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbBuffer));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            if (pRender->DmaSize < cbCmdDma)
+            {
+                WARN(("dma buffer %d too small", pRender->DmaSize));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            pCmd->u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
+            pCmd->u8Flags = 0;
+
+            for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut)
+            {
+                D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
+                memset(pPLL, 0, sizeof (*pPLL));
+                pPLL->AllocationIndex = i;
+                pPLL->PatchOffset = ~0UL;
+                pPLL->AllocationOffset = 0;
+            }
+
+            break;
+        }
+        default:
+        {
+            WARN(("unsupported render command %d", pInputHdr->enmCmd));
+            return STATUS_INVALID_PARAMETER;
+        }
+    }
+
+    pRender->pDmaBufferPrivateData = ((uint8_t*)pRender->pDmaBufferPrivateData) + cbBuffer;
+    pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + cbCmdDma;
+
+    pCmd->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+    /* sanity */
+    pCmd->u32FenceID = 0;
+
+//    LOGF(("LEAVE, hContext(0x%x)", hContext));
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+APIENTRY
+DxgkDdiRenderLegacy(
     CONST HANDLE  hContext,
     DXGKARG_RENDER  *pRender)
@@ -5283,65 +5731,4 @@
     switch (pInputHdr->enmCmd)
     {
-        case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
-        {
-            if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]))
-            {
-                Assert(0);
-                return STATUS_INVALID_PARAMETER;
-            }
-            PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
-            PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD pChromiumCmd = (PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD)pRender->pDmaBufferPrivateData;
-            const uint32_t cbDma = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]);
-            if (pRender->DmaBufferPrivateDataSize < cbDma)
-            {
-                Assert(0);
-                return STATUS_INVALID_PARAMETER;
-            }
-            if (pRender->DmaSize < cbDma)
-            {
-                Assert(0);
-                return STATUS_INVALID_PARAMETER;
-            }
-
-            if (pRender->PatchLocationListOutSize < pInputHdr->u32CmdReserved)
-            {
-                Assert(0);
-                return STATUS_INVALID_PARAMETER;
-            }
-
-            PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
-            PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
-            PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
-
-            pChromiumCmd->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
-            pChromiumCmd->Base.u32CmdReserved = pInputHdr->u32CmdReserved;
-            pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + cbDma;
-            pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + cbDma;
-            D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
-            memset(pPLL, 0, sizeof (*pPLL) * pChromiumCmd->Base.u32CmdReserved);
-            pRender->pPatchLocationListOut += pInputHdr->u32CmdReserved;
-            PVBOXWDDM_UHGSMI_BUFFER_SUBMIT_INFO pSubmInfo = pChromiumCmd->aBufInfos;
-            PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pSubmUmInfo = pUmCmd->aBufInfos;
-            DXGK_ALLOCATIONLIST *pAllocationList = pRender->pAllocationList;
-            for (UINT i = 0; i < pChromiumCmd->Base.u32CmdReserved; ++i)
-            {
-                PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pAllocationList);
-                vboxWddmPopulateDmaAllocInfoWithOffset(&pSubmInfo->Alloc, pAlloc, pAllocationList, pSubmUmInfo->offData);
-
-                pSubmInfo->cbData = pSubmUmInfo->cbData;
-                pSubmInfo->bDoNotSignalCompletion = pSubmUmInfo->bDoNotSignalCompletion;
-
-                pPLL->AllocationIndex = i;
-                pPLL->PatchOffset = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[i].Alloc);
-                pPLL->AllocationOffset = pSubmUmInfo->offData;
-
-                ++pPLL;
-                ++pSubmInfo;
-                ++pSubmUmInfo;
-                ++pAllocationList;
-            }
-
-            break;
-        }
         case VBOXVDMACMD_TYPE_DMA_NOP:
         {
@@ -5359,5 +5746,8 @@
         }
         default:
+        {
+            WARN(("unsupported command %d", pInputHdr->enmCmd));
             return STATUS_INVALID_PARAMETER;
+        }
     }
 
@@ -5403,10 +5793,275 @@
 }
 
+DECLINLINE(bool) VBoxCVDdiFillAllocInfo(VBOXCMDVBVA_HDR* pHdr,
+        VBOXCMDVBVA_ALLOCINFO *pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pList, bool fDst)
+{
+    if (pAlloc->AllocData.hostID)
+    {
+        pHdr->u8Flags |= (fDst ? VBOXCMDVBVA_OPF_ALLOC_DSTID : VBOXCMDVBVA_OPF_ALLOC_SRCID);
+        pInfo->id = pAlloc->AllocData.hostID;
+        return false;
+    }
+
+    Assert(!pList->PhysicalAddress.HighPart);
+    pInfo->offVRAM = pList->PhysicalAddress.LowPart;
+    return true;
+}
+
 /**
  * DxgkDdiPresent
  */
-NTSTATUS
+static NTSTATUS
 APIENTRY
-DxgkDdiPresent(
+DxgkDdiPresentNew(
+    CONST HANDLE  hContext,
+    DXGKARG_PRESENT  *pPresent)
+{
+    PAGED_CODE();
+
+//    LOGF(("ENTER, hContext(0x%x)", hContext));
+
+    vboxVDbgBreakFv();
+
+    PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
+    PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
+    PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
+
+    if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
+    {
+        WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
+        /* @todo: can this actually happen? what status to return? */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    VBOXCMDVBVA_HDR* pHdr = (VBOXCMDVBVA_HDR*)pPresent->pDmaBufferPrivateData;
+
+    UINT u32SrcPatch = ~0UL;
+    UINT u32DstPatch = ~0UL;
+    BOOLEAN fPatchSrc = false;
+    BOOLEAN fPatchDst = false;
+    VBOXCMDVBVA_RECT *paRects = NULL;
+    uint32_t cbMaxRects;
+
+    if (pPresent->DmaSize < VBOXWDDM_DUMMY_DMABUFFER_SIZE)
+    {
+        WARN(("Present->DmaSize(%d) < VBOXWDDM_DUMMY_DMABUFFER_SIZE (%d)", pPresent->DmaSize , VBOXWDDM_DUMMY_DMABUFFER_SIZE));
+        /* @todo: can this actually happen? what status to return? */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if (pPresent->Flags.Blt)
+    {
+        Assert(pPresent->Flags.Value == 1); /* only Blt is set, we do not support anything else for now */
+        DXGK_ALLOCATIONLIST *pSrc =  &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
+        DXGK_ALLOCATIONLIST *pDst =  &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
+        PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
+        if (!pSrcAlloc)
+        {
+            /* this should not happen actually */
+            WARN(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
+            return STATUS_INVALID_HANDLE;
+        }
+
+        PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
+        if (!pDstAlloc)
+        {
+            /* this should not happen actually */
+            WARN(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
+            return STATUS_INVALID_HANDLE;
+        }
+
+        fPatchSrc = TRUE;
+        fPatchDst = TRUE;
+
+        BOOLEAN fDstPrimary = (!pDstAlloc->AllocData.hostID
+                && pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
+                && pDstAlloc->bAssigned);
+        BOOLEAN fSrcPrimary = (!pSrcAlloc->AllocData.hostID
+                && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
+                && pSrcAlloc->bAssigned);
+
+        pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID;
+        pHdr->u8Flags = 0;
+
+        if (fDstPrimary || fSrcPrimary)
+        {
+            if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_BLT_PRIMARY))
+            {
+                WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_BLT_PRIMARY (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_BLT_PRIMARY)));
+                /* @todo: can this actually happen? what status to return? */
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pHdr;
+
+            /* this is the most common case, so we optimize it a bit with VBOXCMDVBVA_BLT_PRIMARY */
+
+            if (fSrcPrimary)
+            {
+                pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY;
+                pBlt->Hdr.u8PrimaryID = pSrcAlloc->AllocData.SurfDesc.VidPnSourceId;
+
+                if (fDstPrimary)
+                {
+                    pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY;
+                    pBlt->alloc.id = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
+                }
+                else if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->alloc, pDstAlloc, pDst, true))
+                    u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, alloc.offVRAM);
+            }
+            else
+            {
+                Assert(fDstPrimary);
+                pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY;
+                pBlt->Hdr.u8PrimaryID = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
+
+                if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->alloc, pSrcAlloc, pSrc, false))
+                    u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, alloc.offVRAM);
+            }
+
+            paRects = pBlt->aRects;
+            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
+        }
+        else
+        {
+            if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID))
+            {
+                WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID)));
+                /* @todo: can this actually happen? what status to return? */
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID *pBlt = (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID*)pHdr;
+
+            if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->src, pSrcAlloc, pSrc, false))
+                u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, src.offVRAM);
+
+            if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->dst, pDstAlloc, pDst, true))
+                u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, dst.offVRAM);
+
+            paRects = pBlt->aRects;
+            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
+        }
+    }
+    else if (pPresent->Flags.Flip)
+    {
+        if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_FLIP))
+        {
+            WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_FLIP (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_FLIP)));
+            /* @todo: can this actually happen? what status to return? */
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        fPatchSrc = TRUE;
+
+        Assert(pPresent->Flags.Value == 4); /* only Blt is set, we do not support anything else for now */
+        Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
+        DXGK_ALLOCATIONLIST *pSrc =  &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
+        PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
+
+        if (!pSrcAlloc)
+        {
+            /* this should not happen actually */
+            WARN(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
+            return STATUS_INVALID_HANDLE;
+        }
+
+        Assert(pDevExt->cContexts3D);
+        pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_FLIP;
+        pHdr->u8Flags = 0;
+        VBOXCMDVBVA_FLIP *pFlip = (VBOXCMDVBVA_FLIP*)pHdr;
+
+        if (VBoxCVDdiFillAllocInfo(pHdr, &pFlip->src, pSrcAlloc, pSrc, false))
+            u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_FLIP, src.offVRAM);
+    }
+    else if (pPresent->Flags.ColorFill)
+    {
+        if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_CLRFILL))
+        {
+            WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_CLRFILL (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_CLRFILL)));
+            /* @todo: can this actually happen? what status to return? */
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        fPatchDst = TRUE;
+
+        Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D);
+        Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
+        DXGK_ALLOCATIONLIST *pDst =  &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
+        PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
+        if (!pDstAlloc)
+        {
+            /* this should not happen actually */
+            WARN(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
+            return STATUS_INVALID_HANDLE;
+        }
+
+        pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_CLRFILL;
+        pHdr->u8Flags = 0;
+        VBOXCMDVBVA_CLRFILL *pCFill = (VBOXCMDVBVA_CLRFILL*)pHdr;
+
+        if (VBoxCVDdiFillAllocInfo(pHdr, &pCFill->dst, pDstAlloc, pDst, true))
+            u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, dst.offVRAM);
+
+        paRects = pCFill->aRects;
+        cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
+    }
+    else
+    {
+        WARN(("cmd NOT IMPLEMENTED!! Flags(0x%x)", pPresent->Flags.Value));
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    if (paRects)
+    {
+        UINT iStartRect = pPresent->MultipassOffset;
+        UINT cMaxRects = cbMaxRects / sizeof (VBOXCMDVBVA_RECT);
+        Assert(pPresent->SubRectCnt > iStartRect);
+        UINT cRects = pPresent->SubRectCnt - iStartRect;
+        if (cRects > cMaxRects)
+        {
+            pPresent->MultipassOffset += cMaxRects;
+            cRects = cMaxRects;
+        }
+        else
+            pPresent->MultipassOffset = 0;
+
+        const RECT *paDstSubRects = &pPresent->pDstSubRects[iStartRect];
+        VBoxCVDdiPackRects(paRects, paDstSubRects, cRects);
+    }
+
+    if (fPatchSrc)
+    {
+        memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
+        pPresent->pPatchLocationListOut->PatchOffset = u32SrcPatch;
+        pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
+        ++pPresent->pPatchLocationListOut;
+    }
+
+    if (fPatchDst)
+    {
+        memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
+        pPresent->pPatchLocationListOut->PatchOffset = u32DstPatch;
+        pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
+        ++pPresent->pPatchLocationListOut;
+    }
+
+    pHdr->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+    /* sanity */
+    pHdr->u32FenceID = 0;
+
+    pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+
+    if (pPresent->MultipassOffset)
+        return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
+    return STATUS_SUCCESS;
+}
+
+/**
+ * DxgkDdiPresent
+ */
+static NTSTATUS
+APIENTRY
+DxgkDdiPresentLegacy(
     CONST HANDLE  hContext,
     DXGKARG_PRESENT  *pPresent)
@@ -5434,5 +6089,4 @@
     pPrivateData->BaseHdr.fFlags.Value = 0;
     uint32_t cContexts2D = ASMAtomicReadU32(&pDevExt->cContexts2D);
-#define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof(RECT)
 
     if (pPresent->Flags.Blt)
@@ -6218,6 +6872,6 @@
     DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
     DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
-    DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
-    DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
+    DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutineNew;
+    DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutineNew;
     DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
     DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
@@ -6265,6 +6919,8 @@
 #endif
 
-static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
-{
+static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath, BOOLEAN fCmdVbva)
+{
+#define VBOXWDDM_CALLBACK_NAME(_base, _fCmdVbva) ((_fCmdVbva) ? _base##New : _base##Legacy)
+
     DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
 
@@ -6277,6 +6933,6 @@
     DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
     DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
-    DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
-    DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
+    DriverInitializationData.DxgkDdiInterruptRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiInterruptRoutine, fCmdVbva);
+    DriverInitializationData.DxgkDdiDpcRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiDpcRoutine, fCmdVbva);
     DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
     DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
@@ -6297,8 +6953,8 @@
     DriverInitializationData.DxgkDdiAcquireSwizzlingRange = DxgkDdiAcquireSwizzlingRange;
     DriverInitializationData.DxgkDdiReleaseSwizzlingRange = DxgkDdiReleaseSwizzlingRange;
-    DriverInitializationData.DxgkDdiPatch = DxgkDdiPatch;
-    DriverInitializationData.DxgkDdiSubmitCommand = DxgkDdiSubmitCommand;
-    DriverInitializationData.DxgkDdiPreemptCommand = DxgkDdiPreemptCommand;
-    DriverInitializationData.DxgkDdiBuildPagingBuffer = DxgkDdiBuildPagingBuffer;
+    DriverInitializationData.DxgkDdiPatch = VBOXWDDM_CALLBACK_NAME(DxgkDdiPatch, fCmdVbva);
+    DriverInitializationData.DxgkDdiSubmitCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiSubmitCommand, fCmdVbva);
+    DriverInitializationData.DxgkDdiPreemptCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiPreemptCommand, fCmdVbva);
+    DriverInitializationData.DxgkDdiBuildPagingBuffer = VBOXWDDM_CALLBACK_NAME(DxgkDdiBuildPagingBuffer, fCmdVbva);
     DriverInitializationData.DxgkDdiSetPalette = DxgkDdiSetPalette;
     DriverInitializationData.DxgkDdiSetPointerPosition = DxgkDdiSetPointerPosition;
@@ -6308,5 +6964,5 @@
     DriverInitializationData.DxgkDdiEscape = DxgkDdiEscape;
     DriverInitializationData.DxgkDdiCollectDbgInfo = DxgkDdiCollectDbgInfo;
-    DriverInitializationData.DxgkDdiQueryCurrentFence = DxgkDdiQueryCurrentFence;
+    DriverInitializationData.DxgkDdiQueryCurrentFence = VBOXWDDM_CALLBACK_NAME(DxgkDdiQueryCurrentFence, fCmdVbva);
     DriverInitializationData.DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn;
     DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = DxgkDdiRecommendFunctionalVidPn;
@@ -6326,6 +6982,6 @@
     DriverInitializationData.DxgkDdiOpenAllocation = DxgkDdiOpenAllocation;
     DriverInitializationData.DxgkDdiCloseAllocation = DxgkDdiCloseAllocation;
-    DriverInitializationData.DxgkDdiRender = DxgkDdiRender;
-    DriverInitializationData.DxgkDdiPresent = DxgkDdiPresent;
+    DriverInitializationData.DxgkDdiRender = VBOXWDDM_CALLBACK_NAME(DxgkDdiRender, fCmdVbva);
+    DriverInitializationData.DxgkDdiPresent = VBOXWDDM_CALLBACK_NAME(DxgkDdiPresent, fCmdVbva);
 
     DriverInitializationData.DxgkDdiUpdateOverlay = DxgkDdiUpdateOverlay;
@@ -6467,5 +7123,5 @@
 #endif
                 {
-                    Status = vboxWddmInitFullGraphicsDriver(DriverObject, RegistryPath);
+                    Status = vboxWddmInitFullGraphicsDriver(DriverObject, RegistryPath, !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_CMDVBVA));
                 }
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h	(revision 49590)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h	(revision 49591)
@@ -128,4 +128,10 @@
 DECLINLINE(void) vboxWddmAssignShadow(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
 {
+    if (pDevExt->fCmdVbvaEnabled)
+    {
+        WARN(("Trying to assign shadow surface for CmdVbva enabled mode!"));
+        return;
+    }
+
     if (pSource->pShadowAllocation == pAllocation && pSource->fGhSynced > 0)
     {
@@ -221,4 +227,9 @@
 
 #define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
+
+BOOLEAN DxgkDdiInterruptRoutineNew(
+    IN CONST PVOID MiniportDeviceContext,
+    IN ULONG MessageNumber
+    );
 
 #ifdef VBOX_WDDM_WIN8
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_protocol.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_protocol.h	(revision 49590)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_protocol.h	(revision 49591)
@@ -25,6 +25,6 @@
 /* new TexPresent mechanism is available */
 #define CR_VBOX_CAP_TEX_PRESENT    0x00000001
-/* no DWM support available, required for Win8 guests to switch to display-only mode gracefully */
-#define CR_VBOX_CAP_NO_DWM_SUPPORT 0x00000002
+/* vbva command submission mechanism supported */
+#define CR_VBOX_CAP_CMDVBVA        0x00000002
 
 
@@ -99,25 +99,30 @@
 #ifdef VBOX_WITH_CRHGSMI
 typedef struct CRVBOXHGSMI_CMDDATA {
-    struct VBOXVDMACMD_CHROMIUM_CMD *pCmd;
+    union
+    {
+        struct VBOXVDMACMD_CHROMIUM_CMD *pHgsmiCmd;
+        struct VBOXCMDVBVA_CRCMD_CMD *pVbvaCmd;
+        void *pvCmd;
+    };
     int          *pCmdRc;
     char         *pWriteback;
     unsigned int *pcbWriteback;
     unsigned int cbWriteback;
-    bool fCompleteNeeded;
+    bool fHgsmiCmd;
 } CRVBOXHGSMI_CMDDATA, *PCRVBOXHGSMI_CMDDATA;
 
 #ifdef DEBUG
 # define CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData)  do { \
-        CRASSERT(!(_pData)->pCmd == !(_pData)->pCmdRc); \
+        CRASSERT(!(_pData)->pvCmd == !(_pData)->pCmdRc); \
         CRASSERT(!(_pData)->pWriteback == !(_pData)->pcbWriteback); \
         CRASSERT(!(_pData)->pWriteback == !(_pData)->cbWriteback); \
         if ((_pData)->pWriteback) \
         { \
-            CRASSERT((_pData)->pCmd); \
+            CRASSERT((_pData)->pvCmd); \
         } \
     } while (0)
 
 # define CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData)  do { \
-        CRASSERT(!(_pData)->pCmd); \
+        CRASSERT(!(_pData)->pvCmd); \
         CRASSERT(!(_pData)->pCmdRc); \
         CRASSERT(!(_pData)->pWriteback); \
@@ -142,6 +147,6 @@
 #endif
 
-#define CRVBOXHGSMI_CMDDATA_IS_COMPLETE_NEEDED(_pData) (!!(_pData)->fCompleteNeeded)
-#define CRVBOXHGSMI_CMDDATA_IS_SET(_pData) (!!(_pData)->pCmd)
+#define CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData) (!!(_pData)->fHgsmiCmd)
+#define CRVBOXHGSMI_CMDDATA_IS_SET(_pData) (!!(_pData)->pvCmd)
 #define CRVBOXHGSMI_CMDDATA_IS_SETWB(_pData) (!!(_pData)->pWriteback)
 
@@ -152,14 +157,14 @@
     } while (0)
 
-#define CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fCompleteNeeded) do { \
+#define CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fHgsmiCmd) do { \
         CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData); \
-        (_pData)->pCmd = (_pCmd); \
+        (_pData)->pvCmd = (_pCmd); \
         (_pData)->pCmdRc = &(_pHdr)->result; \
-        (_pData)->fCompleteNeeded = _fCompleteNeeded; \
-        CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \
-    } while (0)
-
-#define CRVBOXHGSMI_CMDDATA_SETWB(_pData, _pCmd, _pHdr, _pWb, _cbWb, _pcbWb, _fCompleteNeeded) do { \
-        CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fCompleteNeeded); \
+        (_pData)->fHgsmiCmd = (_fHgsmiCmd); \
+        CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \
+    } while (0)
+
+#define CRVBOXHGSMI_CMDDATA_SETWB(_pData, _pCmd, _pHdr, _pWb, _cbWb, _pcbWb, _fHgsmiCmd) do { \
+        CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fHgsmiCmd); \
         (_pData)->pWriteback = (_pWb); \
         (_pData)->pcbWriteback = (_pcbWb); \
Index: /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 49590)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 49591)
@@ -196,7 +196,4 @@
     CR_VBOXHGCM_MEMORY,
     CR_VBOXHGCM_MEMORY_BIG
-#ifdef RT_OS_WINDOWS
-    ,CR_VBOXHGCM_DDRAW_SURFACE
-#endif
 #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     ,CR_VBOXHGCM_UHGSMI_BUFFER
@@ -221,7 +218,4 @@
 #endif
     };
-#ifdef RT_OS_WINDOWS
-    LPDIRECTDRAWSURFACE  pDDS;
-#endif
 } CRVBOXHGCMBUFFER;
 
@@ -706,90 +700,4 @@
                         (unsigned int)sizeof(CRVBOXHGCMBUFFER) + conn->buffer_size);
 
-#if defined(IN_GUEST) && defined(RT_OS_WINDOWS)
-        /* Try to start DDRAW on guest side */
-        if (!g_crvboxhgcm.pDirectDraw && 0)
-        {
-            HRESULT hr;
-
-            hr = DirectDrawCreate(NULL, &g_crvboxhgcm.pDirectDraw, NULL);
-            if (hr != DD_OK)
-            {
-                crWarning("Failed to create DirectDraw interface (%x)\n", hr);
-                g_crvboxhgcm.pDirectDraw = NULL;
-            }
-            else
-            {
-                hr = IDirectDraw_SetCooperativeLevel(g_crvboxhgcm.pDirectDraw, NULL, DDSCL_NORMAL);
-                if (hr != DD_OK)
-                {
-                    crWarning("Failed to SetCooperativeLevel (%x)\n", hr);
-                    IDirectDraw_Release(g_crvboxhgcm.pDirectDraw);
-                    g_crvboxhgcm.pDirectDraw = NULL;
-                }
-                crDebug("Created DirectDraw and set CooperativeLevel successfully\n");
-            }
-        }
-
-        /* Try to allocate buffer via DDRAW */
-        if (g_crvboxhgcm.pDirectDraw)
-        {
-            DDSURFACEDESC       ddsd;
-            HRESULT             hr;
-            LPDIRECTDRAWSURFACE lpDDS;
-
-            memset(&ddsd, 0, sizeof(ddsd));
-            ddsd.dwSize  = sizeof(ddsd);
-
-            /* @todo DDSCAPS_VIDEOMEMORY ain't working for some reason
-             * also, it would be better to request dwLinearSize but it fails too
-             * ddsd.dwLinearSize = sizeof(CRVBOXHGCMBUFFER) + conn->buffer_size;
-             */
-
-            ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
-            ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
-            /* use 1 byte per pixel format */
-            ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
-            ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
-            ddsd.ddpfPixelFormat.dwRGBBitCount = 8;
-            ddsd.ddpfPixelFormat.dwRBitMask = 0xFF;
-            ddsd.ddpfPixelFormat.dwGBitMask = 0;
-            ddsd.ddpfPixelFormat.dwBBitMask = 0;
-            /* request given buffer size, rounded to 1k */
-            ddsd.dwWidth = 1024;
-            ddsd.dwHeight = (sizeof(CRVBOXHGCMBUFFER) + conn->buffer_size + ddsd.dwWidth-1)/ddsd.dwWidth;
-
-            hr = IDirectDraw_CreateSurface(g_crvboxhgcm.pDirectDraw, &ddsd, &lpDDS, NULL);
-            if (hr != DD_OK)
-            {
-                crWarning("Failed to create DirectDraw surface (%x)\n", hr);
-            }
-            else
-            {
-                crDebug("Created DirectDraw surface (%x)\n", lpDDS);
-
-                hr = IDirectDrawSurface_Lock(lpDDS, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
-                if (hr != DD_OK)
-                {
-                    crWarning("Failed to lock DirectDraw surface (%x)\n", hr);
-                    IDirectDrawSurface_Release(lpDDS);
-                }
-                else
-                {
-                    uint32_t cbLocked;
-                    cbLocked = (ddsd.dwFlags & DDSD_LINEARSIZE) ? ddsd.dwLinearSize : ddsd.lPitch*ddsd.dwHeight;
-
-                    crDebug("Locked %d bytes DirectDraw surface\n", cbLocked);
-
-                    buf = (CRVBOXHGCMBUFFER *) ddsd.lpSurface;
-                    CRASSERT(buf);
-                    buf->magic = CR_VBOXHGCM_BUFFER_MAGIC;
-                    buf->kind  = CR_VBOXHGCM_DDRAW_SURFACE;
-                    buf->allocated = cbLocked;
-                    buf->pDDS = lpDDS;
-                }
-            }
-        }
-#endif
-
         /* We're either on host side, or we failed to allocate DDRAW buffer */
         if (!buf)
@@ -801,7 +709,4 @@
             buf->kind  = CR_VBOXHGCM_MEMORY;
             buf->allocated = conn->buffer_size;
-#ifdef RT_OS_WINDOWS
-            buf->pDDS = NULL;
-#endif
         }
     }
@@ -945,16 +850,7 @@
     parms.hdr.cParms      = SHCRGL_CPARMS_WRITE_READ;
 
-    //if (bufferKind != CR_VBOXHGCM_DDRAW_SURFACE)
-    {
-        parms.pBuffer.type                   = VMMDevHGCMParmType_LinAddr_In;
-        parms.pBuffer.u.Pointer.size         = len;
-        parms.pBuffer.u.Pointer.u.linearAddr = (uintptr_t) buf;
-    }
-    /*else ///@todo it fails badly, have to check why. bird: This fails because buf isn't a physical address?
-    {
-        parms.pBuffer.type                 = VMMDevHGCMParmType_PhysAddr;
-        parms.pBuffer.u.Pointer.size       = len;
-        parms.pBuffer.u.Pointer.u.physAddr = (uintptr_t) buf;
-    }*/
+    parms.pBuffer.type                   = VMMDevHGCMParmType_LinAddr_In;
+    parms.pBuffer.u.Pointer.size         = len;
+    parms.pBuffer.u.Pointer.u.linearAddr = (uintptr_t) buf;
 
     CRASSERT(!conn->pBuffer); //make sure there's no data to process
@@ -1203,7 +1099,4 @@
     {
         case CR_VBOXHGCM_MEMORY:
-#ifdef RT_OS_WINDOWS
-        case CR_VBOXHGCM_DDRAW_SURFACE:
-#endif
 #ifdef CHROMIUM_THREADSAFE
             crLockMutex(&g_crvboxhgcm.mutex);
@@ -1284,5 +1177,5 @@
     {
         /* we should NEVER have redir_ptr disabled with HGSMI command now */
-        CRASSERT(!conn->CmdData.pCmd);
+        CRASSERT(!conn->CmdData.pvCmd);
         if ( len <= conn->buffer_size )
         {
@@ -1299,7 +1192,4 @@
             hgcm_buffer->kind      = CR_VBOXHGCM_MEMORY_BIG;
             hgcm_buffer->allocated = sizeof(CRVBOXHGCMBUFFER) + len;
-# ifdef RT_OS_WINDOWS
-            hgcm_buffer->pDDS      = NULL;
-# endif
         }
 
@@ -2421,7 +2311,4 @@
 void crVBoxHGCMBufferFree(void *data)
 {
-#ifdef RT_OS_WINDOWS
-    LPDIRECTDRAWSURFACE lpDDS;
-#endif
     CRVBOXHGCMBUFFER *hgcm_buffer = (CRVBOXHGCMBUFFER *) data;
 
@@ -2433,13 +2320,4 @@
             crFree( hgcm_buffer );
             break;
-#ifdef RT_OS_WINDOWS
-        case CR_VBOXHGCM_DDRAW_SURFACE:
-            lpDDS = hgcm_buffer->pDDS;
-            CRASSERT(lpDDS);
-            IDirectDrawSurface_Unlock(lpDDS, NULL);
-            IDirectDrawSurface_Release(lpDDS);
-            crDebug("DDraw surface freed (%x)\n", lpDDS);
-            break;
-#endif
         case CR_VBOXHGCM_MEMORY_BIG:
             crFree( hgcm_buffer );
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 49590)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 49591)
@@ -42,11 +42,13 @@
 
 #define VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc) do { \
+        Assert(CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData)); \
         CRVBOXHGSMI_CMDDATA_ASSERT_ISSET(_pData); \
         CRVBOXHGSMI_CMDDATA_RC(_pData, _rc); \
-        crServerCrHgsmiCmdComplete((_pData)->pCmd, VINF_SUCCESS); \
+        crServerCrHgsmiCmdComplete((_pData)->pHgsmiCmd, VINF_SUCCESS); \
     } while (0)
 
 #define VBOXCRHGSMI_CMD_CHECK_COMPLETE(_pData, _rc) do { \
-        if (CRVBOXHGSMI_CMDDATA_IS_COMPLETE_NEEDED(_pData) && CRVBOXHGSMI_CMDDATA_IS_SET(_pData)) { \
+        Assert(CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData)); \
+        if (CRVBOXHGSMI_CMDDATA_IS_SET(_pData)) { \
             VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc); \
         } \
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 49590)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 49591)
@@ -247,9 +247,13 @@
     {
         cr_server.u32Caps = crServerVBoxParseNumerics(env, 0);
-        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/);
+        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT | CR_VBOX_CAP_CMDVBVA);
     }
     else
     {
-        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/;
+        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_CMDVBVA*/;
+#ifdef DEBUG_misha
+        cr_server.u32Caps |= CR_VBOX_CAP_CMDVBVA;
+#endif
+
     }
 
@@ -411,9 +415,12 @@
     {
         cr_server.u32Caps = crServerVBoxParseNumerics(env, 0);
-        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/);
+        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT | CR_VBOX_CAP_CMDVBVA);
     }
     else
     {
-        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/;
+        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_CMDVBVA*/;
+#ifdef DEBUG_misha
+        cr_server.u32Caps |= CR_VBOX_CAP_CMDVBVA;
+#endif
     }
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 49590)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 49591)
@@ -3056,5 +3056,5 @@
  * NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
  * */
-static int32_t crVBoxServerCrHgsmiCmdProcess(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, bool fCompleteNeeded)
+static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd)
 {
     int32_t rc;
@@ -3070,9 +3070,5 @@
     {
         crWarning("g_pvVRamBase is not initialized");
-        if (!fCompleteNeeded)
-            return VERR_INVALID_STATE;
-
-        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
-        return VINF_SUCCESS;
+        return VERR_INVALID_STATE;
     }
 
@@ -3080,9 +3076,5 @@
     {
         crWarning("zero buffers passed in!");
-        if (!fCompleteNeeded)
-            return VERR_INVALID_PARAMETER;
-
-        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
-        return VINF_SUCCESS;
+        return VERR_INVALID_PARAMETER;
     }
 
@@ -3094,9 +3086,5 @@
     {
         crWarning("invalid header buffer!");
-        if (!fCompleteNeeded)
-            return VERR_INVALID_PARAMETER;
-
-        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
-        return VINF_SUCCESS;
+        return VERR_INVALID_PARAMETER;
     }
 
@@ -3104,9 +3092,5 @@
     {
         crWarning("invalid header buffer size!");
-        if (!fCompleteNeeded)
-            return VERR_INVALID_PARAMETER;
-
-        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
-        return VINF_SUCCESS;
+        return VERR_INVALID_PARAMETER;
     }
 
@@ -3124,5 +3108,5 @@
             {
                 CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
-                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
+                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
                 /* Fetch parameters. */
                 uint32_t cbBuffer = pBuf->cbBuffer;
@@ -3156,5 +3140,5 @@
                 pClient->conn->pBuffer = pBuffer;
                 pClient->conn->cbBuffer = cbBuffer;
-                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, fCompleteNeeded);
+                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, false);
                 rc = crVBoxServerInternalClientWriteRead(pClient);
                 CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
@@ -3180,5 +3164,5 @@
                 /* Fetch parameters. */
                 uint32_t u32InjectClientID = pFnCmd->u32ClientID;
-                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
+                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
                 uint32_t cbBuffer = pBuf->cbBuffer;
                 uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
@@ -3211,5 +3195,314 @@
                 pClient->conn->pBuffer = pBuffer;
                 pClient->conn->cbBuffer = cbBuffer;
-                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, fCompleteNeeded);
+                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, false);
+                rc = crVBoxServerInternalClientWriteRead(pClient);
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+                return rc;
+            }
+
+            crWarning("invalid number of args");
+            rc = VERR_INVALID_PARAMETER;
+            break;
+        }
+
+        case SHCRGL_GUEST_FN_READ:
+        {
+            Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
+
+            /* @todo: Verify  */
+            if (cParams == 1)
+            {
+                CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
+                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
+                /* Fetch parameters. */
+                uint32_t cbBuffer = pBuf->cbBuffer;
+                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
+
+                if (cbHdr < sizeof (*pFnCmd))
+                {
+                    crWarning("invalid read cmd buffer size!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+
+                if (!pBuffer)
+                {
+                    crWarning("invalid buffer data received from guest!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+                rc = crVBoxServerClientGet(u32ClientID, &pClient);
+                if (RT_FAILURE(rc))
+                {
+                    break;
+                }
+
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+
+                rc = crVBoxServerInternalClientRead(pClient, pBuffer, &cbBuffer);
+
+                /* Return the required buffer size always */
+                pFnCmd->cbBuffer = cbBuffer;
+
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+
+                /* the read command is never pended, complete it right away */
+                pHdr->result = rc;
+
+                return VINF_SUCCESS;
+            }
+
+            crWarning("invalid number of args");
+            rc = VERR_INVALID_PARAMETER;
+            break;
+        }
+
+        case SHCRGL_GUEST_FN_WRITE_READ:
+        {
+            Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
+
+            /* @todo: Verify  */
+            if (cParams == 2)
+            {
+                CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
+                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
+                VBOXCMDVBVA_CRCMD_BUFFER *pWbBuf = &pCmd->aBuffers[2];
+
+                /* Fetch parameters. */
+                uint32_t cbBuffer = pBuf->cbBuffer;
+                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
+
+                uint32_t cbWriteback = pWbBuf->cbBuffer;
+                char *pWriteback  = VBOXCRHGSMI_PTR_SAFE(pWbBuf->offBuffer, cbWriteback, char);
+
+                if (cbHdr < sizeof (*pFnCmd))
+                {
+                    crWarning("invalid write_read cmd buffer size!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+
+                CRASSERT(cbBuffer);
+                if (!pBuffer)
+                {
+                    crWarning("invalid write buffer data received from guest!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+                CRASSERT(cbWriteback);
+                if (!pWriteback)
+                {
+                    crWarning("invalid writeback buffer data received from guest!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+                rc = crVBoxServerClientGet(u32ClientID, &pClient);
+                if (RT_FAILURE(rc))
+                {
+                    pHdr->result = rc;
+                    return VINF_SUCCESS;
+                }
+
+                /* This should never fire unless we start to multithread */
+                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+
+                pClient->conn->pBuffer = pBuffer;
+                pClient->conn->cbBuffer = cbBuffer;
+                CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback, false);
+                rc = crVBoxServerInternalClientWriteRead(pClient);
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+                return rc;
+            }
+
+            crWarning("invalid number of args");
+            rc = VERR_INVALID_PARAMETER;
+            break;
+        }
+
+        case SHCRGL_GUEST_FN_SET_VERSION:
+        {
+            crWarning("invalid function");
+            rc = VERR_NOT_IMPLEMENTED;
+            break;
+        }
+
+        case SHCRGL_GUEST_FN_SET_PID:
+        {
+            crWarning("invalid function");
+            rc = VERR_NOT_IMPLEMENTED;
+            break;
+        }
+
+        default:
+        {
+            crWarning("invalid function");
+            rc = VERR_NOT_IMPLEMENTED;
+            break;
+        }
+
+    }
+
+    /* we can be on fail only here */
+    CRASSERT(RT_FAILURE(rc));
+    pHdr->result = rc;
+
+    return rc;
+}
+
+
+int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd)
+{
+
+    int32_t rc;
+    uint32_t cBuffers = pCmd->cBuffers;
+    uint32_t cParams;
+    uint32_t cbHdr;
+    CRVBOXHGSMIHDR *pHdr;
+    uint32_t u32Function;
+    uint32_t u32ClientID;
+    CRClient *pClient;
+
+    if (!g_pvVRamBase)
+    {
+        crWarning("g_pvVRamBase is not initialized");
+
+        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
+        return VINF_SUCCESS;
+    }
+
+    if (!cBuffers)
+    {
+        crWarning("zero buffers passed in!");
+
+        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
+        return VINF_SUCCESS;
+    }
+
+    cParams = cBuffers-1;
+
+    cbHdr = pCmd->aBuffers[0].cbBuffer;
+    pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR);
+    if (!pHdr)
+    {
+        crWarning("invalid header buffer!");
+
+        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
+        return VINF_SUCCESS;
+    }
+
+    if (cbHdr < sizeof (*pHdr))
+    {
+        crWarning("invalid header buffer size!");
+
+        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
+        return VINF_SUCCESS;
+    }
+
+    u32Function = pHdr->u32Function;
+    u32ClientID = pHdr->u32ClientID;
+
+    switch (u32Function)
+    {
+        case SHCRGL_GUEST_FN_WRITE:
+        {
+            Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
+
+            /* @todo: Verify  */
+            if (cParams == 1)
+            {
+                CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
+                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
+                /* Fetch parameters. */
+                uint32_t cbBuffer = pBuf->cbBuffer;
+                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
+
+                if (cbHdr < sizeof (*pFnCmd))
+                {
+                    crWarning("invalid write cmd buffer size!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+                CRASSERT(cbBuffer);
+                if (!pBuffer)
+                {
+                    crWarning("invalid buffer data received from guest!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+                rc = crVBoxServerClientGet(u32ClientID, &pClient);
+                if (RT_FAILURE(rc))
+                {
+                    break;
+                }
+
+                /* This should never fire unless we start to multithread */
+                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+
+                pClient->conn->pBuffer = pBuffer;
+                pClient->conn->cbBuffer = cbBuffer;
+                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, true);
+                rc = crVBoxServerInternalClientWriteRead(pClient);
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+                return rc;
+            }
+            else
+            {
+                crWarning("invalid number of args");
+                rc = VERR_INVALID_PARAMETER;
+                break;
+            }
+            break;
+        }
+
+        case SHCRGL_GUEST_FN_INJECT:
+        {
+            Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
+
+            /* @todo: Verify  */
+            if (cParams == 1)
+            {
+                CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
+                /* Fetch parameters. */
+                uint32_t u32InjectClientID = pFnCmd->u32ClientID;
+                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
+                uint32_t cbBuffer = pBuf->cbBuffer;
+                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
+
+                if (cbHdr < sizeof (*pFnCmd))
+                {
+                    crWarning("invalid inject cmd buffer size!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+                CRASSERT(cbBuffer);
+                if (!pBuffer)
+                {
+                    crWarning("invalid buffer data received from guest!");
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+
+                rc = crVBoxServerClientGet(u32InjectClientID, &pClient);
+                if (RT_FAILURE(rc))
+                {
+                    break;
+                }
+
+                /* This should never fire unless we start to multithread */
+                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
+                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
+
+                pClient->conn->pBuffer = pBuffer;
+                pClient->conn->cbBuffer = cbBuffer;
+                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, true);
                 rc = crVBoxServerInternalClientWriteRead(pClient);
                 CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
@@ -3267,7 +3560,4 @@
                 /* the read command is never pended, complete it right away */
                 pHdr->result = rc;
-
-                if (!fCompleteNeeded)
-                    return VINF_SUCCESS;
 
                 crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
@@ -3335,5 +3625,5 @@
                 pClient->conn->pBuffer = pBuffer;
                 pClient->conn->cbBuffer = cbBuffer;
-                CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback, fCompleteNeeded);
+                CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback, true);
                 rc = crVBoxServerInternalClientWriteRead(pClient);
                 CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
@@ -3373,14 +3663,7 @@
     pHdr->result = rc;
 
-    if (!fCompleteNeeded)
-        return rc;
-
     crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
     return rc;
-}
-
-int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd)
-{
-    return crVBoxServerCrHgsmiCmdProcess(pCmd, true);
+
 }
 
@@ -3433,15 +3716,14 @@
         {
             VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
-            VBOXCMDVBVAOFFSET offCmd = pCrCmdDr->offCmd;
-            if (offCmd < g_cbVRam && offCmd + cbCmd < g_cbVRam)
+            VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd;
+            int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd);
+            if (RT_SUCCESS(rc))
             {
-                VBOXVDMACMD_CHROMIUM_CMD *pCrCmd = (VBOXVDMACMD_CHROMIUM_CMD*)(g_pvVRamBase + offCmd);
-                crVBoxServerCrHgsmiCmdProcess(pCrCmd, false);
-                /* success */
+            /* success */
                 pCmd->i8Result = 0;
             }
             else
             {
-                crWarning("incorrect command info!");
+                crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc);
                 pCmd->i8Result = -1;
             }
