Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp	(revision 88831)
@@ -911,5 +911,5 @@
 
 #ifdef VBOX_WITH_VMSVGA3D
-int vmsvgaR3UpdateGBSurface(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBox)
+int vmsvgaR3UpdateGBSurface(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBox)
 {
     PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
@@ -924,5 +924,5 @@
         {
             VMSVGA3D_MAPPED_SURFACE map;
-            rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, pImageId, pBox, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
+            rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, idDXContext, pImageId, pBox, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
             if (RT_SUCCESS(rc))
             {
@@ -959,5 +959,5 @@
 
 
-int vmsvgaR3UpdateGBSurfaceEx(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBoxDst, SVGA3dPoint const *pPtSrc)
+int vmsvgaR3UpdateGBSurfaceEx(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBoxDst, SVGA3dPoint const *pPtSrc)
 {
     /* pPtSrc must be verified by the caller. */
@@ -973,5 +973,5 @@
         {
             VMSVGA3D_MAPPED_SURFACE map;
-            rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, pImageId, pBoxDst, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
+            rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, idDXContext, pImageId, pBoxDst, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
             if (RT_SUCCESS(rc))
             {
@@ -1431,5 +1431,6 @@
     static int idxBitmap = 0;
     char *pszFilename = RTStrAPrintf2("bmp\\%s%d.bmp", pszPrefix, idxBitmap++);
-    vmsvga3dBmpWrite(pszFilename, pMap);
+    int rc = vmsvga3dBmpWrite(pszFilename, pMap);
+    Log(("WriteBmpFile %s %Rrc\n", pszFilename, rc)); RT_NOREF(rc);
     RTStrFree(pszFilename);
 }
@@ -1438,5 +1439,5 @@
 
 /* SVGA_3D_CMD_UPDATE_GB_IMAGE 1101 */
-static void vmsvga3dCmdUpdateGBImage(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBImage const *pCmd)
+static void vmsvga3dCmdUpdateGBImage(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dCmdUpdateGBImage const *pCmd)
 {
 //     ASMBreakpoint();
@@ -1456,5 +1457,6 @@
         {
             VMSVGA3D_MAPPED_SURFACE map;
-            rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, &pCmd->image, &pCmd->box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
+            /** @todo vmsvga3dSurfaceMap */
+            rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, idDXContext, &pCmd->image, &pCmd->box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
             if (RT_SUCCESS(rc))
             {
@@ -1709,5 +1711,5 @@
                         /* Copy the screen target surface to the memory buffer. */
                         VMSVGA3D_MAPPED_SURFACE map;
-                        rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, &entryScreenTarget.image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
+                        rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, SVGA_ID_INVALID, &entryScreenTarget.image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
                         if (RT_SUCCESS(rc))
                         {
@@ -1743,4 +1745,5 @@
 static void vmsvga3dCmdDefineGBSurface_v2(PVGASTATECC pThisCC, SVGA3dCmdDefineGBSurface_v2 const *pCmd)
 {
+//ASMBreakpoint();
     PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
 
@@ -1891,5 +1894,5 @@
             if (pCmd->mobid != SVGA_ID_INVALID)
             {
-                /* Bind a new context. Copy existing data from the guyest backing memory. */
+                /* Bind a new context. Copy existing data from the guest backing memory. */
                 if (pCmd->validContents)
                 {
@@ -4281,5 +4284,5 @@
         SVGA3dCmdUpdateGBImage *pCmd = (SVGA3dCmdUpdateGBImage *)pvCmd;
         VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
-        vmsvga3dCmdUpdateGBImage(pThisCC, pCmd);
+        vmsvga3dCmdUpdateGBImage(pThisCC, idDXContext, pCmd);
         break;
     }
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 88831)
@@ -10,4 +10,6 @@
  *  - Log4 for hex dumps of 3D data.
  *  - Log5 for info about GMR pages.
+ *  - Log6 for DX shaders.
+ *  - Log7 for SVGA command dump.
  *  - LogRel for the usual important stuff.
  *  - LogRel2 for cursor.
@@ -152,4 +154,10 @@
 #include <VBoxVideo.h>
 #include <VBox/bioslogo.h>
+
+#ifdef LOG_ENABLED
+RT_C_DECLS_BEGIN
+#include "svgadump/svga_dump.h"
+RT_C_DECLS_END
+#endif
 
 /* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
@@ -3440,5 +3448,17 @@
         uint32_t cbCmd = sizeof(uint32_t);
 
-        LogFlowFunc(("%s %d\n", vmsvgaR3FifoCmdToString(cmdId), cmdId));
+        LogFlowFunc(("[cid=%d] %s %d\n", (int32_t)idDXContext, vmsvgaR3FifoCmdToString(cmdId), cmdId));
+#ifdef LOG_ENABLED
+        if (SVGA_3D_CMD_BASE <= cmdId && cmdId < SVGA_3D_CMD_MAX)
+        {
+            SVGA3dCmdHeader const *header = (SVGA3dCmdHeader *)pu8Cmd;
+            svga_dump_command(cmdId, (uint8_t *)&header[1], header->size);
+        }
+        else if (cmdId == SVGA_CMD_FENCE)
+        {
+            Log7(("\tSVGA_CMD_FENCE\n"));
+            Log7(("\t\t0x%08x\n", ((uint32_t *)pu8Cmd)[1]));
+        }
+#endif
 
         /* At the end of the switch cbCmd is equal to the total length of the command including the cmdId.
@@ -6064,4 +6084,13 @@
 }
 
+static DECLCALLBACK(size_t) vmsvga3dFloatFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                                                const char *pszType, void const *pvValue,
+                                                int cchWidth, int cchPrecision, unsigned fFlags, void *pvUser)
+{
+    RT_NOREF(pszType, cchWidth, cchPrecision, fFlags, pvUser);
+    double const v = *(double *)&pvValue;
+    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, FLOAT_FMT_STR, FLOAT_FMT_ARGS(v));
+}
+
 /**
  * Initialize the SVGA hardware state
@@ -6076,4 +6105,7 @@
     PVMSVGAR3STATE  pSVGAState;
     int             rc;
+
+    rc = RTStrFormatTypeRegister("float", vmsvga3dFloatFormat, NULL);
+    AssertMsgReturn(RT_SUCCESS(rc) || rc == VERR_ALREADY_EXISTS, ("%Rrc\n", rc), rc);
 
     pThis->svga.cScratchRegion = VMSVGA_SCRATCH_SIZE;
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h	(revision 88831)
@@ -644,6 +644,6 @@
 
 #ifdef VBOX_WITH_VMSVGA3D
-int vmsvgaR3UpdateGBSurface(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBox);
-int vmsvgaR3UpdateGBSurfaceEx(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBoxDst, SVGA3dPoint const *pPtSrc);
+int vmsvgaR3UpdateGBSurface(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBox);
+int vmsvgaR3UpdateGBSurfaceEx(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dSurfaceImageId const *pImageId, SVGA3dBox const *pBoxDst, SVGA3dPoint const *pPtSrc);
 #endif
 
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp	(revision 88831)
@@ -101,4 +101,6 @@
     pDXContext = p3dState->papDXContexts[cid];
     memset(pDXContext, 0, sizeof(*pDXContext));
+    /* 0xFFFFFFFF (SVGA_ID_INVALID) is a better initial value than 0 for most of svgaDXContext fields. */
+    memset(&pDXContext->svgaDXContext, 0xFF, sizeof(pDXContext->svgaDXContext));
     pDXContext->cid = cid;
 
@@ -202,4 +204,12 @@
 
     rc = pSvgaR3State->pFuncsDX->pfnDXSetSingleConstantBuffer(pThisCC, pDXContext, pCmd->slot, pCmd->type, pCmd->sid, pCmd->offsetInBytes, pCmd->sizeInBytes);
+    if (RT_SUCCESS(rc))
+    {
+        uint32_t const idxShaderState = pCmd->type - SVGA3D_SHADERTYPE_MIN;
+        SVGA3dConstantBufferBinding *pCBB = &pDXContext->svgaDXContext.shaderState[idxShaderState].constantBuffers[pCmd->slot];
+        pCBB->sid           = pCmd->sid;
+        pCBB->offsetInBytes = pCmd->offsetInBytes;
+        pCBB->sizeInBytes   = pCmd->sizeInBytes;
+    }
     return rc;
 }
@@ -295,4 +305,18 @@
 
     rc = pSvgaR3State->pFuncsDX->pfnDXDraw(pThisCC, pDXContext, pCmd->vertexCount, pCmd->startVertexLocation);
+#ifdef DUMP_BITMAPS
+    SVGACOTableDXRTViewEntry *pRTViewEntry = &pDXContext->cot.paRTView[pDXContext->svgaDXContext.renderState.renderTargetViewIds[0]];
+    SVGA3dSurfaceImageId image;
+    image.sid = pRTViewEntry->sid;
+    image.face = 0;
+    image.mipmap = 0;
+    VMSVGA3D_MAPPED_SURFACE map;
+    int rc2 = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, idDXContext, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
+    if (RT_SUCCESS(rc2))
+    {
+        vmsvga3dMapWriteBmpFile(&map, "rt-");
+        pSvgaR3State->pFuncsMap->pfnSurfaceUnmap(pThisCC, &image, &map, /* fWritten =  */ false);
+    }
+#endif
     return rc;
 }
@@ -422,4 +446,10 @@
 
     rc = pSvgaR3State->pFuncsDX->pfnDXSetIndexBuffer(pThisCC, pDXContext, pCmd->sid, pCmd->format, pCmd->offset);
+    if (RT_SUCCESS(rc))
+    {
+        pDXContext->svgaDXContext.inputAssembly.indexBufferSid = pCmd->sid;
+        pDXContext->svgaDXContext.inputAssembly.indexBufferOffset = pCmd->offset;
+        pDXContext->svgaDXContext.inputAssembly.indexBufferFormat = pCmd->format;
+    }
     return rc;
 }
@@ -441,4 +471,6 @@
 
     rc = pSvgaR3State->pFuncsDX->pfnDXSetTopology(pThisCC, pDXContext, topology);
+    if (RT_SUCCESS(rc))
+        pDXContext->svgaDXContext.inputAssembly.topology = topology;
     return rc;
 }
@@ -457,6 +489,7 @@
     AssertRCReturn(rc, rc);
 
+    ASSERT_GUEST_RETURN(   depthStencilViewId < pDXContext->cot.cDSView
+                        || depthStencilViewId == SVGA_ID_INVALID, VERR_INVALID_PARAMETER);
     ASSERT_GUEST_RETURN(cRenderTargetViewId < SVGA3D_MAX_RENDER_TARGETS, VERR_INVALID_PARAMETER);
-    ASSERT_GUEST_RETURN(depthStencilViewId < pDXContext->cot.cDSView || depthStencilViewId == SVGA_ID_INVALID, VERR_INVALID_PARAMETER);
     for (uint32_t i = 0; i < cRenderTargetViewId; ++i)
         ASSERT_GUEST_RETURN(   paRenderTargetViewId[i] < pDXContext->cot.cRTView
@@ -465,9 +498,10 @@
 
     rc = pSvgaR3State->pFuncsDX->pfnDXSetRenderTargets(pThisCC, pDXContext, depthStencilViewId, cRenderTargetViewId, paRenderTargetViewId);
-    /// @todo if (RT_SUCCESS(rc))
-    //{
-    //    for (uint32_t i = 0; i < cRenderTargetViewId; ++i)
-    //        pDXContext->svgaDXContext.renderState.renderTargetViewIds[i] = paRenderTargetViewId[i];
-    //}
+    if (RT_SUCCESS(rc))
+    {
+        pDXContext->svgaDXContext.renderState.depthStencilViewId = depthStencilViewId;
+        for (uint32_t i = 0; i < cRenderTargetViewId; ++i)
+            pDXContext->svgaDXContext.renderState.renderTargetViewIds[i] = paRenderTargetViewId[i];
+    }
     return rc;
 }
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp	(revision 88831)
@@ -1268,4 +1268,24 @@
 
 
+static UINT dxBindFlags(SVGA3dSurfaceAllFlags surfaceFlags)
+{
+    /* Catch unimplemented flags. */
+    Assert(!RT_BOOL(surfaceFlags & (SVGA3D_SURFACE_BIND_LOGICOPS | SVGA3D_SURFACE_BIND_RAW_VIEWS)));
+
+    UINT BindFlags = 0;
+
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER)   BindFlags |= D3D11_BIND_VERTEX_BUFFER;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_INDEX_BUFFER)    BindFlags |= D3D11_BIND_INDEX_BUFFER;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER) BindFlags |= D3D11_BIND_CONSTANT_BUFFER;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_SHADER_RESOURCE) BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET)   BindFlags |= D3D11_BIND_RENDER_TARGET;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_DEPTH_STENCIL)   BindFlags |= D3D11_BIND_DEPTH_STENCIL;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)   BindFlags |= D3D11_BIND_STREAM_OUTPUT;
+    if (surfaceFlags & SVGA3D_SURFACE_BIND_UAVIEW)          BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
+
+    return BindFlags;
+}
+
+
 static int vmsvga3dBackSurfaceCreateTexture(PVMSVGA3DSTATE p3dState, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
 {
@@ -1282,9 +1302,135 @@
     AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
 
-    /** @todo Various texture types. */
-    ASMBreakpoint();
-
+    uint32_t const cWidth = pSurface->paMipmapLevels[0].mipmapSize.width;
+    uint32_t const cHeight = pSurface->paMipmapLevels[0].mipmapSize.height;
+    uint32_t const cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
+    uint32_t const numMipLevels = pSurface->cLevels;
+
+    DXGI_FORMAT dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
+    AssertReturn(dxgiFormat != DXGI_FORMAT_UNKNOWN, E_FAIL);
+
+    /*
+     * Create D3D11 texture object.
+     */
+    HRESULT hr = S_OK;
+    if (pSurface->surfaceFlags & SVGA3D_SURFACE_CUBEMAP)
+    {
+        Assert(pSurface->cFaces == 6);
+        Assert(cWidth == cHeight);
+        Assert(cDepth == 1);
+
+        pBackendSurface->enmResType = VMSVGA3D_RESTYPE_CUBE_TEXTURE;
+        AssertFailed(); /** @todo implement */
+        hr = E_FAIL;
+    }
+    else if (pSurface->surfaceFlags & SVGA3D_SURFACE_1D)
+    {
+        AssertFailed(); /** @todo implement */
+        hr = E_FAIL;
+    }
+    else
+    {
+        if (cDepth > 1)
+        {
+            /*
+             * Volume texture.
+             */
+            pBackendSurface->enmResType = VMSVGA3D_RESTYPE_VOLUME_TEXTURE;
+            AssertFailed(); /** @todo implement */
+            hr = E_FAIL;
+        }
+        else
+        {
+            /*
+             * 2D texture.
+             */
+            Assert(pSurface->cFaces == 1);
+
+            D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
+            D3D11_SUBRESOURCE_DATA aInitialData[SVGA3D_MAX_MIP_LEVELS];
+            if (pSurface->paMipmapLevels[0].pSurfaceData)
+            {
+                /** @todo Can happen for a non GBO surface. Test this. */
+                for (uint32_t i = 0; i < numMipLevels; ++i)
+                {
+                    PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
+                    D3D11_SUBRESOURCE_DATA *p = &aInitialData[i];
+                    p->pSysMem          = pMipmapLevel->pSurfaceData;
+                    p->SysMemPitch      = pMipmapLevel->cbSurfacePitch;
+                    p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
+                }
+                paInitialData = &aInitialData[0];
+            }
+
+            D3D11_TEXTURE2D_DESC td;
+            RT_ZERO(td);
+            td.Width              = cWidth;
+            td.Height             = cHeight;
+            td.MipLevels          = numMipLevels;
+            td.ArraySize          = 1; /** @todo */
+            td.Format             = dxgiFormat;
+            td.SampleDesc.Count   = 1;
+            td.SampleDesc.Quality = 0;
+            td.Usage              = D3D11_USAGE_DEFAULT;
+            td.BindFlags          = dxBindFlags(pSurface->surfaceFlags);
+            td.CPUAccessFlags     = 0; /** @todo */
+            td.MiscFlags          = 0; /** @todo */
+            if (   numMipLevels > 1
+                && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
+                td.MiscFlags     |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
+
+            hr = pDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.Texture.pTexture);
+            Assert(SUCCEEDED(hr));
+            if (SUCCEEDED(hr))
+            {
+                /* Map-able texture. */
+                td.MipLevels      = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
+                td.Usage          = D3D11_USAGE_DYNAMIC;
+                td.BindFlags      = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
+                td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+                td.MiscFlags      = 0;
+                hr = pDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.Texture.pDynamicTexture);
+                Assert(SUCCEEDED(hr));
+            }
+
+            if (SUCCEEDED(hr))
+            {
+                /* Staging texture. */
+                td.MipLevels      = 1;
+                td.Usage          = D3D11_USAGE_STAGING;
+                td.BindFlags      = 0; /* No flags allowed. */
+                td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+                td.MiscFlags      = 0;
+                hr = pDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.Texture.pStagingTexture);
+                Assert(SUCCEEDED(hr));
+            }
+
+            pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE;
+        }
+    }
+
+    Assert(hr == S_OK);
+
+    if (pSurface->autogenFilter != SVGA3D_TEX_FILTER_NONE)
+    {
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        /*
+         * Success.
+         */
+        pBackendSurface->enmDxgiFormat = dxgiFormat;
+        pSurface->pBackendSurface = pBackendSurface;
+        pSurface->idAssociatedContext = pDXContext->cid;
+        return VINF_SUCCESS;
+    }
+
+    /* Failure. */
+    D3D_RELEASE(pBackendSurface->u.Texture.pStagingTexture);
+    D3D_RELEASE(pBackendSurface->u.Texture.pDynamicTexture);
+    D3D_RELEASE(pBackendSurface->u.Texture.pTexture);
     RTMemFree(pBackendSurface);
-    return VERR_NOT_IMPLEMENTED;
+    return VERR_NO_MEMORY;
 }
 
@@ -1448,4 +1594,103 @@
 
 
+static HRESULT dxCreateConstantBuffer(DXDEVICE *pDevice, VMSVGA3DSURFACE const *pSurface, PVMSVGA3DBACKENDSURFACE pBackendSurface)
+{
+    D3D11_SUBRESOURCE_DATA *pInitialData = NULL; /** @todo */
+    D3D11_BUFFER_DESC bd;
+    RT_ZERO(bd);
+    bd.ByteWidth           = pSurface->paMipmapLevels[0].cbSurface;
+    bd.Usage               = D3D11_USAGE_DYNAMIC; /** @todo HINT_STATIC */
+    bd.BindFlags           = D3D11_BIND_CONSTANT_BUFFER;
+    bd.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
+    bd.MiscFlags           = 0;
+    bd.StructureByteStride = 0;
+
+    return pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.Buffer.pBuffer);
+}
+
+
+static HRESULT dxCreateBuffer(DXDEVICE *pDevice, VMSVGA3DSURFACE const *pSurface, PVMSVGA3DBACKENDSURFACE pBackendSurface)
+{
+    D3D11_SUBRESOURCE_DATA *pInitialData = NULL; /** @todo */
+    D3D11_BUFFER_DESC bd;
+    RT_ZERO(bd);
+    bd.ByteWidth           = pSurface->paMipmapLevels[0].cbSurface;
+    bd.Usage               = D3D11_USAGE_DYNAMIC; /** @todo HINT_STATIC */
+    bd.BindFlags           = D3D11_BIND_VERTEX_BUFFER
+                           | D3D11_BIND_INDEX_BUFFER;
+    bd.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
+    bd.MiscFlags           = 0;
+    bd.StructureByteStride = 0;
+
+    return pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.Buffer.pBuffer);
+}
+
+
+static int vmsvga3dBackSurfaceCreate(PVMSVGA3DSTATE p3dState, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
+{
+    DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
+    AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
+
+    if (pSurface->pBackendSurface != NULL)
+    {
+        AssertFailed(); /** @todo Should the function not be used like that? */
+        vmsvga3dBackSurfaceDestroy(p3dState, pSurface);
+    }
+
+    PVMSVGA3DBACKENDSURFACE pBackendSurface = (PVMSVGA3DBACKENDSURFACE)RTMemAllocZ(sizeof(VMSVGA3DBACKENDSURFACE));
+    AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
+
+    HRESULT hr;
+
+    /*
+     * Figure out the type of the surface.
+     */
+    if (pSurface->surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)
+    {
+        hr = dxCreateConstantBuffer(pDevice, pSurface, pBackendSurface);
+        if (SUCCEEDED(hr))
+        {
+            pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
+            pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
+        }
+        else
+            D3D_RELEASE(pBackendSurface->u.Buffer.pBuffer);
+    }
+    else if (pSurface->surfaceFlags & (  SVGA3D_SURFACE_BIND_VERTEX_BUFFER
+                                       | SVGA3D_SURFACE_BIND_INDEX_BUFFER
+                                       | SVGA3D_SURFACE_HINT_VERTEXBUFFER
+                                       | SVGA3D_SURFACE_HINT_INDEXBUFFER))
+    {
+        hr = dxCreateBuffer(pDevice, pSurface, pBackendSurface);
+        if (SUCCEEDED(hr))
+        {
+            pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
+            pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
+        }
+        else
+            D3D_RELEASE(pBackendSurface->u.Buffer.pBuffer);
+    }
+    else
+    {
+        AssertFailed(); /** @todo implement */
+        hr = E_FAIL;
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        /*
+         * Success.
+         */
+        pSurface->pBackendSurface = pBackendSurface;
+        pSurface->idAssociatedContext = pDXContext->cid;
+        return VINF_SUCCESS;
+    }
+
+    /* Failure. */
+    RTMemFree(pBackendSurface);
+    return VERR_NO_MEMORY;
+}
+
+
 int vmsvga3dInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
 {
@@ -1790,5 +2035,5 @@
 
 
-static DECLCALLBACK(int) vmsvga3dSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
+static DECLCALLBACK(int) vmsvga3dSurfaceMap(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
                                             VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
 {
@@ -1804,11 +2049,25 @@
     AssertRCReturn(rc, rc);
 
+    PVMSVGA3DDXCONTEXT pDXContext;
     PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
     if (!pBackendSurface)
-        return VERR_INVALID_PARAMETER;
-        // AssertFailedReturn(VERR_INVALID_PARAMETER); /** @todo The caller must directly use the surface memory. */
-
-    PVMSVGA3DDXCONTEXT pDXContext;
-    vmsvga3dDXContextFromCid(pState, pSurface->idAssociatedContext, &pDXContext);
+    {
+        /* This means that the guest uploads new data to the surface.
+         * So the data should be copied either to a host memory buffer,
+         * or to the actual surface.
+         * In the latter case the BackendSurface must be created here.
+         */
+        rc = vmsvga3dDXContextFromCid(pState, idDXContext, &pDXContext);
+        AssertRCReturn(rc, rc);
+
+        rc = vmsvga3dBackSurfaceCreate(pState, pDXContext, pSurface);
+        AssertRCReturn(rc, rc);
+
+        pBackendSurface = pSurface->pBackendSurface;
+    }
+    else
+        vmsvga3dDXContextFromCid(pState, pSurface->idAssociatedContext, &pDXContext);
+
+    Assert(pImage->face == 0 && pImage->mipmap == 0); /** @todo implement. */
 
     DXDEVICE *pDevice = NULL;
@@ -3166,5 +3425,5 @@
 
         VMSVGA3D_MAPPED_SURFACE map;
-        rc = vmsvga3dSurfaceMap(pThisCC, &image, &box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
+        rc = vmsvga3dSurfaceMap(pThisCC, pSurface->idAssociatedContext, &image, &box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
         if (RT_SUCCESS(rc))
         {
@@ -3207,4 +3466,70 @@
 #endif
     }
+    else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE)
+    {
+        /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
+        AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
+
+        uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
+        uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
+        Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
+        Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
+        uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
+        uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
+        AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
+
+        /* vmsvgaR3GmrTransfer verifies uGuestOffset.
+         * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
+         * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
+         */
+        uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
+        AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
+
+        SVGA3dSurfaceImageId image;
+        image.sid = pSurface->id;
+        image.face = uHostFace;
+        image.mipmap = uHostMipmap;
+
+        SVGA3dBox box;
+        box.x = pBox->x;
+        box.y = pBox->y;
+        box.z = 0;
+        box.w = pBox->w;
+        box.h = pBox->h;
+        box.d = 1;
+
+        VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
+                                          ? VMSVGA3D_SURFACE_MAP_WRITE_DISCARD
+                                          : VMSVGA3D_SURFACE_MAP_READ;
+
+        VMSVGA3D_MAPPED_SURFACE map;
+        rc = vmsvga3dSurfaceMap(pThisCC, pSurface->idAssociatedContext, &image, &box, enmMap, &map);
+        if (RT_SUCCESS(rc))
+        {
+            /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
+             * and offset of the first scanline.
+             */
+            uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
+            uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
+            uint32_t const offLockedBuf = 0;
+
+            rc = vmsvgaR3GmrTransfer(pThis,
+                                     pThisCC,
+                                     transfer,
+                                     pu8LockedBuf,
+                                     cbLockedBuf,
+                                     offLockedBuf,
+                                     map.cbRowPitch,
+                                     GuestPtr,
+                                     (uint32_t)uGuestOffset,
+                                     cbGuestPitch,
+                                     cBlocksX * pSurface->cbBlock,
+                                     cBlocksY);
+            AssertRC(rc);
+
+            bool const fWritten = (transfer == SVGA3D_WRITE_HOST_VRAM);
+            vmsvga3dSurfaceUnmap(pThisCC, &image, &map, fWritten);
+        }
+    }
     else
     {
@@ -3384,15 +3709,9 @@
         boxDst.d = 1;
 
-        rc = vmsvgaR3UpdateGBSurfaceEx(pThisCC, &imageId, &boxDst, &ptSrc);
+        rc = vmsvgaR3UpdateGBSurfaceEx(pThisCC, pDXContext->cid, &imageId, &boxDst, &ptSrc);
         AssertRCReturn(rc, rc);
     }
 
     dxConstantBufferSet(pDevice, slot, type, pSurface->pBackendSurface->u.Buffer.pBuffer);
-
-    uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
-    SVGA3dConstantBufferBinding *pCBB = &pDXContext->svgaDXContext.shaderState[idxShaderState].constantBuffers[slot];
-    pCBB->sid           = sid;
-    pCBB->offsetInBytes = offsetInBytes;
-    pCBB->sizeInBytes   = sizeInBytes;
     return VINF_SUCCESS;
 }
@@ -3482,5 +3801,71 @@
     AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
 
-    pDevice->pImmediateContext->Draw(vertexCount, startVertexLocation);
+    if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
+        pDevice->pImmediateContext->Draw(vertexCount, startVertexLocation);
+    else
+    {
+        /*
+         * Emulate SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of a triangle list.
+         */
+
+        /* Make sure that 16 bit indices are enough. 20000 ~= 65536 / 3 */
+        AssertReturn(vertexCount <= 20000, VERR_NOT_SUPPORTED);
+
+        /* Generate indices. */
+        UINT const IndexCount = 3 * (vertexCount - 2); /* 3_per_triangle * num_triangles */
+        UINT const cbAlloc = IndexCount * sizeof(USHORT);
+        USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
+        AssertReturn(paIndices, VERR_NO_MEMORY);
+        USHORT iVertex = 1;
+        for (UINT i = 0; i < IndexCount; i+= 3)
+        {
+            paIndices[i] = 0;
+            paIndices[i + 1] = iVertex;
+            ++iVertex;
+            paIndices[i + 2] = iVertex;
+        }
+
+        D3D11_SUBRESOURCE_DATA InitData;
+        InitData.pSysMem          = paIndices;
+        InitData.SysMemPitch      = cbAlloc;
+        InitData.SysMemSlicePitch = cbAlloc;
+
+        D3D11_BUFFER_DESC bd;
+        RT_ZERO(bd);
+        bd.ByteWidth           = cbAlloc;
+        bd.Usage               = D3D11_USAGE_IMMUTABLE;
+        bd.BindFlags           = D3D11_BIND_INDEX_BUFFER;
+        //bd.CPUAccessFlags      = 0;
+        //bd.MiscFlags           = 0;
+        //bd.StructureByteStride = 0;
+
+        ID3D11Buffer *pIndexBuffer = 0;
+        HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
+        Assert(SUCCEEDED(hr));RT_NOREF(hr);
+
+        /* Save the current index buffer. */
+        ID3D11Buffer *pSavedIndexBuffer = 0;
+        DXGI_FORMAT  SavedFormat = DXGI_FORMAT_UNKNOWN;
+        UINT         SavedOffset = 0;
+        pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
+
+        /* Set up the device state. */
+        pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
+        pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+        UINT const StartIndexLocation = 0;
+        INT const BaseVertexLocation = startVertexLocation;
+        pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
+
+        /* Restore the device state. */
+        pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+        pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
+        D3D_RELEASE(pSavedIndexBuffer);
+
+        /* Cleanup. */
+        D3D_RELEASE(pIndexBuffer);
+        RTMemFree(paIndices);
+    }
+
     return VINF_SUCCESS;
 }
@@ -3495,4 +3880,6 @@
     AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
 
+    Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
+
     pDevice->pImmediateContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
     return VINF_SUCCESS;
@@ -3502,4 +3889,5 @@
 static DECLCALLBACK(int) vmsvga3dBackDXDrawInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
 {
+    Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
     PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
 
@@ -3512,4 +3900,5 @@
 static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
 {
+    Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
     PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
 
@@ -3522,4 +3911,5 @@
 static DECLCALLBACK(int) vmsvga3dBackDXDrawAuto(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
 {
+    Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
     PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
 
@@ -3617,5 +4007,5 @@
                 box.d = 1;
 
-                rc = vmsvgaR3UpdateGBSurface(pThisCC, &imageId, &box);
+                rc = vmsvgaR3UpdateGBSurface(pThisCC, pDXContext->cid, &imageId, &box);
                 AssertRCReturn(rc, rc);
             }
@@ -3684,5 +4074,5 @@
             box.d = 1;
 
-            rc = vmsvgaR3UpdateGBSurface(pThisCC, &imageId, &box);
+            rc = vmsvgaR3UpdateGBSurface(pThisCC, pDXContext->cid, &imageId, &box);
             AssertRCReturn(rc, rc);
         }
@@ -3699,9 +4089,4 @@
 
     pDevice->pImmediateContext->IASetIndexBuffer(pResource, enmDxgiFormat, offset);
-
-    pDXContext->svgaDXContext.inputAssembly.indexBufferSid = sid;
-    pDXContext->svgaDXContext.inputAssembly.indexBufferOffset = offset;
-    pDXContext->svgaDXContext.inputAssembly.indexBufferFormat = format;
-
     return VINF_SUCCESS;
 }
@@ -3717,5 +4102,5 @@
         D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
         D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
-        D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11 */
+        D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11. */
         D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
         D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
@@ -3766,7 +4151,6 @@
     AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
 
-    D3D11_PRIMITIVE_TOPOLOGY enmTopology = dxTopology(topology);
+    D3D11_PRIMITIVE_TOPOLOGY const enmTopology = dxTopology(topology);
     pDevice->pImmediateContext->IASetPrimitiveTopology(enmTopology);
-    pDXContext->svgaDXContext.inputAssembly.topology = topology;
     return VINF_SUCCESS;
 }
@@ -3784,5 +4168,5 @@
     for (uint32_t i = 0; i < cRenderTargetViewId; ++i)
     {
-        SVGA3dRenderTargetViewId renderTargetViewId = paRenderTargetViewId[i];
+        SVGA3dRenderTargetViewId const renderTargetViewId = paRenderTargetViewId[i];
         if (renderTargetViewId != SVGA3D_INVALID_ID)
         {
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp	(revision 88831)
@@ -21,4 +21,5 @@
 *********************************************************************************************************************************/
 #define LOG_GROUP LOG_GROUP_DEV_VMSVGA
+#include <VBox/AssertGuest.h>
 #include <VBox/vmm/pdmdev.h>
 #include <iprt/errcore.h>
@@ -67,6 +68,6 @@
              numMipLevels, pMipLevel0Size->width, pMipLevel0Size->height, pMipLevel0Size->depth));
 
-    AssertReturn(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
-    AssertReturn(numMipLevels >= 1, VERR_INVALID_PARAMETER);
+    ASSERT_GUEST_RETURN(sid < SVGA3D_MAX_SURFACE_IDS, VERR_INVALID_PARAMETER);
+    ASSERT_GUEST_RETURN(numMipLevels >= 1 && numMipLevels < SVGA3D_MAX_MIP_LEVELS, VERR_INVALID_PARAMETER);
 
     if (sid >= pState->cSurfaces)
@@ -304,12 +305,51 @@
 #endif
 
-    LogFunc(("surface hint(s):%s%s%s%s%s%s\n",
-            (surfaceFlags & SVGA3D_SURFACE_HINT_INDEXBUFFER)  ? " SVGA3D_SURFACE_HINT_INDEXBUFFER"  : "",
-            (surfaceFlags & SVGA3D_SURFACE_HINT_VERTEXBUFFER) ? " SVGA3D_SURFACE_HINT_VERTEXBUFFER"  : "",
-            (surfaceFlags & SVGA3D_SURFACE_HINT_TEXTURE)      ? " SVGA3D_SURFACE_HINT_TEXTURE"  : "",
-            (surfaceFlags & SVGA3D_SURFACE_HINT_DEPTHSTENCIL) ? " SVGA3D_SURFACE_HINT_DEPTHSTENCIL"  : "",
-            (surfaceFlags & SVGA3D_SURFACE_HINT_RENDERTARGET) ? " SVGA3D_SURFACE_HINT_RENDERTARGET"  : "",
-            (surfaceFlags & SVGA3D_SURFACE_CUBEMAP)           ? " SVGA3D_SURFACE_CUBEMAP"  : ""
+#ifdef LOG_ENABLED
+    SVGA3dSurfaceAllFlags const f = surfaceFlags;
+    LogFunc(("surface flags:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s 0x%RX64\n",
+            (f & SVGA3D_SURFACE_CUBEMAP)              ? " CUBEMAP"  : "",
+            (f & SVGA3D_SURFACE_HINT_STATIC)          ? " HINT_STATIC"  : "",
+            (f & SVGA3D_SURFACE_HINT_DYNAMIC)         ? " HINT_DYNAMIC"  : "",
+            (f & SVGA3D_SURFACE_HINT_INDEXBUFFER)     ? " HINT_INDEXBUFFER"  : "",
+            (f & SVGA3D_SURFACE_HINT_VERTEXBUFFER)    ? " HINT_VERTEXBUFFER"  : "",
+            (f & SVGA3D_SURFACE_HINT_TEXTURE)         ? " HINT_TEXTURE"  : "",
+            (f & SVGA3D_SURFACE_HINT_RENDERTARGET)    ? " HINT_RENDERTARGET"  : "",
+            (f & SVGA3D_SURFACE_HINT_DEPTHSTENCIL)    ? " HINT_DEPTHSTENCIL"  : "",
+            (f & SVGA3D_SURFACE_HINT_WRITEONLY)       ? " HINT_WRITEONLY"  : "",
+            (f & SVGA3D_SURFACE_DEAD2)                ? " DEAD2"  : "",
+            (f & SVGA3D_SURFACE_AUTOGENMIPMAPS)       ? " AUTOGENMIPMAPS"  : "",
+            (f & SVGA3D_SURFACE_DEAD1)                ? " DEAD1"  : "",
+            (f & SVGA3D_SURFACE_MOB_PITCH)            ? " MOB_PITCH"  : "",
+            (f & SVGA3D_SURFACE_INACTIVE)             ? " INACTIVE"  : "",
+            (f & SVGA3D_SURFACE_HINT_RT_LOCKABLE)     ? " HINT_RT_LOCKABLE"  : "",
+            (f & SVGA3D_SURFACE_VOLUME)               ? " VOLUME"  : "",
+            (f & SVGA3D_SURFACE_SCREENTARGET)         ? " SCREENTARGET"  : "",
+            (f & SVGA3D_SURFACE_ALIGN16)              ? " ALIGN16"  : "",
+            (f & SVGA3D_SURFACE_1D)                   ? " 1D"  : "",
+            (f & SVGA3D_SURFACE_ARRAY)                ? " ARRAY"  : "",
+            (f & SVGA3D_SURFACE_BIND_VERTEX_BUFFER)   ? " BIND_VERTEX_BUFFER"  : "",
+            (f & SVGA3D_SURFACE_BIND_INDEX_BUFFER)    ? " BIND_INDEX_BUFFER"  : "",
+            (f & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER) ? " BIND_CONSTANT_BUFFER"  : "",
+            (f & SVGA3D_SURFACE_BIND_SHADER_RESOURCE) ? " BIND_SHADER_RESOURCE"  : "",
+            (f & SVGA3D_SURFACE_BIND_RENDER_TARGET)   ? " BIND_RENDER_TARGET"  : "",
+            (f & SVGA3D_SURFACE_BIND_DEPTH_STENCIL)   ? " BIND_DEPTH_STENCIL"  : "",
+            (f & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)   ? " BIND_STREAM_OUTPUT"  : "",
+            (f & SVGA3D_SURFACE_STAGING_UPLOAD)       ? " STAGING_UPLOAD"  : "",
+            (f & SVGA3D_SURFACE_STAGING_DOWNLOAD)     ? " STAGING_DOWNLOAD"  : "",
+            (f & SVGA3D_SURFACE_HINT_INDIRECT_UPDATE) ? " HINT_INDIRECT_UPDATE"  : "",
+            (f & SVGA3D_SURFACE_TRANSFER_FROM_BUFFER) ? " TRANSFER_FROM_BUFFER"  : "",
+            (f & SVGA3D_SURFACE_RESERVED1)            ? " RESERVED1"  : "",
+            (f & SVGA3D_SURFACE_MULTISAMPLE)          ? " MULTISAMPLE"  : "",
+            (f & SVGA3D_SURFACE_BIND_UAVIEW)          ? " BIND_UAVIEW"  : "",
+            (f & SVGA3D_SURFACE_TRANSFER_TO_BUFFER)   ? " TRANSFER_TO_BUFFER"  : "",
+            (f & SVGA3D_SURFACE_BIND_LOGICOPS)        ? " BIND_LOGICOPS"  : "",
+            (f & SVGA3D_SURFACE_BIND_RAW_VIEWS)       ? " BIND_RAW_VIEWS"  : "",
+            (f & SVGA3D_SURFACE_BUFFER_STRUCTURED)    ? " BUFFER_STRUCTURED"  : "",
+            (f & SVGA3D_SURFACE_DRAWINDIRECT_ARGS)    ? " DRAWINDIRECT_ARGS"  : "",
+            (f & SVGA3D_SURFACE_RESOURCE_CLAMP)       ? " RESOURCE_CLAMP"  : "",
+            (f & SVGA3D_SURFACE_FLAG_MAX)             ? " FLAG_MAX"  : "",
+            f & ~(SVGA3D_SURFACE_FLAG_MAX - 1ULL)
            ));
+#endif
 
     Assert(!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface));
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 88830)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 88831)
@@ -38,4 +38,6 @@
 /** Arbitrary upper limit; 2GB enough for 32768x16384*4. */
 #define SVGA3D_MAX_SURFACE_MEM_SIZE             0x80000000
+/** Arbitrary upper limit. [0,15] is enough for 2^15=32768x32768. */
+#define SVGA3D_MAX_MIP_LEVELS                   16
 
 
@@ -67,4 +69,6 @@
 } VMSVGA3D_MAPPED_SURFACE;
 
+/* Write render targets to bitmaps. */
+//#define DUMP_BITMAPS
 #ifdef DUMP_BITMAPS
 void vmsvga3dMapWriteBmpFile(VMSVGA3D_MAPPED_SURFACE const *pMap, char const *pszPrefix);
@@ -279,5 +283,5 @@
 typedef struct
 {
-    DECLCALLBACKMEMBER(int, pfnSurfaceMap,   (PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox, VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap));
+    DECLCALLBACKMEMBER(int, pfnSurfaceMap,   (PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox, VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap));
     DECLCALLBACKMEMBER(int, pfnSurfaceUnmap, (PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten));
 } VMSVGA3DBACKENDFUNCSMAP;
