aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <[email protected]>2016-01-08 20:29:40 +0100
committerDave Airlie <[email protected]>2016-01-14 07:56:46 +1000
commita50e2bf5a0f674d62b69f51f6935a30e82bd015c (patch)
tree737174e2d86df23c3efe57285e338011c9455e64
parentfb89ac5102ae2875d685c847e6b5dbc141622d43 (diff)
drm/vmwgfx: Fix a width / pitch mismatch on framebuffer updates
When the framebuffer is a vmwgfx dma buffer and a proxy surface is created, the vmw_kms_update_proxy() function requires that the proxy surface width and the framebuffer pitch are compatible, otherwise display corruption occurs as seen in gnome-shell/native with software 3D. Since the framebuffer pitch is determined by user-space, allocate a proxy surface the width of which is based on the framebuffer pitch rather than on the framebuffer width. Cc: <[email protected]> Reported-by: Raphael Hertzog <[email protected]> Tested-by: Mati Aharoni <[email protected]> Signed-off-by: Thomas Hellstrom <[email protected]> Reviewed-by: Brian Paul <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 274c90da44a7..b221a8c40282 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -763,21 +763,25 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
uint32_t format;
struct drm_vmw_size content_base_size;
struct vmw_resource *res;
+ unsigned int bytes_pp;
int ret;
switch (mode_cmd->depth) {
case 32:
case 24:
format = SVGA3D_X8R8G8B8;
+ bytes_pp = 4;
break;
case 16:
case 15:
format = SVGA3D_R5G6B5;
+ bytes_pp = 2;
break;
case 8:
format = SVGA3D_P8;
+ bytes_pp = 1;
break;
default:
@@ -785,7 +789,7 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
return -EINVAL;
}
- content_base_size.width = mode_cmd->width;
+ content_base_size.width = mode_cmd->pitch / bytes_pp;
content_base_size.height = mode_cmd->height;
content_base_size.depth = 1;