Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 50900)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 50913)
@@ -519,5 +519,5 @@
     Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-    PVBOXMP_CRSHGSMITRANSPORT pCon;
+    PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
     PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
     VBOXCMDVBVA_CRCMD_CMD *pCmd;
@@ -1031,5 +1031,5 @@
     }
 
-#if 1 /*def DEBUG_misha*/
+#ifndef DEBUG_misha
     g_VBoxMpCrHostCaps &= ~CR_VBOX_CAP_CMDVBVA;
 #endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp	(revision 50900)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp	(revision 50913)
@@ -174,5 +174,5 @@
 static int vboxCmdVbvaCtlSubmitAsync(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, VBOXCMDVBVA_CTL * pCtl, FNVBOXSHGSMICMDCOMPLETION pfnCompletion, void *pvCompletion)
 {
-    const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepAsynch(&pHGSMICtx->heapCtx, pCtl, pfnCompletion, pvCompletion, 0);
+    const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepAsynch(&pHGSMICtx->heapCtx, pCtl, pfnCompletion, pvCompletion, VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ);
     HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pHGSMICtx->heapCtx, pHdr);
     if (offCmd == HGSMIOFFSET_VOID)
@@ -293,6 +293,9 @@
     // LogFunc(("flags = 0x%08X\n", pCtx->pVBVA? pCtx->pVBVA->u32HostEvents: -1));
 
-    if (   pCtx->pVBVA
-        && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
+    Assert(pCtx->pVBVA);
+    /* we do not use u32HostEvents & VBVA_F_MODE_ENABLED,
+     * VBVA stays enabled once ENABLE call succeeds, until it is disabled with DISABLED call */
+//    if (   pCtx->pVBVA
+//        && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
     {
         uint32_t indexRecordNext;
@@ -366,4 +369,10 @@
 }
 
+DECLINLINE(bool) vboxVBVAExIsEntryInRangeOrEmpty(uint32_t u32First, uint32_t u32Entry, uint32_t u32Free)
+{
+    return vboxVBVAExIsEntryInRange(u32First, u32Entry, u32Free)
+            || (    u32First == u32Entry
+                 && u32Entry == u32Free);
+}
 #ifdef DEBUG
 
@@ -371,10 +380,10 @@
 {
     VBVABUFFER *pVBVA = pCtx->pVBVA;
-    if (!vboxVBVAExIsEntryInRange(pCtx->indexRecordFirstUncompleted, pVBVA->indexRecordFirst, pVBVA->indexRecordFree))
+    if (!vboxVBVAExIsEntryInRangeOrEmpty(pCtx->indexRecordFirstUncompleted, pVBVA->indexRecordFirst, pVBVA->indexRecordFree))
     {
         WARN(("invalid record set"));
     }
 
-    if (!vboxVBVAExIsEntryInRange(pCtx->off32DataUncompleted, pVBVA->off32Data, pVBVA->off32Free))
+    if (!vboxVBVAExIsEntryInRangeOrEmpty(pCtx->off32DataUncompleted, pVBVA->off32Data, pVBVA->off32Free))
     {
         WARN(("invalid data set"));
@@ -904,8 +913,10 @@
     int rc = VINF_SUCCESS;
 
+    Assert(pCmd->u32FenceID);
+
     pCmd->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
     pVbva->u32FenceSubmitted = pCmd->u32FenceID;
 
-    if (VBoxVBVAExGetSize(&pVbva->Vbva) > cbCmd)
+    if (VBoxVBVAExGetSize(&pVbva->Vbva) < cbCmd)
     {
         WARN(("buffer does not fit the vbva buffer, we do not support splitting buffers"));
@@ -1073,5 +1084,5 @@
 }
 
-
+#if 0
 static uint32_t vboxCVDdiSysMemElBuild(VBOXCMDVBVA_SYSMEMEL *pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages)
 {
@@ -1103,9 +1114,5 @@
     VBOXCMDVBVA_SYSMEMEL *pEl = pCmd->aSysMem;
 
-    if (cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
-    {
-        WARN(("cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER)"));
-        goto done;
-    }
+    Assert(cbBuffer >= sizeof (VBOXCMDVBVA_PAGING_TRANSFER));
 
     cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
@@ -1116,8 +1123,27 @@
     }
 
-done:
     *pcPagesWritten = cInitPages - cPages;
     return cbInitBuffer - cbBuffer;
 }
+#endif
+
+uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten)
+{
+    uint32_t cbInitBuffer = cbBuffer;
+    uint32_t i = 0;
+    VBOXCMDVBVAPAGEIDX *pPageNumbers = pCmd->aPageNumbers;
+
+    cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aPageNumbers);
+
+    for (; i < cPages && cbBuffer >= sizeof (*pPageNumbers); ++i, cbBuffer -= sizeof (*pPageNumbers))
+    {
+        pPageNumbers[i] = (VBOXCMDVBVAPAGEIDX)(MmGetMdlPfnArray(pMdl)[iPfn + i]);
+    }
+
+    *pcPagesWritten = i;
+    Assert(cbInitBuffer - cbBuffer == RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aPageNumbers[i]));
+    return cbInitBuffer - cbBuffer;
+}
+
 
 int vboxCmdVbvaConConnect(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
@@ -1144,5 +1170,8 @@
         rc = pConnect->Hdr.i32Result;
         if (RT_SUCCESS(rc))
+        {
+            Assert(pConnect->Connect.Hdr.u32CmdClientId);
             *pu32ClientID = pConnect->Connect.Hdr.u32CmdClientId;
+        }
         else
             WARN(("VBOXCMDVBVA3DCTL_TYPE_CONNECT Disable failed %d", rc));
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 50900)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 50913)
@@ -1979,6 +1979,11 @@
             memset(pCaps, 0, sizeof (*pCaps));
 #endif
-
-            pCaps->HighestAcceptableAddress.QuadPart = ~((uintptr_t)0);
+            pCaps->HighestAcceptableAddress.LowPart = ~0UL;
+#ifdef RT_ARCH_AMD64
+            /* driver talks to host in terms of page numbers when reffering to RAM
+             * we use uint32_t field to pass page index to host, so max would be (~0UL) << PAGE_OFFSET,
+             * which seems quite enough */
+            pCaps->HighestAcceptableAddress.HighPart = PAGE_OFFSET_MASK;
+#endif
             pCaps->MaxPointerWidth  = VBOXWDDM_C_POINTER_MAX_WIDTH;
             pCaps->MaxPointerHeight = VBOXWDDM_C_POINTER_MAX_HEIGHT;
@@ -3095,20 +3100,5 @@
     {
         cbCmd = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
-        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;
-        }
-
-        if (cbCmd > 0xffff)
-        {
-            WARN(("cbCmd too big"));
-            return STATUS_INVALID_PARAMETER;
-        }
-
-        if (VBOXWDDM_DUMMY_DMABUFFER_SIZE == cbCmd)
+        if (!cbCmd || VBOXWDDM_DUMMY_DMABUFFER_SIZE == cbCmd)
         {
             SysMem.Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
@@ -3119,18 +3109,34 @@
         else
         {
+            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;
+            }
+
+            if (cbCmd > 0xffff)
+            {
+                WARN(("cbCmd too big"));
+                return STATUS_INVALID_PARAMETER;
+            }
+
             SysMem.Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_SYSMEMCMD;
             SysMem.Hdr.u8Flags = cbCmd & 0xff;
             SysMem.Hdr.u.u8PrimaryID = (cbCmd >> 8) & 0xff;
             SysMem.Hdr.u8State = VBOXCMDVBVA_STATE_SUBMITTED;
-            SysMem.phSysMem = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset;
-            if (SysMem.phSysMem & PAGE_OFFSET_MASK)
+            if (pSubmitCommand->DmaBufferPhysicalAddress.QuadPart & PAGE_OFFSET_MASK)
             {
                 WARN(("command should be page aligned for now"));
                 return STATUS_INVALID_PARAMETER;
             }
+            SysMem.iPage = (VBOXCMDVBVAPAGEIDX)(pSubmitCommand->DmaBufferPhysicalAddress.QuadPart >> PAGE_SHIFT);
+
+            cbCmd = sizeof (SysMem);
         }
 
         pHdr = &SysMem.Hdr;
-        cbCmd = sizeof (SysMem);
     }
     else
@@ -3403,12 +3409,4 @@
     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)
     {
@@ -3471,15 +3469,17 @@
             }
 
-            uint32_t cPages = (uint32_t)((pBuildPagingBuffer->Transfer.TransferSize + 0xfff) >> PAGE_SHIFT);
-            uint32_t cTotalPages = cPages;
+            Assert(!(pBuildPagingBuffer->Transfer.TransferSize & PAGE_OFFSET_MASK));
+            Assert(!(offVRAM & PAGE_OFFSET_MASK));
+            uint32_t cPages = (uint32_t)(pBuildPagingBuffer->Transfer.TransferSize >> PAGE_SHIFT);
+            Assert(cPages > pBuildPagingBuffer->MultipassOffset);
             cPages -= pBuildPagingBuffer->MultipassOffset;
-            uint32_t iFirstPage = pBuildPagingBuffer->Transfer.MdlOffset + pBuildPagingBuffer->MultipassOffset;
+            uint32_t iFirstPage = pBuildPagingBuffer->MultipassOffset;
             uint32_t cPagesWritten;
-            offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + pBuildPagingBuffer->MultipassOffset;
+            offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + (pBuildPagingBuffer->MultipassOffset << PAGE_SHIFT);
 
             pPaging->Alloc.u.offVRAM = offVRAM;
             if (fIn)
                 pPaging->Hdr.u8Flags |= VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN;
-            cbBuffer = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaBufferPrivateDataSize, &cPagesWritten);
+            cbBuffer = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaSize, &cPagesWritten);
             if (cPagesWritten != cPages)
                 pBuildPagingBuffer->MultipassOffset += cPagesWritten;
@@ -3500,4 +3500,5 @@
             /** @todo: add necessary bits */
             WARN(("Impl!"));
+            cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
             break;
         }
@@ -3510,4 +3511,5 @@
                 return STATUS_INVALID_PARAMETER;
             }
+            WARN(("Do we need to do anything here?"));
             break;
         }
@@ -3521,4 +3523,5 @@
     Assert(!cbPrivateData);
 
+    Assert(pBuildPagingBuffer->Operation == DXGK_OPERATION_DISCARD_CONTENT || cbBuffer);
     pBuildPagingBuffer->pDmaBuffer = ((uint8_t*)pBuildPagingBuffer->pDmaBuffer) + cbBuffer;
     pBuildPagingBuffer->pDmaBufferPrivateData = ((uint8_t*)pBuildPagingBuffer->pDmaBufferPrivateData) + cbPrivateData;
@@ -6088,9 +6091,11 @@
 //    LOGF(("ENTER, hContext(0x%x)", hContext));
 
-    vboxVDbgBreakFv();
+    vboxVDbgBreakF();
 
     PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
     PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
     PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
+    uint32_t cbBuffer = 0;
+    uint32_t cbPrivateData = 0;
 
     if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
@@ -6191,5 +6196,6 @@
 
             paRects = pBlt->aRects;
-            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
+            cbPrivateData = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
+            cbMaxRects = pPresent->DmaBufferPrivateDataSize - cbPrivateData;
         }
         else
@@ -6214,6 +6220,9 @@
 
             paRects = pBlt->aRects;
-            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
-        }
+            cbPrivateData = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
+            cbMaxRects = pPresent->DmaBufferPrivateDataSize - cbPrivateData;
+        }
+
+        cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     }
     else if (pPresent->Flags.Flip)
@@ -6247,4 +6256,7 @@
         if (VBoxCVDdiFillAllocInfo(pHdr, &pFlip->src, pSrcAlloc, pSrc, false))
             u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_FLIP, src.u.offVRAM);
+
+        cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+        cbPrivateData = sizeof (*pFlip);
     }
     else if (pPresent->Flags.ColorFill)
@@ -6278,5 +6290,8 @@
 
         paRects = pCFill->aRects;
-        cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
+        cbPrivateData = RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
+        cbMaxRects = pPresent->DmaBufferPrivateDataSize - cbPrivateData;
+
+        cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     }
     else
@@ -6300,6 +6315,8 @@
             pPresent->MultipassOffset = 0;
 
+        Assert(cRects);
         const RECT *paDstSubRects = &pPresent->pDstSubRects[iStartRect];
         VBoxCVDdiPackRects(paRects, paDstSubRects, cRects);
+        cbPrivateData += (cRects * sizeof (VBOXCMDVBVA_RECT));
     }
 
@@ -6324,5 +6341,8 @@
     pHdr->u32FenceID = 0;
 
-    pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+    Assert(cbBuffer);
+    Assert(cbPrivateData);
+    pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cbBuffer;
+    pPresent->pDmaBufferPrivateData = ((uint8_t*)pPresent->pDmaBufferPrivateData) + cbPrivateData;
 
     if (pPresent->MultipassOffset)
