From 21c3e82495d7c6b7fd419e393f6b71642bf031f0 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 8 Feb 2021 17:49:17 -0500 Subject: [PATCH] panfrost: Fix race condition in UBO mapping to CPU In theory, a compute shader (or transform feedback) could write to an SSBO, rebind as a UBO, and then read as a UBO later in the same frame. We would need to flush in this case so we don't push stale data to the later shader. This seems sufficiently obscure, but if this is a performance issue in a real workload, we could emit a small compute shader to do the copies without flushing. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Boris Brezillon Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index b264521086c..7a61bb5c80d 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -958,7 +958,8 @@ panfrost_upload_sysvals(struct panfrost_batch *batch, void *buf, } static const void * -panfrost_map_constant_buffer_cpu(struct panfrost_constant_buffer *buf, +panfrost_map_constant_buffer_cpu(struct panfrost_context *ctx, + struct panfrost_constant_buffer *buf, unsigned index) { struct pipe_constant_buffer *cb = &buf->cb[index]; @@ -966,9 +967,13 @@ panfrost_map_constant_buffer_cpu(struct panfrost_constant_buffer *buf, if (rsrc) return rsrc->bo->ptr.cpu; - else if (cb->user_buffer) + else if (cb->user_buffer) { + panfrost_bo_mmap(rsrc->bo); + panfrost_flush_batches_accessing_bo(ctx, rsrc->bo, false); + panfrost_bo_wait(rsrc->bo, INT64_MAX, false); + return cb->user_buffer; - else + } else unreachable("No constant buffer"); } @@ -1002,7 +1007,7 @@ panfrost_emit_const_buf(struct panfrost_batch *batch, /* Upload uniforms */ if (has_uniforms && uniform_size) { - const void *cpu = panfrost_map_constant_buffer_cpu(buf, 0); + const void *cpu = panfrost_map_constant_buffer_cpu(ctx, buf, 0); memcpy(transfer.cpu + sys_size, cpu, uniform_size); }