Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 57081)
@@ -44,4 +44,5 @@
 #include <iprt/uuid.h>
 #ifdef IN_RING3
+# include <iprt/ctype.h>
 # include <iprt/mem.h>
 #endif
@@ -92,5 +93,7 @@
 *   Structures and Typedefs                                                    *
 *******************************************************************************/
-/* 64-bit GMR descriptor */
+/**
+ * 64-bit GMR descriptor.
+ */
 typedef struct
 {
@@ -99,5 +102,7 @@
 } VMSVGAGMRDESCRIPTOR, *PVMSVGAGMRDESCRIPTOR;
 
-/* GMR slot */
+/**
+ * GMR slot
+ */
 typedef struct
 {
@@ -108,6 +113,9 @@
 } GMR, *PGMR;
 
-/* Internal SVGA state. */
-typedef struct
+#ifdef IN_RING3
+/**
+ * Internal SVGA ring-3 only state.
+ */
+typedef struct VMSVGAR3STATE
 {
     GMR                     aGMR[VMSVGA_MAX_GMR_IDS];
@@ -130,10 +138,10 @@
     SVGAColorBGRX           colorAnnotation;
 
-#ifdef VMSVGA_USE_EMT_HALT_CODE
+# ifdef VMSVGA_USE_EMT_HALT_CODE
     /** Number of EMTs in BusyDelayedEmts (quicker than scanning the set). */
     uint32_t volatile       cBusyDelayedEmts;
     /** Set of EMTs that are   */
     VMCPUSET                BusyDelayedEmts;
-#else
+# else
     /** Number of EMTs waiting on hBusyDelayedEmts. */
     uint32_t volatile       cBusyDelayedEmts;
@@ -141,5 +149,5 @@
      *  busy (ugly).  */
     RTSEMEVENTMULTI         hBusyDelayedEmts;
-#endif
+# endif
     /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */
     STAMPROFILE             StatBusyDelayEmts;
@@ -156,5 +164,6 @@
     STAMPROFILE             StatFifoStalls;
 
-} VMSVGASTATE, *PVMSVGASTATE;
+} VMSVGAR3STATE, *PVMSVGAR3STATE;
+#endif /* IN_RING3 */
 
 
@@ -200,34 +209,34 @@
 
 /**
- * SSM descriptor table for the VMSVGASTATE structure.
+ * SSM descriptor table for the VMSVGAR3STATE structure.
  */
-static SSMFIELD const g_aVMSVGASTATEFields[] =
+static SSMFIELD const g_aVMSVGAR3STATEFields[] =
 {
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, aGMR),
-    SSMFIELD_ENTRY(             VMSVGASTATE, GMRFB),
-    SSMFIELD_ENTRY(             VMSVGASTATE, Cursor.fActive),
-    SSMFIELD_ENTRY(             VMSVGASTATE, Cursor.xHotspot),
-    SSMFIELD_ENTRY(             VMSVGASTATE, Cursor.yHotspot),
-    SSMFIELD_ENTRY(             VMSVGASTATE, Cursor.width),
-    SSMFIELD_ENTRY(             VMSVGASTATE, Cursor.height),
-    SSMFIELD_ENTRY(             VMSVGASTATE, Cursor.cbData),
-    SSMFIELD_ENTRY_IGN_HCPTR(   VMSVGASTATE, Cursor.pData),
-    SSMFIELD_ENTRY(             VMSVGASTATE, colorAnnotation),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, cBusyDelayedEmts),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, aGMR),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, GMRFB),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, Cursor.fActive),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, Cursor.xHotspot),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, Cursor.yHotspot),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, Cursor.width),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, Cursor.height),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, Cursor.cbData),
+    SSMFIELD_ENTRY_IGN_HCPTR(   VMSVGAR3STATE, Cursor.pData),
+    SSMFIELD_ENTRY(             VMSVGAR3STATE, colorAnnotation),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, cBusyDelayedEmts),
 #ifdef VMSVGA_USE_EMT_HALT_CODE
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, BusyDelayedEmts),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, BusyDelayedEmts),
 #else
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, hBusyDelayedEmts),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, hBusyDelayedEmts),
 #endif
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatBusyDelayEmts),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatR3CmdPresent),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatR3CmdDrawPrimitive),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatR3CmdSurfaceDMA),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatFifoCommands),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatFifoErrors),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatFifoUnkCmds),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatFifoTodoTimeout),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatFifoTodoWoken),
-    SSMFIELD_ENTRY_IGNORE(      VMSVGASTATE, StatFifoStalls),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatBusyDelayEmts),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdPresent),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdDrawPrimitive),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdSurfaceDMA),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoCommands),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoErrors),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoUnkCmds),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoTodoTimeout),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoTodoWoken),
+    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoStalls),
     SSMFIELD_ENTRY_TERM()
 };
@@ -241,5 +250,5 @@
     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, pFIFOR3),
     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, pFIFOR0),
-    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, pSVGAState),
+    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, pSvgaR3State),
     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, p3dState),
     SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, pFrameBufferBackup),
@@ -820,5 +829,5 @@
             /* The guest is basically doing a HLT via the device here, but with
                a special wake up condition on FIFO completion. */
-            PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+            PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
             STAM_REL_PROFILE_START(&pSVGAState->StatBusyDelayEmts, EmtDelay);
             PVM         pVM   = PDMDevHlpGetVM(pThis->pDevInsR3);
@@ -835,5 +844,5 @@
                This used to be a crude 50 ms sleep. The current code tries to be
                more efficient, but the consept is still very crude. */
-            PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+            PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
             STAM_REL_PROFILE_START(&pSVGAState->StatBusyDelayEmts, EmtDelay);
             RTThreadYield();
@@ -1069,6 +1078,8 @@
 PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
 {
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
-    int          rc = VINF_SUCCESS;
+#ifdef IN_RING3
+    PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
+#endif
+    int            rc = VINF_SUCCESS;
 
     Log(("vmsvgaWritePort index=%s (%d) val=%#x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, u32));
@@ -1927,5 +1938,5 @@
     PVGASTATE   pThis = (PVGASTATE)pvUser;
     Assert(pThis);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
     NOREF(pVCpu); NOREF(pvPhys); NOREF(pvBuf); NOREF(cbBuf); NOREF(enmOrigin);
 
@@ -1962,6 +1973,6 @@
 static DECLCALLBACK(int) vmsvgaRegisterGMR(PPDMDEVINS pDevIns, uint32_t gmrId)
 {
-    PVGASTATE    pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
     PGMR pGMR = &pSVGAState->aGMR[gmrId];
     int rc;
@@ -1980,6 +1991,6 @@
 static DECLCALLBACK(int) vmsvgaDeregisterGMR(PPDMDEVINS pDevIns, uint32_t gmrId)
 {
-    PVGASTATE    pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
     PGMR pGMR = &pSVGAState->aGMR[gmrId];
 
@@ -1995,5 +2006,5 @@
 static DECLCALLBACK(int) vmsvgaResetGMRHandlers(PVGASTATE pThis)
 {
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
 
     for (uint32_t i = 0; i < RT_ELEMENTS(pSVGAState->aGMR); i++)
@@ -2075,4 +2086,15 @@
             break;
         }
+
+        case VMSVGA_FIFO_EXTCMD_UPDATE_SURFACE_HEAP_BUFFERS:
+        {
+# ifdef VBOX_WITH_VMSVGA3D
+            uint32_t sid = (uint32_t)(uintptr_t)pThis->svga.pvFIFOExtCmdParam;
+            Log(("vmsvgaFIFOLoop: VMSVGA_FIFO_EXTCMD_UPDATE_SURFACE_HEAP_BUFFERS sid=%#x\n", sid));
+            vmsvga3dUpdateHeapBuffersForSurfaces(pThis, sid);
+# endif
+            break;
+        }
+
 
         default:
@@ -2151,9 +2173,9 @@
     {
         /*
-         * The thread is running, should only happen during reset.
+         * The thread is running, should only happen during reset and vmsvga3dsfc.
          * We ASSUME not racing code here, both wrt thread state and ext commands.
          */
         Log(("vmsvgaR3RunExtCmdOnFifoThread: uExtCmd=%d enmState=RUNNING\n", uExtCmd));
-        Assert(uExtCmd == VMSVGA_FIFO_EXTCMD_RESET);
+        Assert(uExtCmd == VMSVGA_FIFO_EXTCMD_RESET || uExtCmd == VMSVGA_FIFO_EXTCMD_UPDATE_SURFACE_HEAP_BUFFERS);
 
         /* Post the request. */
@@ -2193,5 +2215,5 @@
  * @param   offFifoMin      The start byte offset of the command FIFO.
  */
-static void vmsvgaFifoSetNotBusy(PVGASTATE pThis, PVMSVGASTATE pSVGAState, uint32_t offFifoMin)
+static void vmsvgaFifoSetNotBusy(PVGASTATE pThis, PVMSVGAR3STATE pSVGAState, uint32_t offFifoMin)
 {
     ASMAtomicAndU32(&pThis->svga.fBusy, ~VMSVGA_BUSY_F_FIFO);
@@ -2243,5 +2265,5 @@
                                      uint32_t offCurrentCmd, uint32_t offFifoMin, uint32_t offFifoMax,
                                      uint8_t *pbBounceBuf, uint32_t *pcbAlreadyRead,
-                                     PPDMTHREAD pThread, PVGASTATE pThis, PVMSVGASTATE pSVGAState)
+                                     PPDMTHREAD pThread, PVGASTATE pThis, PVMSVGAR3STATE pSVGAState)
 {
     Assert(pbBounceBuf);
@@ -2375,7 +2397,7 @@
 static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
 {
-    PVGASTATE    pThis = (PVGASTATE)pThread->pvUser;
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
-    int          rc;
+    PVGASTATE       pThis = (PVGASTATE)pThread->pvUser;
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
+    int             rc;
 
     if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
@@ -3428,5 +3450,5 @@
 void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR)
 {
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
 
     /* Free the old descriptor if present. */
@@ -3465,5 +3487,5 @@
                       SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight)
 {
-    PVMSVGASTATE            pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVMSVGAR3STATE          pSVGAState = pThis->svga.pSvgaR3State;
     PGMR                    pGMR;
     int                     rc;
@@ -3741,17 +3763,100 @@
 }
 
+# ifdef VBOX_WITH_VMSVGA3D
 
 /**
- * @callback_method_impl{FNDBGFHANDLERDEV}
+ * Used by vmsvga3dInfoSurfaceWorker to make the FIFO thread to save one or all
+ * surfaces to VMSVGA3DMIPMAPLEVEL::pSurfaceData heap buffers.
+ *
+ * @param   pThis               The VGA device instance data.
+ * @param   sid                 Either UINT32_MAX or the ID of a specific
+ *                              surface.  If UINT32_MAX is used, all surfaces
+ *                              are processed.
  */
-static DECLCALLBACK(void) vmsvgaInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+void vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(PVGASTATE pThis, uint32_t sid)
 {
-    PVGASTATE    pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    vmsvgaR3RunExtCmdOnFifoThread(pThis, VMSVGA_FIFO_EXTCMD_UPDATE_SURFACE_HEAP_BUFFERS, (void *)(uintptr_t)sid,
+                                  sid == UINT32_MAX ? 10 * RT_MS_1SEC : RT_MS_1MIN);
+}
+
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV, "vmsvga3dsfc"}
+ */
+DECLCALLBACK(void) vmsvgaR3Info3dSurface(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    /* There might be a specific context ID at the start of the
+       arguments, if not show all contexts. */
+    uint32_t cid = UINT32_MAX;
+    if (pszArgs)
+        pszArgs = RTStrStripL(pszArgs);
+    if (pszArgs && RT_C_IS_DIGIT(*pszArgs))
+        cid = RTStrToUInt32(pszArgs);
+
+    /* Verbose or terse display, we default to verbose. */
+    bool fVerbose = true;
+    if (RTStrIStr(pszArgs, "terse"))
+        fVerbose = false;
+
+    /* The size of the ascii art (x direction, y is 3/4 of x). */
+    uint32_t cxAscii = 80;
+    if (RTStrIStr(pszArgs, "gigantic"))
+        cxAscii = 300;
+    else if (RTStrIStr(pszArgs, "huge"))
+        cxAscii = 180;
+    else if (RTStrIStr(pszArgs, "big"))
+        cxAscii = 132;
+    else if (RTStrIStr(pszArgs, "normal"))
+        cxAscii = 80;
+    else if (RTStrIStr(pszArgs, "medium"))
+        cxAscii = 64;
+    else if (RTStrIStr(pszArgs, "small"))
+        cxAscii = 48;
+    else if (RTStrIStr(pszArgs, "tiny"))
+        cxAscii = 24;
+
+    /* Y invert the image when producing the ASCII art. */
+    bool fInvY = false;
+    if (RTStrIStr(pszArgs, "invy"))
+        fInvY = true;
+
+    vmsvga3dInfoSurfaceWorker(PDMINS_2_DATA(pDevIns, PVGASTATE), pHlp, cid, fVerbose, cxAscii, fInvY);
+}
+
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV, "vmsvga3dctx"}
+ */
+DECLCALLBACK(void) vmsvgaR3Info3dContext(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    /* There might be a specific surface ID at the start of the
+       arguments, if not show all contexts. */
+    uint32_t sid = UINT32_MAX;
+    if (pszArgs)
+        pszArgs = RTStrStripL(pszArgs);
+    if (pszArgs && RT_C_IS_DIGIT(*pszArgs))
+        sid = RTStrToUInt32(pszArgs);
+
+    /* Verbose or terse display, we default to verbose. */
+    bool fVerbose = true;
+    if (RTStrIStr(pszArgs, "terse"))
+        fVerbose = false;
+
+    vmsvga3dInfoContextWorker(PDMINS_2_DATA(pDevIns, PVGASTATE), pHlp, sid, fVerbose);
+}
+
+# endif /* VBOX_WITH_VMSVGA3D */
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV, "vmsvga"}
+ */
+static DECLCALLBACK(void) vmsvgaR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
 
     pHlp->pfnPrintf(pHlp, "Extension enabled:  %RTbool\n", pThis->svga.fEnabled);
     pHlp->pfnPrintf(pHlp, "Configured:         %RTbool\n", pThis->svga.fConfigured);
     pHlp->pfnPrintf(pHlp, "Base I/O port:      %#x\n", pThis->svga.BasePort);
-    pHlp->pfnPrintf(pHlp, "Host windows ID:    %#RX64\n", pThis->svga.u64HostWindowId);
     pHlp->pfnPrintf(pHlp, "FIFO address:       %RGp\n", pThis->svga.GCPhysFIFO);
     pHlp->pfnPrintf(pHlp, "FIFO size:          %u (%#x)\n", pThis->svga.cbFIFO, pThis->svga.cbFIFO);
@@ -3780,5 +3885,7 @@
 
     pHlp->pfnPrintf(pHlp, "3D enabled:         %RTbool\n", pThis->svga.f3DEnabled);
-
+    pHlp->pfnPrintf(pHlp, "Host windows ID:    %#RX64\n", pThis->svga.u64HostWindowId);
+    if (pThis->svga.u64HostWindowId != 0)
+        vmsvga3dInfoHostWindow(pHlp, pThis->svga.u64HostWindowId);
 }
 
@@ -3789,7 +3896,7 @@
 int vmsvgaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
 {
-    PVGASTATE    pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
-    int          rc;
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
+    int             rc;
 
     /* Load our part of the VGAState */
@@ -3802,5 +3909,5 @@
 
     /* Load the VMSVGA state. */
-    rc = SSMR3GetStructEx(pSSM, pSVGAState, sizeof(*pSVGAState), 0, g_aVMSVGASTATEFields, NULL);
+    rc = SSMR3GetStructEx(pSSM, pSVGAState, sizeof(*pSVGAState), 0, g_aVMSVGAR3STATEFields, NULL);
     AssertRCReturn(rc, rc);
 
@@ -3858,6 +3965,6 @@
 int vmsvgaLoadDone(PPDMDEVINS pDevIns)
 {
-    PVGASTATE    pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
 
     pThis->last_bpp = VMSVGA_VAL_UNINITIALIZED;   /* force mode reset */
@@ -3869,12 +3976,12 @@
         int rc;
 
-        rc = pThis->pDrv->pfnVBVAMousePointerShape (pThis->pDrv,
-                                                    true,
-                                                    true,
-                                                    pSVGAState->Cursor.xHotspot,
-                                                    pSVGAState->Cursor.yHotspot,
-                                                    pSVGAState->Cursor.width,
-                                                    pSVGAState->Cursor.height,
-                                                    pSVGAState->Cursor.pData);
+        rc = pThis->pDrv->pfnVBVAMousePointerShape(pThis->pDrv,
+                                                   true,
+                                                   true,
+                                                   pSVGAState->Cursor.xHotspot,
+                                                   pSVGAState->Cursor.yHotspot,
+                                                   pSVGAState->Cursor.width,
+                                                   pSVGAState->Cursor.height,
+                                                   pSVGAState->Cursor.pData);
         AssertRC(rc);
     }
@@ -3887,7 +3994,7 @@
 int vmsvgaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
 {
-    PVGASTATE    pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
-    int          rc;
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
+    int             rc;
 
     /* Save our part of the VGAState */
@@ -3900,5 +4007,5 @@
 
     /* Save the VMSVGA state. */
-    rc = SSMR3PutStructEx(pSSM, pSVGAState, sizeof(*pSVGAState), 0, g_aVMSVGASTATEFields, NULL);
+    rc = SSMR3PutStructEx(pSSM, pSVGAState, sizeof(*pSVGAState), 0, g_aVMSVGAR3STATEFields, NULL);
     AssertLogRelRCReturn(rc, rc);
 
@@ -3944,6 +4051,6 @@
 int vmsvgaReset(PPDMDEVINS pDevIns)
 {
-    PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVMSVGAR3STATE  pSVGAState = pThis->svga.pSvgaR3State;
 
     /* Reset before init? */
@@ -3960,7 +4067,7 @@
     /* Reset other stuff. */
     pThis->svga.cScratchRegion = VMSVGA_SCRATCH_SIZE;
-    memset(pThis->svga.au32ScratchRegion, 0, sizeof(pThis->svga.au32ScratchRegion));
-    memset(pThis->svga.pSVGAState, 0, sizeof(VMSVGASTATE));
-    memset(pThis->svga.pFrameBufferBackup, 0, VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
+    RT_ZERO(pThis->svga.au32ScratchRegion);
+    RT_ZERO(*pThis->svga.pSvgaR3State);
+    RT_BZERO(pThis->svga.pFrameBufferBackup, VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
 
     /* Register caps. */
@@ -4015,5 +4122,5 @@
      * Destroy the special SVGA state.
      */
-    PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    PVMSVGAR3STATE pSVGAState = pThis->svga.pSvgaR3State;
     if (pSVGAState)
     {
@@ -4033,5 +4140,5 @@
 
         RTMemFree(pSVGAState);
-        pThis->svga.pSVGAState = NULL;
+        pThis->svga.pSvgaR3State = NULL;
     }
 
@@ -4064,5 +4171,5 @@
 {
     PVGASTATE       pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVMSVGASTATE    pSVGAState;
+    PVMSVGAR3STATE  pSVGAState;
     PVM             pVM   = PDMDevHlpGetVM(pDevIns);
     int             rc;
@@ -4071,7 +4178,7 @@
     memset(pThis->svga.au32ScratchRegion, 0, sizeof(pThis->svga.au32ScratchRegion));
 
-    pThis->svga.pSVGAState = RTMemAllocZ(sizeof(VMSVGASTATE));
-    AssertReturn(pThis->svga.pSVGAState, VERR_NO_MEMORY);
-    pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+    pThis->svga.pSvgaR3State = (PVMSVGAR3STATE)RTMemAllocZ(sizeof(VMSVGAR3STATE));
+    AssertReturn(pThis->svga.pSvgaR3State, VERR_NO_MEMORY);
+    pSVGAState = pThis->svga.pSvgaR3State;
 
     /* Necessary for creating a backup of the text mode frame buffer when switching into svga mode. */
@@ -4189,5 +4296,12 @@
      * Info handlers.
      */
-    PDMDevHlpDBGFInfoRegister(pDevIns, "vmsvga", "Basic VMSVGA device state details", vmsvgaInfo);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "vmsvga", "Basic VMSVGA device state details", vmsvgaR3Info);
+# ifdef VBOX_WITH_VMSVGA3D
+    PDMDevHlpDBGFInfoRegister(pDevIns, "vmsvga3dctx", "VMSVGA 3d context details. Accepts 'terse'.", vmsvgaR3Info3dContext);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "vmsvga3dsfc",
+                              "VMSVGA 3d surface details. "
+                              "Accepts 'terse', 'invy', and one of 'tiny', 'medium', 'normal', 'big', 'huge', or 'gigantic'.",
+                              vmsvgaR3Info3dSurface);
+# endif
 
     return VINF_SUCCESS;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp	(revision 57081)
@@ -872,6 +872,4 @@
 #endif
 } VMSVGA3DSTATE;
-/** Pointer to the VMSVGA3d state. */
-typedef VMSVGA3DSTATE *PVMSVGA3DSTATE;
 
 /**
@@ -1396,10 +1394,10 @@
      * Allocate the state.
      */
-    pThis->svga.p3dState = RTMemAllocZ(sizeof(VMSVGA3DSTATE));
+    pThis->svga.p3dState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
 
 #ifdef RT_OS_WINDOWS
     /* Create event semaphore and async IO thread. */
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     rc = RTSemEventCreate(&pState->WndRequestSem);
     if (RT_SUCCESS(rc))
@@ -1427,5 +1425,5 @@
 int vmsvga3dPowerOn(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
     PVMSVGA3DCONTEXT pContext;
@@ -1819,5 +1817,5 @@
 int vmsvga3dReset(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
 
@@ -1844,5 +1842,5 @@
 int vmsvga3dTerminate(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_WRONG_ORDER);
     int            rc;
@@ -2016,5 +2014,5 @@
 int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     int       rc = VINF_SUCCESS;
@@ -2617,5 +2615,5 @@
 {
     PVMSVGA3DSURFACE pSurface;
-    PVMSVGA3DSTATE   pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE   pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -2809,5 +2807,5 @@
 int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -2928,5 +2926,5 @@
 int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     uint32_t            sidSrc = src.sid;
     uint32_t            sidDest = dest.sid;
@@ -3159,5 +3157,5 @@
                               SVGA3dSurfaceImageId src, SVGA3dBox srcBox, SVGA3dStretchBltMode mode)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurfaceSrc;
     uint32_t            sidSrc = src.sid;
@@ -3387,5 +3385,5 @@
                        uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
 {
-    PVMSVGA3DSTATE          pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE          pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE        pSurface;
     PVMSVGA3DMIPMAPLEVEL    pMipLevel;
@@ -3799,5 +3797,5 @@
 int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter filter)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurface;
     int                 rc = VINF_SUCCESS;
@@ -3872,5 +3870,5 @@
 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurface;
     int                 rc = VINF_SUCCESS;
@@ -4289,5 +4287,5 @@
     int                     rc;
     PVMSVGA3DCONTEXT        pContext;
-    PVMSVGA3DSTATE          pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE          pState = pThis->svga.p3dState;
 
     AssertReturn(pState, VERR_NO_MEMORY);
@@ -4588,5 +4586,5 @@
 static int vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     AssertReturn(pContext, VERR_INVALID_PARAMETER);
@@ -4719,5 +4717,5 @@
 int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_WRONG_ORDER);
 
@@ -4736,5 +4734,5 @@
 int vmsvga3dChangeMode(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -4774,5 +4772,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     bool                  fModelViewChanged = false;
@@ -4882,5 +4880,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5024,5 +5022,5 @@
     uint32_t                    val;
     PVMSVGA3DCONTEXT            pContext;
-    PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5854,5 +5852,5 @@
 {
     PVMSVGA3DCONTEXT            pContext;
-    PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE            pRenderTarget;
 
@@ -6185,5 +6183,5 @@
     GLenum                      currentStage = ~0L;
     PVMSVGA3DCONTEXT            pContext;
-    PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -6439,5 +6437,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     GLenum                oglFace;
@@ -6492,5 +6490,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     float                 QuadAttenuation;
@@ -6672,5 +6670,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -6709,5 +6707,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -6755,5 +6753,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     double                oglPlane[4];
@@ -6790,5 +6788,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -6828,5 +6826,5 @@
     GLbitfield            mask = 0;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     GLboolean             fDepthWriteEnabled = GL_FALSE;
@@ -7271,5 +7269,5 @@
 {
     PVMSVGA3DCONTEXT             pContext;
-    PVMSVGA3DSTATE               pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE               pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_INTERNAL_ERROR);
     int                          rc = VERR_NOT_IMPLEMENTED;
@@ -7520,5 +7518,5 @@
     PVMSVGA3DCONTEXT      pContext;
     PVMSVGA3DSHADER       pShader;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     int                   rc;
@@ -7620,5 +7618,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     PVMSVGA3DSHADER       pShader = NULL;
@@ -7673,5 +7671,5 @@
 int vmsvga3dShaderSet(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     int                 rc;
@@ -7749,5 +7747,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     int                   rc;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.cpp	(revision 57081)
@@ -57,4 +57,5 @@
 
 #ifdef RT_OS_WINDOWS
+
 /**
  * Send a message to the async window thread and wait for a reply
@@ -239,5 +240,848 @@
     return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
+
 #endif /* RT_OS_WINDOWS */
+
+
+void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)
+{
+    for (uint32_t i = 0; i < cFlags; i++)
+        if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)
+        {
+            Assert(paFlags[i].fFlags);
+            pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);
+            fFlags &= ~paFlags[i].fFlags;
+            if (!fFlags)
+                return;
+        }
+    if (fFlags)
+        pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);
+}
+
+
+/**
+ * Worker for vmsvgaR3Info that display details of a host window.
+ *
+ * @param   pHlp            The output methods.
+ * @param   idHostWindow    The host window handle/id/whatever.
+ */
+void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)
+{
+#ifdef RT_OS_WINDOWS
+    HWND hwnd = (HWND)(uintptr_t)idHostWindow;
+    Assert((uintptr_t)hwnd == idHostWindow);
+    if (hwnd != NULL)
+    {
+        WINDOWINFO Info;
+        RT_ZERO(Info);
+        Info.cbSize = sizeof(Info);
+        if (GetWindowInfo(hwnd, &Info))
+        {
+            pHlp->pfnPrintf(pHlp, "     Window rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
+                            Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,
+                            Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);
+            pHlp->pfnPrintf(pHlp, "     Client rect:   xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
+                            Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,
+                            Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);
+            pHlp->pfnPrintf(pHlp, "     Style:         %#x", Info.dwStyle);
+            static const VMSVGAINFOFLAGS32 g_aStyles[] =
+            {
+                { WS_POPUP        , "POPUP" },
+                { WS_CHILD        , "CHILD" },
+                { WS_MINIMIZE     , "MINIMIZE" },
+                { WS_VISIBLE      , "VISIBLE" },
+                { WS_DISABLED     , "DISABLED" },
+                { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },
+                { WS_CLIPCHILDREN , "CLIPCHILDREN" },
+                { WS_MAXIMIZE     , "MAXIMIZE" },
+                { WS_BORDER       , "BORDER" },
+                { WS_DLGFRAME     , "DLGFRAME" },
+                { WS_VSCROLL      , "VSCROLL" },
+                { WS_HSCROLL      , "HSCROLL" },
+                { WS_SYSMENU      , "SYSMENU" },
+                { WS_THICKFRAME   , "THICKFRAME" },
+                { WS_GROUP        , "GROUP" },
+                { WS_TABSTOP      , "TABSTOP" },
+            };
+            vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));
+            pHlp->pfnPrintf(pHlp, "\n");
+
+            pHlp->pfnPrintf(pHlp, "     ExStyle:       %#x", Info.dwExStyle);
+            static const VMSVGAINFOFLAGS32 g_aExStyles[] =
+            {
+                { WS_EX_DLGMODALFRAME,   "DLGMODALFRAME" },
+                { 0x00000002,            "DRAGDETECT" },
+                { WS_EX_NOPARENTNOTIFY,  "NOPARENTNOTIFY" },
+                { WS_EX_TOPMOST,         "TOPMOST" },
+                { WS_EX_ACCEPTFILES,     "ACCEPTFILES" },
+                { WS_EX_TRANSPARENT,     "TRANSPARENT" },
+                { WS_EX_MDICHILD,        "MDICHILD" },
+                { WS_EX_TOOLWINDOW,      "TOOLWINDOW" },
+                { WS_EX_WINDOWEDGE,      "WINDOWEDGE" },
+                { WS_EX_CLIENTEDGE,      "CLIENTEDGE" },
+                { WS_EX_CONTEXTHELP,     "CONTEXTHELP" },
+                { WS_EX_RIGHT,           "RIGHT" },
+                /*{ WS_EX_LEFT,            "LEFT" }, = 0 */
+                { WS_EX_RTLREADING,      "RTLREADING" },
+                /*{ WS_EX_LTRREADING,      "LTRREADING" }, = 0 */
+                { WS_EX_LEFTSCROLLBAR,   "LEFTSCROLLBAR" },
+                /*{ WS_EX_RIGHTSCROLLBAR,  "RIGHTSCROLLBAR" }, = 0 */
+                { WS_EX_CONTROLPARENT,   "CONTROLPARENT" },
+                { WS_EX_STATICEDGE,      "STATICEDGE" },
+                { WS_EX_APPWINDOW,       "APPWINDOW" },
+                { WS_EX_LAYERED,         "LAYERED" },
+                { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },
+                { WS_EX_LAYOUTRTL,       "LAYOUTRTL" },
+                { WS_EX_COMPOSITED,      "COMPOSITED" },
+                { WS_EX_NOACTIVATE,      "NOACTIVATE" },
+            };
+            vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));
+            pHlp->pfnPrintf(pHlp, "\n");
+
+            pHlp->pfnPrintf(pHlp, "     Window Status: %#x\n", Info.dwWindowStatus);
+            if (Info.cxWindowBorders || Info.cyWindowBorders)
+                pHlp->pfnPrintf(pHlp, "     Borders:       cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);
+            pHlp->pfnPrintf(pHlp, "     Window Type:   %#x\n", Info.atomWindowType);
+            pHlp->pfnPrintf(pHlp, "     Creator Ver:   %#x\n", Info.wCreatorVersion);
+        }
+        else
+            pHlp->pfnPrintf(pHlp, "     GetWindowInfo: last error %d\n", GetLastError());
+    }
+#else
+    pHlp->pfnPrintf(pHlp, "    Windows info:   Not implemented on this platform\n");
+#endif
+
+}
+
+
+/**
+ * Formats an enum value as a string, sparse mapping table.
+ *
+ * @returns pszBuffer.
+ * @param   pszBuffer           The output buffer.
+ * @param   cbBuffer            The size of the output buffer.
+ * @param   pszName             The variable name, optional.
+ * @param   iValue              The enum value.
+ * @param   pszPrefix           The prefix of the enum values.  Empty string if
+ *                              none.  This helps reduce the memory footprint
+ *                              as well as the source code size.
+ * @param   papszValues         One to one string mapping of the enum values.
+ * @param   cValues             The number of values in the mapping.
+ */
+char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
+                              const char *pszPrefix, PCVMSVGAINFOENUM paValues, size_t cValues)
+{
+    for (uint32_t i = 0; i < cValues; i++)
+        if (paValues[i].iValue == iValue)
+        {
+            if (pszName)
+                RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, paValues[i].pszName, iValue);
+            else
+                RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, paValues[i].pszName, iValue);
+            return pszBuffer;
+        }
+
+    if (pszName)
+        RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
+    else
+        RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
+    return pszBuffer;
+}
+
+
+/**
+ * Formats an enum value as a string.
+ *
+ * @returns pszBuffer.
+ * @param   pszBuffer           The output buffer.
+ * @param   cbBuffer            The size of the output buffer.
+ * @param   pszName             The variable name, optional.
+ * @param   uValue              The enum value.
+ * @param   pszPrefix           The prefix of the enum values.  Empty string if
+ *                              none.  This helps reduce the memory footprint
+ *                              as well as the source code size.
+ * @param   papszValues         One to one string mapping of the enum values.
+ * @param   cValues             The number of values in the mapping.
+ */
+char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
+                            const char *pszPrefix, const char * const *papszValues, size_t cValues)
+{
+    if (uValue < cValues)
+    {
+        if (pszName)
+            RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
+        else
+            RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
+    }
+    else
+    {
+        if (pszName)
+            RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
+        else
+            RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
+    }
+    return pszBuffer;
+}
+
+
+/**
+ * DBGF info printer for vmsvga3dAsciiPrint.
+ *
+ * @param   pszLine             The line to print.
+ * @param   pvUser              The debug info helpers.
+ */
+DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
+{
+    PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
+    pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
+}
+
+
+/**
+ * Log printer for vmsvga3dAsciiPrint.
+ *
+ * @param   pszLine             The line to print.
+ * @param   pvUser              Ignored.
+ */
+DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
+{
+    size_t cch = strlen(pszLine);
+    while (cch > 0 && pszLine[cch - 1] == ' ')
+        cch--;
+    RTLogPrintf("%.*s\n", cch, pszLine);
+    NOREF(pvUser);
+}
+
+
+void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
+                        uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
+                        uint32_t cchMaxX, uint32_t cchMaxY)
+{
+    /*
+     * Skip stuff we can't or won't need to handle.
+     */
+    if (!cx || !cy)
+        return;
+    switch (enmFormat)
+    {
+        /* Compressed. */
+        case SVGA3D_DXT1:
+        case SVGA3D_DXT2:
+        case SVGA3D_DXT3:
+        case SVGA3D_DXT4:
+        case SVGA3D_DXT5:
+            return;
+        /* Generic. */
+        case SVGA3D_BUFFER:
+            return;
+    }
+
+    /*
+     * Figure the pixel conversion factors.
+     */
+    uint32_t cxPerChar = cx / cchMaxX + 1;
+    uint32_t cyPerChar = cy / cchMaxY + 1;
+    /** @todo try keep aspect...   */
+    uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
+    uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
+
+    /*
+     * The very simple conversion we're doing in this function is based on
+     * mapping a block of converted pixels to an ASCII character of similar
+     * weigth.  We do that by summing up all the 8-bit gray scale pixels in
+     * that block, applying a conversion factor and getting an index into an
+     * array of increasingly weighty characters.
+     */
+    static const char       s_szPalette[] = "   ..`',:;icodxkO08XNWM";
+    static const uint32_t   s_cchPalette  = sizeof(s_szPalette) - 1;
+    uint32_t const          cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
+
+    /*
+     * Do the work
+     */
+    uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
+    if (!pauScanline)
+        return;
+    char *pszLine = (char *)&pauScanline[cchLine];
+    RTCPTRUNION uSrc;
+    uSrc.pv              = pvImage;
+    if (fInvY)
+        uSrc.pu8 += (cy - 1) * cbScanline;
+    uint32_t cyLeft = cy;
+    uint32_t cyLeftInScanline = cyPerChar;
+    bool     fHitFormatAssert = false;
+    for (;;)
+    {
+        /*
+         * Process the scanline.  This is tedious because of all the
+         * different formats.  We generally ignore alpha, unless it's
+         * all we've got to work with.
+         * Color to 8-bit grayscale conversion is done by averaging.
+         */
+#define CONVERT_SCANLINE(a_AddExpr) \
+            do { \
+                for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
+                { \
+                    pauScanline[xDst] += (a_AddExpr) & 0xff; \
+                    Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
+                    if (--cxLeftInChar == 0) \
+                    { \
+                        xDst++; \
+                        cxLeftInChar = cxPerChar; \
+                    } \
+                } \
+            } while (0)
+
+        uint32_t u32Tmp;
+        switch (enmFormat)
+        {
+            /* Unsigned RGB and super/subsets. */
+            case SVGA3D_X8R8G8B8:
+            case SVGA3D_A8R8G8B8:
+                CONVERT_SCANLINE( (  ((u32Tmp = uSrc.pu32[xSrc]) & 0xff) /* B */
+                                   + ((u32Tmp >>  8) & 0xff)             /* G */
+                                   + ((u32Tmp >> 16) & 0xff)             /* R */) / 3);
+                break;
+            case SVGA3D_R5G6B5:
+                CONVERT_SCANLINE( (  ( uSrc.pu16[xSrc]         & 0x1f) * 8
+                                   + ((uSrc.pu16[xSrc] >>  5)  & 0x3f) * 4
+                                   + ( uSrc.pu16[xSrc] >> 11)          * 8 ) / 3 );
+                break;
+            case SVGA3D_X1R5G5B5:
+            case SVGA3D_A1R5G5B5:
+                CONVERT_SCANLINE( (  ( uSrc.pu16[xSrc]        & 0x1f) * 8
+                                   + ((uSrc.pu16[xSrc] >> 5)  & 0x1f) * 8
+                                   + ((uSrc.pu16[xSrc] >> 10) & 0x1f) * 8) / 3 );
+                break;
+            case SVGA3D_A4R4G4B4:
+                CONVERT_SCANLINE( (  ( uSrc.pu16[xSrc]        & 0xf) * 16
+                                   + ((uSrc.pu16[xSrc] >> 4)  & 0xf) * 16
+                                   + ((uSrc.pu16[xSrc] >> 8)  & 0xf) * 16) / 3 );
+                break;
+            case SVGA3D_A16B16G16R16:
+                CONVERT_SCANLINE( (  ((uSrc.pu64[xSrc] >>  8) & 0xff) /* R */
+                                   + ((uSrc.pu64[xSrc] >> 24) & 0xff) /* G */
+                                   + ((uSrc.pu64[xSrc] >> 40) & 0xff) /* B */ ) / 3);
+                break;
+            case SVGA3D_A2R10G10B10:
+                CONVERT_SCANLINE( (  ((uSrc.pu32[xSrc]      ) & 0x3ff) /* B */
+                                   + ((uSrc.pu32[xSrc] >> 10) & 0x3ff) /* G */
+                                   + ((uSrc.pu32[xSrc] >> 20) & 0x3ff) /* R */ ) / (3 * 4));
+                break;
+            case SVGA3D_G16R16:
+                CONVERT_SCANLINE( (  (uSrc.pu32[xSrc] & 0xffff) /* R */
+                                   + (uSrc.pu32[xSrc] >> 16 )   /* G */) / 0x200);
+                break;
+
+            /* Depth. */
+            case SVGA3D_Z_D32:
+                CONVERT_SCANLINE(  (((u32Tmp = ~(( uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444)) >> 2) & 1)
+                                 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
+                                 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
+                                 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
+                                 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
+                                 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
+                                 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
+                                 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
+                break;
+            case SVGA3D_Z_D16:
+                CONVERT_SCANLINE(  (((u32Tmp = ~uSrc.pu16[xSrc]) >> 1) & 1)
+                                 | ((u32Tmp >> ( 3 - 1)) & RT_BIT_32(1))
+                                 | ((u32Tmp >> ( 5 - 2)) & RT_BIT_32(2))
+                                 | ((u32Tmp >> ( 7 - 3)) & RT_BIT_32(3))
+                                 | ((u32Tmp >> ( 9 - 4)) & RT_BIT_32(4))
+                                 | ((u32Tmp >> (11 - 5)) & RT_BIT_32(5))
+                                 | ((u32Tmp >> (13 - 6)) & RT_BIT_32(6))
+                                 | ((u32Tmp >> (15 - 7)) & RT_BIT_32(7)) );
+                break;
+            case SVGA3D_Z_D24S8:
+                CONVERT_SCANLINE(  ((u32Tmp = uSrc.pu16[xSrc]) & 0xff) /* stencile */
+                                 | ((~u32Tmp >> 18) & 0x3f));
+                break;
+            case SVGA3D_Z_D15S1:
+                CONVERT_SCANLINE(  (((u32Tmp = uSrc.pu16[xSrc]) & 0x01) << 7) /* stencile */
+                                 | ((~u32Tmp >> 8) & 0x7f));
+                break;
+
+            /* Pure alpha. */
+            case SVGA3D_ALPHA8:
+                CONVERT_SCANLINE(uSrc.pu8[xSrc]);
+                break;
+
+            /* Luminance */
+            case SVGA3D_LUMINANCE8:
+                CONVERT_SCANLINE(uSrc.pu8[xSrc]);
+                break;
+            case SVGA3D_LUMINANCE4_ALPHA4:
+                CONVERT_SCANLINE(uSrc.pu8[xSrc] & 0xf0);
+                break;
+            case SVGA3D_LUMINANCE16:
+                CONVERT_SCANLINE(uSrc.pu16[xSrc] >> 8);
+                break;
+            case SVGA3D_LUMINANCE8_ALPHA8:
+                CONVERT_SCANLINE(uSrc.pu16[xSrc] >> 8);
+                break;
+
+            /* Not supported. */
+            case SVGA3D_DXT1:
+            case SVGA3D_DXT2:
+            case SVGA3D_DXT3:
+            case SVGA3D_DXT4:
+            case SVGA3D_DXT5:
+            case SVGA3D_BUFFER:
+                AssertFailedBreak();
+
+            /* Not considered for implementation yet. */
+            case SVGA3D_BUMPU8V8:
+            case SVGA3D_BUMPL6V5U5:
+            case SVGA3D_BUMPX8L8V8U8:
+            case SVGA3D_BUMPL8V8U8:
+            case SVGA3D_ARGB_S10E5:
+            case SVGA3D_ARGB_S23E8:
+            case SVGA3D_V8U8:
+            case SVGA3D_Q8W8V8U8:
+            case SVGA3D_CxV8U8:
+            case SVGA3D_X8L8V8U8:
+            case SVGA3D_A2W10V10U10:
+            case SVGA3D_R_S10E5:
+            case SVGA3D_R_S23E8:
+            case SVGA3D_RG_S10E5:
+            case SVGA3D_RG_S23E8:
+            case SVGA3D_Z_D24X8:
+            case SVGA3D_V16U16:
+            case SVGA3D_UYVY:
+            case SVGA3D_YUY2:
+            case SVGA3D_NV12:
+            case SVGA3D_AYUV:
+            case SVGA3D_BC4_UNORM:
+            case SVGA3D_BC5_UNORM:
+            case SVGA3D_Z_DF16:
+            case SVGA3D_Z_DF24:
+            case SVGA3D_Z_D24S8_INT:
+                if (!fHitFormatAssert)
+                {
+                    AssertMsgFailed(("%s is not implemented\n", vmsvgaSurfaceType2String(enmFormat)));
+                    fHitFormatAssert = true;
+                }
+                /* fall thru */
+            default:
+                /* Lazy programmer fallbacks. */
+                if (cbSrcPixel == 4)
+                    CONVERT_SCANLINE( (  ((u32Tmp = uSrc.pu32[xSrc]) & 0xff)
+                                       + ((u32Tmp >>  8) & 0xff)
+                                       + ((u32Tmp >> 16) & 0xff)
+                                       + ((u32Tmp >> 24) & 0xff) ) / 4);
+                else if (cbSrcPixel == 3)
+                    CONVERT_SCANLINE( (  (uint32_t)uSrc.pu8[xSrc * 4]
+                                       + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
+                                       + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
+                else if (cbSrcPixel == 2)
+                    CONVERT_SCANLINE( (  ((u32Tmp = uSrc.pu16[xSrc]) & 0xf) * 16
+                                       + ((u32Tmp >>  4) & 0xf)             * 16
+                                       + ((u32Tmp >>  8) & 0xf)             * 16
+                                       + ((u32Tmp >> 12) & 0xf)             * 16 ) / 4);
+                else if (cbSrcPixel == 1)
+                    CONVERT_SCANLINE(uSrc.pu8[xSrc]);
+                else
+                    AssertFailed();
+                break;
+
+        }
+
+        /*
+         * Print we've reached the end of a block in y direction or if we're at
+         * the end of the image.
+         */
+        cyLeft--;
+        if (--cyLeftInScanline == 0 || cyLeft == 0)
+        {
+            for (uint32_t i = 0; i < cchLine; i++)
+            {
+                uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
+                pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
+            }
+            pszLine[cchLine] = '\0';
+            pfnPrintLine(pszLine, pvUser);
+
+            if (!cyLeft)
+                break;
+            cyLeftInScanline = cyPerChar;
+            RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
+        }
+
+        /*
+         * Advance.
+         */
+        if (!fInvY)
+            uSrc.pu8 += cbScanline;
+        else
+            uSrc.pu8 -= cbScanline;
+    }
+}
+
+
+/**
+ * List of render state names with type prefix.
+ *
+ * First char in the name is a type indicator:
+ *      - '*' = requires special handling.
+ *      - 'f' = SVGA3dbool
+ *      - 'd' = uint32_t
+ *      - 'r' = float
+ *      - 'b' = SVGA3dBlendOp
+ *      - 'c' = SVGA3dColor, SVGA3dColorMask
+ *      - 'e' = SVGA3dBlendEquation
+ *      - 'm' = SVGA3dColorMask
+ *      - 'p' = SVGA3dCmpFunc
+ *      - 's' = SVGA3dStencilOp
+ *      - 'v' = SVGA3dVertexMaterial
+ *      - 'w' = SVGA3dWrapFlags
+ */
+static const char * const g_apszRenderStateNamesAndType[] =
+{
+   "*" "INVALID",                       /*  invalid  */
+   "f" "ZENABLE",                       /*  SVGA3dBool  */
+   "f" "ZWRITEENABLE",                  /*  SVGA3dBool  */
+   "f" "ALPHATESTENABLE",               /*  SVGA3dBool  */
+   "f" "DITHERENABLE",                  /*  SVGA3dBool  */
+   "f" "BLENDENABLE",                   /*  SVGA3dBool  */
+   "f" "FOGENABLE",                     /*  SVGA3dBool  */
+   "f" "SPECULARENABLE",                /*  SVGA3dBool  */
+   "f" "STENCILENABLE",                 /*  SVGA3dBool  */
+   "f" "LIGHTINGENABLE",                /*  SVGA3dBool  */
+   "f" "NORMALIZENORMALS",              /*  SVGA3dBool  */
+   "f" "POINTSPRITEENABLE",             /*  SVGA3dBool  */
+   "f" "POINTSCALEENABLE",              /*  SVGA3dBool  */
+   "x" "STENCILREF",                    /*  uint32_t  */
+   "x" "STENCILMASK",                   /*  uint32_t  */
+   "x" "STENCILWRITEMASK",              /*  uint32_t  */
+   "r" "FOGSTART",                      /*  float  */
+   "r" "FOGEND",                        /*  float  */
+   "r" "FOGDENSITY",                    /*  float  */
+   "r" "POINTSIZE",                     /*  float  */
+   "r" "POINTSIZEMIN",                  /*  float  */
+   "r" "POINTSIZEMAX",                  /*  float  */
+   "r" "POINTSCALE_A",                  /*  float  */
+   "r" "POINTSCALE_B",                  /*  float  */
+   "r" "POINTSCALE_C",                  /*  float  */
+   "c" "FOGCOLOR",                      /*  SVGA3dColor  */
+   "c" "AMBIENT",                       /*  SVGA3dColor  */
+   "*" "CLIPPLANEENABLE",               /*  SVGA3dClipPlanes  */
+   "*" "FOGMODE",                       /*  SVGA3dFogMode  */
+   "*" "FILLMODE",                      /*  SVGA3dFillMode  */
+   "*" "SHADEMODE",                     /*  SVGA3dShadeMode  */
+   "*" "LINEPATTERN",                   /*  SVGA3dLinePattern  */
+   "b" "SRCBLEND",                      /*  SVGA3dBlendOp  */
+   "b" "DSTBLEND",                      /*  SVGA3dBlendOp  */
+   "e" "BLENDEQUATION",                 /*  SVGA3dBlendEquation  */
+   "*" "CULLMODE",                      /*  SVGA3dFace  */
+   "p" "ZFUNC",                         /*  SVGA3dCmpFunc  */
+   "p" "ALPHAFUNC",                     /*  SVGA3dCmpFunc  */
+   "p" "STENCILFUNC",                   /*  SVGA3dCmpFunc  */
+   "s" "STENCILFAIL",                   /*  SVGA3dStencilOp  */
+   "s" "STENCILZFAIL",                  /*  SVGA3dStencilOp  */
+   "s" "STENCILPASS",                   /*  SVGA3dStencilOp  */
+   "r" "ALPHAREF",                      /*  float  */
+   "*" "FRONTWINDING",                  /*  SVGA3dFrontWinding  */
+   "*" "COORDINATETYPE",                /*  SVGA3dCoordinateType  */
+   "r" "ZBIAS",                         /*  float  */
+   "f" "RANGEFOGENABLE",                /*  SVGA3dBool  */
+   "c" "COLORWRITEENABLE",              /*  SVGA3dColorMask  */
+   "f" "VERTEXMATERIALENABLE",          /*  SVGA3dBool  */
+   "v" "DIFFUSEMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
+   "v" "SPECULARMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
+   "v" "AMBIENTMATERIALSOURCE",         /*  SVGA3dVertexMaterial  */
+   "v" "EMISSIVEMATERIALSOURCE",        /*  SVGA3dVertexMaterial  */
+   "c" "TEXTUREFACTOR",                 /*  SVGA3dColor  */
+   "f" "LOCALVIEWER",                   /*  SVGA3dBool  */
+   "f" "SCISSORTESTENABLE",             /*  SVGA3dBool  */
+   "c" "BLENDCOLOR",                    /*  SVGA3dColor  */
+   "f" "STENCILENABLE2SIDED",           /*  SVGA3dBool  */
+   "p" "CCWSTENCILFUNC",                /*  SVGA3dCmpFunc  */
+   "s" "CCWSTENCILFAIL",                /*  SVGA3dStencilOp  */
+   "s" "CCWSTENCILZFAIL",               /*  SVGA3dStencilOp  */
+   "s" "CCWSTENCILPASS",                /*  SVGA3dStencilOp  */
+   "*" "VERTEXBLEND",                   /*  SVGA3dVertexBlendFlags  */
+   "r" "SLOPESCALEDEPTHBIAS",           /*  float  */
+   "r" "DEPTHBIAS",                     /*  float  */
+   "r" "OUTPUTGAMMA",                   /*  float  */
+   "f" "ZVISIBLE",                      /*  SVGA3dBool  */
+   "f" "LASTPIXEL",                     /*  SVGA3dBool  */
+   "f" "CLIPPING",                      /*  SVGA3dBool  */
+   "w" "WRAP0",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP1",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP2",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP3",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP4",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP5",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP6",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP7",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP8",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP9",                         /*  SVGA3dWrapFlags  */
+   "w" "WRAP10",                        /*  SVGA3dWrapFlags  */
+   "w" "WRAP11",                        /*  SVGA3dWrapFlags  */
+   "w" "WRAP12",                        /*  SVGA3dWrapFlags  */
+   "w" "WRAP13",                        /*  SVGA3dWrapFlags  */
+   "w" "WRAP14",                        /*  SVGA3dWrapFlags  */
+   "w" "WRAP15",                        /*  SVGA3dWrapFlags  */
+   "f" "MULTISAMPLEANTIALIAS",          /*  SVGA3dBool  */
+   "x" "MULTISAMPLEMASK",               /*  uint32_t  */
+   "f" "INDEXEDVERTEXBLENDENABLE",      /*  SVGA3dBool  */
+   "r" "TWEENFACTOR",                   /*  float  */
+   "f" "ANTIALIASEDLINEENABLE",         /*  SVGA3dBool  */
+   "c" "COLORWRITEENABLE1",             /*  SVGA3dColorMask  */
+   "c" "COLORWRITEENABLE2",             /*  SVGA3dColorMask  */
+   "c" "COLORWRITEENABLE3",             /*  SVGA3dColorMask  */
+   "f" "SEPARATEALPHABLENDENABLE",      /*  SVGA3dBool  */
+   "b" "SRCBLENDALPHA",                 /*  SVGA3dBlendOp  */
+   "b" "DSTBLENDALPHA",                 /*  SVGA3dBlendOp  */
+   "e" "BLENDEQUATIONALPHA",            /*  SVGA3dBlendEquation  */
+   "*" "TRANSPARENCYANTIALIAS",         /*  SVGA3dTransparencyAntialiasType  */
+   "f" "LINEAA",                        /*  SVGA3dBool  */
+   "r" "LINEWIDTH",                     /*  float  */
+};
+
+
+/**
+ * Formats a SVGA3dRenderState structure as a string.
+ *
+ * @returns pszBuffer.
+ * @param   pszBuffer       Output string buffer.
+ * @param   cbBuffer        Size of output buffer.
+ * @param   pRenderState    The SVGA3d render state to format.
+ */
+char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
+{
+    uint32_t iState = pRenderState->state;
+    if (iState != SVGA3D_RS_INVALID)
+    {
+        if (iState < RT_ELEMENTS(g_apszRenderStateNamesAndType))
+        {
+            const char *pszName = g_apszRenderStateNamesAndType[iState];
+            char const  chType  = *pszName++;
+
+            union
+            {
+               uint32_t  u;
+               float     r;
+               SVGA3dColorMask Color;
+            } uValue;
+            uValue.u = pRenderState->uintValue;
+
+            switch (chType)
+            {
+                case 'f':
+                    if (uValue.u == 0)
+                        RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
+                    else if (uValue.u == 1)
+                        RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
+                    else
+                        RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
+                    break;
+                case 'x':
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
+                    break;
+                case 'r':
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
+                                pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
+                    break;
+                case 'c': //SVGA3dColor, SVGA3dColorMask
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
+                                uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
+                    break;
+                case 'w': //SVGA3dWrapFlags
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
+                                uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
+                    break;
+                default:
+                    AssertFailed();
+                case 'b': //SVGA3dBlendOp
+                case 'e': //SVGA3dBlendEquation
+                case 'p': //SVGA3dCmpFunc
+                case 's': //SVGA3dStencilOp
+                case 'v': //SVGA3dVertexMaterial
+                case '*':
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
+                    break;
+            }
+        }
+        else
+            RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
+    }
+    else
+        RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
+    return pszBuffer;
+}
+
+/**
+ * Texture state names with type prefix.
+ */
+static const char * const g_apszTextureStateNamesAndType[] =
+{
+    "*" "INVALID",                      /*  invalid  */
+    "x" "BIND_TEXTURE",                 /*  SVGA3dSurfaceId  */
+    "m" "COLOROP",                      /*  SVGA3dTextureCombiner  */
+    "a" "COLORARG1",                    /*  SVGA3dTextureArgData  */
+    "a" "COLORARG2",                    /*  SVGA3dTextureArgData  */
+    "m" "ALPHAOP",                      /*  SVGA3dTextureCombiner  */
+    "a" "ALPHAARG1",                    /*  SVGA3dTextureArgData  */
+    "a" "ALPHAARG2",                    /*  SVGA3dTextureArgData  */
+    "e" "ADDRESSU",                     /*  SVGA3dTextureAddress  */
+    "e" "ADDRESSV",                     /*  SVGA3dTextureAddress  */
+    "l" "MIPFILTER",                    /*  SVGA3dTextureFilter  */
+    "l" "MAGFILTER",                    /*  SVGA3dTextureFilter  */
+    "m" "MINFILTER",                    /*  SVGA3dTextureFilter  */
+    "c" "BORDERCOLOR",                  /*  SVGA3dColor  */
+    "r" "TEXCOORDINDEX",                /*  uint32_t  */
+    "t" "TEXTURETRANSFORMFLAGS",        /*  SVGA3dTexTransformFlags  */
+    "g" "TEXCOORDGEN",                  /*  SVGA3dTextureCoordGen  */
+    "r" "BUMPENVMAT00",                 /*  float  */
+    "r" "BUMPENVMAT01",                 /*  float  */
+    "r" "BUMPENVMAT10",                 /*  float  */
+    "r" "BUMPENVMAT11",                 /*  float  */
+    "x" "TEXTURE_MIPMAP_LEVEL",         /*  uint32_t  */
+    "r" "TEXTURE_LOD_BIAS",             /*  float  */
+    "x" "TEXTURE_ANISOTROPIC_LEVEL",    /*  uint32_t  */
+    "e" "ADDRESSW",                     /*  SVGA3dTextureAddress  */
+    "r" "GAMMA",                        /*  float  */
+    "r" "BUMPENVLSCALE",                /*  float  */
+    "r" "BUMPENVLOFFSET",               /*  float  */
+    "a" "COLORARG0",                    /*  SVGA3dTextureArgData  */
+    "a" "ALPHAARG0"                     /*  SVGA3dTextureArgData */
+};
+
+/**
+ * Formats a SVGA3dTextureState structure as a string.
+ *
+ * @returns pszBuffer.
+ * @param   pszBuffer       Output string buffer.
+ * @param   cbBuffer        Size of output buffer.
+ * @param   pTextureState   The SVGA3d texture state to format.
+ */
+char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
+{
+    /*
+     * Format the stage first.
+     */
+    char  *pszRet    = pszBuffer;
+    size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
+    if (cchPrefix < cbBuffer)
+    {
+        cbBuffer  -= cchPrefix;
+        pszBuffer += cchPrefix;
+    }
+    else
+        cbBuffer = 0;
+
+    /*
+     * Format the name and value.
+     */
+    uint32_t iName = pTextureState->name;
+    if (iName != SVGA3D_TS_INVALID)
+    {
+        if (iName < RT_ELEMENTS(g_apszTextureStateNamesAndType))
+        {
+            const char *pszName = g_apszTextureStateNamesAndType[iName];
+            char        chType  = *pszName++;
+
+            union
+            {
+               uint32_t  u;
+               float     r;
+               SVGA3dColorMask Color;
+            } uValue;
+            uValue.u = pTextureState->value;
+
+            switch (chType)
+            {
+                case 'x':
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
+                    break;
+
+                case 'r':
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
+                                pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
+                    break;
+
+                case 'a': //SVGA3dTextureArgData
+                {
+                    static const char * const s_apszValues[] =
+                    {
+                        "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
+                    };
+                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
+                                          "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
+                    break;
+                }
+
+                case 'c': //SVGA3dColor, SVGA3dColorMask
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
+                                uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
+                    break;
+
+                case 'e': //SVGA3dTextureAddress
+                {
+                    static const char * const s_apszValues[] =
+                    {
+                        "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
+                    };
+                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
+                                          "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
+                    break;
+                }
+
+                case 'l': //SVGA3dTextureFilter
+                {
+                    static const char * const s_apszValues[] =
+                    {
+                        "NONE", "NEAREST", "LINEAR",  "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
+                    };
+                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
+                                          "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
+                    break;
+                }
+
+                case 'g': //SVGA3dTextureCoordGen
+                {
+                    static const char * const s_apszValues[] =
+                    {
+                        "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
+                    };
+                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
+                                          "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
+                    break;
+                }
+
+                case 'm': //SVGA3dTextureCombiner
+                {
+                    static const char * const s_apszValues[] =
+                    {
+                        "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
+                        "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
+                        "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
+                        "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
+                        "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
+                    };
+                    vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
+                                          "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
+                    break;
+                }
+
+                default:
+                    AssertFailed();
+                    RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
+                    break;
+            }
+        }
+        else
+            RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
+    }
+    else
+        RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
+    return pszRet;
+}
+
+
+
 
 /**
@@ -349,4 +1193,5 @@
 
 #ifdef LOG_ENABLED
+
 const char *vmsvga3dGetCapString(uint32_t idxCap)
 {
@@ -1125,2 +1970,3 @@
 
 #endif /* LOG_ENABLED */
+
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h	(revision 57081)
@@ -1,6 +1,12 @@
 /* $Id$ */
 /** @file
- * VMware SVGA device -- 3D part
+ * DevVMWare - VMWare SVGA device, shared part.
+ *
+ * @remarks This is code that's very similar on both for OpenGL and D3D
+ *          backends, so instead of moving backend specific structures
+ *          into header files with #ifdefs and stuff, we just include
+ *          the code into the backend implementation source file.
  */
+
 /*
  * Copyright (C) 2013-2015 Oracle Corporation
@@ -18,7 +24,312 @@
 #define ___DevVGA_SVGA3d_shared_h___
 
+/**
+ * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.
+ *
+ * This will allocate heap buffers if necessary, thus increasing the memory
+ * usage of the process.
+ *
+ * @todo Would be interesting to share this code with the saved state code.
+ *
+ * @returns VBox status code.
+ * @param   pState              The 3D state structure.
+ * @param   pSurface            The surface to refresh the heap buffers for.
+ */
+static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
+{
+    /*
+     * Currently we've got trouble retreving bit for DEPTHSTENCIL
+     * surfaces both for OpenGL and D3D, so skip these here (don't
+     * wast memory on them).
+     */
+    uint32_t const fSwitchFlags = pSurface->flags
+                                & (  SVGA3D_SURFACE_HINT_INDEXBUFFER  | SVGA3D_SURFACE_HINT_VERTEXBUFFER
+                                   | SVGA3D_SURFACE_HINT_TEXTURE      | SVGA3D_SURFACE_HINT_RENDERTARGET
+                                   | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);
+    if (   fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL
+        && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))
+    {
+
+#ifdef VMSVGA3D_OPENGL
+        /*
+         * Change OpenGL context to the one the surface is associated with.
+         */
+# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
+        PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
+        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+# else
+        /** @todo stricter checks for associated context */
+        uint32_t cid = pSurface->idAssociatedContext;
+        if (    cid >= pState->cContexts
+            ||  pState->papContexts[cid]->id != cid)
+        {
+            Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
+            AssertFailedReturn(VERR_INVALID_PARAMETER);
+        }
+        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
+        VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+# endif
+#endif
+
+        /*
+         * Work thru each mipmap level for each face.
+         */
+        for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
+        {
+            Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
+            PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
+            for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
+            {
+#ifdef VMSVGA3D_DIRECT3D
+                if (pSurface->u.pSurface)
+#else
+                if (pSurface->oglId.texture != OPENGL_INVALID_ID)
+#endif
+                {
+                    Assert(pMipmapLevel->cbSurface);
+                    Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */
+
+                    /*
+                     * Make sure we've got surface memory buffer.
+                     */
+                    uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;
+                    if (!pbDst)
+                    {
+                        pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);
+                        AssertReturn(pbDst, VERR_NO_MEMORY);
+                    }
+
+#ifdef VMSVGA3D_DIRECT3D
+                    /*
+                     * D3D specifics.
+                     */
+                    HRESULT  hr;
+                    switch (fSwitchFlags)
+                    {
+                        case SVGA3D_SURFACE_HINT_TEXTURE:
+                        case SVGA3D_SURFACE_HINT_RENDERTARGET:
+                        case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
+                        {
+                            /*
+                             * Lock the buffer and make it accessible to memcpy.
+                             */
+                            D3DLOCKED_RECT LockedRect;
+                            if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
+                            {
+                                if (pSurface->bounce.pTexture)
+                                {
+                                    if (    !pSurface->fDirty
+                                        &&  fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)
+                                        &&  i == 0 /* only the first time */)
+                                    {
+                                        /** @todo stricter checks for associated context */
+                                        uint32_t cid = pSurface->idAssociatedContext;
+                                        if (   cid >= pState->cContexts
+                                            || pState->papContexts[cid]->id != cid)
+                                        {
+                                            Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
+                                            AssertFailedReturn(VERR_INVALID_PARAMETER);
+                                        }
+                                        PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
+
+                                        IDirect3DSurface9 *pDst = NULL;
+                                        hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);
+                                        AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
+
+                                        IDirect3DSurface9 *pSrc = NULL;
+                                        hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
+                                        AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
+
+                                        hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);
+                                        AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);
+
+                                        pSrc->Release();
+                                        pDst->Release();
+                                    }
+
+                                    hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
+                                                                             &LockedRect,
+                                                                             NULL,
+                                                                             D3DLOCK_READONLY);
+                                }
+                                else
+                                    hr = pSurface->u.pTexture->LockRect(i, /* texture level */
+                                                                        &LockedRect,
+                                                                        NULL,
+                                                                        D3DLOCK_READONLY);
+                            }
+                            else
+                                hr = pSurface->u.pSurface->LockRect(&LockedRect,
+                                                                    NULL,
+                                                                    D3DLOCK_READONLY);
+                            AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
+
+                            /*
+                             * Copy the data.  Take care in case the pitch differs.
+                             */
+                            if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)
+                                memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);
+                            else
+                                for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
+                                    memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,
+                                           (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,
+                                           pMipmapLevel->cbSurfacePitch);
+
+                            /*
+                             * Release the buffer.
+                             */
+                            if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
+                            {
+                                if (pSurface->bounce.pTexture)
+                                {
+                                    hr = pSurface->bounce.pTexture->UnlockRect(i);
+                                    AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
+                                }
+                                else
+                                    hr = pSurface->u.pTexture->UnlockRect(i);
+                            }
+                            else
+                                hr = pSurface->u.pSurface->UnlockRect();
+                            AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
+                            break;
+                        }
+
+                        case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
+                        {
+                            void *pvD3DData = NULL;
+                            hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
+                            AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);
+
+                            memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
+
+                            hr = pSurface->u.pVertexBuffer->Unlock();
+                            AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));
+                            break;
+                        }
+
+                        case SVGA3D_SURFACE_HINT_INDEXBUFFER:
+                        {
+                            void *pvD3DData = NULL;
+                            hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
+                            AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);
+
+                            memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
+
+                            hr = pSurface->u.pIndexBuffer->Unlock();
+                            AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));
+                            break;
+                        }
+
+                        default:
+                            AssertMsgFailed(("%#x\n", fSwitchFlags));
+                    }
+
+#elif defined(VMSVGA3D_OPENGL)
+                    /*
+                     * OpenGL specifics.
+                     */
+                    switch (fSwitchFlags)
+                    {
+                        case SVGA3D_SURFACE_HINT_TEXTURE:
+                        case SVGA3D_SURFACE_HINT_RENDERTARGET:
+                        case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
+                        {
+                            GLint activeTexture;
+                            glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
+                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
+
+                            glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
+                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
+
+                            /* Set row length and alignment of the output data. */
+                            VMSVGAPACKPARAMS SavedParams;
+                            vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
+
+                            glGetTexImage(GL_TEXTURE_2D,
+                                          i,
+                                          pSurface->formatGL,
+                                          pSurface->typeGL,
+                                          pbDst);
+                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
+
+                            vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
+
+                            /* Restore the old active texture. */
+                            glBindTexture(GL_TEXTURE_2D, activeTexture);
+                            VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
+                            break;
+                        }
+
+                        case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
+                        case SVGA3D_SURFACE_HINT_INDEXBUFFER:
+                        {
+                            pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
+                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+
+                            void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+                            if (RT_VALID_PTR(pvSrc))
+                                memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);
+                            else
+                                AssertPtr(pvSrc);
+
+                            pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
+                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+
+                            pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
+                            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
+                            break;
+                        }
+
+                        default:
+                            AssertMsgFailed(("%#x\n", fSwitchFlags));
+                    }
+#else
+# error "misconfigured"
+#endif
+                }
+                /* else: There is no data in hardware yet, so whatever we got is already current. */
+            }
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Updates the heap buffers for all surfaces or one specific one.
+ *
+ * @param   pThis               The VGA device instance data.
+ * @param   sid                 The surface ID, UINT32_MAX if all.
+ * @thread  VMSVGAFIFO
+ */
+void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)
+{
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
+    AssertReturnVoid(pState);
+
+    if (sid == UINT32_MAX)
+    {
+        uint32_t cSurfaces = pState->cSurfaces;
+        for (sid = 0; sid < cSurfaces; sid++)
+        {
+            PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
+            if (pSurface && pSurface->id == sid)
+                vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
+        }
+    }
+    else if (sid < pState->cSurfaces)
+    {
+        PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
+        if (pSurface && pSurface->id == sid)
+            vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
+    }
+}
+
+
 int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     int            rc;
@@ -348,5 +659,5 @@
 int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     int            rc;
@@ -811,4 +1122,613 @@
 
 
+
+static const char * const g_apszTransformTypes[] =
+{
+    "SVGA3D_TRANSFORM_INVALID",
+    "SVGA3D_TRANSFORM_WORLD",
+    "SVGA3D_TRANSFORM_VIEW",
+    "SVGA3D_TRANSFORM_PROJECTION",
+    "SVGA3D_TRANSFORM_TEXTURE0",
+    "SVGA3D_TRANSFORM_TEXTURE1",
+    "SVGA3D_TRANSFORM_TEXTURE2",
+    "SVGA3D_TRANSFORM_TEXTURE3",
+    "SVGA3D_TRANSFORM_TEXTURE4",
+    "SVGA3D_TRANSFORM_TEXTURE5",
+    "SVGA3D_TRANSFORM_TEXTURE6",
+    "SVGA3D_TRANSFORM_TEXTURE7",
+    "SVGA3D_TRANSFORM_WORLD1",
+    "SVGA3D_TRANSFORM_WORLD2",
+    "SVGA3D_TRANSFORM_WORLD3",
+};
+
+static const char * const g_apszFaces[] =
+{
+    "SVGA3D_FACE_INVALID",
+    "SVGA3D_FACE_NONE",
+    "SVGA3D_FACE_FRONT",
+    "SVGA3D_FACE_BACK",
+    "SVGA3D_FACE_FRONT_BACK",
+};
+
+static const char * const g_apszLightTypes[] =
+{
+    "SVGA3D_LIGHTTYPE_INVALID",
+    "SVGA3D_LIGHTTYPE_POINT",
+    "SVGA3D_LIGHTTYPE_SPOT1",
+    "SVGA3D_LIGHTTYPE_SPOT2",
+    "SVGA3D_LIGHTTYPE_DIRECTIONAL",
+};
+
+static const char * const g_apszRenderTargets[] =
+{
+    "SVGA3D_RT_DEPTH",
+    "SVGA3D_RT_STENCIL",
+    "SVGA3D_RT_COLOR0",
+    "SVGA3D_RT_COLOR1",
+    "SVGA3D_RT_COLOR2",
+    "SVGA3D_RT_COLOR3",
+    "SVGA3D_RT_COLOR4",
+    "SVGA3D_RT_COLOR5",
+    "SVGA3D_RT_COLOR6",
+    "SVGA3D_RT_COLOR7",
+};
+
+static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
+{
+    char szTmp[128];
+
+    pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
+#ifdef RT_OS_WINDOWS
+    pHlp->pfnPrintf(pHlp, "hwnd:                    %p\n", pContext->hwnd);
+    if (fVerbose)
+        vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
+# ifdef VMSVGA3D_DIRECT3D
+    pHlp->pfnPrintf(pHlp, "pDevice:                 %p\n", pContext->pDevice);
+# else
+    pHlp->pfnPrintf(pHlp, "hdc:                     %p\n", pContext->hdc);
+    pHlp->pfnPrintf(pHlp, "hglrc:                   %p\n", pContext->hglrc);
+# endif
+#else
+/** @todo Other hosts... */
+#endif
+    pHlp->pfnPrintf(pHlp, "sidRenderTarget:         %#x\n", pContext->sidRenderTarget);
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
+        if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
+            pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]:    %#x\n", i, pContext->aSidActiveTexture[i]);
+
+    pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
+        if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
+            pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
+                            vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
+        for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
+            if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
+                pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
+                                vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
+
+    AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
+        if (pContext->state.aTransformState[i].fValid)
+        {
+            pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
+            for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
+                pHlp->pfnPrintf(pHlp,
+                                (j % 4) == 0 ? "    [ " FLOAT_FMT_STR : (j % 4) < 3  ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
+                                FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
+        }
+
+    AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
+        if (pContext->state.aMaterial[i].fValid)
+        {
+            pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
+                            g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
+            pHlp->pfnPrintf(pHlp, "    diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
+            pHlp->pfnPrintf(pHlp, "    ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
+            pHlp->pfnPrintf(pHlp, "    specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
+            pHlp->pfnPrintf(pHlp, "    emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
+        }
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
+        if (pContext->state.aClipPlane[i].fValid)
+            pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
+        if (pContext->state.aLightData[i].fValidData)
+        {
+            pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
+                            i,
+                            pContext->state.aLightData[i].fEnabled,
+                            pContext->state.aLightData[i].data.inWorldSpace,
+                            pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
+                            ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
+                            pContext->state.aLightData[i].data.type);
+            pHlp->pfnPrintf(pHlp, "    diffuse  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
+            pHlp->pfnPrintf(pHlp, "    specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
+            pHlp->pfnPrintf(pHlp, "    ambient  =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
+            pHlp->pfnPrintf(pHlp, "    position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
+            pHlp->pfnPrintf(pHlp, "    direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
+            pHlp->pfnPrintf(pHlp, "    range=" FLOAT_FMT_STR "  falloff=" FLOAT_FMT_STR "\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
+            pHlp->pfnPrintf(pHlp, "    attenuation0=" FLOAT_FMT_STR "  attenuation1=" FLOAT_FMT_STR "  attenuation2=" FLOAT_FMT_STR "\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
+            pHlp->pfnPrintf(pHlp, "    theta=" FLOAT_FMT_STR "  phi=" FLOAT_FMT_STR "\n",
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
+                            FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
+        }
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
+        if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
+            pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
+                            i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
+                            pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
+
+    pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
+                    pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
+                    pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
+    pHlp->pfnPrintf(pHlp, "zRange:        (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
+                    FLOAT_FMT_ARGS(pContext->state.zRange.min),
+                    FLOAT_FMT_ARGS(pContext->state.zRange.max));
+    pHlp->pfnPrintf(pHlp, "fUpdateFlags:            %#x\n", pContext->state.u32UpdateFlags);
+    pHlp->pfnPrintf(pHlp, "shidPixel:               %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
+    pHlp->pfnPrintf(pHlp, "shidVertex:              %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
+
+    for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
+    {
+        uint32_t            cConsts  = iWhich == 0 ? pContext->state.cPixelShaderConst   : pContext->state.cVertexShaderConst;
+        PVMSVGASHADERCONST  paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst  : pContext->state.paVertexShaderConst;
+        const char         *pszName  = iWhich      ?                "paPixelShaderConst" :                "paVertexShaderConst";
+
+        for (uint32_t i = 0; i < cConsts; i++)
+            if (paConsts[i].fValid)
+            {
+                if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
+                    pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
+                                    pszName, i, i,
+                                    FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
+                                    FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
+                else
+                    pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
+                                    pszName, i, i,
+                                    paConsts[i].value[0], paConsts[i].value[1],
+                                    paConsts[i].value[2], paConsts[i].value[3],
+                                    paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
+                                    : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
+            }
+    }
+
+    for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
+    {
+        uint32_t        cShaders  = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
+        PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
+        const char     *pszName   = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
+        for (uint32_t i = 0; i < cShaders; i++)
+            if (paShaders[i].id == i)
+            {
+                pHlp->pfnPrintf(pHlp, "%s[%u]:   id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
+                                pszName, i,
+                                paShaders[i].id,
+                                paShaders[i].cid,
+                                paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
+                                : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
+                                paShaders[i].type,
+                                paShaders[i].cbData,
+                                paShaders[i].pShaderProgram);
+            }
+    }
+}
+
+
+void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
+{
+    /* Warning! This code is currently racing papContexts reallocation! */
+    /* Warning! This code is currently racing papContexts reallocation! */
+    /* Warning! This code is currently racing papContexts reallocation! */
+    VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
+    if (pState)
+    {
+        /*
+         * Deal with a specific request first.
+         */
+        if (cid != UINT32_MAX)
+        {
+            if (cid < pState->cContexts)
+            {
+                PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
+                if (pContext && pContext->id == cid)
+                {
+                    vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
+                    return;
+                }
+            }
+            pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
+        }
+        else
+        {
+            /*
+             * Dump all.
+             */
+            uint32_t cContexts = pState->cContexts;
+            pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
+            for (cid = 0; cid < cContexts; cid++)
+            {
+                PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
+                if (pContext && pContext->id == cid)
+                {
+                    pHlp->pfnPrintf(pHlp, "\n");
+                    vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
+                }
+            }
+        }
+    }
+}
+
+/** Values for SVGA3dTextureFilter, prefix SVGA3D_TEX_FILTER_. */
+static const char * const g_apszTexureFilters[] =
+{
+    "NONE",
+    "NEAREST",
+    "LINEAR",
+    "ANISOTROPIC",
+    "FLATCUBIC",
+    "GAUSSIANCUBIC",
+    "PYRAMIDALQUAD",
+    "GAUSSIANQUAD",
+};
+
+/** SVGA3dSurfaceFlags values, prefix SVGA3D_SURFACE_. */
+static VMSVGAINFOFLAGS32 const g_aSvga3DSurfaceFlags[] =
+{
+    { SVGA3D_SURFACE_CUBEMAP            , "CUBEMAP" },
+    { SVGA3D_SURFACE_HINT_STATIC        , "HINT_STATIC" },
+    { SVGA3D_SURFACE_HINT_DYNAMIC       , "HINT_DYNAMIC" },
+    { SVGA3D_SURFACE_HINT_INDEXBUFFER   , "HINT_INDEXBUFFER" },
+    { SVGA3D_SURFACE_HINT_VERTEXBUFFER  , "HINT_VERTEXBUFFER" },
+    { SVGA3D_SURFACE_HINT_TEXTURE       , "HINT_TEXTURE" },
+    { SVGA3D_SURFACE_HINT_RENDERTARGET  , "HINT_RENDERTARGET" },
+    { SVGA3D_SURFACE_HINT_DEPTHSTENCIL  , "HINT_DEPTHSTENCIL" },
+    { SVGA3D_SURFACE_HINT_WRITEONLY     , "HINT_WRITEONLY" },
+    { SVGA3D_SURFACE_MASKABLE_ANTIALIAS , "MASKABLE_ANTIALIAS" },
+    { SVGA3D_SURFACE_AUTOGENMIPMAPS     , "AUTOGENMIPMAPS" },
+};
+
+
+#ifdef VMSVGA3D_DIRECT3D
+
+/** Values for D3DFORMAT, prefix D3DFMT_. */
+static VMSVGAINFOENUM const g_aD3DFormats[] =
+{
+    { D3DFMT_UNKNOWN        , "UNKNOWN" },
+    { D3DFMT_R8G8B8         , "R8G8B8" },
+    { D3DFMT_A8R8G8B8       , "A8R8G8B8" },
+    { D3DFMT_X8R8G8B8       , "X8R8G8B8" },
+    { D3DFMT_R5G6B5         , "R5G6B5" },
+    { D3DFMT_X1R5G5B5       , "X1R5G5B5" },
+    { D3DFMT_A1R5G5B5       , "A1R5G5B5" },
+    { D3DFMT_A4R4G4B4       , "A4R4G4B4" },
+    { D3DFMT_R3G3B2         , "R3G3B2" },
+    { D3DFMT_A8             , "A8" },
+    { D3DFMT_A8R3G3B2       , "A8R3G3B2" },
+    { D3DFMT_X4R4G4B4       , "X4R4G4B4" },
+    { D3DFMT_A2B10G10R10    , "A2B10G10R10" },
+    { D3DFMT_A8B8G8R8       , "A8B8G8R8" },
+    { D3DFMT_X8B8G8R8       , "X8B8G8R8" },
+    { D3DFMT_G16R16         , "G16R16" },
+    { D3DFMT_A2R10G10B10    , "A2R10G10B10" },
+    { D3DFMT_A16B16G16R16   , "A16B16G16R16" },
+    { D3DFMT_A8P8           , "A8P8" },
+    { D3DFMT_P8             , "P8" },
+    { D3DFMT_L8             , "L8" },
+    { D3DFMT_A8L8           , "A8L8" },
+    { D3DFMT_A4L4           , "A4L4" },
+    { D3DFMT_V8U8           , "V8U8" },
+    { D3DFMT_L6V5U5         , "L6V5U5" },
+    { D3DFMT_X8L8V8U8       , "X8L8V8U8" },
+    { D3DFMT_Q8W8V8U8       , "Q8W8V8U8" },
+    { D3DFMT_V16U16         , "V16U16" },
+    { D3DFMT_A2W10V10U10    , "A2W10V10U10" },
+    { D3DFMT_D16_LOCKABLE   , "D16_LOCKABLE" },
+    { D3DFMT_D32            , "D32" },
+    { D3DFMT_D15S1          , "D15S1" },
+    { D3DFMT_D24S8          , "D24S8" },
+    { D3DFMT_D24X8          , "D24X8" },
+    { D3DFMT_D24X4S4        , "D24X4S4" },
+    { D3DFMT_D16            , "D16" },
+    { D3DFMT_L16            , "L16" },
+    { D3DFMT_D32F_LOCKABLE  , "D32F_LOCKABLE" },
+    { D3DFMT_D24FS8         , "D24FS8" },
+    { D3DFMT_VERTEXDATA     , "VERTEXDATA" },
+    { D3DFMT_INDEX16        , "INDEX16" },
+    { D3DFMT_INDEX32        , "INDEX32" },
+    { D3DFMT_Q16W16V16U16   , "Q16W16V16U16" },
+    { D3DFMT_R16F           , "R16F" },
+    { D3DFMT_G16R16F        , "G16R16F" },
+    { D3DFMT_A16B16G16R16F  , "A16B16G16R16F" },
+    { D3DFMT_R32F           , "R32F" },
+    { D3DFMT_G32R32F        , "G32R32F" },
+    { D3DFMT_A32B32G32R32F  , "A32B32G32R32F" },
+    { D3DFMT_CxV8U8         , "CxV8U8" },
+    { D3DFMT_UYVY           , "UYVY" },
+    { D3DFMT_YUY2           , "YUY2" },
+    { D3DFMT_DXT1           , "DXT1" },
+    { D3DFMT_DXT2           , "DXT2" },
+    { D3DFMT_DXT3           , "DXT3" },
+    { D3DFMT_DXT4           , "DXT4" },
+    { D3DFMT_DXT5           , "DXT5" },
+    { D3DFMT_MULTI2_ARGB8   , "MULTI2_ARGB8" },
+    { D3DFMT_G8R8_G8B8      , "G8R8_G8B8" },
+    { D3DFMT_R8G8_B8G8      , "R8G8_B8G8" },
+    { D3DFMT_FORCE_DWORD    , "FORCE_DWORD" },
+};
+
+/** Values for D3DMULTISAMPLE_TYPE, prefix D3DMULTISAMPLE_. */
+static VMSVGAINFOENUM const g_aD3DMultiSampleTypes[] =
+{
+    { D3DMULTISAMPLE_NONE           , "NONE" },
+    { D3DMULTISAMPLE_NONMASKABLE    , "NONMASKABLE" },
+    { D3DMULTISAMPLE_2_SAMPLES      , "2_SAMPLES" },
+    { D3DMULTISAMPLE_3_SAMPLES      , "3_SAMPLES" },
+    { D3DMULTISAMPLE_4_SAMPLES      , "4_SAMPLES" },
+    { D3DMULTISAMPLE_5_SAMPLES      , "5_SAMPLES" },
+    { D3DMULTISAMPLE_6_SAMPLES      , "6_SAMPLES" },
+    { D3DMULTISAMPLE_7_SAMPLES      , "7_SAMPLES" },
+    { D3DMULTISAMPLE_8_SAMPLES      , "8_SAMPLES" },
+    { D3DMULTISAMPLE_9_SAMPLES      , "9_SAMPLES" },
+    { D3DMULTISAMPLE_10_SAMPLES     , "10_SAMPLES" },
+    { D3DMULTISAMPLE_11_SAMPLES     , "11_SAMPLES" },
+    { D3DMULTISAMPLE_12_SAMPLES     , "12_SAMPLES" },
+    { D3DMULTISAMPLE_13_SAMPLES     , "13_SAMPLES" },
+    { D3DMULTISAMPLE_14_SAMPLES     , "14_SAMPLES" },
+    { D3DMULTISAMPLE_15_SAMPLES     , "15_SAMPLES" },
+    { D3DMULTISAMPLE_16_SAMPLES     , "16_SAMPLES" },
+    { D3DMULTISAMPLE_FORCE_DWORD    , "FORCE_DWORD" },
+};
+
+/** D3DUSAGE_XXX flag value, prefix D3DUSAGE_. */
+static VMSVGAINFOFLAGS32 const g_aD3DUsageFlags[] =
+{
+    { D3DUSAGE_RENDERTARGET                     , "RENDERTARGET" },
+    { D3DUSAGE_DEPTHSTENCIL                     , "DEPTHSTENCIL" },
+    { D3DUSAGE_WRITEONLY                        , "WRITEONLY" },
+    { D3DUSAGE_SOFTWAREPROCESSING               , "SOFTWAREPROCESSING" },
+    { D3DUSAGE_DONOTCLIP                        , "DONOTCLIP" },
+    { D3DUSAGE_POINTS                           , "POINTS" },
+    { D3DUSAGE_RTPATCHES                        , "RTPATCHES" },
+    { D3DUSAGE_NPATCHES                         , "NPATCHES" },
+    { D3DUSAGE_DYNAMIC                          , "DYNAMIC" },
+    { D3DUSAGE_AUTOGENMIPMAP                    , "AUTOGENMIPMAP" },
+    { D3DUSAGE_RESTRICTED_CONTENT               , "RESTRICTED_CONTENT" },
+    { D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER  , "RESTRICT_SHARED_RESOURCE_DRIVER" },
+    { D3DUSAGE_RESTRICT_SHARED_RESOURCE         , "RESTRICT_SHARED_RESOURCE" },
+    { D3DUSAGE_DMAP                             , "DMAP" },
+    { D3DUSAGE_NONSECURE                        , "NONSECURE" },
+    { D3DUSAGE_TEXTAPI                          , "TEXTAPI" },
+};
+
+
+/**
+ * Release all shared surface objects.
+ */
+static DECLCALLBACK(int) vmsvga3dInfoSharedObjectCallback(PAVLU32NODECORE pNode, void *pvUser)
+{
+    PVMSVGA3DSHAREDSURFACE  pSharedSurface = (PVMSVGA3DSHAREDSURFACE)pNode;
+    PCDBGFINFOHLP           pHlp           = (PCDBGFINFOHLP)pvUser;
+
+    pHlp->pfnPrintf(pHlp, "Shared surface:          %#x  pv=%p\n", pSharedSurface->Core.Key, pSharedSurface->u.pCubeTexture);
+
+    return 0;
+}
+
+#elif defined(VMSVGA3D_OPENGL)
+    /** @todo   */
+
+#else
+# error "Build config error."
+#endif
+
+
+static void vmsvga3dInfoSurfaceWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
+                                         bool fVerbose, uint32_t cxAscii, bool fInvY)
+{
+    char szTmp[128];
+
+    pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : "");
+#if defined(VMSVGA3D_OPENGL) && defined(VMSVGA3D_OGL_WITH_SHARED_CTX)
+    pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation);
+#else
+    pHlp->pfnPrintf(pHlp, "idAssociatedContext:     %#x\n", pSurface->idAssociatedContext);
+#endif
+    pHlp->pfnPrintf(pHlp, "Format:                  %s (%d)\n", vmsvgaSurfaceType2String(pSurface->format), pSurface->format);
+    pHlp->pfnPrintf(pHlp, "Flags:                   %#x", pSurface->flags);
+    vmsvga3dInfoU32Flags(pHlp, pSurface->flags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags));
+    pHlp->pfnPrintf(pHlp, "\n");
+    if (pSurface->cFaces == 0)
+        pHlp->pfnPrintf(pHlp, "Faces:                   %u\n", pSurface->cFaces);
+    for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
+    {
+        Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
+        if (pSurface->faces[iFace].numMipLevels == 0)
+            pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels:  %u\n", iFace, pSurface->faces[iFace].numMipLevels);
+
+        uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
+        for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
+        {
+            pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s  cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x",
+                            iFace, iLevel, iMipmap, iMipmap < 10 ? " " : "",
+                            pSurface->pMipmapLevels[iMipmap].size.width,
+                            pSurface->pMipmapLevels[iMipmap].size.height,
+                            pSurface->pMipmapLevels[iMipmap].size.depth,
+                            pSurface->pMipmapLevels[iMipmap].cbSurface,
+                            pSurface->pMipmapLevels[iMipmap].cbSurfacePitch);
+            if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
+                pHlp->pfnPrintf(pHlp, " pvData=%p", pSurface->pMipmapLevels[iMipmap].pSurfaceData);
+            if (pSurface->pMipmapLevels[iMipmap].fDirty)
+                pHlp->pfnPrintf(pHlp, " dirty");
+            pHlp->pfnPrintf(pHlp, "\n");
+        }
+    }
+
+    pHlp->pfnPrintf(pHlp, "cbBlock:                 %u (%#x)\n", pSurface->cbBlock, pSurface->cbBlock);
+    pHlp->pfnPrintf(pHlp, "Multi-sample count:      %u\n", pSurface->multiSampleCount);
+    pHlp->pfnPrintf(pHlp, "Autogen filter:          %s\n",
+                    vmsvgaFormatEnumValue(szTmp, sizeof(szTmp), NULL, pSurface->autogenFilter,
+                                          "SVGA3D_TEX_FILTER_", g_apszTexureFilters, RT_ELEMENTS(g_apszTexureFilters)));
+
+#ifdef VMSVGA3D_DIRECT3D
+    pHlp->pfnPrintf(pHlp, "formatD3D:               %s\n",
+                    vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->formatD3D,
+                                            "D3DFMT_", g_aD3DFormats, RT_ELEMENTS(g_aD3DFormats)));
+    pHlp->pfnPrintf(pHlp, "fUsageD3D:               %#x", pSurface->fUsageD3D);
+    vmsvga3dInfoU32Flags(pHlp, pSurface->fUsageD3D, "D3DUSAGE_", g_aD3DUsageFlags, RT_ELEMENTS(g_aD3DUsageFlags));
+    pHlp->pfnPrintf(pHlp, "\n");
+    pHlp->pfnPrintf(pHlp, "multiSampleTypeD3D:      %s\n",
+                    vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->multiSampleTypeD3D,
+                                            "D3DMULTISAMPLE", g_aD3DMultiSampleTypes, RT_ELEMENTS(g_aD3DMultiSampleTypes)));
+    if (pSurface->hSharedObject != NULL)
+        pHlp->pfnPrintf(pHlp, "hSharedObject:           %p\n", pSurface->hSharedObject);
+    if (pSurface->pQuery)
+        pHlp->pfnPrintf(pHlp, "pQuery:                  %p\n", pSurface->pQuery);
+    if (pSurface->u.pSurface)
+        pHlp->pfnPrintf(pHlp, "u.pXxxx:                 %p\n", pSurface->u.pSurface);
+    if (pSurface->bounce.pTexture)
+        pHlp->pfnPrintf(pHlp, "bounce.pXxxx:            %p\n", pSurface->bounce.pTexture);
+    RTAvlU32DoWithAll(&pSurface->pSharedObjectTree, true /*fFromLeft*/, vmsvga3dInfoSharedObjectCallback, (void *)pHlp);
+    pHlp->pfnPrintf(pHlp, "fStencilAsTexture:       %RTbool\n", pSurface->fStencilAsTexture);
+
+#elif defined(VMSVGA3D_OPENGL)
+    /** @todo   */
+#else
+# error "Build config error."
+#endif
+
+    if (fVerbose)
+        for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
+        {
+            uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
+            for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
+                if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
+                {
+                    if (  ASMMemIsAll8(pSurface->pMipmapLevels[iMipmap].pSurfaceData,
+                                       pSurface->pMipmapLevels[iMipmap].cbSurface, 0) == NULL)
+                        pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: all zeros ---\n", iFace, iLevel, iMipmap);
+                    else
+                    {
+                        pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: cx=%u, cy=%u, cz=%u ---\n",
+                                        iFace, iLevel, iMipmap,
+                                        pSurface->pMipmapLevels[iMipmap].size.width,
+                                        pSurface->pMipmapLevels[iMipmap].size.height,
+                                        pSurface->pMipmapLevels[iMipmap].size.depth);
+                        vmsvga3dAsciiPrint(vmsvga3dAsciiPrintlnInfo, (void *)pHlp,
+                                           pSurface->pMipmapLevels[iMipmap].pSurfaceData,
+                                           pSurface->pMipmapLevels[iMipmap].cbSurface,
+                                           pSurface->pMipmapLevels[iMipmap].size.width,
+                                           pSurface->pMipmapLevels[iMipmap].size.height,
+                                           pSurface->pMipmapLevels[iMipmap].cbSurfacePitch,
+                                           pSurface->format,
+                                           fInvY,
+                                           cxAscii, cxAscii * 3 / 4);
+                    }
+                }
+        }
+}
+
+
+void vmsvga3dInfoSurfaceWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t sid, bool fVerbose, uint32_t cxAscii, bool fInvY)
+{
+    /* Warning! This code is currently racing papSurfaces reallocation! */
+    /* Warning! This code is currently racing papSurfaces reallocation! */
+    /* Warning! This code is currently racing papSurfaces reallocation! */
+    VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
+    if (pState)
+    {
+        /*
+         * Deal with a specific request first.
+         */
+        if (sid != UINT32_MAX)
+        {
+            if (sid < pState->cSurfaces)
+            {
+                PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
+                if (pSurface && pSurface->id == sid)
+                {
+                    if (fVerbose)
+                        vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, sid);
+                    vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
+                    return;
+                }
+            }
+            pHlp->pfnPrintf(pHlp, "Surface ID %#x not found.\n", sid);
+        }
+        else
+        {
+            /*
+             * Dump all.
+             */
+            if (fVerbose)
+                vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, UINT32_MAX);
+            uint32_t cSurfaces = pState->cSurfaces;
+            pHlp->pfnPrintf(pHlp, "cSurfaces=%d\n", cSurfaces);
+            for (sid = 0; sid < cSurfaces; sid++)
+            {
+                PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
+                if (pSurface && pSurface->id == sid)
+                {
+                    pHlp->pfnPrintf(pHlp, "\n");
+                    vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
+                }
+            }
+        }
+    }
+
+}
+
+
 #endif /* !___DevVGA_SVGA3d_shared_h___ */
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp	(revision 57081)
@@ -329,5 +329,5 @@
 };
 
-typedef struct
+typedef struct VMSVGA3DSTATE
 {
 #ifdef VBOX_VMSVGA3D_WITH_OPENGL
@@ -355,5 +355,5 @@
     bool                    fSupportedSurfaceINTZ;
     bool                    fSupportedSurfaceNULL;
-} VMSVGA3DSTATE, *PVMSVGA3DSTATE;
+} VMSVGA3DSTATE;
 
 /**
@@ -474,7 +474,6 @@
     int rc;
 
-    pThis->svga.p3dState = RTMemAllocZ(sizeof(VMSVGA3DSTATE));
+    pThis->svga.p3dState = pState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
-    pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
 
     /* Create event semaphore. */
@@ -499,5 +498,5 @@
 int vmsvga3dPowerOn(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
     HRESULT hr;
@@ -592,5 +591,5 @@
 int vmsvga3dReset(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
 
@@ -613,5 +612,5 @@
 int vmsvga3dTerminate(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
 
@@ -732,5 +731,5 @@
 int vmsvga3dQueryCaps(PVGASTATE pThis, uint32_t idx3dCaps, uint32_t *pu32Val)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     D3DCAPS9 *pCaps = &pState->caps;
@@ -1389,5 +1388,5 @@
 {
     PVMSVGA3DSURFACE pSurface;
-    PVMSVGA3DSTATE   pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE   pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -1590,5 +1589,5 @@
  * Release all shared surface objects.
  */
-static int vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pParam)
+static DECLCALLBACK(int) vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pParam)
 {
     PVMSVGA3DSHAREDSURFACE pSharedSurface = (PVMSVGA3DSHAREDSURFACE)pNode;
@@ -1615,5 +1614,5 @@
 int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -1758,5 +1757,5 @@
 static int vmsvga3dSurfaceTrackUsage(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t sid)
 {
-    PVMSVGA3DSTATE   pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE   pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE pSurface  = pState->papSurfaces[sid];
     HRESULT          hr;
@@ -1819,5 +1818,5 @@
 int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurfaceSrc;
     uint32_t            sidSrc = src.sid;
@@ -2193,5 +2192,5 @@
 int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dBox destBox, SVGA3dSurfaceImageId src, SVGA3dBox srcBox, SVGA3dStretchBltMode mode)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurfaceSrc;
     uint32_t            sidSrc = src.sid;
@@ -2323,5 +2322,5 @@
                        uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
 {
-    PVMSVGA3DSTATE          pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE          pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE        pSurface;
     PVMSVGA3DMIPMAPLEVEL    pMipLevel;
@@ -2689,5 +2688,5 @@
 #if 0
         {
-            PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+            PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
             HRESULT hr;
             PVMSVGA3DSURFACE    pSurface;
@@ -2731,5 +2730,5 @@
 int vmsvga3dGenerateMipmaps(PVGASTATE pThis, uint32_t sid, SVGA3dTextureFilter filter)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurface;
     int                 rc = VINF_SUCCESS;
@@ -2784,5 +2783,5 @@
 int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE    pSurface;
     int                 rc = VINF_SUCCESS;
@@ -2925,5 +2924,5 @@
     HRESULT                 hr;
     D3DPRESENT_PARAMETERS   PresParam;
-    PVMSVGA3DSTATE          pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE          pState = pThis->svga.p3dState;
 
     AssertReturn(pState, VERR_NO_MEMORY);
@@ -3042,5 +3041,5 @@
 int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -3184,5 +3183,5 @@
 int vmsvga3dChangeMode(PVGASTATE pThis)
 {
-    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -3437,5 +3436,5 @@
     HRESULT               hr;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -3519,5 +3518,5 @@
     HRESULT               hr;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -3595,5 +3594,5 @@
     HRESULT                     hr;
     PVMSVGA3DCONTEXT            pContext;
-    PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -4266,5 +4265,5 @@
     HRESULT                     hr;
     PVMSVGA3DCONTEXT            pContext;
-    PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
     PVMSVGA3DSURFACE            pRenderTarget;
 
@@ -4698,5 +4697,5 @@
     HRESULT                     hr;
     PVMSVGA3DCONTEXT            pContext;
-    PVMSVGA3DSTATE              pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE              pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -4967,5 +4966,5 @@
     D3DMATERIAL9          material;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5022,5 +5021,5 @@
     D3DLIGHT9             light;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5100,5 +5099,5 @@
     HRESULT               hr;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5130,5 +5129,5 @@
     D3DVIEWPORT9          viewPort;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5165,5 +5164,5 @@
     HRESULT               hr;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5194,5 +5193,5 @@
     HRESULT               hr;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5394,5 +5393,5 @@
 {
     PVMSVGA3DCONTEXT             pContext;
-    PVMSVGA3DSTATE               pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE               pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_INTERNAL_ERROR);
     int                          rc;
@@ -5694,5 +5693,5 @@
     RECT                  rect;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5728,5 +5727,5 @@
     PVMSVGA3DCONTEXT      pContext;
     PVMSVGA3DSHADER       pShader;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
@@ -5827,5 +5826,5 @@
 {
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     PVMSVGA3DSHADER       pShader = NULL;
@@ -5877,5 +5876,5 @@
 int vmsvga3dShaderSet(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
 {
-    PVMSVGA3DSTATE      pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE      pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
     HRESULT             hr;
@@ -5951,5 +5950,5 @@
     HRESULT               hr;
     PVMSVGA3DCONTEXT      pContext;
-    PVMSVGA3DSTATE        pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+    PVMSVGA3DSTATE        pState = pThis->svga.p3dState;
     AssertReturn(pState, VERR_NO_MEMORY);
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h	(revision 57081)
@@ -23,17 +23,4 @@
 #include "vmsvga/svga_overlay.h"
 
-#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
-# include <Windows.h>
-
-# define WM_VMSVGA3D_WAKEUP                     (WM_APP+1)
-# define WM_VMSVGA3D_CREATEWINDOW               (WM_APP+2)
-# define WM_VMSVGA3D_DESTROYWINDOW              (WM_APP+3)
-# define WM_VMSVGA3D_RESIZEWINDOW               (WM_APP+4)
-# define WM_VMSVGA3D_EXIT                       (WM_APP+5)
-
-DECLCALLBACK(int) vmsvga3dWindowThread(RTTHREAD ThreadSelf, void *pvUser);
-int vmsvga3dSendThreadMessage(RTTHREAD pWindowThread, RTSEMEVENT WndRequestSem, UINT msg, WPARAM wParam, LPARAM lParam);
-
-#endif
 
 /** Arbitrary limit */
@@ -44,8 +31,22 @@
 #define SVGA3D_MAX_LIGHTS                       32
 
+
+/**@def FLOAT_FMT_STR
+ * Format string bits to go with FLOAT_FMT_ARGS. */
+#define FLOAT_FMT_STR                           "%d.%06d"
+/** @def FLOAT_FMT_ARGS
+ * Format arguments for a float value, corresponding to FLOAT_FMT_STR.
+ * @param   r       The floating point value to format.  */
+#define FLOAT_FMT_ARGS(r)                       (int)(r), ((unsigned)((r) * 1000000) % 1000000U)
+
+
+/* DevVGA-SVGA.cpp: */
 void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR);
 int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pDest, int32_t cbDestPitch,
                       SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight);
+void vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(PVGASTATE pThis, uint32_t sid);
 
+
+/* DevVGA-SVGA3d-ogl.cpp & DevVGA-SVGA3d-win.cpp: */
 int vmsvga3dInit(PVGASTATE pThis);
 int vmsvga3dPowerOn(PVGASTATE pThis);
@@ -93,4 +94,75 @@
 int vmsvga3dQueryWait(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type, SVGAGuestPtr guestResult);
 
+/* DevVGA-SVGA3d-shared.h: */
+#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
+# include <Windows.h>
+
+# define WM_VMSVGA3D_WAKEUP                     (WM_APP+1)
+# define WM_VMSVGA3D_CREATEWINDOW               (WM_APP+2)
+# define WM_VMSVGA3D_DESTROYWINDOW              (WM_APP+3)
+# define WM_VMSVGA3D_RESIZEWINDOW               (WM_APP+4)
+# define WM_VMSVGA3D_EXIT                       (WM_APP+5)
+
+DECLCALLBACK(int) vmsvga3dWindowThread(RTTHREAD ThreadSelf, void *pvUser);
+int vmsvga3dSendThreadMessage(RTTHREAD pWindowThread, RTSEMEVENT WndRequestSem, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#endif
+
+void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid);
+void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose);
+void vmsvga3dInfoSurfaceWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t sid, bool fVerbose, uint32_t cxAscii, bool fInvY);
+
+
+/* DevVGA-SVGA3d-shared.cpp: */
+
+/**
+ * Structure for use with vmsvga3dInfoU32Flags.
+ */
+typedef struct VMSVGAINFOFLAGS32
+{
+    /** The flags. */
+    uint32_t    fFlags;
+    /** The corresponding mnemonic. */
+    const char *pszJohnny;
+} VMSVGAINFOFLAGS32;
+/** Pointer to a read-only flag translation entry. */
+typedef VMSVGAINFOFLAGS32 const *PCVMSVGAINFOFLAGS32;
+void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags);
+
+/**
+ * Structure for use with vmsvgaFormatEnumValueEx and vmsvgaFormatEnumValue.
+ */
+typedef struct VMSVGAINFOENUM
+{
+    /** The enum value. */
+    int32_t     iValue;
+    /** The corresponding value name. */
+    const char *pszName;
+} VMSVGAINFOENUM;
+/** Pointer to a read-only enum value translation entry. */
+typedef VMSVGAINFOENUM const *PCVMSVGAINFOENUM;
+char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
+                              const char *pszPrefix, PCVMSVGAINFOENUM paValues, size_t cValues);
+char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
+                            const char *pszPrefix, const char * const *papszValues, size_t cValues);
+
+/**
+ * ASCII "art" scanline printer callback.
+ *
+ * @param   pszLine         The line to output.
+ * @param   pvUser          The user argument.
+ */
+typedef DECLCALLBACK(void) FMVMSVGAASCIIPRINTLN(const char *pszLine, void *pvUser);
+/** Pointer to an ASCII "art" print line callback. */
+typedef FMVMSVGAASCIIPRINTLN *PFMVMSVGAASCIIPRINTLN;
+void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
+                        uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
+                        uint32_t cchMaxX, uint32_t cchMaxY);
+DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser);
+DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser);
+
+char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState);
+char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState);
+void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow);
 
 uint32_t vmsvga3dSurfaceFormatSize(SVGA3dSurfaceFormat format);
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 57080)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 57081)
@@ -214,9 +214,10 @@
 #ifdef VBOX_WITH_VMSVGA
 
-#define VMSVGA_FIFO_EXTCMD_NONE                 0
-#define VMSVGA_FIFO_EXTCMD_TERMINATE            1
-#define VMSVGA_FIFO_EXTCMD_SAVESTATE            2
-#define VMSVGA_FIFO_EXTCMD_LOADSTATE            3
-#define VMSVGA_FIFO_EXTCMD_RESET                4
+#define VMSVGA_FIFO_EXTCMD_NONE                         0
+#define VMSVGA_FIFO_EXTCMD_TERMINATE                    1
+#define VMSVGA_FIFO_EXTCMD_SAVESTATE                    2
+#define VMSVGA_FIFO_EXTCMD_LOADSTATE                    3
+#define VMSVGA_FIFO_EXTCMD_RESET                        4
+#define VMSVGA_FIFO_EXTCMD_UPDATE_SURFACE_HEAP_BUFFERS  5
 
 /** Size of the region to backup when switching into svga mode. */
@@ -230,5 +231,12 @@
 } VMSVGA_STATE_LOAD, *PVMSVGA_STATE_LOAD;
 
-typedef struct
+/** Pointer to the private VMSVGA ring-3 state structure.
+ * @todo Still not entirely satisfired with the type name, but better than
+ *       the previous lower/upper case only distinction. */
+typedef struct VMSVGAR3STATE *PVMSVGAR3STATE;
+/** Pointer to the private (implementation specific) VMSVGA3d state. */
+typedef struct VMSVGA3DSTATE *PVMSVGA3DSTATE;
+
+typedef struct VMSVGAState
 {
     /** The host window handle */
@@ -239,7 +247,7 @@
     R0PTRTYPE(uint32_t *)       pFIFOR0;
     /** R3 Opaque pointer to svga state. */
-    R3PTRTYPE(void *)           pSVGAState;
+    R3PTRTYPE(PVMSVGAR3STATE)   pSvgaR3State;
     /** R3 Opaque pointer to 3d state. */
-    R3PTRTYPE(void *)           p3dState;
+    R3PTRTYPE(PVMSVGA3DSTATE)   p3dState;
     /** R3 Opaque pointer to a copy of the first 32k of the framebuffer before switching into svga mode. */
     R3PTRTYPE(void *)           pFrameBufferBackup;
Index: /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 57080)
+++ /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 57081)
@@ -334,5 +334,5 @@
     GEN_CHECK_OFF(VGASTATE, svga.pFIFOR3);
     GEN_CHECK_OFF(VGASTATE, svga.pFIFOR0);
-    GEN_CHECK_OFF(VGASTATE, svga.pSVGAState);
+    GEN_CHECK_OFF(VGASTATE, svga.pSvgaR3State);
     GEN_CHECK_OFF(VGASTATE, svga.p3dState);
     GEN_CHECK_OFF(VGASTATE, svga.pFrameBufferBackup);
