From 88a344253c2091f7935b3dfc7fe3be99b76033a3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 30 Jun 2016 13:27:57 -0600 Subject: [PATCH] svga: flush buffers when mapping for reading With host-side buffer copies (via SVGA3D_vgpu10_BufferCopy()) we have to make sure any pending map-write operations are completed before reading if the buffer is dirty. Otherwise the ReadbackSubResource operation could get stale data from the host buffer. This allows the piglit arb_copy_buffer-subdata-sync test to pass when we start using the SVGA3D_vgpu10_BufferCopy command. v2: check the sbuf->dirty flag in the outer conditional, per Charmaine. Acked-by: Roland Scheidegger Reviewed-by: Charmaine Lee --- src/gallium/drivers/svga/svga_resource_buffer.c | 37 ++++++++++++++++--------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index 9ecb975..a92a5c1 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -96,25 +96,36 @@ svga_buffer_transfer_map(struct pipe_context *pipe, transfer->box = *box; if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty) { - /* Only need to test for vgpu10 since only vgpu10 features (streamout, - * buffer copy) can modify buffers on the device. + enum pipe_error ret; + + /* Host-side buffers can only be dirtied with vgpu10 features + * (streamout and buffer copy). */ - if (svga_have_vgpu10(svga)) { - enum pipe_error ret; - assert(sbuf->handle); - ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0); - if (ret != PIPE_OK) { - svga_context_flush(svga, NULL); - ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0); - assert(ret == PIPE_OK); - } + assert(svga_have_vgpu10(svga)); - svga->hud.num_readbacks++; + if (!sbuf->user) { + (void) svga_buffer_handle(svga, resource); + } + if (sbuf->dma.pending > 0) { + svga_buffer_upload_flush(svga, sbuf); svga_context_finish(svga); + } + + assert(sbuf->handle); - sbuf->dirty = FALSE; + ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0); + if (ret != PIPE_OK) { + svga_context_flush(svga, NULL); + ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0); + assert(ret == PIPE_OK); } + + svga->hud.num_readbacks++; + + svga_context_finish(svga); + + sbuf->dirty = FALSE; } if (usage & PIPE_TRANSFER_WRITE) { -- 2.7.4