[Mesa-dev] [PATCH 39/53] r600/shader: handle VS shader writing to the LDS outputs.

Dave Airlie airlied at gmail.com
Sun Nov 29 22:20:48 PST 2015


From: Dave Airlie <airlied at redhat.com>

This writes the VS shaders outputs to the LDS memory in
the correct places.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/drivers/r600/r600_shader.c | 76 +++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 69675b2..ee83114 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -2385,6 +2385,71 @@ static int r600_fetch_tess_io_info(struct r600_shader_ctx *ctx)
 	return 0;
 }
 
+static int emit_lds_vs_writes(struct r600_shader_ctx *ctx)
+{
+	int i, j, r;
+	int temp_reg;
+
+	/* fetch tcs input values into input_vals */
+	ctx->tess_input_info = r600_get_temp(ctx);
+	ctx->tess_output_info = 0;
+	r = r600_fetch_tess_io_info(ctx);
+	if (r)
+		return r;
+
+	temp_reg = r600_get_temp(ctx);
+	/* dst reg contains LDS address stride * idx */
+	/* MUL vertexID, vertex_dw_stride */
+	r = single_alu_op2(ctx, ALU_OP2_MULLO_INT,
+			   temp_reg, 0,
+			   ctx->tess_input_info, 1,
+			   0, 1); /* rel id in r0.y? */
+	if (r)
+		return r;
+
+	for (i = 0; i < ctx->shader->noutput; i++) {
+		struct r600_bytecode_alu alu;
+		int param = r600_get_lds_unique_index(ctx->shader->output[i].name, ctx->shader->output[i].sid);
+
+		if (param) {
+			r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+					   temp_reg, 1,
+					   temp_reg, 0,
+					   V_SQ_ALU_SRC_LITERAL, param * 16);
+			if (r)
+				return r;
+		}
+
+		r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+				   temp_reg, 2,
+				   temp_reg, param ? 1 : 0,
+				   V_SQ_ALU_SRC_LITERAL, 8);
+		if (r)
+			return r;
+
+
+		for (j = 0; j < 2; j++) {
+			int chan = (j == 1) ? 2 : (param ? 1 : 0);
+			memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+			alu.op = LDS_OP3_LDS_WRITE_REL;
+			alu.src[0].sel = temp_reg;
+			alu.src[0].chan = chan;
+			alu.src[1].sel = ctx->shader->output[i].gpr;
+			alu.src[1].chan = j * 2;
+			alu.src[2].sel = ctx->shader->output[i].gpr;
+			alu.src[2].chan = (j * 2) + 1;
+			alu.last = 1;
+			alu.dst.chan = 0;
+			alu.lds_idx = 1;
+			alu.is_lds_idx_op = true;
+			r = r600_bytecode_add_alu(ctx->bc, &alu);
+			if (r)
+				return r;
+		}
+	}
+	return 0;
+}
+
 static int r600_shader_from_tgsi(struct r600_context *rctx,
 				 struct r600_pipe_shader *pipeshader,
 				 union r600_shader_key key)
@@ -2405,6 +2470,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
 	bool use_llvm = false;
 	bool indirect_gprs;
 	bool ring_outputs = false;
+	bool lds_outputs = false;
 	bool lds_inputs = false;
 	bool pos_emitted = false;
 
@@ -2437,12 +2503,15 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
 		shader->vs_as_ls = key.vs.as_ls;
 		if (shader->vs_as_es)
 			ring_outputs = true;
+		if (shader->vs_as_ls)
+			lds_outputs = true;
 		break;
 	case TGSI_PROCESSOR_GEOMETRY:
 		ring_outputs = true;
 		break;
 	case TGSI_PROCESSOR_TESS_CTRL:
 		shader->tcs_prim_mode = key.tcs.prim_mode;
+		lds_outputs = true;
 		lds_inputs = true;
 		break;
 	case TGSI_PROCESSOR_TESS_EVAL:
@@ -2882,7 +2951,12 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
 	pipeshader->enabled_stream_buffers_mask = ctx.enabled_stream_buffers_mask;
 	convert_edgeflag_to_int(&ctx);
 
-	if (ring_outputs) {
+	if (lds_outputs) {
+		if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+			if (ctx.shader->noutput)
+				emit_lds_vs_writes(&ctx);
+		}
+	} else if (ring_outputs) {
 		if (shader->vs_as_es || shader->tes_as_es) {
 			ctx.gs_export_gpr_tregs[0] = r600_get_temp(&ctx);
 			ctx.gs_export_gpr_tregs[1] = -1;
-- 
2.5.0



More information about the mesa-dev mailing list