Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h	(revision 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h	(revision 81594)
@@ -50,6 +50,13 @@
 #define VBOXWDDM_C_PATH_LOCATION_LIST_SIZE 0xc00
 
+#ifndef VBOX_WITH_MESA3D
 #define VBOXWDDM_C_POINTER_MAX_WIDTH  64
 #define VBOXWDDM_C_POINTER_MAX_HEIGHT 64
+#else
+#define VBOXWDDM_C_POINTER_MAX_WIDTH  256
+#define VBOXWDDM_C_POINTER_MAX_HEIGHT 256
+#define VBOXWDDM_C_POINTER_MAX_WIDTH_LEGACY  64
+#define VBOXWDDM_C_POINTER_MAX_HEIGHT_LEGACY 64
+#endif
 
 #define VBOXWDDM_POINTER_ATTRIBUTES_SIZE VBOXWDDM_ROUNDBOUND( \
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 81594)
@@ -1868,4 +1868,11 @@
             pCaps->MaxPointerWidth  = VBOXWDDM_C_POINTER_MAX_WIDTH;
             pCaps->MaxPointerHeight = VBOXWDDM_C_POINTER_MAX_HEIGHT;
+#ifdef VBOX_WITH_MESA3D
+            if (pDevExt->enmHwType == VBOXVIDEO_HWTYPE_VBOX)
+            {
+                pCaps->MaxPointerWidth  = VBOXWDDM_C_POINTER_MAX_WIDTH_LEGACY;
+                pCaps->MaxPointerHeight = VBOXWDDM_C_POINTER_MAX_HEIGHT_LEGACY;
+            }
+#endif
             pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, disable for now */
             if (!g_VBoxDisplayOnly)
@@ -2932,4 +2939,78 @@
 }
 
+bool vboxWddmUpdatePointerShape(PVBOXMP_DEVEXT pDevExt, PVIDEO_POINTER_ATTRIBUTES pAttrs, uint32_t cbLength)
+{
+#ifdef VBOX_WITH_MESA3D
+    if (pDevExt->enmHwType != VBOXVIDEO_HWTYPE_VBOX)
+    {
+        NTSTATUS Status = STATUS_SUCCESS;
+
+        /** @todo Get rid of the unnecesary en-/decode procedure (XPDM legacy). */
+        uint32_t fFlags = pAttrs->Enable & 0x0000FFFF;
+        uint32_t xHot = (pAttrs->Enable >> 16) & 0xFF;
+        uint32_t yHot = (pAttrs->Enable >> 24) & 0xFF;
+        uint32_t cWidth = pAttrs->Width;
+        uint32_t cHeight = pAttrs->Height;
+        uint32_t cbAndMask = 0;
+        uint32_t cbXorMask = 0;
+
+        if (fFlags & VBOX_MOUSE_POINTER_SHAPE)
+        {
+            /* Size of the pointer data: sizeof(AND mask) + sizeof(XOR mask) */
+            cbAndMask = ((((cWidth + 7) / 8) * cHeight + 3) & ~3);
+            cbXorMask = cWidth * 4 * cHeight;
+
+            /* Send the shape to the host. */
+            if (fFlags & VBOX_MOUSE_POINTER_ALPHA)
+            {
+                void const *pvImage = &pAttrs->Pixels[cbAndMask];
+                Status = GaDefineAlphaCursor(pDevExt->pGa,
+                                             xHot,
+                                             yHot,
+                                             cWidth,
+                                             cHeight,
+                                             pvImage,
+                                             cbXorMask);
+            }
+            else
+            {
+                uint32_t u32AndMaskDepth = 1;
+                uint32_t u32XorMaskDepth = 32;
+
+                void const *pvAndMask = &pAttrs->Pixels[0];
+                void const *pvXorMask = &pAttrs->Pixels[cbAndMask];
+                Status = GaDefineCursor(pDevExt->pGa,
+                                        xHot,
+                                        yHot,
+                                        cWidth,
+                                        cHeight,
+                                        u32AndMaskDepth,
+                                        u32XorMaskDepth,
+                                        pvAndMask,
+                                        cbAndMask,
+                                        pvXorMask,
+                                        cbXorMask);
+            }
+        }
+
+        /** @todo Hack: Use the legacy interface to handle visibility.
+         * Eventually the VMSVGA WDDM driver should use the SVGA_FIFO_CURSOR_* interface.
+         */
+        VIDEO_POINTER_ATTRIBUTES attrs;
+        RT_ZERO(attrs);
+        attrs.Enable = pAttrs->Enable & VBOX_MOUSE_POINTER_VISIBLE;
+        if (!VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &attrs, sizeof(attrs)))
+        {
+            Status = STATUS_INVALID_PARAMETER;
+        }
+
+        return Status == STATUS_SUCCESS;
+    }
+#endif
+
+    /* VBOXVIDEO_HWTYPE_VBOX */
+    return VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), pAttrs, cbLength);
+}
+
 static void vboxWddmHostPointerEnable(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable)
 {
@@ -2940,5 +3021,5 @@
         PointerAttributes.Enable = VBOX_MOUSE_POINTER_VISIBLE;
     }
-    VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &PointerAttributes, sizeof(PointerAttributes));
+    vboxWddmUpdatePointerShape(pDevExt, &PointerAttributes, sizeof(PointerAttributes));
 }
 
@@ -2985,5 +3066,5 @@
         if (fScreenChanged)
         {
-            BOOLEAN bResult = VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE);
+            BOOLEAN bResult = vboxWddmUpdatePointerShape(pDevExt, &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE);
             if (!bResult)
             {
@@ -3023,5 +3104,5 @@
         {
             pDevExt->PointerInfo.iLastReportedScreen = pSetPointerShape->VidPnSourceId;
-            if (VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE))
+            if (vboxWddmUpdatePointerShape(pDevExt, &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE))
                 Status = STATUS_SUCCESS;
             else
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 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.cpp	(revision 81594)
@@ -1014,4 +1014,131 @@
 }
 
+NTSTATUS SvgaGenDefineCursor(PVBOXWDDM_EXT_VMSVGA pSvga,
+                             uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                             uint32_t u32AndMaskDepth, uint32_t u32XorMaskDepth,
+                             void const *pvAndMask, uint32_t cbAndMask, void const *pvXorMask, uint32_t cbXorMask,
+                             void *pvDst,
+                             uint32_t cbDst,
+                             uint32_t *pcbOut)
+{
+    RT_NOREF(pSvga);
+
+    const uint32_t cbCmd =   sizeof(uint32_t)
+                           + sizeof(SVGAFifoCmdDefineCursor)
+                           + cbAndMask
+                           + cbXorMask;
+
+    const uint32_t cbRequired = cbCmd;
+    if (pcbOut)
+    {
+        *pcbOut = cbRequired;
+    }
+
+    if (cbDst < cbRequired)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
+
+    SvgaCmdDefineCursor(pvDst, u32HotspotX, u32HotspotY, u32Width, u32Height,
+                        u32AndMaskDepth, u32XorMaskDepth,
+                        pvAndMask, cbAndMask, pvXorMask, cbXorMask);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS SvgaDefineCursor(PVBOXWDDM_EXT_VMSVGA pSvga,
+                          uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                          uint32_t u32AndMaskDepth, uint32_t u32XorMaskDepth,
+                          void const *pvAndMask, uint32_t cbAndMask, void const *pvXorMask, uint32_t cbXorMask)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    uint32_t cbSubmit = 0;
+    SvgaGenDefineCursor(pSvga,
+                        u32HotspotX, u32HotspotY, u32Width, u32Height,
+                        u32AndMaskDepth, u32XorMaskDepth,
+                        pvAndMask, cbAndMask, pvXorMask, cbXorMask,
+                        NULL, 0, &cbSubmit);
+
+    void *pvCmd = SvgaFifoReserve(pSvga, cbSubmit);
+    if (pvCmd)
+    {
+        Status = SvgaGenDefineCursor(pSvga,
+                                     u32HotspotX, u32HotspotY, u32Width, u32Height,
+                                     u32AndMaskDepth, u32XorMaskDepth,
+                                     pvAndMask, cbAndMask, pvXorMask, cbXorMask,
+                                     pvCmd, cbSubmit, NULL);
+        Assert(Status == STATUS_SUCCESS);
+        SvgaFifoCommit(pSvga, cbSubmit);
+    }
+    else
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    return Status;
+}
+
+NTSTATUS SvgaGenDefineAlphaCursor(PVBOXWDDM_EXT_VMSVGA pSvga,
+                                  uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                                  void const *pvImage, uint32_t cbImage,
+                                  void *pvDst,
+                                  uint32_t cbDst,
+                                  uint32_t *pcbOut)
+{
+    RT_NOREF(pSvga);
+
+    const uint32_t cbCmd =   sizeof(uint32_t)
+                           + sizeof(SVGAFifoCmdDefineAlphaCursor)
+                           + cbImage;
+
+    const uint32_t cbRequired = cbCmd;
+    if (pcbOut)
+    {
+        *pcbOut = cbRequired;
+    }
+
+    if (cbDst < cbRequired)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
+
+    SvgaCmdDefineAlphaCursor(pvDst, u32HotspotX, u32HotspotY, u32Width, u32Height,
+                             pvImage, cbImage);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS SvgaDefineAlphaCursor(PVBOXWDDM_EXT_VMSVGA pSvga,
+                               uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                               void const *pvImage, uint32_t cbImage)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    uint32_t cbSubmit = 0;
+    SvgaGenDefineAlphaCursor(pSvga,
+                             u32HotspotX, u32HotspotY, u32Width, u32Height,
+                             pvImage, cbImage,
+                             NULL, 0, &cbSubmit);
+
+    void *pvCmd = SvgaFifoReserve(pSvga, cbSubmit);
+    if (pvCmd)
+    {
+        Status = SvgaGenDefineAlphaCursor(pSvga,
+                                          u32HotspotX, u32HotspotY, u32Width, u32Height,
+                                          pvImage, cbImage,
+                                          pvCmd, cbSubmit, NULL);
+        Assert(Status == STATUS_SUCCESS);
+        SvgaFifoCommit(pSvga, cbSubmit);
+    }
+    else
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    return Status;
+}
+
+
 NTSTATUS SvgaGenDefineGMRFB(PVBOXWDDM_EXT_VMSVGA pSvga,
                             uint32_t u32Offset,
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 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/Svga.h	(revision 81594)
@@ -269,4 +269,24 @@
                     uint32_t u32Height);
 
+NTSTATUS SvgaDefineCursor(PVBOXWDDM_EXT_VMSVGA pSvga,
+                          uint32_t u32HotspotX,
+                          uint32_t u32HotspotY,
+                          uint32_t u32Width,
+                          uint32_t u32Height,
+                          uint32_t u32AndMaskDepth,
+                          uint32_t u32XorMaskDepth,
+                          void const *pvAndMask,
+                          uint32_t cbAndMask,
+                          void const *pvXorMask,
+                          uint32_t cbXorMask);
+
+NTSTATUS SvgaDefineAlphaCursor(PVBOXWDDM_EXT_VMSVGA pSvga,
+                               uint32_t u32HotspotX,
+                               uint32_t u32HotspotY,
+                               uint32_t u32Width,
+                               uint32_t u32Height,
+                               void const *pvImage,
+                               uint32_t cbImage);
+
 NTSTATUS SvgaGenDefineGMRFB(PVBOXWDDM_EXT_VMSVGA pSvga,
                             uint32_t u32Offset,
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.cpp	(revision 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.cpp	(revision 81594)
@@ -73,4 +73,46 @@
 }
 
+void SvgaCmdDefineCursor(void *pvCmd, uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                         uint32_t u32AndMaskDepth, uint32_t u32XorMaskDepth,
+                         void const *pvAndMask, uint32_t cbAndMask, void const *pvXorMask, uint32_t cbXorMask)
+{
+    uint32_t *pu32Id = (uint32_t *)pvCmd;
+    SVGAFifoCmdDefineCursor *pCommand = (SVGAFifoCmdDefineCursor *)&pu32Id[1];
+
+    *pu32Id = SVGA_CMD_DEFINE_CURSOR;
+
+    pCommand->id = 0;
+    pCommand->hotspotX = u32HotspotX;
+    pCommand->hotspotY = u32HotspotY;
+    pCommand->width = u32Width;
+    pCommand->height = u32Height;
+    pCommand->andMaskDepth = u32AndMaskDepth;
+    pCommand->xorMaskDepth = u32XorMaskDepth;
+
+    uint8_t *pu8AndMask = (uint8_t *)&pCommand[1];
+    memcpy(pu8AndMask, pvAndMask, cbAndMask);
+
+    uint8_t *pu8XorMask = pu8AndMask + cbAndMask;
+    memcpy(pu8XorMask, pvXorMask, cbXorMask);
+}
+
+void SvgaCmdDefineAlphaCursor(void *pvCmd, uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                              void const *pvImage, uint32_t cbImage)
+{
+    uint32_t *pu32Id = (uint32_t *)pvCmd;
+    SVGAFifoCmdDefineAlphaCursor *pCommand = (SVGAFifoCmdDefineAlphaCursor *)&pu32Id[1];
+
+    *pu32Id = SVGA_CMD_DEFINE_ALPHA_CURSOR;
+
+    pCommand->id = 0;
+    pCommand->hotspotX = u32HotspotX;
+    pCommand->hotspotY = u32HotspotY;
+    pCommand->width = u32Width;
+    pCommand->height = u32Height;
+
+    uint8_t *pu8Image = (uint8_t *)&pCommand[1];
+    memcpy(pu8Image, pvImage, cbImage);
+}
+
 void SvgaCmdFence(void *pvCmd, uint32_t u32Fence)
 {
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.h	(revision 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/SvgaCmd.h	(revision 81594)
@@ -29,4 +29,9 @@
 void SvgaCmdDestroyScreen(void *pvCmd, uint32_t u32Id);
 void SvgaCmdUpdate(void *pvCmd, uint32_t u32X, uint32_t u32Y, uint32_t u32Width, uint32_t u32Height);
+void SvgaCmdDefineCursor(void *pvCmd, uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                         uint32_t u32AndMaskDepth, uint32_t u32XorMaskDepth,
+                         void const *pvAndMask, uint32_t cbAndMask, void const *pvXorMask, uint32_t cbXorMask);
+void SvgaCmdDefineAlphaCursor(void *pvCmd, uint32_t u32HotspotX, uint32_t u32HotspotY, uint32_t u32Width, uint32_t u32Height,
+                              void const *pvImage, uint32_t cbImage);
 void SvgaCmdFence(void *pvCmd, uint32_t u32Fence);
 void SvgaCmdDefineGMRFB(void *pvCmd, uint32_t u32Offset, uint32_t u32BytesPerLine);
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 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.cpp	(revision 81594)
@@ -193,4 +193,35 @@
     VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
     return SvgaUpdate(pSvga, u32X, u32Y, u32Width, u32Height);
+}
+
+NTSTATUS GaDefineCursor(PVBOXWDDM_EXT_GA pGaDevExt,
+                        uint32_t u32HotspotX,
+                        uint32_t u32HotspotY,
+                        uint32_t u32Width,
+                        uint32_t u32Height,
+                        uint32_t u32AndMaskDepth,
+                        uint32_t u32XorMaskDepth,
+                        void const *pvAndMask,
+                        uint32_t cbAndMask,
+                        void const *pvXorMask,
+                        uint32_t cbXorMask)
+{
+    VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
+    return SvgaDefineCursor(pSvga, u32HotspotX, u32HotspotY, u32Width, u32Height,
+                            u32AndMaskDepth, u32XorMaskDepth,
+                            pvAndMask, cbAndMask, pvXorMask, cbXorMask);
+}
+
+NTSTATUS GaDefineAlphaCursor(PVBOXWDDM_EXT_GA pGaDevExt,
+                             uint32_t u32HotspotX,
+                             uint32_t u32HotspotY,
+                             uint32_t u32Width,
+                             uint32_t u32Height,
+                             void const *pvImage,
+                             uint32_t cbImage)
+{
+    VBOXWDDM_EXT_VMSVGA *pSvga = pGaDevExt->hw.pSvga;
+    return SvgaDefineAlphaCursor(pSvga, u32HotspotX, u32HotspotY, u32Width, u32Height,
+                                 pvImage, cbImage);
 }
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h	(revision 81369)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/gallium/VBoxMPGaWddm.h	(revision 81594)
@@ -58,4 +58,24 @@
                   uint32_t u32Height);
 
+NTSTATUS GaDefineCursor(PVBOXWDDM_EXT_GA pGaDevExt,
+                        uint32_t u32HotspotX,
+                        uint32_t u32HotspotY,
+                        uint32_t u32Width,
+                        uint32_t u32Height,
+                        uint32_t u32AndMaskDepth,
+                        uint32_t u32XorMaskDepth,
+                        void const *pvAndMask,
+                        uint32_t cbAndMask,
+                        void const *pvXorMask,
+                        uint32_t cbXorMask);
+
+NTSTATUS GaDefineAlphaCursor(PVBOXWDDM_EXT_GA pGaDevExt,
+                             uint32_t u32HotspotX,
+                             uint32_t u32HotspotY,
+                             uint32_t u32Width,
+                             uint32_t u32Height,
+                             void const *pvImage,
+                             uint32_t cbImage);
+
 NTSTATUS APIENTRY GaDxgkDdiBuildPagingBuffer(const HANDLE hAdapter,
                                              DXGKARG_BUILDPAGINGBUFFER *pBuildPagingBuffer);
