freedreno/a6xx: Pre-bake SO-disable stateobj

No need to re-create this every time we transition from stream-out
enabled to disabled.

Creation of streamout_disable_stateobj is deferred until we create
a program state using streamout to avoid creating it unnecessarily
and because fd6_prog_init() is called before ctx->pipe is created.
(Changing that ordering is complicated by the fact that u_blitter
copies pctx->bind_fs_state(), and friends.)

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12918>
This commit is contained in:
Rob Clark
2021-09-17 12:22:30 -07:00
committed by Marge Bot
parent 60f12ac127
commit bf74d58f21
4 changed files with 41 additions and 23 deletions
@@ -51,6 +51,9 @@ fd6_context_destroy(struct pipe_context *pctx) in_dt
u_upload_destroy(fd6_ctx->border_color_uploader);
pipe_resource_reference(&fd6_ctx->border_color_buf, NULL);
if (fd6_ctx->streamout_disable_stateobj)
fd_ringbuffer_del(fd6_ctx->streamout_disable_stateobj);
fd_context_destroy(pctx);
if (fd6_ctx->vsc_draw_strm)
@@ -70,6 +70,9 @@ struct fd6_context {
struct u_upload_mgr *border_color_uploader;
struct pipe_resource *border_color_buf;
/* pre-backed stateobj for stream-out disable: */
struct fd_ringbuffer *streamout_disable_stateobj;
/* storage for ctx->last.key: */
struct ir3_shader_key last_key;
+3 -23
View File
@@ -909,32 +909,12 @@ fd6_emit_streamout(struct fd_ringbuffer *ring, struct fd6_emit *emit) assert_dt
if (emit->streamout_mask) {
fd6_emit_add_group(emit, prog->streamout_stateobj, FD6_GROUP_SO,
ENABLE_ALL);
} else {
} else if (ctx->last.streamout_mask != 0) {
/* If we transition from a draw with streamout to one without, turn
* off streamout.
*/
if (ctx->last.streamout_mask != 0) {
unsigned sizedw = 4;
if (ctx->screen->info->a6xx.tess_use_shared)
sizedw += 2;
struct fd_ringbuffer *obj = fd_submit_new_ringbuffer(
emit->ctx->batch->submit, (1 + sizedw) * 4, FD_RINGBUFFER_STREAMING);
OUT_PKT7(obj, CP_CONTEXT_REG_BUNCH, sizedw);
OUT_RING(obj, REG_A6XX_VPC_SO_CNTL);
OUT_RING(obj, 0);
OUT_RING(obj, REG_A6XX_VPC_SO_STREAM_CNTL);
OUT_RING(obj, 0);
if (ctx->screen->info->a6xx.tess_use_shared) {
OUT_RING(ring, REG_A6XX_PC_SO_STREAM_CNTL);
OUT_RING(ring, 0);
}
fd6_emit_take_group(emit, obj, FD6_GROUP_SO, ENABLE_ALL);
}
fd6_emit_add_group(emit, fd6_context(ctx)->streamout_disable_stateobj,
FD6_GROUP_SO, ENABLE_ALL);
}
/* Make sure that any use of our TFB outputs (indirect draw source or shader
@@ -152,6 +152,35 @@ fd6_emit_shader(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RELOC(ring, so->bo, 0, 0, 0);
}
/**
* Build a pre-baked state-obj to disable SO, so that we aren't dynamically
* building this at draw time whenever we transition from SO enabled->disabled
*/
static void
setup_stream_out_disable(struct fd_context *ctx)
{
unsigned sizedw = 4;
if (ctx->screen->info->a6xx.tess_use_shared)
sizedw += 2;
struct fd_ringbuffer *ring =
fd_ringbuffer_new_object(ctx->pipe, (1 + sizedw) * 4);
OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, sizedw);
OUT_RING(ring, REG_A6XX_VPC_SO_CNTL);
OUT_RING(ring, 0);
OUT_RING(ring, REG_A6XX_VPC_SO_STREAM_CNTL);
OUT_RING(ring, 0);
if (ctx->screen->info->a6xx.tess_use_shared) {
OUT_RING(ring, REG_A6XX_PC_SO_STREAM_CNTL);
OUT_RING(ring, 0);
}
fd6_context(ctx)->streamout_disable_stateobj = ring;
}
static void
setup_stream_out(struct fd_context *ctx, struct fd6_program_state *state,
const struct ir3_shader_variant *v,
@@ -568,6 +597,9 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_context *ctx,
*/
if (do_streamout && !binning_pass) {
setup_stream_out(ctx, state, last_shader, &l);
if (!fd6_context(ctx)->streamout_disable_stateobj)
setup_stream_out_disable(ctx);
}
debug_assert(l.cnt <= 32);