Mesa (master): freedreno: Upload gallium constbufs as needed when referenced as a UBO.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 5 21:08:36 UTC 2020


Module: Mesa
Branch: master
Commit: 4065861807f1f488f9e9dc0254009982ccbf7784
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4065861807f1f488f9e9dc0254009982ccbf7784

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jun  1 11:53:22 2020 -0700

freedreno: Upload gallium constbufs as needed when referenced as a UBO.

For now we never ask to set up UBO 0 as a real UBO, so this doesn't
trigger, but it gets us ready for handling the case where UBO 0 is too big
to be push constants in the HW.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5273>

---

 src/gallium/drivers/freedreno/a6xx/fd6_const.c | 21 ++++++++++++++++++---
 src/gallium/drivers/freedreno/ir3/ir3_const.h  | 19 ++++++++++++++++---
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_const.c b/src/gallium/drivers/freedreno/a6xx/fd6_const.c
index 1d24d8aafe2..5b7f7518ab7 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_const.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_const.c
@@ -228,7 +228,7 @@ emit_tess_consts(struct fd6_emit *emit)
 }
 
 static void
-fd6_emit_ubos(const struct ir3_shader_variant *v,
+fd6_emit_ubos(struct fd_context *ctx, const struct ir3_shader_variant *v,
 		struct fd_ringbuffer *ring, struct fd_constbuf_stateobj *constbuf)
 {
 	if (!v->shader->num_ubos)
@@ -250,6 +250,21 @@ fd6_emit_ubos(const struct ir3_shader_variant *v,
 		 * and UBO load indices decremented by one.
 		 */
 		struct pipe_constant_buffer *cb = &constbuf->cb[i + 1];
+
+		/* If we have user pointers (constbuf 0, aka GL uniforms), upload them
+		 * to a buffer now, and save it in the constbuf so that we don't have
+		 * to reupload until they get changed.
+		 */
+		if (cb->user_buffer) {
+			struct pipe_context *pctx = &ctx->base;
+			u_upload_data(pctx->stream_uploader, 0,
+					cb->buffer_size,
+					64,
+					cb->user_buffer,
+					&cb->buffer_offset, &cb->buffer);
+			cb->user_buffer = NULL;
+		}
+
 		if (cb->buffer) {
 			int size_vec4s = DIV_ROUND_UP(cb->buffer_size, 16);
 			OUT_RELOC(ring, fd_resource(cb->buffer)->bo,
@@ -289,7 +304,7 @@ emit_user_consts(struct fd6_emit *emit)
 		if (!variants[i])
 			continue;
 		ir3_emit_user_consts(ctx->screen, variants[i], constobj, &ctx->constbuf[types[i]]);
-		fd6_emit_ubos(variants[i], constobj, &ctx->constbuf[types[i]]);
+		fd6_emit_ubos(ctx, variants[i], constobj, &ctx->constbuf[types[i]]);
 	}
 
 	fd6_emit_take_group(emit, constobj, FD6_GROUP_CONST, ENABLE_ALL);
@@ -336,7 +351,7 @@ fd6_emit_cs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin
 		struct fd_context *ctx, const struct pipe_grid_info *info)
 {
 	ir3_emit_cs_consts(v, ring, ctx, info);
-	fd6_emit_ubos(v, ring, &ctx->constbuf[PIPE_SHADER_COMPUTE]);
+	fd6_emit_ubos(ctx, v, ring, &ctx->constbuf[PIPE_SHADER_COMPUTE]);
 }
 
 void
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_const.h b/src/gallium/drivers/freedreno/ir3/ir3_const.h
index 64cd39684ad..6ed49baa8fa 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_const.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_const.h
@@ -131,7 +131,7 @@ ir3_emit_user_consts(struct fd_screen *screen, const struct ir3_shader_variant *
 }
 
 static inline void
-ir3_emit_ubos(struct fd_screen *screen, const struct ir3_shader_variant *v,
+ir3_emit_ubos(struct fd_context *ctx, const struct ir3_shader_variant *v,
 		struct fd_ringbuffer *ring, struct fd_constbuf_stateobj *constbuf)
 {
 	const struct ir3_const_state *const_state = &v->shader->const_state;
@@ -144,7 +144,20 @@ ir3_emit_ubos(struct fd_screen *screen, const struct ir3_shader_variant *v,
 		for (uint32_t i = 0; i < params; i++) {
 			const uint32_t index = i + 1;   /* UBOs start at index 1 */
 			struct pipe_constant_buffer *cb = &constbuf->cb[index];
-			assert(!cb->user_buffer);
+
+			/* If we have user pointers (constbuf 0, aka GL uniforms), upload
+			 * them to a buffer now, and save it in the constbuf so that we
+			 * don't have to reupload until they get changed.
+			 */
+			if (cb->user_buffer) {
+				struct pipe_context *pctx = &ctx->base;
+				u_upload_data(pctx->stream_uploader, 0,
+						cb->buffer_size,
+						64,
+						cb->user_buffer,
+						&cb->buffer_offset, &cb->buffer);
+				cb->user_buffer = NULL;
+			}
 
 			if ((constbuf->enabled_mask & (1 << index)) && cb->buffer) {
 				offsets[i] = cb->buffer_offset;
@@ -391,7 +404,7 @@ emit_common_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin
 		ring_wfi(ctx->batch, ring);
 
 		ir3_emit_user_consts(ctx->screen, v, ring, constbuf);
-		ir3_emit_ubos(ctx->screen, v, ring, constbuf);
+		ir3_emit_ubos(ctx, v, ring, constbuf);
 		if (shader_dirty)
 			ir3_emit_immediates(ctx->screen, v, ring);
 	}



More information about the mesa-commit mailing list