Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp	(revision 102808)
@@ -1299,7 +1299,9 @@
 
     /* Create the surface. */
+    SVGA3dMSPattern const multisamplePattern = pCmd->multisampleCount > 1 ? SVGA3D_MS_PATTERN_STANDARD : SVGA3D_MS_PATTERN_NONE;
+    SVGA3dMSQualityLevel const qualityLevel = pCmd->multisampleCount > 1 ? SVGA3D_MS_QUALITY_FULL : SVGA3D_MS_QUALITY_NONE;
     vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
-                          pCmd->multisampleCount, pCmd->autogenFilter,
-                          pCmd->face[0].numMipLevels, &paMipLevelSizes[0], /* arraySize = */ 0, /* fAllocMipLevels = */ true);
+                          pCmd->multisampleCount, multisamplePattern, qualityLevel, pCmd->autogenFilter,
+                          pCmd->face[0].numMipLevels, &paMipLevelSizes[0], /* arraySize = */ 0, /* bufferByteStride = */ 0, /* fAllocMipLevels = */ true);
 }
 
@@ -1375,4 +1377,9 @@
     // entry.arraySize = 0;
     // entry.mobPitch = 0;
+    // entry.surface2Flags = 0;
+    // entry.multisamplePattern = 0;
+    // entry.qualityLevel = 0;
+    // entry.bufferByteStride = 0;
+    // entry.minLOD = 0;
     int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                                  pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
@@ -1380,7 +1387,9 @@
     {
         /* Create the host surface. */
+        SVGA3dMSPattern const multisamplePattern = pCmd->multisampleCount > 1 ? SVGA3D_MS_PATTERN_STANDARD : SVGA3D_MS_PATTERN_NONE;
+        SVGA3dMSQualityLevel const qualityLevel = pCmd->multisampleCount > 1 ? SVGA3D_MS_QUALITY_FULL : SVGA3D_MS_QUALITY_NONE;
         vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
-                              pCmd->multisampleCount, pCmd->autogenFilter,
-                              pCmd->numMipLevels, &pCmd->size, /* arraySize = */ 0, /* fAllocMipLevels = */ false);
+                              pCmd->multisampleCount, multisamplePattern, qualityLevel, pCmd->autogenFilter,
+                              pCmd->numMipLevels, &pCmd->size, /* arraySize = */ 0, /* bufferByteStride = */ 0, /* fAllocMipLevels = */ false);
     }
 }
@@ -1657,4 +1666,10 @@
                                         SVGA3dTransferType enmTransfer)
 {
+    if (vmsvga3dIsMultisampleSurface(pThisCC, pImage->sid))
+    {
+        /* Multisample surfaces can't be accessed. Skip. */
+        return VINF_SUCCESS;
+    }
+
     PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
 
@@ -2067,5 +2082,4 @@
     entry.arraySize = pCmd->arraySize;
     // entry.mobPitch = 0;
-    // entry.mobPitch = 0;
     // entry.surface2Flags = 0;
     // entry.multisamplePattern = 0;
@@ -2079,8 +2093,9 @@
     {
         /* Create the host surface. */
-        /** @todo SVGAOTableSurfaceEntry as input parameter? */
+        SVGA3dMSPattern const multisamplePattern = pCmd->multisampleCount > 1 ? SVGA3D_MS_PATTERN_STANDARD : SVGA3D_MS_PATTERN_NONE;
+        SVGA3dMSQualityLevel const qualityLevel = pCmd->multisampleCount > 1 ? SVGA3D_MS_QUALITY_FULL : SVGA3D_MS_QUALITY_NONE;
         vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
-                              pCmd->multisampleCount, pCmd->autogenFilter,
-                              pCmd->numMipLevels, &pCmd->size, pCmd->arraySize, /* fAllocMipLevels = */ false);
+                              pCmd->multisampleCount, multisamplePattern, qualityLevel, pCmd->autogenFilter,
+                              pCmd->numMipLevels, &pCmd->size, pCmd->arraySize, /* bufferByteStride = */ 0, /* fAllocMipLevels = */ false);
     }
 }
@@ -3753,8 +3768,7 @@
     entry.arraySize = pCmd->arraySize;
     // entry.mobPitch = 0;
-    // entry.mobPitch = 0;
     entry.surface2Flags = (uint32_t)(pCmd->surfaceFlags >> UINT64_C(32));
-    // entry.multisamplePattern = 0;
-    // entry.qualityLevel = 0;
+    entry.multisamplePattern = pCmd->multisamplePattern;
+    entry.qualityLevel = pCmd->qualityLevel;
     // entry.bufferByteStride = 0;
     // entry.minLOD = 0;
@@ -3765,8 +3779,7 @@
     {
         /* Create the host surface. */
-        /** @todo SVGAOTableSurfaceEntry as input parameter? */
         vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
-                              pCmd->multisampleCount, pCmd->autogenFilter,
-                              pCmd->numMipLevels, &pCmd->size, pCmd->arraySize, /* fAllocMipLevels = */ false);
+                              pCmd->multisampleCount, pCmd->multisamplePattern, pCmd->qualityLevel, pCmd->autogenFilter,
+                              pCmd->numMipLevels, &pCmd->size, pCmd->arraySize, /* bufferByteStride = */ 0, /* fAllocMipLevels = */ false);
     }
     return rc;
@@ -3782,8 +3795,7 @@
 {
 #ifdef VMSVGA3D_DX
-    DEBUG_BREAKPOINT_TEST();
-    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
-    RT_NOREF(pSvgaR3State, pCmd, cbCmd);
-    return vmsvga3dDXResolveCopy(pThisCC, idDXContext);
+    //DEBUG_BREAKPOINT_TEST();
+    RT_NOREF(cbCmd);
+    return vmsvga3dDXResolveCopy(pThisCC, idDXContext, pCmd);
 #else
     RT_NOREF(pThisCC, idDXContext, pCmd, cbCmd);
@@ -4163,8 +4175,7 @@
     entry.arraySize = pCmd->arraySize;
     // entry.mobPitch = 0;
-    // entry.mobPitch = 0;
     entry.surface2Flags = (uint32_t)(pCmd->surfaceFlags >> UINT64_C(32));
-    // entry.multisamplePattern = 0;
-    // entry.qualityLevel = 0;
+    entry.multisamplePattern = pCmd->multisamplePattern;
+    entry.qualityLevel = pCmd->qualityLevel;
     entry.bufferByteStride = pCmd->bufferByteStride;
     // entry.minLOD = 0;
@@ -4175,8 +4186,7 @@
     {
         /* Create the host surface. */
-        /** @todo SVGAOTableSurfaceEntry as input parameter? */
         vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
-                              pCmd->multisampleCount, pCmd->autogenFilter,
-                              pCmd->numMipLevels, &pCmd->size, pCmd->arraySize, /* fAllocMipLevels = */ false);
+                              pCmd->multisampleCount, pCmd->multisamplePattern, pCmd->qualityLevel, pCmd->autogenFilter,
+                              pCmd->numMipLevels, &pCmd->size, pCmd->arraySize, pCmd->bufferByteStride, /* fAllocMipLevels = */ false);
     }
     return rc;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h	(revision 102808)
@@ -361,5 +361,7 @@
     /** Whether the VirtualBox extensions for VMSVGA device (new commands and caps) are enabled. */
     bool                        fVBoxExtensions;
-    bool                        afPadding[3];
+    /** Whether MSAA support is enabled. */
+    bool                        fVMSVGA3dMSAA;
+    bool                        afPadding[2];
     uint32_t                    uWidth;
     uint32_t                    uHeight;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp	(revision 102808)
@@ -106,4 +106,6 @@
     IDXGIFactory               *pDxgiFactory;          /* DXGI Factory. */
     D3D_FEATURE_LEVEL           FeatureLevel;
+
+    uint32_t                    MultisampleCountMask;  /* 1 << (MSCount - 1) for MSCount = 2, 4, 8, 16, 32 */
 
     ID3D11VideoDevice          *pVideoDevice;
@@ -909,8 +911,11 @@
                 *pu32DevCap |= SVGA3D_DXFMT_DX_VERTEX_BUFFER;
 
-            UINT NumQualityLevels;
-            hr = pDevice->CheckMultisampleQualityLevels(dxgiFormat, 2, &NumQualityLevels);
-            if (SUCCEEDED(hr) && NumQualityLevels != 0)
-                *pu32DevCap |= SVGA3D_DXFMT_MULTISAMPLE;
+            if (pState->pBackend->dxDevice.MultisampleCountMask != 0)
+            {
+                UINT NumQualityLevels;
+                hr = pDevice->CheckMultisampleQualityLevels(dxgiFormat, 2, &NumQualityLevels);
+                if (SUCCEEDED(hr) && NumQualityLevels != 0)
+                    *pu32DevCap |= SVGA3D_DXFMT_MULTISAMPLE;
+            }
         }
         else
@@ -1357,4 +1362,17 @@
         rc = VERR_NOT_SUPPORTED;
 
+    if (SUCCEEDED(hr))
+    {
+        /* Query multisample support for a common format. */
+        DXGI_FORMAT const dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
+
+        for (uint32_t i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i *= 2)
+        {
+            UINT NumQualityLevels = 0;
+            HRESULT hr2 = pDXDevice->pDevice->CheckMultisampleQualityLevels(dxgiFormat, i, &NumQualityLevels);
+            if (SUCCEEDED(hr2) && NumQualityLevels > 0)
+                pDXDevice->MultisampleCountMask |= UINT32_C(1) << (i - 1);
+        }
+    }
     return rc;
 }
@@ -2026,10 +2044,14 @@
             if (pSurface->surfaceDesc.numArrayElements <= 1)
             {
-                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+                desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
+                                   ? D3D11_RTV_DIMENSION_TEXTURE2DMS
+                                   : D3D11_RTV_DIMENSION_TEXTURE2D;
                 desc.Texture2D.MipSlice = pEntry->desc.tex.mipSlice;
             }
             else
             {
-                desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+                desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
+                                   ? D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY
+                                   : D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
                 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
                 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
@@ -2102,5 +2124,7 @@
             if (pSurface->surfaceDesc.numArrayElements <= 1)
             {
-                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+                desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
+                                   ? D3D11_SRV_DIMENSION_TEXTURE2DMS
+                                   : D3D11_SRV_DIMENSION_TEXTURE2D;
                 desc.Texture2D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
                 desc.Texture2D.MipLevels = pEntry->desc.tex.mipLevels;
@@ -2108,5 +2132,7 @@
             else
             {
-                desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+                desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
+                                   ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
+                                   : D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
                 desc.Texture2DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
                 desc.Texture2DArray.MipLevels = pEntry->desc.tex.mipLevels;
@@ -2245,10 +2271,14 @@
             if (pSurface->surfaceDesc.numArrayElements <= 1)
             {
-                desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+                desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
+                                   ? D3D11_DSV_DIMENSION_TEXTURE2DMS
+                                   : D3D11_DSV_DIMENSION_TEXTURE2D;
                 desc.Texture2D.MipSlice = pEntry->mipSlice;
             }
             else
             {
-                desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+                desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
+                                   ? D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY
+                                   : D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
                 desc.Texture2DArray.MipSlice = pEntry->mipSlice;
                 desc.Texture2DArray.FirstArraySlice = pEntry->firstArraySlice;
@@ -2702,5 +2732,5 @@
      */
     D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
-    if (pSurface->paMipmapLevels[0].pSurfaceData)
+    if (pSurface->paMipmapLevels[0].pSurfaceData && pSurface->surfaceDesc.multisampleCount <= 1)
     {
         /* Can happen for a non GBO surface or if GBO texture was updated prior to creation of the hardware resource. */
@@ -2912,5 +2942,5 @@
             td.ArraySize          = pSurface->surfaceDesc.numArrayElements;
             td.Format             = dxgiFormat;
-            td.SampleDesc.Count   = 1;
+            td.SampleDesc.Count   = pSurface->surfaceDesc.multisampleCount;
             td.SampleDesc.Quality = 0;
             td.Usage              = D3D11_USAGE_DEFAULT;
@@ -2930,4 +2960,6 @@
                 td.MipLevels      = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
                 td.ArraySize      = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
+                td.SampleDesc.Count   = 1;
+                td.SampleDesc.Quality = 0;
                 td.Usage          = D3D11_USAGE_DYNAMIC;
                 td.BindFlags      = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
@@ -3483,5 +3515,5 @@
     LogRelMax(1, ("VMSVGA: Single DX device mode: %s\n", pBackend->fSingleDevice ? "enabled" : "disabled"));
 
-    vmsvga3dDXInitContextMobData(&pBackend->svgaDXContext); /** @todo */
+    vmsvga3dDXInitContextMobData(&pBackend->svgaDXContext);
 //DEBUG_BREAKPOINT_TEST();
     return rc;
@@ -3524,4 +3556,7 @@
         if (pBackend->dxDevice.pVideoDevice)
             dxLogRelVideoCaps(pBackend->dxDevice.pVideoDevice);
+
+        if (!pThis->svga.fVMSVGA3dMSAA)
+            pBackend->dxDevice.MultisampleCountMask = 0;
     }
     return rc;
@@ -4769,9 +4804,9 @@
 
     case SVGA3D_DEVCAP_MULTISAMPLE_2X:
-        *pu32Val = 0; /* boolean */
+        *pu32Val = RT_BOOL(pState->pBackend->dxDevice.MultisampleCountMask & (1 << (2 - 1))); /* boolean */
         break;
 
     case SVGA3D_DEVCAP_MULTISAMPLE_4X:
-        *pu32Val = 0; /* boolean */
+        *pu32Val = RT_BOOL(pState->pBackend->dxDevice.MultisampleCountMask & (1 << (4 - 1))); /* boolean */
         break;
 
@@ -4800,5 +4835,5 @@
 
     case SVGA3D_DEVCAP_MULTISAMPLE_8X:
-        *pu32Val = 0; /* boolean */
+        *pu32Val = RT_BOOL(pState->pBackend->dxDevice.MultisampleCountMask & (1 << (8 - 1))); /* boolean */
         break;
 
@@ -7131,7 +7166,11 @@
                                 case SVGA3D_RESOURCE_TEXTURE2D:
                                     if (pSurface->surfaceDesc.numArrayElements <= 1)
-                                        aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
+                                        aResourceDimension[idxSR] = pSurface->surfaceDesc.multisampleCount > 1
+                                                                  ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS
+                                                                  : VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
                                     else
-                                        aResourceDimension[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY;
+                                        aResourceDimension[idxSR] = pSurface->surfaceDesc.multisampleCount > 1
+                                                                  ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMSARRAY
+                                                                  : VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY;
                                     break;
                                 case SVGA3D_RESOURCE_TEXTURE3D:
@@ -8769,4 +8808,9 @@
     }
 
+#ifdef DEBUG_sunlover
+    if (pSrcSurface->surfaceDesc.multisampleCount > 1 || pDstSurface->surfaceDesc.multisampleCount > 1)
+        DEBUG_BREAKPOINT_TEST();
+#endif
+
     LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
              pDXContext->cid, pSrcSurface->idAssociatedContext,
@@ -9858,11 +9902,28 @@
 
 
-static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
-{
-    PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
-
-    RT_NOREF(pBackend, pDXContext);
-    AssertFailed(); /** @todo Implement */
-    return VERR_NOT_IMPLEMENTED;
+static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
+                                                   SVGA3dSurfaceId dstSid, uint32_t dstSubResource,
+                                                   SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dSurfaceFormat copyFormat)
+{
+    DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
+    AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
+
+    PVMSVGA3DSURFACE pSrcSurface;
+    ID3D11Resource *pSrcResource;
+    int rc = dxEnsureResource(pThisCC, pDXContext, srcSid, &pSrcSurface, &pSrcResource);
+    AssertRCReturn(rc, rc);
+
+    PVMSVGA3DSURFACE pDstSurface;
+    ID3D11Resource *pDstResource;
+    rc = dxEnsureResource(pThisCC, pDXContext, dstSid, &pDstSurface, &pDstResource);
+    AssertRCReturn(rc, rc);
+
+    LogFunc(("cid %d: src sid = %u -> dst sid = %u\n", pDXContext->cid, srcSid, dstSid));
+
+    DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(copyFormat);
+    pDXDevice->pImmediateContext->ResolveSubresource(pDstResource, dstSubResource, pSrcResource, srcSubResource, dxgiFormat);
+
+    pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
+    return VINF_SUCCESS;
 }
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-savedstate.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-savedstate.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-savedstate.cpp	(revision 102808)
@@ -71,8 +71,8 @@
 
     /** @todo fAllocMipLevels=false and alloc miplevels if there is data to be loaded. */
-    rc = vmsvga3dSurfaceDefine(pThisCC, sid, entrySurface.surface1Flags, entrySurface.format,
-                               entrySurface.multisampleCount, entrySurface.autogenFilter,
+    rc = vmsvga3dSurfaceDefine(pThisCC, sid, RT_MAKE_U64(entrySurface.surface1Flags, entrySurface.surface2Flags), entrySurface.format,
+                               entrySurface.multisampleCount, (SVGA3dMSPattern)entrySurface.multisamplePattern, (SVGA3dMSQualityLevel)entrySurface.qualityLevel, entrySurface.autogenFilter,
                                entrySurface.numMipLevels, &entrySurface.size,
-                               entrySurface.arraySize,
+                               entrySurface.arraySize, entrySurface.bufferByteStride,
                                /* fAllocMipLevels = */ true);
     AssertRCReturn(rc, rc);
@@ -309,4 +309,13 @@
             uint32_t idx = iMipmap + iArray * pSurface->cLevels;
             PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[idx];
+
+            /* Multisample surface content can't be accessed. */
+            if (pSurface->surfaceDesc.multisampleCount > 1)
+            {
+                /* No data follows */
+                rc = pHlp->pfnSSMPutBool(pSSM, false);
+                AssertRCReturn(rc, rc);
+                continue;
+            }
 
             if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx.cpp	(revision 102808)
@@ -2624,5 +2624,5 @@
 
 
-int vmsvga3dDXResolveCopy(PVGASTATECC pThisCC, uint32_t idDXContext)
+int vmsvga3dDXResolveCopy(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dCmdDXResolveCopy const *pCmd)
 {
     int rc;
@@ -2636,5 +2636,6 @@
     AssertRCReturn(rc, rc);
 
-    rc = pSvgaR3State->pFuncsDX->pfnDXResolveCopy(pThisCC, pDXContext);
+    rc = pSvgaR3State->pFuncsDX->pfnDXResolveCopy(pThisCC, pDXContext, pCmd->dstSid, pCmd->dstSubResource,
+                                                  pCmd->srcSid, pCmd->srcSubResource, pCmd->copyFormat);
     return rc;
 }
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp	(revision 102808)
@@ -685,5 +685,6 @@
 
                 rc = vmsvga3dSurfaceDefine(pThisCC, sid, surface.f.surfaceFlags, surface.format, surface.multiSampleCount,
-                                           surface.autogenFilter, surface.cLevels, &pMipmapLevelSize[0], /* arraySize = */ 0, /* fAllocMipLevels = */ true);
+                                           SVGA3D_MS_PATTERN_NONE, SVGA3D_MS_QUALITY_NONE,
+                                           surface.autogenFilter, surface.cLevels, &pMipmapLevelSize[0], /* arraySize = */ 0, /* bufferByteStride = */ 0, /* fAllocMipLevels = */ true);
                 AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp	(revision 102808)
@@ -313,5 +313,5 @@
 }
 
-void vmsvga3dSurfaceMipBufferSize(SVGA3dSurfaceFormat format, SVGA3dSize mipmapSize,
+void vmsvga3dSurfaceMipBufferSize(SVGA3dSurfaceFormat format, SVGA3dSize mipmapSize, uint32_t multisampleCount,
                                   uint32_t *pcBlocksX,
                                   uint32_t *pcBlocksY,
@@ -331,5 +331,7 @@
     cbSurfacePlane = clamped_umul32(cbSurfacePlane, desc->bytes_per_block);
 
-    uint32_t const cbSurface = clamped_umul32(cbSurfacePlane, czBlocks);
+    uint32_t const cbSurfaceResolved = clamped_umul32(cbSurfacePlane, czBlocks);
+
+    uint32_t const cbSurface = clamped_umul32(cbSurfaceResolved, RT_MAX(multisampleCount, 1));
 
     *pcBlocksX = cxBlocks;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp	(revision 102808)
@@ -2741,6 +2741,6 @@
                 AssertRC(rc);
 
-                rc = vmsvga3dSurfaceDefine(pThisCC, sid, surfaceFlags, format, multisampleCount, autogenFilter,
-                                           cMipLevels, &pMipLevelSize[0], /* arraySize = */ 0, /* fAllocMipLevels = */ true);
+                rc = vmsvga3dSurfaceDefine(pThisCC, sid, surfaceFlags, format, multisampleCount, SVGA3D_MS_PATTERN_NONE, SVGA3D_MS_QUALITY_NONE, autogenFilter,
+                                           cMipLevels, &pMipLevelSize[0], /* arraySize = */ 0, /* bufferByteStride = */ 0, /* fAllocMipLevels = */ true);
                 AssertRC(rc);
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp	(revision 102808)
@@ -86,13 +86,16 @@
  * @param   format              .
  * @param   multisampleCount    .
+ * @param   multisamplePattern  .
+ * @param   qualityLevel        .
  * @param   autogenFilter       .
  * @param   numMipLevels        .
  * @param   pMipLevel0Size      .
  * @param   arraySize           Number of elements in a texture array.
+ * @param   bufferByteStride    .
  * @param   fAllocMipLevels     .
  */
 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, SVGA3dSurfaceAllFlags surfaceFlags, SVGA3dSurfaceFormat format,
-                          uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter,
-                          uint32_t numMipLevels, SVGA3dSize const *pMipLevel0Size, uint32_t arraySize, bool fAllocMipLevels)
+                          uint32_t multisampleCount, SVGA3dMSPattern multisamplePattern, SVGA3dMSQualityLevel qualityLevel, SVGA3dTextureFilter autogenFilter,
+                          uint32_t numMipLevels, SVGA3dSize const *pMipLevel0Size, uint32_t arraySize, uint32_t bufferByteStride, bool fAllocMipLevels)
 {
     PVMSVGA3DSURFACE pSurface;
@@ -140,4 +143,9 @@
     else
         pSurface->surfaceDesc.numArrayElements = 1;
+
+    pSurface->surfaceDesc.multisampleCount = RT_MAX(multisampleCount, 1);
+    pSurface->surfaceDesc.multisamplePattern = RT_CLAMP(multisamplePattern, SVGA3D_MS_PATTERN_MIN, SVGA3D_MS_PATTERN_MAX);
+    pSurface->surfaceDesc.qualityLevel = RT_CLAMP(qualityLevel, SVGA3D_MS_QUALITY_MIN, SVGA3D_MS_QUALITY_MAX);
+    pSurface->surfaceDesc.bufferByteStride = bufferByteStride;
 
     /** @todo This 'switch' and the surfaceFlags tweaks should not be necessary.
@@ -228,5 +236,5 @@
     pSurface->cFaces            = (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1);
     pSurface->cLevels           = numMipLevels;
-    pSurface->multiSampleCount  = multisampleCount;
+    pSurface->multiSampleCount  = pSurface->surfaceDesc.multisampleCount; /** @todo Remove the field. */
     pSurface->autogenFilter     = autogenFilter;
     Assert(autogenFilter != SVGA3D_TEX_FILTER_FLATCUBIC);
@@ -257,5 +265,5 @@
             uint32_t cbSurfacePlane;
             uint32_t cbSurface;
-            vmsvga3dSurfaceMipBufferSize(format, mipmapSize,
+            vmsvga3dSurfaceMipBufferSize(format, mipmapSize, pSurface->surfaceDesc.multisampleCount,
                                          &cBlocksX, &cBlocksY, &cbSurfacePitch, &cbSurfacePlane, &cbSurface);
             AssertBreakStmt(cbMemRemaining >= cbSurface, rc = VERR_INVALID_PARAMETER);
@@ -1732,4 +1740,14 @@
 
 
+bool vmsvga3dIsMultisampleSurface(PVGASTATECC pThisCC, SVGA3dSurfaceId sid)
+{
+    PVMSVGA3DSURFACE pSurface;
+    int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
+    AssertRCReturn(rc, 0);
+
+    return pSurface->surfaceDesc.multisampleCount > 1;
+}
+
+
 /*
  * Calculates memory layout of a surface box for memcpy:
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 102808)
@@ -54,5 +54,4 @@
 
 
-/** @todo Use this as a parameter for vmsvga3dSurfaceDefine and a field in VMSVGA3DSURFACE instead of a multiple values. */
 /* A surface description provided by the guest. Mostly mirrors SVGA3dCmdDefineGBSurface_v4 */
 typedef struct VMSVGA3D_SURFACE_DESC
@@ -117,6 +116,6 @@
 
 int vmsvga3dSurfaceDefine(PVGASTATECC pThisCC, uint32_t sid, SVGA3dSurfaceAllFlags surfaceFlags, SVGA3dSurfaceFormat format,
-                          uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter,
-                          uint32_t cMipLevels, SVGA3dSize const *pMipLevel0Size, uint32_t arraySize, bool fAllocMipLevels);
+                          uint32_t multisampleCount, SVGA3dMSPattern multisamplePattern, SVGA3dMSQualityLevel qualityLevel, SVGA3dTextureFilter autogenFilter,
+                          uint32_t numMipLevels, SVGA3dSize const *pMipLevel0Size, uint32_t arraySize, uint32_t bufferByteStride, bool fAllocMipLevels);
 int vmsvga3dSurfaceDestroy(PVGASTATECC pThisCC, uint32_t sid);
 int vmsvga3dSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
@@ -197,4 +196,5 @@
 uint32_t vmsvga3dGetArrayElements(PVGASTATECC pThisCC, SVGA3dSurfaceId sid);
 uint32_t vmsvga3dGetSubresourceCount(PVGASTATECC pThisCC, SVGA3dSurfaceId sid);
+bool vmsvga3dIsMultisampleSurface(PVGASTATECC pThisCC, SVGA3dSurfaceId sid);
 
 DECLINLINE(uint32_t) vmsvga3dCalcSubresource(uint32_t iMipLevel, uint32_t iArray, uint32_t cMipLevels)
@@ -345,5 +345,5 @@
                                    uint32_t *pu32BlockHeight,
                                    uint32_t *pcbPitchBlock);
-void vmsvga3dSurfaceMipBufferSize(SVGA3dSurfaceFormat format, SVGA3dSize mipmapSize,
+void vmsvga3dSurfaceMipBufferSize(SVGA3dSurfaceFormat format, SVGA3dSize mipmapSize, uint32_t multisampleCount,
                                   uint32_t *pcBlocksX,
                                   uint32_t *pcBlocksY,
@@ -532,5 +532,5 @@
     DECLCALLBACKMEMBER(int, pfnScreenCopy,                  (PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext));
     DECLCALLBACKMEMBER(int, pfnIntraSurfaceCopy,            (PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceImageId const &surface, SVGA3dCopyBox const &box));
-    DECLCALLBACKMEMBER(int, pfnDXResolveCopy,               (PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext));
+    DECLCALLBACKMEMBER(int, pfnDXResolveCopy,               (PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dSurfaceFormat copyFormat));
     DECLCALLBACKMEMBER(int, pfnDXPredResolveCopy,           (PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext));
     DECLCALLBACKMEMBER(int, pfnDXPredConvertRegion,         (PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext));
@@ -708,5 +708,5 @@
 int vmsvga3dDXGrowCOTable(PVGASTATECC pThisCC, SVGA3dCmdDXGrowCOTable const *pCmd);
 int vmsvga3dIntraSurfaceCopy(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dCmdIntraSurfaceCopy const *pCmd);
-int vmsvga3dDXResolveCopy(PVGASTATECC pThisCC, uint32_t idDXContext);
+int vmsvga3dDXResolveCopy(PVGASTATECC pThisCC, uint32_t idDXContext, SVGA3dCmdDXResolveCopy const *pCmd);
 int vmsvga3dDXPredResolveCopy(PVGASTATECC pThisCC, uint32_t idDXContext);
 int vmsvga3dDXPredConvertRegion(PVGASTATECC pThisCC, uint32_t idDXContext);
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 102807)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 102808)
@@ -6478,4 +6478,5 @@
                                             "|VMSVGA3dEnabled"
                                             "|VMSVGA3dOverlayEnabled"
+                                            "|VMSVGA3dMSAA"
 # endif
                                             "|SuppressNewYearSplash"
@@ -6549,4 +6550,8 @@
     AssertLogRelRCReturn(rc, rc);
     Log(("VMSVGA: VMSVGA3dOverlayEnabled = %d\n", pThis->svga.f3DOverlayEnabled));
+
+    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "VMSVGA3dMSAA", &pThis->svga.fVMSVGA3dMSAA, true);
+    AssertLogRelRCReturn(rc, rc);
+    Log(("VMSVGA: VMSVGA3dMSAA = %d\n", pThis->svga.fVMSVGA3dMSAA));
 # endif
 
