[Mesa-dev] [PATCH 19/30] r600g: fix dynamic_input_array_index.shader_test

Dave Airlie airlied at gmail.com
Tue Feb 4 00:53:36 CET 2014


From: Dave Airlie <airlied at redhat.com>

This follows what fglrx does, it unpacks the input we are
going to indirect into a bunch of registers and indirects
inside them.

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

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index cc2000d..a58955a 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -834,10 +834,12 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx, unsigned int cb_idx
 	return 0;
 }
 
-static int fetch_gs_input(struct r600_shader_ctx *ctx, unsigned index, unsigned vtx_id, unsigned int dst_reg)
+static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_register *src, unsigned int dst_reg)
 {
 	struct r600_bytecode_vtx vtx;
 	int r;
+	unsigned index = src->Register.Index;
+	unsigned vtx_id = src->Dimension.Index;
 	int offset_reg = vtx_id / 3;
 	int offset_chan = vtx_id % 3;
 
@@ -847,6 +849,46 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, unsigned index, unsigned
 	if (offset_reg == 0 && offset_chan == 2)
 		offset_chan = 3;
 
+	if (src->Dimension.Indirect) {
+		int treg[3];
+		int t2;
+		struct r600_bytecode_alu alu;
+		int r, i;
+
+		/* you have got to be shitting me -
+		   we have to put the R0.x/y/w into Rt.x Rt+1.x Rt+2.x then index reg from Rt.
+		   at least this is what fglrx seems to do. */
+		for (i = 0; i < 3; i++) {
+			treg[i] = r600_get_temp(ctx);
+		}
+		t2 = r600_get_temp(ctx);
+		for (i = 0; i < 3; i++) {
+			memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+			alu.op = ALU_OP1_MOV;
+			alu.src[0].sel = 0;
+			alu.src[0].chan = i == 2 ? 3 : i;
+			alu.dst.sel = treg[i];
+			alu.dst.chan = 0;
+			alu.dst.write = 1;
+			alu.last = 1;
+			r = r600_bytecode_add_alu(ctx->bc, &alu);
+			if (r)
+				return r;
+		}
+		memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+		alu.op = ALU_OP1_MOV;
+		alu.src[0].sel = treg[0];
+		alu.src[0].rel = 1;
+		alu.dst.sel = t2;
+		alu.dst.write = 1;
+		alu.last = 1;
+		r = r600_bytecode_add_alu(ctx->bc, &alu);
+		if (r)
+			return r;
+		offset_reg = t2;
+	}
+
+
 	memset(&vtx, 0, sizeof(vtx));
 	vtx.buffer_id = R600_GS_RING_CONST_BUFFER;
 	vtx.fetch_type = 2;		/* VTX_FETCH_NO_INDEX_OFFSET */
@@ -884,10 +926,8 @@ static int tgsi_split_gs_inputs(struct r600_shader_ctx *ctx)
 		}
 		if (src->Register.File == TGSI_FILE_INPUT && src->Register.Dimension) {
 			int treg = r600_get_temp(ctx);
-			int index = src->Register.Index;
-			int vtx_id = src->Dimension.Index;
 
-			fetch_gs_input(ctx, index, vtx_id, treg);
+			fetch_gs_input(ctx, src, treg);
 			ctx->src[i].sel = treg;
 		}
 	}
-- 
1.8.3.1



More information about the mesa-dev mailing list