summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2012-10-11 12:21:21 +0200
committerAlon Levy <alevy@redhat.com>2012-10-14 18:41:29 +0200
commit5020ad9f4a54d632daca3ccbc5522e3d44909c33 (patch)
treeee855d08a47cbb1278665f6c1aa23bf531198960
parenta1889087f1f1b64227ed725770464692bbcb19d6 (diff)
only allow word aligned strides
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.
-rw-r--r--display/driver.c7
-rw-r--r--display/res.c2
-rw-r--r--miniport/qxl.c4
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;