Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 30565)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 30566)
@@ -1177,5 +1177,6 @@
     VBOXVDMACMD_TYPE_DMA_BPB_FILL,
     VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY,
-    VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL
+    VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL,
+    VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP
 } VBOXVDMACMD_TYPE;
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 30565)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 30566)
@@ -1863,8 +1863,19 @@
 static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
 {
-    vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
-    AssertBreakpoint();
-    vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
-    return E_FAIL;
+    vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
+    PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
+    Assert(pDevice);
+    Assert(pDevice->pDevice9If);
+    HRESULT hr = pDevice->pDevice9If->DrawIndexedPrimitive(
+            pData->PrimitiveType,
+            pData->BaseVertexIndex,
+            pData->MinIndex,
+            pData->NumVertices,
+            pData->StartIndex,
+            pData->PrimitiveCount);
+    Assert(hr == S_OK);
+
+    vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
+    return hr;
 }
 
@@ -2645,6 +2656,21 @@
                 Assert(hr == S_OK);
             }
-            else if (pRc->RcDesc.fFlags.IndexBuffer)
-            {
+            else
+            {
+                Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
+            }
+        }
+        else if (pRc->RcDesc.fFlags.IndexBuffer)
+        {
+            Assert(pData->SubResourceIndex < pRc->cAllocations);
+            PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
+
+            --pAlloc->LockInfo.cLocks;
+            Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
+            if (!pAlloc->LockInfo.cLocks
+                && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
+                    || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
+            {
+//                Assert(!pAlloc->LockInfo.cLocks);
                 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
                 Assert(pD3D9IBuf);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h	(revision 30565)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h	(revision 30566)
@@ -44,4 +44,12 @@
     , VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC
 } VBOXWDDM_ALLOC_TYPE;
+
+/* usage */
+typedef enum
+{
+    VBOXWDDM_ALLOCUSAGE_TYPE_UNEFINED = 0,
+    /* set for the allocation being primary */
+    VBOXWDDM_ALLOCUSAGE_TYPE_PRIMARY,
+} VBOXWDDM_ALLOCUSAGE_TYPE;
 
 typedef struct VBOXWDDM_SURFACE_DESC
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 30565)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 30566)
@@ -1437,4 +1437,5 @@
     {
         case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
+        case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
         {
             if (pAllocation->bAssigned)
@@ -1930,4 +1931,5 @@
             case VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY:
             case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
+            case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
             {
                 const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[0];
@@ -2101,42 +2103,46 @@
             {
                 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
+                case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
                 {
-                    VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->DstAllocInfo.srcId];
-                    Assert(pSource->pPrimaryAllocation == pDstAlloc);
-                    switch (pSrcAlloc->enmType)
+                    if (pDstAlloc->bAssigned)
                     {
-                        case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
+                        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->DstAllocInfo.srcId];
+                        Assert(pSource->pPrimaryAllocation == pDstAlloc);
+                        switch (pSrcAlloc->enmType)
                         {
-                            RECT rect;
-                            Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
-                            vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pPrivateData->SrcAllocInfo.segmentIdAlloc, pPrivateData->SrcAllocInfo.offAlloc);
-                            if (pBlt->DstRects.UpdateRects.cRects)
+                            case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
                             {
-                                rect = pBlt->DstRects.UpdateRects.aRects[0];
-                                for (UINT i = 1; i < pBlt->DstRects.UpdateRects.cRects; ++i)
+                                RECT rect;
+                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
+                                vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pPrivateData->SrcAllocInfo.segmentIdAlloc, pPrivateData->SrcAllocInfo.offAlloc);
+                                if (pBlt->DstRects.UpdateRects.cRects)
                                 {
-                                    vboxWddmRectUnited(&rect, &rect, &pBlt->DstRects.UpdateRects.aRects[i]);
+                                    rect = pBlt->DstRects.UpdateRects.aRects[0];
+                                    for (UINT i = 1; i < pBlt->DstRects.UpdateRects.cRects; ++i)
+                                    {
+                                        vboxWddmRectUnited(&rect, &rect, &pBlt->DstRects.UpdateRects.aRects[i]);
+                                    }
                                 }
+                                else
+                                    rect = pBlt->DstRects.ContextRect;
+
+                                VBOXVBVA_OP(ReportDirtyRect, pDevExt, &pSource->Vbva, &rect);
+                                vboxWddmSubmitBltCmd(pDevExt, pContext, pBlt);
+                                break;
                             }
-                            else
-                                rect = pBlt->DstRects.ContextRect;
-
-                            VBOXVBVA_OP(ReportDirtyRect, pDevExt, &pSource->Vbva, &rect);
-                            vboxWddmSubmitBltCmd(pDevExt, pContext, pBlt);
-                            break;
+                            case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
+                            {
+                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
+                                Assert(pSrcAlloc->fRcFlags.RenderTarget);
+                                if (pSrcAlloc->fRcFlags.RenderTarget)
+                                {
+                                    vboxWddmSubmitBltCmd(pDevExt, pContext, pBlt);
+                                }
+                                break;
+                            }
+                            default:
+                                AssertBreakpoint();
+                                break;
                         }
-                        case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
-                        {
-                            Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
-                            Assert(pSrcAlloc->fRcFlags.RenderTarget);
-                            if (pSrcAlloc->fRcFlags.RenderTarget)
-                            {
-                                vboxWddmSubmitBltCmd(pDevExt, pContext, pBlt);
-                            }
-                            break;
-                        }
-                        default:
-                            AssertBreakpoint();
-                            break;
                     }
                     break;
@@ -2160,4 +2166,39 @@
                     AssertBreakpoint();
                     break;
+            }
+
+            VBOXWDDM_SHADOW_UPDATE_COMPLETION context;
+            context.pDevExt = pDevExt;
+            context.pTransactionData = pPrivateData;
+            context.SubmissionFenceId = pSubmitCommand->SubmissionFenceId;
+            Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+                    pDevExt->u.primary.DxgkInterface.DeviceHandle,
+                    vboxWddmNotifyShadowUpdateCompletion,
+                    &context,
+                    0, /* IN ULONG MessageNumber */
+                    &bRet);
+            break;
+        }
+        case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
+        {
+            PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
+            PVBOXVDMAPIPE_CMD_RECTSINFO pRectsCmd = (PVBOXVDMAPIPE_CMD_RECTSINFO)vboxVdmaGgCmdCreate(&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_RECTSINFO, RT_OFFSETOF(VBOXVDMAPIPE_CMD_RECTSINFO, ContextsRects.UpdateRects.aRects[1]));
+            Assert(pRectsCmd);
+            if (pRectsCmd)
+            {
+                PVBOXWDDM_ALLOCATION pDstAlloc = pPrivateData->DstAllocInfo.pAlloc;
+                pRectsCmd->pContext = pContext;
+                RECT r;
+                r.top = 0;
+                r.left = 0;
+                r.right = pDstAlloc->SurfDesc.width;
+                r.bottom = pDstAlloc->SurfDesc.height;
+                pRectsCmd->ContextsRects.ContextRect = r;
+                pRectsCmd->ContextsRects.UpdateRects.cRects = 1;
+                pRectsCmd->ContextsRects.UpdateRects.aRects[0] = r;
+                NTSTATUS tmpStatus = vboxVdmaGgCmdSubmit(&pDevExt->u.primary.Vdma.DmaGg, &pRectsCmd->Hdr);
+                Assert(tmpStatus == STATUS_SUCCESS);
+                if (tmpStatus != STATUS_SUCCESS)
+                    vboxVdmaGgCmdDestroy(&pRectsCmd->Hdr);
             }
 
@@ -3083,5 +3124,5 @@
         if (pAllocation)
         {
-            Assert(pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
+//            Assert(pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
             pAllocation->offVram = (VBOXVIDEOOFFSET)pSetVidPnSourceAddress->PrimaryAddress.QuadPart;
             pAllocation->SegmentId = pSetVidPnSourceAddress->PrimarySegment;
@@ -3624,6 +3665,8 @@
 }
 
+#if 0
 DECLINLINE(bool) vboxWddmCheckForVisiblePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
 {
+    !!!primary could be of pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC!!!
     if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
         return false;
@@ -3642,4 +3685,5 @@
     return true;
 }
+#endif
 
 static void vboxWddmPopulateDmaAllocInfo(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc)
@@ -4001,4 +4045,50 @@
 #endif
     }
+    else if (pPresent->Flags.Flip)
+    {
+        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);
+        Assert(pSrcAlloc);
+        if (pSrcAlloc)
+        {
+            PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
+            Assert(pDstAlloc);
+            if (pDstAlloc)
+            {
+                Assert(cContexts3D);
+                pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
+
+                vboxWddmPopulateDmaAllocInfo(&pPrivateData->SrcAllocInfo, pSrcAlloc, pSrc);
+                vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
+
+                UINT cbCmd = sizeof (VBOXVDMACMD_DMA_PRESENT_FLIP);
+                pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbCmd;
+                pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+                Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
+
+                memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
+                pPresent->pPatchLocationListOut->PatchOffset = 0;
+                pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
+                ++pPresent->pPatchLocationListOut;
+                pPresent->pPatchLocationListOut->PatchOffset = 4;
+                pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
+                ++pPresent->pPatchLocationListOut;
+            }
+            else
+            {
+                /* this should not happen actually */
+                drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
+                Status = STATUS_INVALID_HANDLE;
+            }
+        }
+        else
+        {
+            /* this should not happen actually */
+            drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
+            Status = STATUS_INVALID_HANDLE;
+        }
+    }
     else
     {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h	(revision 30565)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h	(revision 30566)
@@ -54,4 +54,5 @@
 {
     VBOXWDDM_ALLOC_TYPE enmType;
+//    VBOXWDDM_ALLOCUSAGE_TYPE enmCurrentUsage;
     D3DDDI_RESOURCEFLAGS fRcFlags;
     UINT SegmentId;
@@ -181,4 +182,9 @@
 }VBOXWDDM_DMA_PRESENT_BLT, *PVBOXWDDM_DMA_PRESENT_BLT;
 
+typedef struct VBOXVDMACMD_DMA_PRESENT_FLIP
+{
+    VBOXWDDM_DMA_PRIVATEDATA_HDR Hdr;
+} VBOXVDMACMD_DMA_PRESENT_FLIP, *PVBOXVDMACMD_DMA_PRESENT_FLIP;
+
 
 typedef struct VBOXWDDM_OPENALLOCATION
