summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2019-06-17 09:53:48 -0700
committerChia-I Wu <[email protected]>2019-06-18 10:38:21 -0700
commit98eda99ab88b8a5bcf5da5daa7ca4edbf34592fd (patch)
treee4aaf0bd2bc553a4b87cc39fc240a1ee40ca33c6
parent2a717f300bb6fdb610f20ec8c693af4896e4fc5a (diff)
virgl: fix sync issue regarding discard/unsync transfers
GL_MAP_INVALIDATE_BUFFER_BIT cannot be treated as GL_MAP_INVALIDATE_RANGE_BIT naively. When we run into ptr = glMapBufferRange(buf, 0, size, GL_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT); memcpy(ptr, data1, size); glUnmapBuffer(buf); ptr = glMapBufferRange(buf, size, size, GL_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT); memcpy(ptr, data2, size); glUnmapBuffer(buf); we never want data1 to be copy_transfer'ed. Because that would mean that data2 might overwrite valid data. Signed-off-by: Chia-I Wu <[email protected]> Reviewed-by: Alexandros Frantzis [email protected] Fixes: a22c5df0794 ("virgl: Use buffer copy transfers to avoid waiting when mapping") Reviewed-by: Emil Velikov <[email protected]>
-rw-r--r--src/gallium/drivers/virgl/virgl_resource.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c
index 9b908afd852..4e585d72490 100644
--- a/src/gallium/drivers/virgl/virgl_resource.c
+++ b/src/gallium/drivers/virgl/virgl_resource.c
@@ -129,11 +129,21 @@ virgl_resource_transfer_prepare(struct virgl_context *vctx,
*/
if (wait && (xfer->base.usage & (PIPE_TRANSFER_DISCARD_RANGE |
PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE))) {
- const bool can_realloc =
- (xfer->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) &&
- virgl_can_rebind_resource(vctx, &res->u.b);
- const bool can_staging = vctx->transfer_uploader &&
- !vctx->transfer_uploader_in_use;
+ bool can_realloc = false;
+ bool can_staging = false;
+
+ /* A PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE transfer may be followed by
+ * PIPE_TRANSFER_UNSYNCHRONIZED transfers to non-overlapping regions.
+ * It cannot be treated as a PIPE_TRANSFER_DISCARD_RANGE transfer,
+ * otherwise those following unsynchronized transfers may overwrite
+ * valid data.
+ */
+ if (xfer->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+ can_realloc = virgl_can_rebind_resource(vctx, &res->u.b);
+ } else {
+ can_staging = vctx->transfer_uploader &&
+ !vctx->transfer_uploader_in_use;
+ }
/* discard implies no readback */
assert(!readback);