Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 76746)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 76790)
@@ -5195,4 +5195,12 @@
                 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
                 {
+#ifdef VBOX_WITH_MESA3D
+                    if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
+                    {
+                        GaVidPnSourceCheckPos(pDevExt, i);
+                        continue;
+                    }
+#endif
+
                     vboxWddmDisplaySettingsCheckPos(pDevExt, i);
                 }
@@ -5446,4 +5454,11 @@
 
     LOGF(("ENTER, context(0x%x)", hAdapter));
+    LOG(("id %d, seg %d, addr 0x%RX64, hAllocation %p, ctx cnt %d, f 0x%x",
+         pSetVidPnSourceAddress->VidPnSourceId,
+         pSetVidPnSourceAddress->PrimarySegment,
+         pSetVidPnSourceAddress->PrimaryAddress.QuadPart,
+         pSetVidPnSourceAddress->hAllocation,
+         pSetVidPnSourceAddress->ContextCount,
+         pSetVidPnSourceAddress->Flags.Value));
 
     PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
@@ -5454,19 +5469,15 @@
     }
 
+#ifdef VBOX_WITH_MESA3D
+    if (pDevExt->enmHwType != VBOXVIDEO_HWTYPE_VMSVGA)
+#endif
     vboxWddmDisplaySettingsCheckPos(pDevExt, pSetVidPnSourceAddress->VidPnSourceId);
 
     NTSTATUS Status = STATUS_SUCCESS;
     PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceAddress->VidPnSourceId];
-#ifdef VBOX_WITH_MESA3D
-    if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
-    {
-        GaScreenDefine(pDevExt->pGa, (uint32_t)pSetVidPnSourceAddress->PrimaryAddress.QuadPart,
-                       pSetVidPnSourceAddress->VidPnSourceId,
-                       pSource->VScreenPos.x, pSource->VScreenPos.y,
-                       pSource->AllocData.SurfDesc.width, pSource->AllocData.SurfDesc.height);
-        return STATUS_SUCCESS;
-    }
-#endif
-
+
+    /*
+     * Update the source VRAM address.
+     */
     PVBOXWDDM_ALLOCATION pAllocation;
     Assert(pSetVidPnSourceAddress->hAllocation);
@@ -5502,4 +5513,18 @@
 
     pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
+
+    /*
+     * Report the source.
+     */
+#ifdef VBOX_WITH_MESA3D
+    if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
+    {
+        /* Query the position of the screen to make sure it is up to date. */
+        vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceAddress->VidPnSourceId, &pSource->VScreenPos);
+
+        GaVidPnSourceReport(pDevExt, pSource);
+        return STATUS_SUCCESS;
+    }
+#endif
 
     vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
@@ -5532,4 +5557,7 @@
     }
 
+#ifdef VBOX_WITH_MESA3D
+    if (pDevExt->enmHwType != VBOXVIDEO_HWTYPE_VMSVGA)
+#endif
     vboxWddmDisplaySettingsCheckPos(pDevExt, pSetVidPnSourceVisibility->VidPnSourceId);
 
@@ -5553,4 +5581,11 @@
     }
 
+#ifdef VBOX_WITH_MESA3D
+    if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
+    {
+        GaVidPnSourceCheckPos(pDevExt, pSetVidPnSourceVisibility->VidPnSourceId);
+    }
+#endif
+
     LOGF(("LEAVE, status(0x%x), context(0x%x)", Status, hAdapter));
 
@@ -5639,4 +5674,43 @@
         VBoxDumpSourceTargetArrays(paSources, paTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
 
+#ifdef VBOX_WITH_MESA3D
+        if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
+        {
+            for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+            {
+                VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[i];
+
+                LOG(("Source [%d]: visible %d, blanked %d", i, pSource->bVisible, pSource->bBlankedByPowerOff));
+
+                /* Update positions of all screens. */
+                vboxWddmDisplaySettingsQueryPos(pDevExt, i, &pSource->VScreenPos);
+
+                GaVidPnSourceReport(pDevExt, pSource);
+            }
+
+            for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+            {
+                VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[i];
+                Assert(pTarget->u32Id == i);
+                if (pTarget->VidPnSourceId != D3DDDI_ID_UNINITIALIZED)
+                {
+                    continue;
+                }
+
+                LOG(("Target [%d]: blanked %d", i, pTarget->fBlankedByPowerOff));
+
+                if (pTarget->fBlankedByPowerOff)
+                {
+                    GaScreenDefine(pDevExt->pGa, 0, pTarget->u32Id, 0, 0, 0, 0, true);
+                }
+                else
+                {
+                    GaScreenDestroy(pDevExt->pGa, pTarget->u32Id);
+                }
+            }
+
+            break;
+        }
+#endif
         vboxWddmGhDisplayCheckSetInfo(pDevExt);
     } while (0);
@@ -7080,11 +7154,12 @@
             Assert(pCreateContext->Flags.Value <= 2); /* 2 is a GDI context in Win7 */
             pContext->enmType = VBOXWDDM_CONTEXT_TYPE_SYSTEM;
-            for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
-            {
-                vboxWddmDisplaySettingsCheckPos(pDevExt, i);
-            }
 
             if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VBOX)
             {
+                for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+                {
+                    vboxWddmDisplaySettingsCheckPos(pDevExt, i);
+                }
+
 #ifdef VBOX_WITH_CROGL
                 if (!VBOXWDDM_IS_DISPLAYONLY() && pDevExt->f3DEnabled)
@@ -7444,4 +7519,10 @@
 
     PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+#ifdef VBOX_WITH_MESA3D
+    if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
+    {
+        return GaDxgkDdiPresentDisplayOnly(hAdapter, pPresentDisplayOnly);
+    }
+#endif
     PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pPresentDisplayOnly->VidPnSourceId];
     Assert(pSource->AllocData.Addr.SegmentId == 1);
@@ -7518,16 +7599,4 @@
     if (bUpdateRectInited && pSource->bVisible)
     {
-#ifdef VBOX_WITH_MESA3D
-        if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
-        {
-            /** @todo BLIT_GMRFB_TO_SCREEN */
-            GaUpdate(pDevExt->pGa,
-                     UpdateRect.left,
-                     UpdateRect.top,
-                     UpdateRect.right - UpdateRect.left,
-                     UpdateRect.bottom - UpdateRect.top);
-        }
-        else
-#endif
         VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UpdateRect);
     }
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp	(revision 76746)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp	(revision 76790)
@@ -216,12 +216,11 @@
                           int32_t yOrigin,
                           uint32_t u32Width,
-                          uint32_t u32Height)
+                          uint32_t u32Height,
+                          bool fBlank)
 {
     NTSTATUS Status = STATUS_SUCCESS;
 
     const uint32_t cbSubmit =   sizeof(uint32_t)
-                              + sizeof(SVGAScreenObject)
-                              + sizeof(uint32_t)
-                              + sizeof(SVGAFifoCmdDefineGMRFB);
+                              + sizeof(SVGAScreenObject);
     void *pvCmd = SvgaFifoReserve(pSvga, cbSubmit);
     if (pvCmd)
@@ -229,15 +228,6 @@
         SvgaCmdDefineScreen(pvCmd, u32ScreenId, true,
                             xOrigin, yOrigin, u32Width, u32Height,
-                            /* fPrimary = */ false, u32Offset, /* fBlank = */ false);
-        pvCmd = (uint8_t *)pvCmd + sizeof(uint32_t) + sizeof(SVGAScreenObject);
-
-        uint32_t u32BytesPerLine = u32Width * 4;
-        /* Start at offset 0, because we use it to address entire VRAM. */
-        SvgaCmdDefineGMRFB(pvCmd, 0, u32BytesPerLine);
+                            /* fPrimary = */ false, u32Offset, fBlank);
         SvgaFifoCommit(pSvga, cbSubmit);
-
-        /* Save the screen offset. */
-        pSvga->u32ScreenOffset = u32Offset;
-        pSvga->cbScreenPitch = u32BytesPerLine;
     }
     else
@@ -260,4 +250,5 @@
     {
         SvgaCmdDestroyScreen(pvCmd, u32ScreenId);
+        SvgaFifoCommit(pSvga, cbSubmit);
     }
     else
@@ -764,8 +755,11 @@
                             uint32_t u32Width,
                             uint32_t u32Height,
+                            uint32_t u32VRAMOffset,
                             void *pvDst,
                             uint32_t cbDst,
                             uint32_t *pcbOut)
 {
+    RT_NOREF(pSvga);
+
     const uint32_t cbCmdSurfaceDMAToFB =   sizeof(SVGA3dCmdHeader)
                                          + sizeof(SVGA3dCmdSurfaceDMA)
@@ -786,5 +780,5 @@
     }
 
-    Svga3dCmdSurfaceDMAToFB(pvDst, u32Sid, u32Width, u32Height, pSvga->u32ScreenOffset);
+    Svga3dCmdSurfaceDMAToFB(pvDst, u32Sid, u32Width, u32Height, u32VRAMOffset);
     SvgaCmdUpdate((uint8_t *)pvDst + cbCmdSurfaceDMAToFB, 0, 0, u32Width, u32Height);
 
@@ -795,15 +789,16 @@
                          uint32_t u32Sid,
                          uint32_t u32Width,
-                         uint32_t u32Height)
+                         uint32_t u32Height,
+                         uint32_t u32VRAMOffset)
 {
     NTSTATUS Status = STATUS_SUCCESS;
 
     uint32_t cbSubmit = 0;
-    SvgaGenPresentVRAM(pSvga, 0, 0, 0, NULL, 0, &cbSubmit);
+    SvgaGenPresentVRAM(pSvga, 0, 0, 0, 0, NULL, 0, &cbSubmit);
 
     void *pvCmd = SvgaFifoReserve(pSvga, cbSubmit);
     if (pvCmd)
     {
-        Status = SvgaGenPresentVRAM(pSvga, u32Sid, u32Width, u32Height, pvCmd, cbSubmit, NULL);
+        Status = SvgaGenPresentVRAM(pSvga, u32Sid, u32Width, u32Height, u32VRAMOffset, pvCmd, cbSubmit, NULL);
         Assert(Status == STATUS_SUCCESS);
         SvgaFifoCommit(pSvga, cbSubmit);
@@ -878,4 +873,32 @@
 
     return STATUS_SUCCESS;
+}
+
+NTSTATUS SvgaBlitGMRFBToScreen(PVBOXWDDM_EXT_VMSVGA pSvga,
+                               uint32_t idDstScreen,
+                               int32_t xSrc,
+                               int32_t ySrc,
+                               RECT const *pDstRect)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    uint32_t cbSubmit = 0;
+    SvgaGenBlitGMRFBToScreen(pSvga, idDstScreen, xSrc, ySrc, pDstRect,
+                             NULL, 0, &cbSubmit);
+
+    void *pvCmd = SvgaFifoReserve(pSvga, cbSubmit);
+    if (pvCmd)
+    {
+        Status = SvgaGenBlitGMRFBToScreen(pSvga, idDstScreen, xSrc, ySrc, pDstRect,
+                                          pvCmd, cbSubmit, NULL);
+        Assert(Status == STATUS_SUCCESS);
+        SvgaFifoCommit(pSvga, cbSubmit);
+    }
+    else
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    return Status;
 }
 
@@ -1021,7 +1044,18 @@
 NTSTATUS SvgaDefineGMRFB(PVBOXWDDM_EXT_VMSVGA pSvga,
                          uint32_t u32Offset,
-                         uint32_t u32BytesPerLine)
+                         uint32_t u32BytesPerLine,
+                         bool fForce)
 {
     NTSTATUS Status = STATUS_SUCCESS;
+
+    ExAcquireFastMutex(&pSvga->SvgaMutex);
+    if (   !fForce
+        && pSvga->lastGMRFB.u32Offset == u32Offset
+        && pSvga->lastGMRFB.u32BytesPerLine == u32BytesPerLine)
+    {
+        ExReleaseFastMutex(&pSvga->SvgaMutex);
+        return VINF_SUCCESS;
+    }
+    ExReleaseFastMutex(&pSvga->SvgaMutex);
 
     uint32_t cbSubmit = 0;
@@ -1040,4 +1074,12 @@
     {
         Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    if (Status == STATUS_SUCCESS)
+    {
+        ExAcquireFastMutex(&pSvga->SvgaMutex);
+        pSvga->lastGMRFB.u32Offset = u32Offset;
+        pSvga->lastGMRFB.u32BytesPerLine = u32BytesPerLine;
+        ExReleaseFastMutex(&pSvga->SvgaMutex);
     }
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h	(revision 76746)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h	(revision 76790)
@@ -86,10 +86,4 @@
     VMSVGAFIFO fifo;
 
-    /** Offset of the screen relative to VRAM start. */
-    uint32_t u32ScreenOffset;
-
-    /** Scanline width in bytes of the screen. */
-    uint32_t cbScreenPitch;
-
     /** For atomic hardware access. */
     KSPIN_LOCK HwSpinLock;
@@ -104,4 +98,10 @@
     /** SVGA data access. */
     FAST_MUTEX SvgaMutex;
+
+    struct
+    {
+        uint32_t u32Offset;
+        uint32_t u32BytesPerLine;
+    } lastGMRFB;
 
     /** AVL tree for mapping sids to the original sid for shared resources. */
@@ -135,5 +135,6 @@
                           int32_t yOrigin,
                           uint32_t u32Width,
-                          uint32_t u32Height);
+                          uint32_t u32Height,
+                          bool fBlank);
 NTSTATUS SvgaScreenDestroy(PVBOXWDDM_EXT_VMSVGA pSvga,
                            uint32_t u32ScreenId);
@@ -208,4 +209,5 @@
                             uint32_t u32Width,
                             uint32_t u32Height,
+                            uint32_t u32VRAMOffset,
                             void *pvDst,
                             uint32_t cbDst,
@@ -214,5 +216,6 @@
                          uint32_t u32Sid,
                          uint32_t u32Width,
-                         uint32_t u32Height);
+                         uint32_t u32Height,
+                         uint32_t u32VRAMOffset);
 
 NTSTATUS SvgaGenSurfaceDMA(PVBOXWDDM_EXT_VMSVGA pSvga,
@@ -242,4 +245,10 @@
                                   uint32_t *pcbOut);
 
+NTSTATUS SvgaBlitGMRFBToScreen(PVBOXWDDM_EXT_VMSVGA pSvga,
+                               uint32_t idDstScreen,
+                               int32_t xSrc,
+                               int32_t ySrc,
+                               RECT const *pDstRect);
+
 NTSTATUS SvgaGenBlitSurfaceToScreen(PVBOXWDDM_EXT_VMSVGA pSvga,
                                     uint32_t sid,
@@ -266,4 +275,9 @@
                             uint32_t cbDst,
                             uint32_t *pcbOut);
+
+NTSTATUS SvgaDefineGMRFB(PVBOXWDDM_EXT_VMSVGA pSvga,
+                         uint32_t u32Offset,
+                         uint32_t u32BytesPerLine,
+                         bool fForce);
 
 NTSTATUS SvgaGenGMRReport(PVBOXWDDM_EXT_VMSVGA pSvga,
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 76746)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 76790)
@@ -17,4 +17,5 @@
 
 #include "VBoxMPGaWddm.h"
+#include "../VBoxMPVidPn.h"
 
 #include "Svga.h"
@@ -472,7 +473,8 @@
                         int32_t yOrigin,
                         uint32_t u32Width,
-                        uint32_t u32Height)
-{
-    return SvgaScreenDefine(pGaDevExt->hw.pSvga, u32Offset, u32ScreenId, xOrigin, yOrigin, u32Width, u32Height);
+                        uint32_t u32Height,
+                        bool fBlank)
+{
+    return SvgaScreenDefine(pGaDevExt->hw.pSvga, u32Offset, u32ScreenId, xOrigin, yOrigin, u32Width, u32Height, fBlank);
 }
 
@@ -652,7 +654,8 @@
                           uint32_t u32Sid,
                           uint32_t u32Width,
-                          uint32_t u32Height)
-{
-    return SvgaPresentVRAM(pGaDevExt->hw.pSvga, u32Sid, u32Width, u32Height);
+                          uint32_t u32Height,
+                          uint32_t u32VRAMOffset)
+{
+    return SvgaPresentVRAM(pGaDevExt->hw.pSvga, u32Sid, u32Width, u32Height, u32VRAMOffset);
 }
 
@@ -878,13 +881,4 @@
                                               pu8Target, cbTarget, &cbCmd);
             }
-            else
-            {
-                /* Define GMRFB to point to the start of VRAM. */
-                /** @todo This is a workaround for current BlitSurfaceToScreen host implementation
-                 *        expecting that GMRFB will be at the start of VRAM.
-                 */
-                Status = SvgaGenDefineGMRFB(pSvga, 0, pSvga->cbScreenPitch,
-                                            pu8Target, cbTarget, &cbCmd);
-            }
 
             if (Status == STATUS_BUFFER_OVERFLOW)
@@ -1017,23 +1011,4 @@
         pu8Target += cbCmd;
         cbTarget -= cbCmd;
-    }
-
-    if (Status == STATUS_SUCCESS)
-    {
-        if (iSubRect == pPresent->SubRectCnt)
-        {
-            /** @todo No more rects. Have to reset the GMRFB, some code expects this. */
-            Status = SvgaGenDefineGMRFB(pSvga, 0, pSvga->cbScreenPitch,
-                                        pu8Target, cbTarget, &cbCmd);
-            if (Status == STATUS_BUFFER_OVERFLOW)
-            {
-                Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
-            }
-            else
-            {
-                pu8Target += cbCmd;
-                cbTarget -= cbCmd;
-            }
-        }
     }
 
@@ -1988,5 +1963,8 @@
 
             VBOXDISPIFESCAPE_GAPRESENT *pGaPresent = (VBOXDISPIFESCAPE_GAPRESENT *)pEscapeHdr;
-            Status = gaPresent(pDevExt->pGa, pGaPresent->u32Sid, pGaPresent->u32Width, pGaPresent->u32Height);
+            /** @todo This always writes to the start of VRAM. This is a debug function
+             * and is not used for normal operations anymore.
+             */
+            Status = gaPresent(pDevExt->pGa, pGaPresent->u32Sid, pGaPresent->u32Width, pGaPresent->u32Height, 0);
             break;
         }
@@ -2106,2 +2084,175 @@
     return Status;
 }
+
+DECLINLINE(VBOXVIDEOOFFSET) vboxWddmAddrVRAMOffset(VBOXWDDM_ADDR const *pAddr)
+{
+    return (pAddr->offVram != VBOXVIDEOOFFSET_VOID && pAddr->SegmentId) ?
+                (pAddr->SegmentId == 1 ? pAddr->offVram : 0) :
+                VBOXVIDEOOFFSET_VOID;
+}
+
+static void vboxWddmRectCopy(void *pvDst, uint32_t cbDstBytesPerPixel, uint32_t cbDstPitch,
+                             void const *pvSrc, uint32_t cbSrcBytesPerPixel, uint32_t cbSrcPitch,
+                             RECT const *pRect)
+{
+    uint8_t *pu8Dst = (uint8_t *)pvDst;
+    pu8Dst += pRect->top * cbDstPitch + pRect->left * cbDstBytesPerPixel;
+
+    uint8_t const *pu8Src = (uint8_t *)pvSrc;
+    pu8Src += pRect->top * cbSrcPitch + pRect->left * cbSrcBytesPerPixel;
+
+    uint32_t const cbLine = (pRect->right - pRect->left) * cbDstBytesPerPixel;
+    for (INT y = pRect->top; y < pRect->bottom; ++y)
+    {
+        memcpy(pu8Dst, pu8Src, cbLine);
+        pu8Dst += cbDstPitch;
+        pu8Src += cbSrcPitch;
+    }
+}
+
+static NTSTATUS gaSourceBlitToScreen(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_SOURCE *pSource, RECT const *pRect)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PVBOXWDDM_EXT_VMSVGA pSvga = pDevExt->pGa->hw.pSvga;
+
+    VBOXWDDM_TARGET_ITER Iter;
+    VBoxVidPnStTIterInit(pSource, pDevExt->aTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays, &Iter);
+    for (PVBOXWDDM_TARGET pTarget = VBoxVidPnStTIterNext(&Iter);
+         pTarget;
+         pTarget = VBoxVidPnStTIterNext(&Iter))
+    {
+        Status = SvgaBlitGMRFBToScreen(pSvga,
+                                       pTarget->u32Id,
+                                       pRect->left,
+                                       pRect->top,
+                                       pRect);
+        AssertBreak(Status == STATUS_SUCCESS);
+    }
+
+    return Status;
+}
+
+NTSTATUS APIENTRY GaDxgkDdiPresentDisplayOnly(const HANDLE hAdapter,
+                                              const DXGKARG_PRESENT_DISPLAYONLY *pPresentDisplayOnly)
+{
+    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+
+    LOG(("VidPnSourceId %d, pSource %p, BytesPerPixel %d, Pitch %d, Flags 0x%x, NumMoves %d, NumDirtyRects %d, pfn %p\n",
+         pPresentDisplayOnly->VidPnSourceId,
+         pPresentDisplayOnly->pSource,
+         pPresentDisplayOnly->BytesPerPixel,
+         pPresentDisplayOnly->Pitch,
+         pPresentDisplayOnly->Flags.Value,
+         pPresentDisplayOnly->NumMoves,
+         pPresentDisplayOnly->NumDirtyRects,
+         pPresentDisplayOnly->pDirtyRect,
+         pPresentDisplayOnly->pfnPresentDisplayOnlyProgress));
+
+    /*
+     * Copy the image to the corresponding VidPn source allocation.
+     */
+    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pPresentDisplayOnly->VidPnSourceId];
+    AssertReturn(pSource->AllocData.Addr.SegmentId == 1, STATUS_SUCCESS); /* Ignore such VidPn sources. */
+
+    VBOXVIDEOOFFSET const offVRAM = vboxWddmAddrVRAMOffset(&pSource->AllocData.Addr);
+    AssertReturn(offVRAM != VBOXVIDEOOFFSET_VOID, STATUS_SUCCESS); /* Ignore such VidPn sources. */
+
+    for (ULONG i = 0; i < pPresentDisplayOnly->NumMoves; ++i)
+    {
+        RECT *pRect = &pPresentDisplayOnly->pMoves[i].DestRect;
+        vboxWddmRectCopy(pDevExt->pvVisibleVram + offVRAM,    // dst pointer
+                         pSource->AllocData.SurfDesc.bpp / 8, // dst bytes per pixel
+                         pSource->AllocData.SurfDesc.pitch,   // dst pitch
+                         pPresentDisplayOnly->pSource,        // src pointer
+                         pPresentDisplayOnly->BytesPerPixel,  // src bytes per pixel
+                         pPresentDisplayOnly->Pitch,          // src pitch
+                         pRect);
+    }
+
+    for (ULONG i = 0; i < pPresentDisplayOnly->NumDirtyRects; ++i)
+    {
+        RECT *pRect = &pPresentDisplayOnly->pDirtyRect[i];
+        if (pRect->left >= pRect->right || pRect->top >= pRect->bottom)
+        {
+            continue;
+        }
+
+        vboxWddmRectCopy(pDevExt->pvVisibleVram + offVRAM,    // dst pointer
+                         pSource->AllocData.SurfDesc.bpp / 8, // dst bytes per pixel
+                         pSource->AllocData.SurfDesc.pitch,   // dst pitch
+                         pPresentDisplayOnly->pSource,        // src pointer
+                         pPresentDisplayOnly->BytesPerPixel,  // src bytes per pixel
+                         pPresentDisplayOnly->Pitch,          // src pitch
+                         pRect);
+    }
+
+    NTSTATUS Status = STATUS_SUCCESS;
+    if (pSource->bVisible) /// @todo Does/should this have any effect?
+    {
+        PVBOXWDDM_EXT_VMSVGA pSvga = pDevExt->pGa->hw.pSvga;
+        Status = SvgaDefineGMRFB(pSvga, (uint32_t)offVRAM, pSource->AllocData.SurfDesc.pitch, false);
+        if (Status == STATUS_SUCCESS)
+        {
+            for (ULONG i = 0; i < pPresentDisplayOnly->NumMoves; ++i)
+            {
+                RECT *pRect = &pPresentDisplayOnly->pMoves[i].DestRect;
+                Status = gaSourceBlitToScreen(pDevExt, pSource, pRect);
+                AssertBreak(Status == STATUS_SUCCESS);
+            }
+        }
+
+        if (Status == STATUS_SUCCESS)
+        {
+            for (ULONG i = 0; i < pPresentDisplayOnly->NumDirtyRects; ++i)
+            {
+                RECT *pRect = &pPresentDisplayOnly->pDirtyRect[i];
+                Status = gaSourceBlitToScreen(pDevExt, pSource, pRect);
+                AssertBreak(Status == STATUS_SUCCESS);
+            }
+        }
+    }
+
+    return Status;
+}
+
+NTSTATUS GaVidPnSourceReport(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_SOURCE *pSource)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    VBOXVIDEOOFFSET offVRAM = vboxWddmAddrVRAMOffset(&pSource->AllocData.Addr);
+    if (offVRAM == VBOXVIDEOOFFSET_VOID)
+        return STATUS_SUCCESS; /* Ignore such VidPn sources. */
+
+    VBOXWDDM_TARGET_ITER Iter;
+    VBoxVidPnStTIterInit(pSource, pDevExt->aTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays, &Iter);
+    for (PVBOXWDDM_TARGET pTarget = VBoxVidPnStTIterNext(&Iter);
+         pTarget;
+         pTarget = VBoxVidPnStTIterNext(&Iter))
+    {
+        Status = GaScreenDefine(pDevExt->pGa,
+                                (uint32_t)offVRAM,
+                                pTarget->u32Id,
+                                pSource->VScreenPos.x, pSource->VScreenPos.y,
+                                pSource->AllocData.SurfDesc.width, pSource->AllocData.SurfDesc.height,
+                                RT_BOOL(pSource->bBlankedByPowerOff));
+        AssertBreak(Status == STATUS_SUCCESS);
+    }
+
+    return Status;
+}
+
+NTSTATUS GaVidPnSourceCheckPos(PVBOXMP_DEVEXT pDevExt, UINT iSource)
+{
+    POINT Pos = {0};
+    NTSTATUS Status = vboxWddmDisplaySettingsQueryPos(pDevExt, iSource, &Pos);
+    if (NT_SUCCESS(Status))
+    {
+        PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[iSource];
+        if (memcmp(&pSource->VScreenPos, &Pos, sizeof(Pos)))
+        {
+            pSource->VScreenPos = Pos;
+            Status = GaVidPnSourceReport(pDevExt, pSource);
+        }
+    }
+    return Status;
+}
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h	(revision 76746)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h	(revision 76790)
@@ -37,5 +37,6 @@
                         int32_t yOrigin,
                         uint32_t u32Width,
-                        uint32_t u32Height);
+                        uint32_t u32Height,
+                        bool fBlank);
 NTSTATUS GaScreenDestroy(PVBOXWDDM_EXT_GA pGaDevExt,
                          uint32_t u32ScreenId);
@@ -59,4 +60,6 @@
 NTSTATUS APIENTRY GaDxgkDdiBuildPagingBuffer(const HANDLE hAdapter,
                                              DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer);
+NTSTATUS APIENTRY GaDxgkDdiPresentDisplayOnly(const HANDLE hAdapter,
+                                              const DXGKARG_PRESENT_DISPLAYONLY *pPresentDisplayOnly);
 NTSTATUS APIENTRY GaDxgkDdiPresent(const HANDLE hContext,
                                    DXGKARG_PRESENT *pPresent);
@@ -87,3 +90,6 @@
 }
 
+NTSTATUS GaVidPnSourceReport(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_SOURCE *pSource);
+NTSTATUS GaVidPnSourceCheckPos(PVBOXMP_DEVEXT pDevExt, UINT iSource);
+
 #endif /* !GA_INCLUDED_SRC_WINNT_Graphics_Video_mp_wddm_gallium_VBoxMPGaWddm_h */
