Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp	(revision 86847)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp	(revision 86855)
@@ -314,5 +314,75 @@
  */
 
-static int vmsvgaR3GboCreate(PVMSVGAR3STATE pSvgaR3State, SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, bool fGCPhys64, PVMSVGAGBO pGbo)
+/**
+ * HC access handler for GBOs which require write protection, i.e. OTables, etc.
+ *
+ * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
+ * @param   pVM             VM Handle.
+ * @param   pVCpu           The cross context CPU structure for the calling EMT.
+ * @param   GCPhys          The physical address the guest is writing to.
+ * @param   pvPhys          The HC mapping of that address.
+ * @param   pvBuf           What the guest is reading/writing.
+ * @param   cbBuf           How much it's reading/writing.
+ * @param   enmAccessType   The access type.
+ * @param   enmOrigin       Who is making the access.
+ * @param   pvUser          User argument.
+ */
+DECLCALLBACK(VBOXSTRICTRC)
+vmsvgaR3GboAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                         PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
+{
+    RT_NOREF(pVM, pVCpu, pvPhys, enmAccessType);
+
+    if (RT_LIKELY(enmOrigin == PGMACCESSORIGIN_DEVICE || enmOrigin == PGMACCESSORIGIN_DEBUGGER))
+        return VINF_PGM_HANDLER_DO_DEFAULT;
+
+    PPDMDEVINS  pDevIns = (PPDMDEVINS)pvUser;
+    PVGASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PVGASTATE);
+    PVGASTATECC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVGASTATECC);
+    PVMSVGAR3STATE pSvgaR3State = pThisCC->svga.pSvgaR3State;
+
+    /*
+     * The guest is not allowed to access the memory.
+     * Set the error condition.
+     */
+    ASMAtomicWriteBool(&pThis->svga.fBadGuest, true);
+
+    /* Try to find the GBO which the guest is accessing. */
+    char const *pszTarget = NULL;
+    for (uint32_t i = 0; i < RT_ELEMENTS(pSvgaR3State->aGboOTables) && !pszTarget; ++i)
+    {
+        PVMSVGAGBO pGbo = &pSvgaR3State->aGboOTables[i];
+        if (pGbo->cDescriptors)
+        {
+            for (uint32_t j = 0; j < pGbo->cDescriptors; ++j)
+            {
+                if (   GCPhys >= pGbo->paDescriptors[j].GCPhys
+                    && GCPhys < pGbo->paDescriptors[j].GCPhys + pGbo->paDescriptors[j].cPages * PAGE_SIZE)
+                {
+                    switch (i)
+                    {
+                        case SVGA_OTABLE_MOB:          pszTarget = "SVGA_OTABLE_MOB";          break;
+                        case SVGA_OTABLE_SURFACE:      pszTarget = "SVGA_OTABLE_SURFACE";      break;
+                        case SVGA_OTABLE_CONTEXT:      pszTarget = "SVGA_OTABLE_CONTEXT";      break;
+                        case SVGA_OTABLE_SHADER:       pszTarget = "SVGA_OTABLE_SHADER";       break;
+                        case SVGA_OTABLE_SCREENTARGET: pszTarget = "SVGA_OTABLE_SCREENTARGET"; break;
+                        case SVGA_OTABLE_DXCONTEXT:    pszTarget = "SVGA_OTABLE_DXCONTEXT";    break;
+                        default:                       pszTarget = "Unknown OTABLE";           break;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    LogRelMax(8, ("VMSVGA: invalid guest access to page %RGp, target %s:\n"
+                  "%.*Rhxd\n",
+                  GCPhys, pszTarget ? pszTarget : "unknown", RT_MIN(cbBuf, 256), pvBuf));
+
+    return VINF_PGM_HANDLER_DO_DEFAULT;
+}
+
+
+static int vmsvgaR3GboCreate(PVMSVGAR3STATE pSvgaR3State, SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, bool fGCPhys64, bool fWriteProtected, PVMSVGAGBO pGbo)
 {
     ASSERT_GUEST_RETURN(sizeInBytes <= _128M, VERR_INVALID_PARAMETER); /** @todo Less than SVGA_REG_MOB_MAX_SIZE */
@@ -481,4 +551,16 @@
         pGbo->paDescriptors = paDescriptors;
 
+    if (fWriteProtected)
+    {
+        pGbo->fGboFlags |= VMSVGAGBO_F_WRITE_PROTECTED;
+        for (uint32_t i = 0; i < pGbo->cDescriptors; ++i)
+        {
+            rc = PGMHandlerPhysicalRegister(PDMDevHlpGetVM(pSvgaR3State->pDevIns),
+                                            pGbo->paDescriptors[i].GCPhys, pGbo->paDescriptors[i].GCPhys + pGbo->paDescriptors[i].cPages * PAGE_SIZE - 1,
+                                            pSvgaR3State->hGboAccessHandlerType, pSvgaR3State->pDevIns, NIL_RTR0PTR, NIL_RTRCPTR, "VMSVGA GBO");
+            AssertRC(rc);
+        }
+    }
+
     return VINF_SUCCESS;
 }
@@ -487,7 +569,14 @@
 static void vmsvgaR3GboDestroy(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo)
 {
-    RT_NOREF(pSvgaR3State);
     if (RT_LIKELY(VMSVGA_IS_GBO_CREATED(pGbo)))
     {
+        if (pGbo->fGboFlags & VMSVGAGBO_F_WRITE_PROTECTED)
+        {
+            for (uint32_t i = 0; i < pGbo->cDescriptors; ++i)
+            {
+                int rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pSvgaR3State->pDevIns), pGbo->paDescriptors[i].GCPhys);
+                AssertRC(rc);
+            }
+        }
         RTMemFree(pGbo->paDescriptors);
         RT_ZERO(pGbo);
@@ -644,10 +733,10 @@
     entry.sizeInBytes = sizeInBytes;
     entry.base        = baseAddress;
-    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableMob,
+    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_MOB],
                                  mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry));
     if (RT_SUCCESS(rc))
     {
         /* Create the corresponding GBO. */
-        rc = vmsvgaR3GboCreate(pSvgaR3State, ptDepth, baseAddress, sizeInBytes, fGCPhys64, &pMob->Gbo);
+        rc = vmsvgaR3GboCreate(pSvgaR3State, ptDepth, baseAddress, sizeInBytes, fGCPhys64, /* fWriteProtected = */ false, &pMob->Gbo);
         if (RT_SUCCESS(rc))
         {
@@ -673,5 +762,5 @@
     SVGAOTableMobEntry entry;
     RT_ZERO(entry);
-    vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableMob,
+    vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_MOB],
                         mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry));
 
@@ -1008,5 +1097,5 @@
     // entry.arraySize = 0;
     // entry.mobPitch = 0;
-    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                                  pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
     if (RT_SUCCESS(rc))
@@ -1031,5 +1120,5 @@
     RT_ZERO(entry);
     entry.mobid = SVGA_ID_INVALID;
-    vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+    vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                         pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
 
@@ -1048,15 +1137,15 @@
     int rc = VINF_SUCCESS;
     if (pCmd->mobid != SVGA_ID_INVALID)
-        rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->GboOTableMob,
+        rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_MOB],
                                        pCmd->mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE);
     if (RT_SUCCESS(rc))
     {
         SVGAOTableSurfaceEntry entry;
-        rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+        rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                                 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
         if (RT_SUCCESS(rc))
         {
             entry.mobid = pCmd->mobid;
-            rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+            rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                                      pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
             if (RT_SUCCESS(rc))
@@ -1142,5 +1231,5 @@
     /* "update a surface from its backing MOB." */
     SVGAOTableSurfaceEntry entrySurface;
-    int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+    int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                             pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface));
     if (RT_SUCCESS(rc))
@@ -1202,35 +1291,13 @@
      */
     PVMSVGAGBO pGbo;
-    switch (pCmd->type)
-    {
-        case SVGA_OTABLE_MOB:
-        {
-            pGbo = &pSvgaR3State->GboOTableMob;
-            break;
-        }
-        case SVGA_OTABLE_SURFACE:
-        {
-            pGbo = &pSvgaR3State->GboOTableSurface;
-            break;
-        }
-        case SVGA_OTABLE_CONTEXT:
-        {
-            pGbo = &pSvgaR3State->GboOTableContext;
-            break;
-        }
-        case SVGA_OTABLE_SHADER:
-        {
-            pGbo = &pSvgaR3State->GboOTableShader;
-            break;
-        }
-        case SVGA_OTABLE_SCREENTARGET:
-        {
-            pGbo = &pSvgaR3State->GboOTableScreenTarget;
-            break;
-        }
-        default:
-            pGbo = NULL;
-            ASSERT_GUEST_FAILED();
-            break;
+    if (pCmd->type <= RT_ELEMENTS(pSvgaR3State->aGboOTables))
+    {
+        RT_UNTRUSTED_VALIDATED_FENCE();
+        pGbo = &pSvgaR3State->aGboOTables[pCmd->type];
+    }
+    else
+    {
+        ASSERT_GUEST_FAILED();
+        pGbo = NULL;
     }
 
@@ -1239,5 +1306,5 @@
         /* Recreate. */
         vmsvgaR3GboDestroy(pSvgaR3State, pGbo);
-        int rc = vmsvgaR3GboCreate(pSvgaR3State, pCmd->ptDepth, pCmd->baseAddress, pCmd->sizeInBytes, /*fGCPhys64=*/ true, pGbo);
+        int rc = vmsvgaR3GboCreate(pSvgaR3State, pCmd->ptDepth, pCmd->baseAddress, pCmd->sizeInBytes, /*fGCPhys64=*/ true, /* fWriteProtected = */ true, pGbo);
         AssertRC(rc);
     }
@@ -1268,5 +1335,5 @@
     entry.flags = pCmd->flags;
     entry.dpi = pCmd->dpi;
-    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
+    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
                                  pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
     if (RT_SUCCESS(rc))
@@ -1316,5 +1383,5 @@
     SVGAOTableScreenTargetEntry entry;
     RT_ZERO(entry);
-    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
+    int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
                                  pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
     if (RT_SUCCESS(rc))
@@ -1353,15 +1420,15 @@
     int rc = VINF_SUCCESS;
     if (pCmd->image.sid != SVGA_ID_INVALID)
-        rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+        rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                                        pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE);
     if (RT_SUCCESS(rc))
     {
         SVGAOTableScreenTargetEntry entry;
-        rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
+        rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
                                 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
         if (RT_SUCCESS(rc))
         {
             entry.image = pCmd->image;
-            rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
+            rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
                                      pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
             if (RT_SUCCESS(rc))
@@ -1388,5 +1455,5 @@
     /* Get the screen target info. */
     SVGAOTableScreenTargetEntry entryScreenTarget;
-    int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableScreenTarget,
+    int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
                                 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entryScreenTarget, sizeof(entryScreenTarget));
     if (RT_SUCCESS(rc))
@@ -1398,5 +1465,5 @@
         {
             SVGAOTableSurfaceEntry entrySurface;
-            rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->GboOTableSurface,
+            rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
                                     entryScreenTarget.image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface));
             if (RT_SUCCESS(rc))
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-internal.h
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-internal.h	(revision 86847)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-internal.h	(revision 86855)
@@ -78,5 +78,5 @@
 typedef struct VMSVGAGBO
 {
-    uint32_t                u32Reserved;
+    uint32_t                fGboFlags;
     uint32_t                cTotalPages;
     uint32_t                cbTotal;
@@ -85,4 +85,6 @@
 } VMSVGAGBO, *PVMSVGAGBO;
 typedef VMSVGAGBO const *PCVMSVGAGBO;
+
+#define VMSVGAGBO_F_WRITE_PROTECTED 1
 
 #define VMSVGA_IS_GBO_CREATED(a_Gbo) ((a_Gbo)->paDescriptors != NULL)
@@ -175,10 +177,9 @@
     RTCRITSECT              CritSectCmdBuf;
 
+    /** Write protected GBOs (OTables) access handler type handle. */
+    PGMPHYSHANDLERTYPE      hGboAccessHandlerType;
+
     /**  */
-    VMSVGAGBO               GboOTableMob;
-    VMSVGAGBO               GboOTableSurface;
-    VMSVGAGBO               GboOTableContext;
-    VMSVGAGBO               GboOTableShader;
-    VMSVGAGBO               GboOTableScreenTarget;
+    VMSVGAGBO               aGboOTables[SVGA_OTABLE_MAX];
 
     /** Tree of guest's Memory OBjects. Key is mobid. */
@@ -285,4 +286,7 @@
 #endif
 
+DECLCALLBACK(VBOXSTRICTRC) vmsvgaR3GboAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                                    PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser);
+
 void vmsvgaR3ResetScreens(PVGASTATE pThis, PVGASTATECC pThisCC);
 
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 86847)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 86855)
@@ -420,6 +420,6 @@
 
 
+#define SVGA_CASE_ID2STR(idx) case idx: return #idx
 #if defined(LOG_ENABLED)
-# define SVGA_CASE_ID2STR(idx) case idx: return #idx
 /**
  * Index register string name lookup
@@ -507,6 +507,264 @@
     }
 }
-# undef SVGA_CASE_ID2STR
 #endif /* LOG_ENABLED */
+
+static const char *vmsvgaDevCapIndexToString(SVGA3dDevCapIndex idxDevCap)
+{
+    switch (idxDevCap)
+    {
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_INVALID);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_3D);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_LIGHTS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_CLIP_PLANES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_VERTEX_SHADER_VERSION);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_VERTEX_SHADER);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_FRAGMENT_SHADER);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_RENDER_TARGETS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_S23E8_TEXTURES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_S10E5_TEXTURES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_D16_BUFFER_FORMAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_QUERY_TYPES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_POINT_SIZE);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_SHADER_TEXTURES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_VOLUME_EXTENT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_VERTEX_INDEX);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_TEXTURE_OPS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_R5G6B5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_ALPHA8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Z_D16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_DXT1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_DXT2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_DXT3);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_DXT4);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_DXT5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_CxV8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_R_S10E5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_R_S23E8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MISSING62);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_V16U16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_G16R16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_UYVY);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_YUY2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_ALPHATOCOVERAGE);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SUPERSAMPLE);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_AUTOGENMIPMAPS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_NV12);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_AYUV);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_CONTEXT_IDS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_SURFACE_IDS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Z_DF16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Z_DF24);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_ATI1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_ATI2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DEAD1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_VIDEO_DECODE);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_VIDEO_PROCESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_LINE_AA);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_LINE_STIPPLE);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_LINE_WIDTH);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_SURFACEFMT_YV12);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_LOGICOPS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_TS_COLOR_KEY);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DEAD2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DX);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DX_PROVOKING_VERTEX);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_X8R8G8B8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A8R8G8B8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R5G6B5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_X1R5G5B5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A1R5G5B5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A4R4G4B4);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_D32);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_D16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_D24S8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_D15S1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_LUMINANCE8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_LUMINANCE16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_DXT1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_DXT2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_DXT3);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_DXT4);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_DXT5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BUMPU8V8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_ARGB_S10E5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_ARGB_S23E8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A2R10G10B10);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_V8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Q8W8V8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_CxV8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_X8L8V8U8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A2W10V10U10);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_ALPHA8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R_S10E5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R_S23E8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_RG_S10E5);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_RG_S23E8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BUFFER);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_D24X8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_V16U16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_G16R16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A16B16G16R16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_UYVY);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_YUY2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_NV12);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_AYUV);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_X32_TYPELESS_G8X24_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_D32_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_X24_TYPELESS_G8_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8_UINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8_SINT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_P8);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_ATI1);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC4_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_ATI2);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC5_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_DF16);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_DF24);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_YV12);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16G16_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R32_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R8G8_SNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_R16_FLOAT);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_D16_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_A8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC1_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC2_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC3_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC4_UNORM);
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_DXFMT_BC5_UNORM);
+
+        SVGA_CASE_ID2STR(SVGA3D_DEVCAP_MAX);
+
+        default:
+            break;
+    }
+    return "UNKNOWN";
+}
+#undef SVGA_CASE_ID2STR
 
 
@@ -1488,5 +1746,10 @@
         Log(("vmsvgaWritePort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg));
     }
-    Log(("vmsvgaWritePort index=%s (%d) val=%#x\n", vmsvgaIndexToString(pThis, idxReg), idxReg, u32));
+#ifdef LOG_ENABLED
+    if (idxReg != SVGA_REG_DEV_CAP)
+        Log(("vmsvgaWritePort index=%s (%d) val=%#x\n", vmsvgaIndexToString(pThis, idxReg), idxReg, u32));
+    else
+        Log(("vmsvgaWritePort index=%s (%d) val=%s (%d)\n", vmsvgaIndexToString(pThis, idxReg), idxReg, vmsvgaDevCapIndexToString((SVGA3dDevCapIndex)u32), u32));
+#endif
     /* Check if the guest uses legacy registers. See vmsvgaR3ChangeMode */
     switch (idxReg)
@@ -4023,5 +4286,6 @@
        to recheck it before doing the signalling. */
     if (   vmsvgaR3FifoHasWork(pThisCC, ASMAtomicReadU32(&pThis->svga.uLastCursorUpdateCount))
-        && pThis->svga.fFIFOThreadSleeping)
+        && pThis->svga.fFIFOThreadSleeping
+        && !ASMAtomicReadBool(&pThis->svga.fBadGuest))
     {
         int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->svga.hFIFORequestSem);
@@ -4179,5 +4443,5 @@
      */
     LogFlow(("vmsvgaR3FifoLoop: started loop\n"));
-    bool fBadOrDisabledFifo = false;
+    bool fBadOrDisabledFifo = ASMAtomicReadBool(&pThis->svga.fBadGuest);
     while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     {
@@ -4230,5 +4494,5 @@
         else
             rc = VINF_SUCCESS;
-        fBadOrDisabledFifo = false;
+        fBadOrDisabledFifo = ASMAtomicReadBool(&pThis->svga.fBadGuest);
         if (rc == VERR_TIMEOUT)
         {
@@ -4256,4 +4520,15 @@
         {
             vmsvgaR3FifoHandleExtCmd(pDevIns, pThis, pThisCC);
+            continue;
+        }
+
+        /*
+         * If guest misbehaves, then do nothing.
+         */
+        if (ASMAtomicReadBool(&pThis->svga.fBadGuest))
+        {
+            vmsvgaR3FifoSetNotBusy(pDevIns, pThis, pThisCC, pSVGAState, pFIFO[SVGA_FIFO_MIN]);
+            cMsSleep = cMsExtendedSleep;
+            LogRelMax(1, ("VMSVGA: FIFO processing stopped because of the guest misbehavior\n"));
             continue;
         }
@@ -5473,253 +5748,4 @@
 
 # ifdef VBOX_WITH_VMSVGA3D
-/** Names for the vmsvga 3d capabilities, prefixed with format type hint char. */
-static const char * const g_apszVmSvgaDevCapNames[] =
-{
-    "x3D",                           /* = 0 */
-    "xMAX_LIGHTS",
-    "xMAX_TEXTURES",
-    "xMAX_CLIP_PLANES",
-    "xVERTEX_SHADER_VERSION",
-    "xVERTEX_SHADER",
-    "xFRAGMENT_SHADER_VERSION",
-    "xFRAGMENT_SHADER",
-    "xMAX_RENDER_TARGETS",
-    "xS23E8_TEXTURES",
-    "xS10E5_TEXTURES",
-    "xMAX_FIXED_VERTEXBLEND",
-    "xD16_BUFFER_FORMAT",
-    "xD24S8_BUFFER_FORMAT",
-    "xD24X8_BUFFER_FORMAT",
-    "xQUERY_TYPES",
-    "xTEXTURE_GRADIENT_SAMPLING",
-    "rMAX_POINT_SIZE",
-    "xMAX_SHADER_TEXTURES",
-    "xMAX_TEXTURE_WIDTH",
-    "xMAX_TEXTURE_HEIGHT",
-    "xMAX_VOLUME_EXTENT",
-    "xMAX_TEXTURE_REPEAT",
-    "xMAX_TEXTURE_ASPECT_RATIO",
-    "xMAX_TEXTURE_ANISOTROPY",
-    "xMAX_PRIMITIVE_COUNT",
-    "xMAX_VERTEX_INDEX",
-    "xMAX_VERTEX_SHADER_INSTRUCTIONS",
-    "xMAX_FRAGMENT_SHADER_INSTRUCTIONS",
-    "xMAX_VERTEX_SHADER_TEMPS",
-    "xMAX_FRAGMENT_SHADER_TEMPS",
-    "xTEXTURE_OPS",
-    "xSURFACEFMT_X8R8G8B8",
-    "xSURFACEFMT_A8R8G8B8",
-    "xSURFACEFMT_A2R10G10B10",
-    "xSURFACEFMT_X1R5G5B5",
-    "xSURFACEFMT_A1R5G5B5",
-    "xSURFACEFMT_A4R4G4B4",
-    "xSURFACEFMT_R5G6B5",
-    "xSURFACEFMT_LUMINANCE16",
-    "xSURFACEFMT_LUMINANCE8_ALPHA8",
-    "xSURFACEFMT_ALPHA8",
-    "xSURFACEFMT_LUMINANCE8",
-    "xSURFACEFMT_Z_D16",
-    "xSURFACEFMT_Z_D24S8",
-    "xSURFACEFMT_Z_D24X8",
-    "xSURFACEFMT_DXT1",
-    "xSURFACEFMT_DXT2",
-    "xSURFACEFMT_DXT3",
-    "xSURFACEFMT_DXT4",
-    "xSURFACEFMT_DXT5",
-    "xSURFACEFMT_BUMPX8L8V8U8",
-    "xSURFACEFMT_A2W10V10U10",
-    "xSURFACEFMT_BUMPU8V8",
-    "xSURFACEFMT_Q8W8V8U8",
-    "xSURFACEFMT_CxV8U8",
-    "xSURFACEFMT_R_S10E5",
-    "xSURFACEFMT_R_S23E8",
-    "xSURFACEFMT_RG_S10E5",
-    "xSURFACEFMT_RG_S23E8",
-    "xSURFACEFMT_ARGB_S10E5",
-    "xSURFACEFMT_ARGB_S23E8",
-    "xMISSING62",
-    "xMAX_VERTEX_SHADER_TEXTURES",
-    "xMAX_SIMULTANEOUS_RENDER_TARGETS",
-    "xSURFACEFMT_V16U16",
-    "xSURFACEFMT_G16R16",
-    "xSURFACEFMT_A16B16G16R16",
-    "xSURFACEFMT_UYVY",
-    "xSURFACEFMT_YUY2",
-    "xMULTISAMPLE_NONMASKABLESAMPLES",
-    "xMULTISAMPLE_MASKABLESAMPLES",
-    "xALPHATOCOVERAGE",
-    "xSUPERSAMPLE",
-    "xAUTOGENMIPMAPS",
-    "xSURFACEFMT_NV12",
-    "xSURFACEFMT_AYUV",
-    "xMAX_CONTEXT_IDS",
-    "xMAX_SURFACE_IDS",
-    "xSURFACEFMT_Z_DF16",
-    "xSURFACEFMT_Z_DF24",
-    "xSURFACEFMT_Z_D24S8_INT",
-    "xSURFACEFMT_ATI1",
-    "xSURFACEFMT_ATI2", /* 83 */
-    "xDEAD1",
-    "xVIDEO_DECODE",
-    "xVIDEO_PROCESS",
-    "xLINE_AA",
-    "xLINE_STIPPLE",
-    "rMAX_LINE_WIDTH",
-    "rMAX_AA_LINE_WIDTH",
-    "xSURFACEFMT_YV12",
-    "xLOGICOPS",
-    "xTS_COLOR_KEY",
-    "xDEAD2",
-    "xDX",
-    "xMAX_TEXTURE_ARRAY_SIZE",
-    "xDX_MAX_VERTEXBUFFERS",
-    "xDX_MAX_CONSTANT_BUFFERS",
-    "xDX_PROVOKING_VERTEX",
-    "xDXFMT_X8R8G8B8",
-    "xDXFMT_A8R8G8B8",
-    "xDXFMT_R5G6B5",
-    "xDXFMT_X1R5G5B5",
-    "xDXFMT_A1R5G5B5",
-    "xDXFMT_A4R4G4B4",
-    "xDXFMT_Z_D32",
-    "xDXFMT_Z_D16",
-    "xDXFMT_Z_D24S8",
-    "xDXFMT_Z_D15S1",
-    "xDXFMT_LUMINANCE8",
-    "xDXFMT_LUMINANCE4_ALPHA4",
-    "xDXFMT_LUMINANCE16",
-    "xDXFMT_LUMINANCE8_ALPHA8",
-    "xDXFMT_DXT1",
-    "xDXFMT_DXT2",
-    "xDXFMT_DXT3",
-    "xDXFMT_DXT4",
-    "xDXFMT_DXT5",
-    "xDXFMT_BUMPU8V8",
-    "xDXFMT_BUMPL6V5U5",
-    "xDXFMT_BUMPX8L8V8U8",
-    "xDXFMT_FORMAT_DEAD1",
-    "xDXFMT_ARGB_S10E5",
-    "xDXFMT_ARGB_S23E8",
-    "xDXFMT_A2R10G10B10",
-    "xDXFMT_V8U8",
-    "xDXFMT_Q8W8V8U8",
-    "xDXFMT_CxV8U8",
-    "xDXFMT_X8L8V8U8",
-    "xDXFMT_A2W10V10U10",
-    "xDXFMT_ALPHA8",
-    "xDXFMT_R_S10E5",
-    "xDXFMT_R_S23E8",
-    "xDXFMT_RG_S10E5",
-    "xDXFMT_RG_S23E8",
-    "xDXFMT_BUFFER",
-    "xDXFMT_Z_D24X8",
-    "xDXFMT_V16U16",
-    "xDXFMT_G16R16",
-    "xDXFMT_A16B16G16R16",
-    "xDXFMT_UYVY",
-    "xDXFMT_YUY2",
-    "xDXFMT_NV12",
-    "xDXFMT_AYUV",
-    "xDXFMT_R32G32B32A32_TYPELESS",
-    "xDXFMT_R32G32B32A32_UINT",
-    "xDXFMT_R32G32B32A32_SINT",
-    "xDXFMT_R32G32B32_TYPELESS",
-    "xDXFMT_R32G32B32_FLOAT",
-    "xDXFMT_R32G32B32_UINT",
-    "xDXFMT_R32G32B32_SINT",
-    "xDXFMT_R16G16B16A16_TYPELESS",
-    "xDXFMT_R16G16B16A16_UINT",
-    "xDXFMT_R16G16B16A16_SNORM",
-    "xDXFMT_R16G16B16A16_SINT",
-    "xDXFMT_R32G32_TYPELESS",
-    "xDXFMT_R32G32_UINT",
-    "xDXFMT_R32G32_SINT",
-    "xDXFMT_R32G8X24_TYPELESS",
-    "xDXFMT_D32_FLOAT_S8X24_UINT",
-    "xDXFMT_R32_FLOAT_X8X24_TYPELESS",
-    "xDXFMT_X32_TYPELESS_G8X24_UINT",
-    "xDXFMT_R10G10B10A2_TYPELESS",
-    "xDXFMT_R10G10B10A2_UINT",
-    "xDXFMT_R11G11B10_FLOAT",
-    "xDXFMT_R8G8B8A8_TYPELESS",
-    "xDXFMT_R8G8B8A8_UNORM",
-    "xDXFMT_R8G8B8A8_UNORM_SRGB",
-    "xDXFMT_R8G8B8A8_UINT",
-    "xDXFMT_R8G8B8A8_SINT",
-    "xDXFMT_R16G16_TYPELESS",
-    "xDXFMT_R16G16_UINT",
-    "xDXFMT_R16G16_SINT",
-    "xDXFMT_R32_TYPELESS",
-    "xDXFMT_D32_FLOAT",
-    "xDXFMT_R32_UINT",
-    "xDXFMT_R32_SINT",
-    "xDXFMT_R24G8_TYPELESS",
-    "xDXFMT_D24_UNORM_S8_UINT",
-    "xDXFMT_R24_UNORM_X8_TYPELESS",
-    "xDXFMT_X24_TYPELESS_G8_UINT",
-    "xDXFMT_R8G8_TYPELESS",
-    "xDXFMT_R8G8_UNORM",
-    "xDXFMT_R8G8_UINT",
-    "xDXFMT_R8G8_SINT",
-    "xDXFMT_R16_TYPELESS",
-    "xDXFMT_R16_UNORM",
-    "xDXFMT_R16_UINT",
-    "xDXFMT_R16_SNORM",
-    "xDXFMT_R16_SINT",
-    "xDXFMT_R8_TYPELESS",
-    "xDXFMT_R8_UNORM",
-    "xDXFMT_R8_UINT",
-    "xDXFMT_R8_SNORM",
-    "xDXFMT_R8_SINT",
-    "xDXFMT_P8",
-    "xDXFMT_R9G9B9E5_SHAREDEXP",
-    "xDXFMT_R8G8_B8G8_UNORM",
-    "xDXFMT_G8R8_G8B8_UNORM",
-    "xDXFMT_BC1_TYPELESS",
-    "xDXFMT_BC1_UNORM_SRGB",
-    "xDXFMT_BC2_TYPELESS",
-    "xDXFMT_BC2_UNORM_SRGB",
-    "xDXFMT_BC3_TYPELESS",
-    "xDXFMT_BC3_UNORM_SRGB",
-    "xDXFMT_BC4_TYPELESS",
-    "xDXFMT_ATI1",
-    "xDXFMT_BC4_SNORM",
-    "xDXFMT_BC5_TYPELESS",
-    "xDXFMT_ATI2",
-    "xDXFMT_BC5_SNORM",
-    "xDXFMT_R10G10B10_XR_BIAS_A2_UNORM",
-    "xDXFMT_B8G8R8A8_TYPELESS",
-    "xDXFMT_B8G8R8A8_UNORM_SRGB",
-    "xDXFMT_B8G8R8X8_TYPELESS",
-    "xDXFMT_B8G8R8X8_UNORM_SRGB",
-    "xDXFMT_Z_DF16",
-    "xDXFMT_Z_DF24",
-    "xDXFMT_Z_D24S8_INT",
-    "xDXFMT_YV12",
-    "xDXFMT_R32G32B32A32_FLOAT",
-    "xDXFMT_R16G16B16A16_FLOAT",
-    "xDXFMT_R16G16B16A16_UNORM",
-    "xDXFMT_R32G32_FLOAT",
-    "xDXFMT_R10G10B10A2_UNORM",
-    "xDXFMT_R8G8B8A8_SNORM",
-    "xDXFMT_R16G16_FLOAT",
-    "xDXFMT_R16G16_UNORM",
-    "xDXFMT_R16G16_SNORM",
-    "xDXFMT_R32_FLOAT",
-    "xDXFMT_R8G8_SNORM",
-    "xDXFMT_R16_FLOAT",
-    "xDXFMT_D16_UNORM",
-    "xDXFMT_A8_UNORM",
-    "xDXFMT_BC1_UNORM",
-    "xDXFMT_BC2_UNORM",
-    "xDXFMT_BC3_UNORM",
-    "xDXFMT_B5G6R5_UNORM",
-    "xDXFMT_B5G5R5A1_UNORM",
-    "xDXFMT_B8G8R8A8_UNORM",
-    "xDXFMT_B8G8R8X8_UNORM",
-    "xDXFMT_BC4_UNORM",
-    "xDXFMT_BC5_UNORM",
-};
-
 /**
  * Initializes the host 3D capabilities and writes them to FIFO memory.
@@ -5744,18 +5770,21 @@
 
         /* LogRel the capability value. */
-        if (i < RT_ELEMENTS(g_apszVmSvgaDevCapNames))
+        if (i < SVGA3D_DEVCAP_MAX)
         {
+            char const *pszDevCapName = &vmsvgaDevCapIndexToString((SVGA3dDevCapIndex)i)[sizeof("SVGA3D_DEVCAP")];
             if (RT_SUCCESS(rc))
             {
-                if (g_apszVmSvgaDevCapNames[i][0] == 'x')
-                    LogRel(("VMSVGA3d: cap[%u]=%#010x {%s}\n", i, val, &g_apszVmSvgaDevCapNames[i][1]));
-                else
+                if (   i == SVGA3D_DEVCAP_MAX_POINT_SIZE
+                    || i == SVGA3D_DEVCAP_MAX_LINE_WIDTH
+                    || i == SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH)
                 {
                     float const fval = *(float *)&val;
-                    LogRel(("VMSVGA3d: cap[%u]=" FLOAT_FMT_STR " {%s}\n", i, FLOAT_FMT_ARGS(fval), &g_apszVmSvgaDevCapNames[i][1]));
+                    LogRel(("VMSVGA3d: cap[%u]=" FLOAT_FMT_STR " {%s}\n", i, FLOAT_FMT_ARGS(fval), pszDevCapName));
                 }
+                else
+                    LogRel(("VMSVGA3d: cap[%u]=%#010x {%s}\n", i, val, pszDevCapName));
             }
             else
-                LogRel(("VMSVGA3d: cap[%u]=failed rc=%Rrc {%s}\n", i, rc, &g_apszVmSvgaDevCapNames[i][1]));
+                LogRel(("VMSVGA3d: cap[%u]=failed rc=%Rrc {%s}\n", i, rc, pszDevCapName));
         }
         else
@@ -5822,4 +5851,6 @@
     RT_ZERO(pThis->svga.au32ScratchRegion);
 
+    ASMAtomicWriteBool(&pThis->svga.fBadGuest, false);
+
     vmsvgaR3StateTerm(pThis, pThisCC->svga.pSvgaR3State);
     vmsvgaR3StateInit(pDevIns, pThis, pThisCC->svga.pSvgaR3State);
@@ -5937,5 +5968,5 @@
     AssertRCReturn(rc, rc);
 
-    pThisCC->svga.pSvgaR3State = (PVMSVGAR3STATE)RTMemAlloc(sizeof(VMSVGAR3STATE));
+    pThisCC->svga.pSvgaR3State = (PVMSVGAR3STATE)RTMemAllocZ(sizeof(VMSVGAR3STATE));
     AssertReturn(pThisCC->svga.pSvgaR3State, VERR_NO_MEMORY);
 
@@ -5944,4 +5975,12 @@
 
     pSVGAState = pThisCC->svga.pSvgaR3State;
+
+    /* Register the write-protected GBO access handler type. */
+    rc = PGMR3HandlerPhysicalTypeRegister(PDMDevHlpGetVM(pDevIns), PGMPHYSHANDLERKIND_WRITE,
+                                          vmsvgaR3GboAccessHandler,
+                                          NULL, NULL, NULL,
+                                          NULL, NULL, NULL,
+                                          "VMSVGA GBO", &pSVGAState->hGboAccessHandlerType);
+    AssertRCReturn(rc, rc);
 
     /* Initialize FIFO and register capabilities. */
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h	(revision 86847)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h	(revision 86855)
@@ -329,5 +329,7 @@
     /** SVGA 3D overlay enabled or not. */
     bool                        f3DOverlayEnabled;
-    bool                        afPadding[5];
+    /** Indicates that the guest behaves incorrectly. */
+    bool volatile               fBadGuest;
+    bool                        afPadding[4];
     uint32_t                    uWidth;
     uint32_t                    uHeight;
@@ -382,5 +384,7 @@
     /** Index written to the SVGA_REG_DEV_CAP register. */
     uint32_t                    u32DevCapIndex;
+    /** Low 32 bit of a command buffer address written to the SVGA_REG_COMMAND_LOW register. */
     uint32_t                    u32RegCommandLow;
+    /** High 32 bit of a command buffer address written to the SVGA_REG_COMMAND_HIGH register. */
     uint32_t                    u32RegCommandHigh;
 
Index: trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp	(revision 86847)
+++ trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp	(revision 86855)
@@ -799,8 +799,12 @@
     AssertReturn(pState, VERR_INVALID_STATE);
 
-    int rc= VINF_SUCCESS;
+    int rc = VINF_SUCCESS;
 
     switch (idx3dCaps)
     {
+    case SVGA3D_DEVCAP_3D:
+        *pu32Val = 1;
+        break;
+
     case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
         *pu32Val = 8192;
@@ -809,4 +813,8 @@
     case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
         *pu32Val = 8192;
+        break;
+
+    case SVGA3D_DEVCAP_DX:
+        *pu32Val = 1;
         break;
 
