[Spice-devel] [PATCH qxl-win32 v2] miniport/qxl: FillVideoMode: only allow word aligned strides

Alon Levy alevy at redhat.com
Sun Oct 14 09:40:57 PDT 2012


This is a pixman requirement. If it isn't enforced spice crashes, qemu
with it. That should be fixed, but there is no simple way to allow for
non word aligned strides, and the only down side is that for 16 bit
modes we will require even widths. And we already have the same
implementation detail in the X driver, only there it is a multiple of 8,
not 4.

The SurfaceCreate command's stride is computed in one place:
 miniport:FillVidModeInfo sets ScreenStride as word aligned
 display:pdev->stride is set from ScreenStride

A third change at GetSurfaceMemory fixes the stride used for GDI
allocated surface, but since surface 0 has a fixed larger then required
area this isn't required for the bug fix, just for consistency.
---
 display/driver.c | 7 ++++---
 display/res.c    | 2 +-
 miniport/qxl.c   | 4 +++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/display/driver.c b/display/driver.c
index 90c52c5..d7fdbf7 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -620,13 +620,13 @@ static VOID HideMouse(PDev *pdev)
 }
 
 static VOID CreatePrimarySurface(PDev *pdev, UINT32 depth, UINT32 format,
-                                 UINT32 width, UINT32 height,
+                                 UINT32 width, UINT32 height, INT32 stride,
                                  QXLPHYSICAL phys_mem)
 {
     pdev->primary_surface_create->format = format;
     pdev->primary_surface_create->width = width;
     pdev->primary_surface_create->height = height;
-    pdev->primary_surface_create->stride = -(INT32)width * (depth / 8);
+    pdev->primary_surface_create->stride = -stride;
     pdev->primary_surface_create->mem = phys_mem;
 
     pdev->primary_surface_create->flags = 0;
@@ -898,7 +898,8 @@ VOID EnableQXLPrimarySurface(PDev *pdev)
     };
 
     CreatePrimarySurface(pdev, depth, format,
-                         pdev->resolution.cx, pdev->resolution.cy, pdev->surf_phys);
+                         pdev->resolution.cx, pdev->resolution.cy,
+                         pdev->stride, pdev->surf_phys);
     pdev->surf_enable = TRUE;
 }
 
diff --git a/display/res.c b/display/res.c
index e9c301e..e494271 100644
--- a/display/res.c
+++ b/display/res.c
@@ -698,7 +698,7 @@ _inline void GetSurfaceMemory(PDev *pdev, UINT32 x, UINT32 y, UINT32 depth, INT3
         ASSERT(pdev, x * y * depth /8 <= pdev->primary_memory_size);
         *base_mem = pdev->primary_memory_start;
         *phys_mem = PA(pdev, *base_mem, pdev->main_mem_slot);
-        *stride = x * depth / 8;
+        *stride = (x * depth / 8 + 3) & ~0x3; /* Pixman requires 4 byte aligned stride */
         break;
     case DEVICE_BITMAP_ALLOCATION_TYPE_DEVRAM:
         *stride = x * depth / 8;
diff --git a/miniport/qxl.c b/miniport/qxl.c
index 55e55d3..58ba15e 100644
--- a/miniport/qxl.c
+++ b/miniport/qxl.c
@@ -469,6 +469,8 @@ VP_STATUS FillVidModeInfo(VIDEO_MODE_INFORMATION *pMode, ULONG xres, ULONG yres,
 /* Fills given video mode structure */
 VP_STATUS FillVidModeInfo(VIDEO_MODE_INFORMATION *pMode, ULONG xres, ULONG yres, ULONG bpp, ULONG index)
 {
+    unsigned bytes_pp = (bpp + 7) / 8;
+
     if (xres <= 0 || yres <= 0)
         return ERROR_INVALID_DATA;
 
@@ -479,7 +481,7 @@ VP_STATUS FillVidModeInfo(VIDEO_MODE_INFORMATION *pMode, ULONG xres, ULONG yres,
     pMode->ModeIndex                    = index;
     pMode->VisScreenWidth               = xres;
     pMode->VisScreenHeight              = yres;
-    pMode->ScreenStride                 = xres * ((bpp + 7) / 8);
+    pMode->ScreenStride                 = (xres * bytes_pp + 3) & ~0x3; /* Pixman requirement */
     pMode->NumberOfPlanes               = 1;
     pMode->BitsPerPlane                 = bpp;
     pMode->Frequency                    = 60;
-- 
1.7.12.1



More information about the Spice-devel mailing list