We previously only did a buffer readback if it was dirty and we were about to do a read-transfer. Now also do a readback for write-transfers when not overwriting the entire buffer. We have to do that to keep the guest/host buffers synchronized in order to support host-side buffer copies with SVGA3dCmdDXBufferCopy.
Tested with full piglit run. --- src/gallium/drivers/svga/svga_resource_buffer.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index 9ecb975..192425b 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -95,11 +95,16 @@ svga_buffer_transfer_map(struct pipe_context *pipe, transfer->usage = usage; 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. + if (sbuf->dirty) { + /* dirty means the host copy of the resource was modified, probably + * either with stream output or a buffer copy (only possible with vgpu10. + * We may need to do a readback to update the guest copy. */ - if (svga_have_vgpu10(svga)) { + if (svga_have_vgpu10(svga) && + ((usage & PIPE_TRANSFER_READ) != 0 || + ((usage & PIPE_TRANSFER_WRITE) != 0 && + (box->x != 0 || box->width != resource->width0)))) { + /* mapping for read, or writing a subset of the resource */ enum pipe_error ret; assert(sbuf->handle); ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0); @@ -112,9 +117,9 @@ svga_buffer_transfer_map(struct pipe_context *pipe, svga->hud.num_readbacks++; svga_context_finish(svga); - - sbuf->dirty = FALSE; } + + sbuf->dirty = FALSE; } if (usage & PIPE_TRANSFER_WRITE) { -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev