From: Eric Anholt Date: Mon, 1 Jun 2020 18:53:22 +0000 (-0700) Subject: freedreno: Upload gallium constbufs as needed when referenced as a UBO. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4065861807f1f488f9e9dc0254009982ccbf7784;p=mesa.git 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: --- 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); }