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,13 +229,13 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
/* Add the new surface to the buffer surface list */ /* Add the new surface to the buffer surface list */
ret = svga_buffer_add_host_surface(sbuf, sbuf->handle, &sbuf->key, ret = svga_buffer_add_host_surface(sbuf, sbuf->handle, &sbuf->key,
bind_flags); bind_flags);
}
if (ss->sws->have_gb_objects) { if (ss->sws->have_gb_objects) {
/* Initialize the surface with zero */ /* Initialize the surface with zero */
ss->sws->surface_init(ss->sws, sbuf->handle, svga_surface_size(&sbuf->key), ss->sws->surface_init(ss->sws, sbuf->handle, svga_surface_size(&sbuf->key),
sbuf->key.flags); sbuf->key.flags);
} }
}
return ret; return ret;
} }

View file

@ -44,15 +44,15 @@ vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws,
struct pb_buffer *pb_buf; struct pb_buffer *pb_buf;
uint32_t pb_flags; uint32_t pb_flags;
struct vmw_winsys_screen *vws = vsrf->screen; 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_manager *provider;
struct pb_desc desc; struct pb_desc desc;
data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, mtx_lock(&vsrf->mutex);
PIPE_TRANSFER_DONTBLOCK | pb_flags); data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags);
if (data) if (data)
goto out_unlock; goto out_mapped;
provider = vws->pools.mob_fenced; provider = vws->pools.mob_fenced;
memset(&desc, 0, sizeof(desc)); 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); data = vmw_svga_winsys_buffer_map(&vws->base, vbuf, pb_flags);
if (data) { if (data) {
if (vsrf->buf) { vsrf->rebind = TRUE;
if (vsrf->buf)
vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf); vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf);
vsrf->buf = vbuf; vsrf->buf = vbuf;
goto out_unlock; goto out_mapped;
} else } else {
vmw_svga_winsys_buffer_destroy(&vws->base, vbuf); vmw_svga_winsys_buffer_destroy(&vws->base, vbuf);
}
}
data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags);
if (data == NULL)
goto out_unlock; goto out_unlock;
}
}
else {
/* Cannot create a buffer, just unlock */
goto out_unlock;
}
out_unlock: out_mapped:
mtx_unlock(&vsrf->mutex); mtx_unlock(&vsrf->mutex);
if (data) if (data) {
{
if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) { if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) {
memset(data, 0, surf_size + sizeof(SVGA3dDXSOState)); memset(data, 0, surf_size + sizeof(SVGA3dDXSOState));
} }
@ -89,8 +90,10 @@ out_unlock:
memset(data, 0, surf_size); memset(data, 0, surf_size);
} }
} }
mtx_lock(&vsrf->mutex); mtx_lock(&vsrf->mutex);
vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf); vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf);
out_unlock:
mtx_unlock(&vsrf->mutex); mtx_unlock(&vsrf->mutex);
} }