Index: trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 29895)
@@ -734,17 +734,4 @@
 }
 
-static uint32_t vboxFormatToFourcc(D3DDDIFORMAT format)
-{
-    uint32_t uFormat = (uint32_t)format;
-    /* assume that in case both four bytes are non-zero, this is a fourcc */
-    if ((format & 0xff000000)
-            && (format & 0x00ff0000)
-            && (format & 0x0000ff00)
-            && (format & 0x000000ff)
-            )
-        return uFormat;
-    return 0;
-}
-
 int vboxCapsInit(PVBOXWDDMDISP_ADAPTER pAdapter)
 {
@@ -832,5 +819,5 @@
                     for (uint32_t j = 0; j < pVhwa->Settings.cFormats; ++j)
                     {
-                        uint32_t fourcc = vboxFormatToFourcc(pVhwa->Settings.aFormats[j]);
+                        uint32_t fourcc = vboxWddmFormatToFourcc(pVhwa->Settings.aFormats[j]);
                         if (fourcc)
                         {
@@ -1600,4 +1587,5 @@
                 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pAllocInfo->SurfDesc.bpp);
 
+            pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
             pAllocInfo->SurfDesc.depth = pSurf->Depth;
             pAllocInfo->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 29895)
@@ -157,4 +157,5 @@
 {
     VBOXVHWA_INFO Settings;
+    bool cOverlaysCreated;
 } VBOXWDDM_VHWA;
 #endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h	(revision 29895)
@@ -50,4 +50,5 @@
     UINT depth;
     UINT slicePitch;
+    UINT cbSize;
     D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
     D3DDDI_RATIONAL RefreshRate;
@@ -159,4 +160,17 @@
 }
 
+DECLINLINE(uint32_t) vboxWddmFormatToFourcc(D3DDDIFORMAT format)
+{
+    uint32_t uFormat = (uint32_t)format;
+    /* assume that in case both four bytes are non-zero, this is a fourcc */
+    if ((format & 0xff000000)
+            && (format & 0x00ff0000)
+            && (format & 0x0000ff00)
+            && (format & 0x000000ff)
+            )
+        return uFormat;
+    return 0;
+}
+
 #define VBOXWDDM_ROUNDBOUND(_v, _b) (((_v) + ((_b) - 1)) & ~((_b) - 1))
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp	(revision 29895)
@@ -413,2 +413,204 @@
     }
 }
+
+int vboxVhwaHlpTranslateFormat(VBOXVHWA_PIXELFORMAT *pFormat, D3DDDIFORMAT enmFormat)
+{
+    pFormat->Reserved = 0;
+    switch (enmFormat)
+    {
+        case D3DDDIFMT_A8R8G8B8:
+        case D3DDDIFMT_X8R8G8B8:
+            pFormat->flags = VBOXVHWA_PF_RGB;
+            pFormat->c.rgbBitCount = 32;
+            pFormat->m1.rgbRBitMask = 0xff0000;
+            pFormat->m2.rgbGBitMask = 0xff00;
+            pFormat->m3.rgbBBitMask = 0xff;
+            /* always zero for now */
+            pFormat->m4.rgbABitMask = 0;
+            return VINF_SUCCESS;
+        case D3DDDIFMT_R8G8B8:
+            pFormat->flags = VBOXVHWA_PF_RGB;
+            pFormat->c.rgbBitCount = 24;
+            pFormat->m1.rgbRBitMask = 0xff0000;
+            pFormat->m2.rgbGBitMask = 0xff00;
+            pFormat->m3.rgbBBitMask = 0xff;
+            /* always zero for now */
+            pFormat->m4.rgbABitMask = 0;
+            return VINF_SUCCESS;
+        case D3DDDIFMT_R5G6B5:
+            pFormat->flags = VBOXVHWA_PF_RGB;
+            pFormat->c.rgbBitCount = 16;
+            pFormat->m1.rgbRBitMask = 0xf800;
+            pFormat->m2.rgbGBitMask = 0x7e0;
+            pFormat->m3.rgbBBitMask = 0x1f;
+            /* always zero for now */
+            pFormat->m4.rgbABitMask = 0;
+            return VINF_SUCCESS;
+        case D3DDDIFMT_P8:
+        case D3DDDIFMT_A8:
+        case D3DDDIFMT_X1R5G5B5:
+        case D3DDDIFMT_A1R5G5B5:
+        case D3DDDIFMT_A4R4G4B4:
+        case D3DDDIFMT_R3G3B2:
+        case D3DDDIFMT_A8R3G3B2:
+        case D3DDDIFMT_X4R4G4B4:
+        case D3DDDIFMT_A2B10G10R10:
+        case D3DDDIFMT_A8B8G8R8:
+        case D3DDDIFMT_X8B8G8R8:
+        case D3DDDIFMT_G16R16:
+        case D3DDDIFMT_A2R10G10B10:
+        case D3DDDIFMT_A16B16G16R16:
+        case D3DDDIFMT_A8P8:
+        default:
+        {
+            uint32_t fourcc = vboxWddmFormatToFourcc(enmFormat);
+            Assert(fourcc);
+            if (fourcc)
+            {
+                pFormat->flags = VBOXVHWA_PF_FOURCC;
+                pFormat->fourCC = fourcc;
+                return VINF_SUCCESS;
+            }
+            return VERR_NOT_SUPPORTED;
+        }
+    }
+}
+
+int vboxVhwaHlpCreateSurface(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf,
+        uint32_t fFlags, uint32_t cBackBuffers, uint32_t fSCaps,
+        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
+{
+    /* the first thing we need is to post create primary */
+    VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId,
+                VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE));
+    Assert(pCmd);
+    if(pCmd)
+    {
+        VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
+        int rc = VINF_SUCCESS;
+
+        memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE));
+
+        pBody->SurfInfo.height = pSurf->SurfDesc.height;
+        pBody->SurfInfo.width = pSurf->SurfDesc.width;
+        pBody->SurfInfo.flags |= VBOXVHWA_SD_HEIGHT | VBOXVHWA_SD_WIDTH;
+        if (fFlags & VBOXVHWA_SD_PITCH)
+        {
+            pBody->SurfInfo.pitch = pSurf->SurfDesc.pitch;
+            pBody->SurfInfo.flags |= VBOXVHWA_SD_PITCH;
+            pBody->SurfInfo.sizeX = pSurf->SurfDesc.cbSize;
+            pBody->SurfInfo.sizeY = 1;
+        }
+        if (cBackBuffers)
+        {
+            pBody->SurfInfo.cBackBuffers = cBackBuffers;
+            pBody->SurfInfo.flags |= VBOXVHWA_SD_BACKBUFFERCOUNT;
+        }
+        else
+            pBody->SurfInfo.cBackBuffers = 0;
+        pBody->SurfInfo.Reserved = 0;
+        /* @todo: color keys */
+//                        pBody->SurfInfo.DstOverlayCK;
+//                        pBody->SurfInfo.DstBltCK;
+//                        pBody->SurfInfo.SrcOverlayCK;
+//                        pBody->SurfInfo.SrcBltCK;
+        rc = vboxVhwaHlpTranslateFormat(&pBody->SurfInfo.PixelFormat, pSurf->SurfDesc.format);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT;
+            pBody->SurfInfo.surfCaps = fSCaps;
+            pBody->SurfInfo.flags |= VBOXVHWA_SD_CAPS;
+            pBody->SurfInfo.offSurface = pSurf->offVram;
+
+            vboxVhwaCommandSubmit(pDevExt, pCmd);
+            Assert(pCmd->rc == VINF_SUCCESS);
+            if(pCmd->rc == VINF_SUCCESS)
+            {
+                if (!(fFlags & VBOXVHWA_SD_PITCH))
+                {
+                    /* should be set by host */
+                    Assert(pBody->SurfInfo.flags & VBOXVHWA_SD_PITCH);
+                    pSurf->SurfDesc.cbSize = pBody->SurfInfo.sizeX * pBody->SurfInfo.sizeY;
+                    Assert(pSurf->SurfDesc.cbSize);
+                    pSurf->SurfDesc.pitch = pBody->SurfInfo.pitch;
+                    Assert(pSurf->SurfDesc.pitch);
+                }
+                else
+                {
+                    Assert(pSurf->SurfDesc.cbSize ==  pBody->SurfInfo.sizeX);
+                    Assert(pBody->SurfInfo.sizeY == 1);
+                    Assert(pBody->SurfInfo.pitch == pSurf->SurfDesc.pitch);
+                    if (pSurf->SurfDesc.cbSize !=  pBody->SurfInfo.sizeX
+                            || pBody->SurfInfo.sizeY != 1
+                            || pBody->SurfInfo.pitch != pSurf->SurfDesc.pitch)
+                    {
+                        rc = VERR_INVALID_PARAMETER;
+                    }
+                }
+
+                if (RT_SUCCESS(rc))
+                {
+                        pSurf->hHostHandle = pBody->SurfInfo.hSurf;
+                }
+            }
+            else
+                rc = pCmd->rc;
+        }
+        vboxVhwaCommandFree(pDevExt, pCmd);
+        return rc;
+    }
+
+    return VERR_OUT_OF_RESOURCES;
+}
+
+int vboxVhwaHlpCreatePriary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
+{
+    Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
+    if (!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED))
+        return VERR_NOT_SUPPORTED;
+
+#ifdef VBOXWDDM_RENDER_FROM_SHADOW
+    PVBOXWDDM_ALLOCATION pFbSurf = pSource->pShadowAllocation;
+#else
+    PVBOXWDDM_ALLOCATION pFbSurf = pSource->pPrimaryAllocation;
+#endif
+
+    Assert(!pSource->Vhwa.cOverlaysCreated);
+    if (pSource->Vhwa.cOverlaysCreated)
+    {
+        Assert(pFbSurf->hHostHandle);
+        if (pFbSurf->hHostHandle)
+            return VINF_ALREADY_INITIALIZED;
+        return VERR_INVALID_STATE;
+    }
+
+    int rc = vboxVhwaHlpCreateSurface(pDevExt, pFbSurf,
+            VBOXVHWA_SD_PITCH, 0, VBOXVHWA_SCAPS_PRIMARYSURFACE | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM,
+            VidPnSourceId);
+    AssertRC(rc);
+    return rc;
+}
+
+int vboxVhwaHlpCreateOverlay(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf, uint32_t cBackBuffers, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
+{
+    Assert(VidPnSourceId < pDevExt->cSources);
+    if (VidPnSourceId >= pDevExt->cSources)
+        return VERR_INVALID_PARAMETER;
+
+    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
+
+    int rc = vboxVhwaHlpCreatePriary(pDevExt, pSource, VidPnSourceId);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        rc = vboxVhwaHlpCreateSurface(pDevExt, pSurf,
+                    0, cBackBuffers, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX,
+                    VidPnSourceId);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+            ++pSource->Vhwa.cOverlaysCreated;
+    }
+
+    return rc;
+}
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h	(revision 29895)
@@ -54,3 +54,5 @@
 void vboxVHWAFree(PDEVICE_EXTENSION pDevExt);
 
+int vboxVhwaHlpCreateOverlay(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf, uint32_t cBackBuffers, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId);
+
 #endif /* #ifndef ___VBoxVideoVhwa_h___ */
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 29895)
@@ -1406,5 +1406,5 @@
 }
 
-NTSTATUS vboxWddmCreateAllocation(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONINFO* pAllocationInfo)
+NTSTATUS vboxWddmCreateAllocation(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_RCINFO pRcInfo, DXGK_ALLOCATIONINFO* pAllocationInfo)
 {
     PAGED_CODE();
@@ -1429,5 +1429,5 @@
             pAllocationInfo->PrivateDriverDataSize = 0;
             pAllocationInfo->Alignment = 0;
-            pAllocationInfo->Size = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
+            pAllocationInfo->Size = pAllocInfo->SurfDesc.cbSize;
             pAllocationInfo->PitchAlignedSize = 0;
             pAllocationInfo->HintedBank.Value = 0;
@@ -1453,7 +1453,27 @@
 #endif
                     break;
+                case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                    Assert(pRcInfo);
+                    if (pRcInfo)
+                    {
+                        Assert(pRcInfo->cAllocInfos);
+                        if (pRcInfo->cAllocInfos)
+                        {
+                            if (pRcInfo->RcDesc.fFlags.Overlay)
+                            {
+                                int rc = vboxVhwaHlpCreateOverlay(pDevExt, pAllocation, pRcInfo->cAllocInfos - 1, pRcInfo->RcDesc.VidPnSourceId);
+                                AssertRC(rc);
+                                if (RT_FAILURE(rc))
+                                    Status = STATUS_UNSUCCESSFUL;
+                            }
+                        }
+                        else
+                            Status = STATUS_INVALID_PARAMETER;
+                    }
+#endif
+                    /* do not break to set CPU visibility flag */
                 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
                 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
-                case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
                     pAllocationInfo->Flags.Value = 0;
                     pAllocationInfo->Flags.CpuVisible = 1;
@@ -1496,27 +1516,41 @@
     vboxVDbgBreakFv();
 
+    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
     NTSTATUS Status = STATUS_SUCCESS;
+    PVBOXWDDM_RCINFO pRcInfo = NULL;
 
     if (pCreateAllocation->PrivateDriverDataSize)
     {
+        Assert(pCreateAllocation->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
+        Assert(pCreateAllocation->pPrivateDriverData);
+        if (pCreateAllocation->PrivateDriverDataSize >= sizeof (VBOXWDDM_RCINFO))
+        {
+            pRcInfo = (PVBOXWDDM_RCINFO)pCreateAllocation->pPrivateDriverData;
+            Assert(pRcInfo->RcDesc.VidPnSourceId < pDevExt->cSources);
+            Assert(pRcInfo->cAllocInfos == pCreateAllocation->NumAllocations);
+        }
+        else
+            Status = STATUS_INVALID_PARAMETER;
         /* @todo: Implement Resource Data Handling */
         drprintf((__FUNCTION__ ": WARNING: Implement Resource Data Handling\n"));
     }
 
-    for (UINT i = 0; i < pCreateAllocation->NumAllocations; ++i)
-    {
-        Status = vboxWddmCreateAllocation((PDEVICE_EXTENSION)hAdapter, &pCreateAllocation->pAllocationInfo[i]);
-        Assert(Status == STATUS_SUCCESS);
-        if (Status != STATUS_SUCCESS)
-        {
-            drprintf((__FUNCTION__ ": ERROR: vboxWddmCreateAllocation error (0x%x)\n", Status));
-            /* note: i-th allocation is expected to be cleared in a fail handling code above */
-            for (UINT j = 0; j < i; ++j)
-            {
-                vboxWddmDestroyAllocation((PDEVICE_EXTENSION)hAdapter, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
-            }
-        }
-    }
-
+    if (Status == STATUS_SUCCESS)
+    {
+        for (UINT i = 0; i < pCreateAllocation->NumAllocations; ++i)
+        {
+            Status = vboxWddmCreateAllocation(pDevExt, pRcInfo, &pCreateAllocation->pAllocationInfo[i]);
+            Assert(Status == STATUS_SUCCESS);
+            if (Status != STATUS_SUCCESS)
+            {
+                drprintf((__FUNCTION__ ": ERROR: vboxWddmCreateAllocation error (0x%x)\n", Status));
+                /* note: i-th allocation is expected to be cleared in a fail handling code above */
+                for (UINT j = 0; j < i; ++j)
+                {
+                    vboxWddmDestroyAllocation(pDevExt, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
+                }
+            }
+        }
+    }
     dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
 
@@ -1610,4 +1644,5 @@
                 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->SurfDesc.format);
                 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width, pAllocInfo->SurfDesc.bpp);
+                pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
                 pAllocInfo->SurfDesc.depth = 0;
                 pAllocInfo->SurfDesc.slicePitch = 0;
@@ -1641,4 +1676,5 @@
                     pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->SurfDesc.format);
                     pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pAllocInfo->SurfDesc.bpp);
+                    pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
                     pAllocInfo->SurfDesc.depth = 0;
                     pAllocInfo->SurfDesc.slicePitch = 0;
@@ -1672,4 +1708,5 @@
                 pAllocInfo->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->SurfDesc.format);
                 pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width, pAllocInfo->SurfDesc.bpp);
+                pAllocInfo->SurfDesc.cbSize = pAllocInfo->SurfDesc.pitch * pAllocInfo->SurfDesc.height;
                 pAllocInfo->SurfDesc.depth = 0;
                 pAllocInfo->SurfDesc.slicePitch = 0;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h	(revision 29894)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h	(revision 29895)
@@ -54,4 +54,7 @@
     UINT SegmentId;
     VBOXVIDEOOFFSET offVram;
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    VBOXVHWA_SURFHANDLE hHostHandle;
+#endif
     BOOLEAN bVisible;
     BOOLEAN bAssigned;
