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 <bhenden@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6415>
This commit is contained in:
Charmaine Lee 2020-08-20 16:43:00 -07:00 committed by Marge Bot
parent 090239ea6b
commit f41848a9df
2 changed files with 23 additions and 20 deletions

View file

@ -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;

View file

@ -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);
}