Mesa (master): freedreno/a6xx: Create shader dependent streamout state at compile time

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 21 00:46:50 UTC 2020


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

Author: Kristian H. Kristensen <hoegsberg at google.com>
Date:   Fri May 15 13:07:38 2020 -0700

freedreno/a6xx: Create shader dependent streamout state at compile time

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

---

 src/gallium/drivers/freedreno/a6xx/fd6_emit.c     | 42 +++++++++----------
 src/gallium/drivers/freedreno/a6xx/fd6_emit.h     |  1 +
 src/gallium/drivers/freedreno/a6xx/fd6_program.c  | 49 +++++++++++++++++------
 src/gallium/drivers/freedreno/a6xx/fd6_program.h  | 11 +----
 src/gallium/drivers/freedreno/freedreno_context.h |  1 +
 5 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
index 2f96eebc5d6..42adf5df9a9 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
@@ -695,32 +695,26 @@ fd6_emit_streamout(struct fd_ringbuffer *ring, struct fd6_emit *emit, struct ir3
 	}
 
 	if (emit->streamout_mask) {
-		const struct fd6_streamout_state *tf = &prog->tf;
-
-		OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, 12 + (2 * tf->prog_count));
-		OUT_RING(ring, REG_A6XX_VPC_SO_BUF_CNTL);
-		OUT_RING(ring, tf->vpc_so_buf_cntl);
-		OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(0));
-		OUT_RING(ring, tf->ncomp[0]);
-		OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(1));
-		OUT_RING(ring, tf->ncomp[1]);
-		OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(2));
-		OUT_RING(ring, tf->ncomp[2]);
-		OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(3));
-		OUT_RING(ring, tf->ncomp[3]);
-		OUT_RING(ring, REG_A6XX_VPC_SO_CNTL);
-		OUT_RING(ring, A6XX_VPC_SO_CNTL_ENABLE);
-		for (unsigned i = 0; i < tf->prog_count; i++) {
-			OUT_RING(ring, REG_A6XX_VPC_SO_PROG);
-			OUT_RING(ring, tf->prog[i]);
-		}
+		fd6_emit_add_group(emit, prog->streamout_stateobj, FD6_GROUP_SO, ENABLE_ALL);
 	} else {
-		OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, 4);
-		OUT_RING(ring, REG_A6XX_VPC_SO_CNTL);
-		OUT_RING(ring, 0);
-		OUT_RING(ring, REG_A6XX_VPC_SO_BUF_CNTL);
-		OUT_RING(ring, 0);
+		/* If we transition from a draw with streamout to one without, turn
+		 * off streamout.
+		 */
+		if (ctx->last.streamout_mask != 0) {
+			struct fd_ringbuffer *obj = fd_submit_new_ringbuffer(emit->ctx->batch->submit,
+					5 * 4, FD_RINGBUFFER_STREAMING);
+
+			OUT_PKT7(obj, CP_CONTEXT_REG_BUNCH, 4);
+			OUT_RING(obj, REG_A6XX_VPC_SO_CNTL);
+			OUT_RING(obj, 0);
+			OUT_RING(obj, REG_A6XX_VPC_SO_BUF_CNTL);
+			OUT_RING(obj, 0);
+
+			fd6_emit_take_group(emit, obj, FD6_GROUP_SO, ENABLE_ALL);
+		}
 	}
+
+	ctx->last.streamout_mask = emit->streamout_mask;
 }
 
 void
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h
index bf62e34e232..9f4d1b4ce42 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h
@@ -65,6 +65,7 @@ enum fd6_state_id {
 	FD6_GROUP_BLEND,
 	FD6_GROUP_SCISSOR,
 	FD6_GROUP_BLEND_COLOR,
+	FD6_GROUP_SO,
 };
 
 #define ENABLE_ALL (CP_SET_DRAW_STATE__0_BINNING | CP_SET_DRAW_STATE__0_GMEM | CP_SET_DRAW_STATE__0_SYSMEM)
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c
index 58613d105c4..24c8ab080e2 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c
@@ -145,20 +145,24 @@ setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_varian
 		struct ir3_shader_linkage *l)
 {
 	const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
-	struct fd6_streamout_state *tf = &state->tf;
 
-	memset(tf, 0, sizeof(*tf));
+	uint32_t ncomp[PIPE_MAX_SO_BUFFERS];
+	uint32_t prog[256/2];
+	uint32_t prog_count;
 
-	tf->prog_count = align(l->max_loc, 2) / 2;
+	memset(ncomp, 0, sizeof(ncomp));
+	memset(prog, 0, sizeof(prog));
 
-	debug_assert(tf->prog_count < ARRAY_SIZE(tf->prog));
+	prog_count = align(l->max_loc, 2) / 2;
+
+	debug_assert(prog_count < ARRAY_SIZE(prog));
 
 	for (unsigned i = 0; i < strmout->num_outputs; i++) {
 		const struct ir3_stream_output *out = &strmout->output[i];
 		unsigned k = out->register_index;
 		unsigned idx;
 
-		tf->ncomp[out->output_buffer] += out->num_components;
+		ncomp[out->output_buffer] += out->num_components;
 
 		/* linkage map sorted by order frag shader wants things, so
 		 * a bit less ideal here..
@@ -175,22 +179,40 @@ setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_varian
 			unsigned off = j + out->dst_offset;  /* in dwords */
 
 			if (loc & 1) {
-				tf->prog[loc/2] |= A6XX_VPC_SO_PROG_B_EN |
+				prog[loc/2] |= A6XX_VPC_SO_PROG_B_EN |
 						A6XX_VPC_SO_PROG_B_BUF(out->output_buffer) |
 						A6XX_VPC_SO_PROG_B_OFF(off * 4);
 			} else {
-				tf->prog[loc/2] |= A6XX_VPC_SO_PROG_A_EN |
+				prog[loc/2] |= A6XX_VPC_SO_PROG_A_EN |
 						A6XX_VPC_SO_PROG_A_BUF(out->output_buffer) |
 						A6XX_VPC_SO_PROG_A_OFF(off * 4);
 			}
 		}
 	}
 
-	tf->vpc_so_buf_cntl = A6XX_VPC_SO_BUF_CNTL_ENABLE |
-			COND(tf->ncomp[0] > 0, A6XX_VPC_SO_BUF_CNTL_BUF0) |
-			COND(tf->ncomp[1] > 0, A6XX_VPC_SO_BUF_CNTL_BUF1) |
-			COND(tf->ncomp[2] > 0, A6XX_VPC_SO_BUF_CNTL_BUF2) |
-			COND(tf->ncomp[3] > 0, A6XX_VPC_SO_BUF_CNTL_BUF3);
+	struct fd_ringbuffer *ring = state->streamout_stateobj;
+
+	OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, 12 + (2 * prog_count));
+	OUT_RING(ring, REG_A6XX_VPC_SO_BUF_CNTL);
+	OUT_RING(ring, A6XX_VPC_SO_BUF_CNTL_ENABLE |
+			COND(ncomp[0] > 0, A6XX_VPC_SO_BUF_CNTL_BUF0) |
+			COND(ncomp[1] > 0, A6XX_VPC_SO_BUF_CNTL_BUF1) |
+			COND(ncomp[2] > 0, A6XX_VPC_SO_BUF_CNTL_BUF2) |
+			COND(ncomp[3] > 0, A6XX_VPC_SO_BUF_CNTL_BUF3));
+	OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(0));
+	OUT_RING(ring, ncomp[0]);
+	OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(1));
+	OUT_RING(ring, ncomp[1]);
+	OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(2));
+	OUT_RING(ring, ncomp[2]);
+	OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(3));
+	OUT_RING(ring, ncomp[3]);
+	OUT_RING(ring, REG_A6XX_VPC_SO_CNTL);
+	OUT_RING(ring, A6XX_VPC_SO_CNTL_ENABLE);
+	for (unsigned i = 0; i < prog_count; i++) {
+		OUT_RING(ring, REG_A6XX_VPC_SO_PROG);
+		OUT_RING(ring, prog[i]);
+	}
 }
 
 static void
@@ -973,6 +995,8 @@ fd6_program_create(void *data, struct ir3_shader_variant *bs,
 	state->config_stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
 	state->binning_stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
 	state->stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
+	state->streamout_stateobj = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
+
 
 #ifdef DEBUG
 	if (!ds) {
@@ -1000,6 +1024,7 @@ fd6_program_destroy(void *data, struct ir3_program_state *state)
 	fd_ringbuffer_del(so->binning_stateobj);
 	fd_ringbuffer_del(so->config_stateobj);
 	fd_ringbuffer_del(so->interp_stateobj);
+	fd_ringbuffer_del(so->streamout_stateobj);
 	free(so);
 }
 
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.h b/src/gallium/drivers/freedreno/a6xx/fd6_program.h
index f1f4838fb38..54a7c1fb52c 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_program.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.h
@@ -34,13 +34,6 @@
 #include "ir3/ir3_shader.h"
 #include "ir3_cache.h"
 
-struct fd6_streamout_state {
-	uint32_t ncomp[PIPE_MAX_SO_BUFFERS];
-	uint32_t prog[256/2];
-	uint32_t prog_count;
-	uint32_t vpc_so_buf_cntl;
-};
-
 struct fd6_emit;
 
 struct fd6_program_state {
@@ -54,10 +47,8 @@ struct fd6_program_state {
 	struct fd_ringbuffer *config_stateobj;
 	struct fd_ringbuffer *interp_stateobj;
 	struct fd_ringbuffer *binning_stateobj;
+	struct fd_ringbuffer *streamout_stateobj;
 	struct fd_ringbuffer *stateobj;
-
-	/* cached state about current emitted shader program (3d): */
-	struct fd6_streamout_state tf;
 };
 
 static inline struct fd6_program_state *
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index e756411d183..faafad5c672 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -410,6 +410,7 @@ struct fd_context {
 		uint32_t index_start;
 		uint32_t instance_start;
 		uint32_t restart_index;
+		uint32_t streamout_mask;
 	} last;
 };
 



More information about the mesa-commit mailing list