Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk	(revision 103983)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk	(revision 103999)
@@ -157,4 +157,5 @@
  ifdef VBOX_WITH_MESA3D
   VBoxDispD3D_DEFS   += VBOX_WITH_MESA3D
+  VBoxDispD3D_DEFS   += VBOX_MESA_V_MAJOR=$(VBOX_MESA_V_MAJOR)
   VBoxDispD3D_INCS   += \
   	$(VBOX_PATH_MESA)/src/gallium/include \
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGaD3DDevice9Ex.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGaD3DDevice9Ex.cpp	(revision 103983)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGaD3DDevice9Ex.cpp	(revision 103999)
@@ -597,4 +597,5 @@
 STDMETHODIMP GaDirect3DDevice9Ex::GaSurfaceId(IUnknown *pSurface, uint32_t *pu32Sid)
 {
+#if VBOX_MESA_V_MAJOR < 24
     struct pipe_resource *pResource = mpStack->GaNinePipeResourceFromSurface(pSurface);
     if (pResource)
@@ -603,4 +604,7 @@
         *pu32Sid = mpStack->GaDrvGetSurfaceId(pScreen, pResource);
     }
+#else
+    *pu32Sid = mpStack->GaNineGetSurfaceId(pSurface);
+#endif
 
     return S_OK;
@@ -609,4 +613,5 @@
 STDMETHODIMP GaDirect3DDevice9Ex::GaWDDMContextHandle(HANDLE *phContext)
 {
+#if VBOX_MESA_V_MAJOR < 24
     struct pipe_context *pPipeContext = mpStack->GaNinePipeContextFromDevice(this->mpDevice);
     if (pPipeContext)
@@ -622,4 +627,13 @@
         }
     }
+#else
+    uint32_t u32Cid = mpStack->GaNineGetContextId(mpDevice);
+    WDDMGalliumDriverEnv const *pEnv = mpD3D9Ex->GetWDDMEnv();
+    if (pEnv)
+    {
+        GaDrvEnvWddm *pEnvWddm = (GaDrvEnvWddm *)pEnv->pvEnv;
+        *phContext = pEnvWddm->GaDrvEnvWddmContextHandle(u32Cid);
+    }
+#endif
 
     return S_OK;
@@ -628,4 +642,5 @@
 STDMETHODIMP GaDirect3DDevice9Ex::GaFlush()
 {
+#if VBOX_MESA_V_MAJOR < 24
     struct pipe_context *pPipeContext = mpStack->GaNinePipeContextFromDevice(this->mpDevice);
     if (pPipeContext)
@@ -633,4 +648,7 @@
         mpStack->GaDrvContextFlush(pPipeContext);
     }
+#else
+    mpStack->GaNineFlush(this->mpDevice);
+#endif
 
     return S_OK;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.cpp	(revision 103983)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.cpp	(revision 103999)
@@ -39,4 +39,5 @@
 #include <iprt/string.h>
 
+#if VBOX_MESA_V_MAJOR < 24
 /*
  * Loading Gallium state tracker and driver:
@@ -66,4 +67,23 @@
 #endif
 ;
+#else /* VBOX_MESA_V_MAJOR >= 24 */
+/*
+ * Loading Gallium D3D9 state tracker and driver:
+ *   1) load the state tracker DLL (VBoxNine) which contains the driver code too
+ *      (they have to be in the same dll because both use and compare adresses of global constant
+ *       glsl_type glsl_type_builtin_* structures from Mesa code).
+ *     a) get an entry point to create the ID3DAdapter interface (GaNineD3DAdapter9Create);
+ *     b) create ID3DAdapter, which will create the pipe_screen to access the driver internally.
+ *   3) create GaDirect3D9Ex to have IDirect3DEx or GaDirect3DDevice9Ex to have IDirect3DDevice9Ex,
+ *      which is returned to WDDM user mode driver to substitute wine's IDirect3DDevice9Ex.
+ */
+static const char *gpszNineDll =
+#ifdef VBOX_WDDM_WOW64
+    "VBoxNine-x86.dll"
+#else
+    "VBoxNine.dll"
+#endif
+;
+#endif /* VBOX_MESA_V_MAJOR >= 24 */
 
 /**
@@ -159,8 +179,16 @@
                                     IDirect3DDevice9Ex** ppReturnedDeviceInterface);
 
+#if VBOX_MESA_V_MAJOR < 24
         STDMETHOD(GaNineD3DAdapter9Create)(struct pipe_screen *s, ID3DAdapter9 **ppOut);
         STDMETHOD_(struct pipe_resource *, GaNinePipeResourceFromSurface)(IUnknown *pSurface);
         STDMETHOD_(struct pipe_context *, GaNinePipeContextFromDevice)(IDirect3DDevice9 *pDevice);
-
+#else
+        STDMETHOD(GaNineD3DAdapter9Create)(const WDDMGalliumDriverEnv *pEnv, ID3DAdapter9 **ppOut);
+        STDMETHOD_(uint32_t, GaNineGetSurfaceId)(IUnknown *pSurface);
+        STDMETHOD_(uint32_t, GaNineGetContextId)(IDirect3DDevice9 *pDevice);
+        STDMETHOD_(void, GaNineFlush)(IDirect3DDevice9 *pDevice);
+#endif
+
+#if VBOX_MESA_V_MAJOR < 24
         STDMETHOD_(struct pipe_screen *, GaDrvScreenCreate)(const WDDMGalliumDriverEnv *pEnv);
         STDMETHOD_(void, GaDrvScreenDestroy)(struct pipe_screen *s);
@@ -169,4 +197,5 @@
         STDMETHOD_(uint32_t, GaDrvGetSurfaceId)(struct pipe_screen *pScreen, struct pipe_resource *pResource);
         STDMETHOD_(void, GaDrvContextFlush)(struct pipe_context *pPipeContext);
+#endif
 
     private:
@@ -176,13 +205,23 @@
 
         HMODULE mhmodStateTracker;
+#if VBOX_MESA_V_MAJOR < 24
         HMODULE mhmodDriver;
+#endif
 
         struct GaNineFunctions
         {
+#if VBOX_MESA_V_MAJOR < 24
             PFNGaNineD3DAdapter9Create       pfnGaNineD3DAdapter9Create;
             PFNGaNinePipeResourceFromSurface pfnGaNinePipeResourceFromSurface;
             PFNGaNinePipeContextFromDevice   pfnGaNinePipeContextFromDevice;
+#else
+            PFNGaNineD3DAdapter9Create pfnGaNineD3DAdapter9Create;
+            PFNGaNineGetSurfaceId      pfnGaNineGetSurfaceId;
+            PFNGaNineGetContextId      pfnGaNineGetContextId;
+            PFNGaNineFlush             pfnGaNineFlush;
+#endif
         } mNine;
 
+#if VBOX_MESA_V_MAJOR < 24
         struct GaDrvFunctions
         {
@@ -194,4 +233,5 @@
             PFNGaDrvContextFlush  pfnGaDrvContextFlush;
         } mDrv;
+#endif
 };
 
@@ -253,5 +293,9 @@
         STDMETHOD_(IGalliumStack *, GetGalliumStack)(THIS);
         STDMETHOD_(ID3DAdapter9 *, GetAdapter9)(THIS);
+#if VBOX_MESA_V_MAJOR < 24
         STDMETHOD_(struct pipe_screen *, GetScreen)(THIS);
+#else
+        STDMETHOD_(const WDDMGalliumDriverEnv *, GetWDDMEnv)(THIS);
+#endif
 
     private:
@@ -261,5 +305,7 @@
 
         VBoxGalliumStack *mpStack;
+#if VBOX_MESA_V_MAJOR < 24
         struct pipe_screen *mpPipeScreen;
+#endif
         ID3DAdapter9 *mpD3DAdapter9;
 
@@ -275,10 +321,14 @@
 VBoxGalliumStack::VBoxGalliumStack()
     :
-    mcRefs(0),
-    mhmodStateTracker(0),
-    mhmodDriver(0)
+    mcRefs(0)
+    , mhmodStateTracker(0)
+#if VBOX_MESA_V_MAJOR < 24
+    , mhmodDriver(0)
+#endif
 {
     RT_ZERO(mNine);
+#if VBOX_MESA_V_MAJOR < 24
     RT_ZERO(mDrv);
+#endif
 }
 
@@ -327,10 +377,18 @@
     struct VBOXGAPROC aNineProcs[] =
     {
+#if VBOX_MESA_V_MAJOR < 24
         { "GaNineD3DAdapter9Create",        (FARPROC *)&mNine.pfnGaNineD3DAdapter9Create },
         { "GaNinePipeResourceFromSurface",  (FARPROC *)&mNine.pfnGaNinePipeResourceFromSurface },
         { "GaNinePipeContextFromDevice",    (FARPROC *)&mNine.pfnGaNinePipeContextFromDevice },
+#else
+        { "GaNineD3DAdapter9Create", (FARPROC *)&mNine.pfnGaNineD3DAdapter9Create },
+        { "GaNineGetSurfaceId",      (FARPROC *)&mNine.pfnGaNineGetSurfaceId },
+        { "GaNineGetContextId",      (FARPROC *)&mNine.pfnGaNineGetContextId },
+        { "GaNineFlush",             (FARPROC *)&mNine.pfnGaNineFlush },
+#endif
         { NULL, NULL }
     };
 
+#if VBOX_MESA_V_MAJOR < 24
     struct VBOXGAPROC aDrvProcs[] =
     {
@@ -352,4 +410,7 @@
         hr = loadDll(gpszNineDll, &mhmodStateTracker, aNineProcs);
     }
+#else
+    HRESULT hr = loadDll(gpszNineDll, &mhmodStateTracker, aNineProcs);
+#endif
 
     return hr;
@@ -359,5 +420,7 @@
 {
     RT_ZERO(mNine);
+#if VBOX_MESA_V_MAJOR < 24
     RT_ZERO(mDrv);
+#endif
 
     if (mhmodStateTracker)
@@ -367,4 +430,5 @@
     }
 
+#if VBOX_MESA_V_MAJOR < 24
     if (mhmodDriver)
     {
@@ -372,6 +436,8 @@
         mhmodDriver = 0;
     }
-}
-
+#endif
+}
+
+#if VBOX_MESA_V_MAJOR < 24
 STDMETHODIMP VBoxGalliumStack::GaNineD3DAdapter9Create(struct pipe_screen *s,
                                                        ID3DAdapter9 **ppOut)
@@ -389,5 +455,28 @@
     return mNine.pfnGaNinePipeContextFromDevice(pDevice);
 }
-
+#else
+STDMETHODIMP VBoxGalliumStack::GaNineD3DAdapter9Create(const WDDMGalliumDriverEnv *pEnv,
+                                                       ID3DAdapter9 **ppOut)
+{
+    return mNine.pfnGaNineD3DAdapter9Create(pEnv, ppOut);
+}
+
+STDMETHODIMP_(uint32_t) VBoxGalliumStack::GaNineGetSurfaceId(IUnknown *pSurface)
+{
+    return mNine.pfnGaNineGetSurfaceId(pSurface);
+}
+
+STDMETHODIMP_(uint32_t) VBoxGalliumStack::GaNineGetContextId(IDirect3DDevice9 *pDevice)
+{
+    return mNine.pfnGaNineGetContextId(pDevice);
+}
+
+STDMETHODIMP_(void) VBoxGalliumStack::GaNineFlush(IDirect3DDevice9 *pDevice)
+{
+    return mNine.pfnGaNineFlush(pDevice);
+}
+#endif
+
+#if VBOX_MESA_V_MAJOR < 24
 STDMETHODIMP_(struct pipe_screen *) VBoxGalliumStack::GaDrvScreenCreate(const WDDMGalliumDriverEnv *pEnv)
 {
@@ -420,4 +509,5 @@
     mDrv.pfnGaDrvContextFlush(pPipeContext);
 }
+#endif
 
 STDMETHODIMP VBoxGalliumStack::CreateDirect3DEx(HANDLE hAdapter,
@@ -522,5 +612,7 @@
     mcRefs(0),
     mpStack(pStack),
+#if VBOX_MESA_V_MAJOR < 24
     mpPipeScreen(0),
+#endif
     mpD3DAdapter9(0)
 {
@@ -583,4 +675,5 @@
     const WDDMGalliumDriverEnv *pEnv = mEnv.Env();
 
+#if VBOX_MESA_V_MAJOR < 24
     mpPipeScreen = mpStack->GaDrvScreenCreate(pEnv);
     if (mpPipeScreen)
@@ -594,4 +687,8 @@
         AssertFailed();
     }
+#else
+    hr = mpStack->GaNineD3DAdapter9Create(pEnv, &mpD3DAdapter9);
+    Assert(SUCCEEDED(hr));
+#endif
 
     return hr;
@@ -606,4 +703,5 @@
     }
 
+#if VBOX_MESA_V_MAJOR < 24
     if (mpPipeScreen)
     {
@@ -611,4 +709,5 @@
         mpPipeScreen = NULL;
     }
+#endif
 
     if (mpStack)
@@ -815,6 +914,13 @@
 }
 
+#if VBOX_MESA_V_MAJOR < 24
 STDMETHODIMP_(struct pipe_screen *) GaDirect3D9Ex::GetScreen(void)
 {
     return mpPipeScreen;
 }
+#else
+STDMETHODIMP_(const WDDMGalliumDriverEnv *) GaDirect3D9Ex::GetWDDMEnv(void)
+{
+    return mEnv.Env();
+}
+#endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.h	(revision 103983)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/VBoxGallium.h	(revision 103999)
@@ -63,5 +63,9 @@
         STDMETHOD_(IGalliumStack *, GetGalliumStack)(THIS) PURE;
         STDMETHOD_(ID3DAdapter9 *, GetAdapter9)(THIS) PURE;
+#if VBOX_MESA_V_MAJOR < 24
         STDMETHOD_(struct pipe_screen *, GetScreen)(THIS) PURE;
+#else
+        STDMETHOD_(const WDDMGalliumDriverEnv *, GetWDDMEnv)(THIS) PURE;
+#endif
 };
 
@@ -85,8 +89,16 @@
                                     IDirect3DDevice9Ex** ppReturnedDeviceInterface) PURE;
 
+#if VBOX_MESA_V_MAJOR < 24
         STDMETHOD(GaNineD3DAdapter9Create)(struct pipe_screen *s, ID3DAdapter9 **ppOut) PURE;
         STDMETHOD_(struct pipe_resource *, GaNinePipeResourceFromSurface)(IUnknown *pSurface) PURE;
         STDMETHOD_(struct pipe_context *, GaNinePipeContextFromDevice)(IDirect3DDevice9 *pDevice) PURE;
+#else
+        STDMETHOD(GaNineD3DAdapter9Create)(const WDDMGalliumDriverEnv *pEnv, ID3DAdapter9 **ppOut) PURE;
+        STDMETHOD_(uint32_t, GaNineGetSurfaceId)(IUnknown *pSurface) PURE;
+        STDMETHOD_(uint32_t, GaNineGetContextId)(IDirect3DDevice9 *pDevice) PURE;
+        STDMETHOD_(void, GaNineFlush)(IDirect3DDevice9 *pDevice) PURE;
+#endif
 
+#if VBOX_MESA_V_MAJOR < 24
         STDMETHOD_(struct pipe_screen *, GaDrvScreenCreate)(const WDDMGalliumDriverEnv *pEnv) PURE;
         STDMETHOD_(void, GaDrvScreenDestroy)(struct pipe_screen *s) PURE;
@@ -95,4 +107,5 @@
         STDMETHOD_(uint32_t, GaDrvGetSurfaceId)(struct pipe_screen *pScreen, struct pipe_resource *pResource) PURE;
         STDMETHOD_(void, GaDrvContextFlush)(struct pipe_context *pPipeContext) PURE;
+#endif
 };
 
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 103983)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp	(revision 103999)
@@ -1073,4 +1073,10 @@
         } break;
 
+        case SVGA_3D_CMD_READBACK_GB_SURFACE:
+        {
+            SVGA3dCmdReadbackGBSurface *p = (SVGA3dCmdReadbackGBSurface *)pCommand;
+            Status = SvgaProcessSurface(pSvga, &p->sid, pHOA);
+        } break;
+
         /*
          * Unsupported commands, which might include a sid.
@@ -1086,5 +1092,4 @@
         case SVGA_3D_CMD_DEFINE_GB_SURFACE:
         case SVGA_3D_CMD_DESTROY_GB_SURFACE:
-        case SVGA_3D_CMD_READBACK_GB_SURFACE:
         case SVGA_3D_CMD_READBACK_GB_IMAGE:
         case SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL:
