Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp	(revision 83577)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp	(revision 83578)
@@ -62,4 +62,11 @@
         pSvga->u32MaxTextureHeight = 8192;
     }
+
+    /* 1 + floor(log2(max(u32MaxTextureWidth, u32MaxTextureHeight))):
+     * In Direct3D the next mipmap level size is floor(prev_size / 2), for example 5 -> 2 -> 1
+     * Therefore we only need to know the position of the highest non-zero bit. And since
+     * ASMBitLastSetU32 returns a 1 based index, there is no need to add 1.
+     */
+    pSvga->u32MaxTextureLevels = ASMBitLastSetU32(RT_MAX(pSvga->u32MaxTextureWidth, pSvga->u32MaxTextureHeight));
 
     NTSTATUS Status = SvgaFifoInit(pSvga);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h	(revision 83577)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h	(revision 83578)
@@ -83,4 +83,6 @@
     uint32_t u32MaxTextureWidth;  /** SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH */
     uint32_t u32MaxTextureHeight; /** SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT */
+
+    uint32_t u32MaxTextureLevels; /** 1 + floor(log2(max(u32MaxTextureWidth, u32MaxTextureHeight))) */
 
     /** Fifo state. */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaHostObjects.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaHostObjects.cpp	(revision 83577)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaHostObjects.cpp	(revision 83578)
@@ -319,4 +319,6 @@
     AssertReturn(Status == STATUS_SUCCESS, Status);
 
+    AssertReturn(cSizes <= pSvga->u32MaxTextureLevels, STATUS_INVALID_PARAMETER);
+
     SURFACEOBJECT *pSO = (SURFACEOBJECT *)GaMemAllocZero(sizeof(SURFACEOBJECT));
     if (pSO)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h	(revision 83577)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaExt.h	(revision 83578)
@@ -77,4 +77,5 @@
 
 #define GAFENCE_F_WAITED        0x1 /* KEVENT is initialized and there is(are) waiter(s). */
+#define GAFENCE_F_DELETED       0x2 /* The user mode driver deleted this fence. */
 
 NTSTATUS GaFenceCreate(PVBOXWDDM_EXT_GA pGaDevExt,
@@ -89,6 +90,6 @@
                      uint32_t u32FenceHandle,
                      uint32_t u32TimeoutUS);
-NTSTATUS GaFenceUnref(PVBOXWDDM_EXT_GA pGaDevExt,
-                      uint32_t u32FenceHandle);
+NTSTATUS GaFenceDelete(PVBOXWDDM_EXT_GA pGaDevExt,
+                       uint32_t u32FenceHandle);
 
 DECLINLINE(void) gaFenceObjectsLock(VBOXWDDM_EXT_GA *pGaDevExt)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaFence.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaFence.cpp	(revision 83577)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaFence.cpp	(revision 83578)
@@ -249,6 +249,6 @@
 }
 
-NTSTATUS GaFenceUnref(PVBOXWDDM_EXT_GA pGaDevExt,
-                      uint32_t u32FenceHandle)
+NTSTATUS GaFenceDelete(PVBOXWDDM_EXT_GA pGaDevExt,
+                       uint32_t u32FenceHandle)
 {
     gaFenceObjectsLock(pGaDevExt);
@@ -257,4 +257,15 @@
     AssertReturnStmt(pFO, gaFenceObjectsUnlock(pGaDevExt), STATUS_INVALID_PARAMETER);
 
+    if (RT_BOOL(pFO->fu32FenceFlags & GAFENCE_F_DELETED))
+    {
+        /* Undo GaFenceLookup ref. */
+        GaFenceUnrefLocked(pGaDevExt, pFO);
+
+        gaFenceObjectsUnlock(pGaDevExt);
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    pFO->fu32FenceFlags |= GAFENCE_F_DELETED;
+
     if (RT_BOOL(pFO->fu32FenceFlags & GAFENCE_F_WAITED))
     {
@@ -263,14 +274,14 @@
     }
 
+    /* Undo GaFenceLookup ref. */
+    GaFenceUnrefLocked(pGaDevExt, pFO);
+
+    /* Undo the GaFenceCreate ref. */
+    GaFenceUnrefLocked(pGaDevExt, pFO);
+
     gaFenceObjectsUnlock(pGaDevExt);
 
     GALOG(("u32FenceHandle = %d, pFO %p\n", u32FenceHandle, pFO));
 
-    /* Undo GaFenceLookup ref. */
-    gaFenceUnref(pGaDevExt, pFO);
-
-    /* Undo the GaFenceCreate ref. */
-    gaFenceUnref(pGaDevExt, pFO);
-
     return STATUS_SUCCESS;
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 83577)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 83578)
@@ -1741,5 +1741,4 @@
             GASURFSIZE *paSizes = (GASURFSIZE *)&pCreateParms[1];
 
-            /// @todo verify the data
             Status = gaSurfaceDefine(pDevExt->pGa, pCreateParms, paSizes, pGaSurfaceDefine->cSizes, &pGaSurfaceDefine->u32Sid);
             break;
@@ -1829,5 +1828,5 @@
 
             VBOXDISPIFESCAPE_GAFENCEUNREF *pFenceUnref = (VBOXDISPIFESCAPE_GAFENCEUNREF *)pEscapeHdr;
-            Status = GaFenceUnref(pDevExt->pGa, pFenceUnref->u32FenceHandle);
+            Status = GaFenceDelete(pDevExt->pGa, pFenceUnref->u32FenceHandle);
             break;
         }
