diff options
author | Brian Paul <[email protected]> | 2016-06-30 13:27:57 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2016-06-30 14:32:10 -0600 |
commit | 88a344253c2091f7935b3dfc7fe3be99b76033a3 (patch) | |
tree | 7a0b1cfc009bb38b6c8ac9cff396002517ab939e | |
parent | fa2cdd973d466528c2c353c86457ce12f46e5cc4 (diff) |
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 <[email protected]>
Reviewed-by: Charmaine Lee <[email protected]>
-rw-r--r-- | src/gallium/drivers/svga/svga_resource_buffer.c | 37 |
1 files 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 9ecb97509c2..a92a5c11904 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) { |