From: Charmaine Lee Date: Thu, 20 Aug 2020 23:43:00 +0000 (-0700) Subject: winsys/svga: fix display corruption after surface_init X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=f41848a9df3c6eb81059edfd63347584790e0a3a winsys/svga: fix display corruption after surface_init When we initialize the buffer surface, do not map the existing storage with DONTBLOCK, leave it as a synchronized map. This patch also sets the surface rebind flag after it is bound to a new buffer and sets the surface buffer pointer accordingly. This fixes display corruption issue seen with running steam. Reviewed-by: Neha Bhende Reviewed-by: Roland Scheidegger Part-of: --- diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index 78535643563..fecc1ae54d0 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -229,12 +229,12 @@ svga_buffer_create_host_surface(struct svga_screen *ss, /* Add the new surface to the buffer surface list */ ret = svga_buffer_add_host_surface(sbuf, sbuf->handle, &sbuf->key, bind_flags); - } - if (ss->sws->have_gb_objects) { - /* Initialize the surface with zero */ - ss->sws->surface_init(ss->sws, sbuf->handle, svga_surface_size(&sbuf->key), - sbuf->key.flags); + if (ss->sws->have_gb_objects) { + /* Initialize the surface with zero */ + ss->sws->surface_init(ss->sws, sbuf->handle, svga_surface_size(&sbuf->key), + sbuf->key.flags); + } } return ret; diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c index f6f40fcdf20..25c6d320c74 100644 --- a/src/gallium/winsys/svga/drm/vmw_surface.c +++ b/src/gallium/winsys/svga/drm/vmw_surface.c @@ -44,15 +44,15 @@ vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws, struct pb_buffer *pb_buf; uint32_t pb_flags; struct vmw_winsys_screen *vws = vsrf->screen; - pb_flags = PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; + pb_flags = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; struct pb_manager *provider; struct pb_desc desc; - data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, - PIPE_TRANSFER_DONTBLOCK | pb_flags); + mtx_lock(&vsrf->mutex); + data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags); if (data) - goto out_unlock; + goto out_mapped; provider = vws->pools.mob_fenced; memset(&desc, 0, sizeof(desc)); @@ -64,24 +64,25 @@ vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws, data = vmw_svga_winsys_buffer_map(&vws->base, vbuf, pb_flags); if (data) { - if (vsrf->buf) { + vsrf->rebind = TRUE; + if (vsrf->buf) vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf); - vsrf->buf = vbuf; - goto out_unlock; - } else - vmw_svga_winsys_buffer_destroy(&vws->base, vbuf); + vsrf->buf = vbuf; + goto out_mapped; + } else { + vmw_svga_winsys_buffer_destroy(&vws->base, vbuf); + goto out_unlock; } } - - data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags); - if (data == NULL) + else { + /* Cannot create a buffer, just unlock */ goto out_unlock; + } -out_unlock: +out_mapped: mtx_unlock(&vsrf->mutex); - if (data) - { + if (data) { if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) { memset(data, 0, surf_size + sizeof(SVGA3dDXSOState)); } @@ -89,8 +90,10 @@ out_unlock: memset(data, 0, surf_size); } } + mtx_lock(&vsrf->mutex); vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf); +out_unlock: mtx_unlock(&vsrf->mutex); }