[Mesa-dev] [PATCH 04/11] freedreno: a2xx: map tgsi ids to ir2 ids

Jonathan Marek jonathan at marek.ca
Mon Oct 8 04:06:04 UTC 2018


this is for a2xx specific semantics (vertex id) and a basic SSA form

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
---
 .../drivers/freedreno/a2xx/fd2_compiler.c     | 54 +++++++++----------
 src/gallium/drivers/freedreno/a2xx/ir-a2xx.c  | 45 ++++++++++------
 src/gallium/drivers/freedreno/a2xx/ir-a2xx.h  |  9 ++++
 3 files changed, 64 insertions(+), 44 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_compiler.c b/src/gallium/drivers/freedreno/a2xx/fd2_compiler.c
index 12f9a1ce0a..54f0df54da 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_compiler.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_compiler.c
@@ -244,8 +244,8 @@ compile_vtx_fetch(struct fd2_compile_context *ctx)
 
 		ctx->need_sync |= 1 << (i+1);
 
-		ir2_dst_create(instr, i+1, "xyzw", 0);
 		ir2_reg_create(instr, 0, "x", IR2_REG_INPUT);
+		ir2_dst_create(instr, i+1, "xyzw", 0);
 
 		if (i == 0)
 			instr->sync = true;
@@ -421,9 +421,9 @@ add_regs_vector_1(struct fd2_compile_context *ctx,
 	assert(inst->Instruction.NumSrcRegs == 1);
 	assert(inst->Instruction.NumDstRegs == 1);
 
-	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[0].Register);
+	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_vector_clamp(inst, alu);
 }
 
@@ -434,9 +434,9 @@ add_regs_vector_2(struct fd2_compile_context *ctx,
 	assert(inst->Instruction.NumSrcRegs == 2);
 	assert(inst->Instruction.NumDstRegs == 1);
 
-	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[1].Register);
+	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_vector_clamp(inst, alu);
 }
 
@@ -447,10 +447,10 @@ add_regs_vector_3(struct fd2_compile_context *ctx,
 	assert(inst->Instruction.NumSrcRegs == 3);
 	assert(inst->Instruction.NumDstRegs == 1);
 
-	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[1].Register);
 	add_src_reg(ctx, alu, &inst->Src[2].Register);
+	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_vector_clamp(inst, alu);
 }
 
@@ -461,8 +461,8 @@ add_regs_scalar_1(struct fd2_compile_context *ctx,
 	assert(inst->Instruction.NumSrcRegs == 1);
 	assert(inst->Instruction.NumDstRegs == 1);
 
-	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_src_reg(ctx, alu, &inst->Src[0].Register);
+	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_scalar_clamp(inst, alu);
 }
 
@@ -544,17 +544,17 @@ push_predicate(struct fd2_compile_context *ctx, struct tgsi_src_register *src)
 		get_predicate(ctx, &pred_dst, NULL);
 
 		alu = ir2_instr_create_alu_s(ctx->so->ir, PRED_SETNEs);
-		add_dst_reg(ctx, alu, &pred_dst);
 		add_src_reg(ctx, alu, src);
+		add_dst_reg(ctx, alu, &pred_dst);
 	} else {
 		struct tgsi_src_register pred_src;
 
 		get_predicate(ctx, &pred_dst, &pred_src);
 
 		alu = ir2_instr_create_alu_v(ctx->so->ir, MULv);
-		add_dst_reg(ctx, alu, &pred_dst);
 		add_src_reg(ctx, alu, &pred_src);
 		add_src_reg(ctx, alu, src);
+		add_dst_reg(ctx, alu, &pred_dst);
 
 		// XXX need to make PRED_SETE_PUSHv IR2_PRED_NONE.. but need to make
 		// sure src reg is valid if it was calculated with a predicate
@@ -580,8 +580,8 @@ pop_predicate(struct fd2_compile_context *ctx)
 		get_predicate(ctx, &pred_dst, &pred_src);
 
 		alu = ir2_instr_create_alu_s(ctx->so->ir, PRED_SET_POPs);
-		add_dst_reg(ctx, alu, &pred_dst);
 		add_src_reg(ctx, alu, &pred_src);
+		add_dst_reg(ctx, alu, &pred_dst);
 		alu->pred = IR2_PRED_NONE;
 	} else {
 		/* predicate register no longer needed: */
@@ -648,13 +648,13 @@ translate_pow(struct fd2_compile_context *ctx,
 	get_internal_temp(ctx, &tmp_dst, &tmp_src);
 
 	alu = ir2_instr_create_alu_s(ctx->so->ir, LOG_CLAMP);
-	add_dst_reg(ctx, alu, &tmp_dst);
 	add_src_reg(ctx, alu, &inst->Src[0].Register);
+	add_dst_reg(ctx, alu, &tmp_dst);
 
 	alu = ir2_instr_create_alu_v(ctx->so->ir, MULv);
-	add_dst_reg(ctx, alu, &tmp_dst);
 	add_src_reg(ctx, alu, &tmp_src);
 	add_src_reg(ctx, alu, &inst->Src[1].Register);
+	add_dst_reg(ctx, alu, &tmp_dst);
 
 	/* NOTE: some of the instructions, like EXP_IEEE, seem hard-
 	 * coded to take their input from the w component.
@@ -679,8 +679,8 @@ translate_pow(struct fd2_compile_context *ctx,
 	}
 
 	alu = ir2_instr_create_alu_s(ctx->so->ir, EXP_IEEE);
-	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_src_reg(ctx, alu, &tmp_src);
+	add_dst_reg(ctx, alu, &inst->Dst[0].Register);
 	add_scalar_clamp(inst, alu);
 }
 
@@ -720,19 +720,19 @@ translate_tex(struct fd2_compile_context *ctx,
 		 */
 
 		instr = ir2_instr_create_alu_v(ctx->so->ir, MAXv);
-		add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "___w";
 		add_src_reg(ctx, instr, &inst->Src[0].Register);
 		add_src_reg(ctx, instr, &inst->Src[0].Register);
+		add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "___w";
 
 		instr = ir2_instr_create_alu_s(ctx->so->ir, RECIP_IEEE);
-		add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "x___";
 		add_src_reg(ctx, instr, &inst->Src[0].Register)->swizzle =
 				swiz[inst->Src[0].Register.SwizzleW];
+		add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "x___";
 
 		instr = ir2_instr_create_alu_v(ctx->so->ir, MULv);
-		add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "xyz_";
 		add_src_reg(ctx, instr, &tmp_src)->swizzle = "xxxx";
 		add_src_reg(ctx, instr, &inst->Src[0].Register);
+		add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "xyz_";
 
 		coord = &tmp_src;
 	} else {
@@ -750,8 +750,8 @@ translate_tex(struct fd2_compile_context *ctx,
 	ctx->so->tfetch_instrs[idx].samp_id = inst->Src[1].Register.Index;
 	ctx->so->tfetch_instrs[idx].instr = instr;
 
-	add_dst_reg(ctx, instr, using_temp ? &tmp_dst : &inst->Dst[0].Register);
 	reg = add_src_reg(ctx, instr, coord);
+	add_dst_reg(ctx, instr, using_temp ? &tmp_dst : &inst->Dst[0].Register);
 
 	/* blob compiler always sets 3rd component to same as 1st for 2d: */
 	if (inst->Texture.Texture == TGSI_TEXTURE_2D || inst->Texture.Texture == TGSI_TEXTURE_RECT)
@@ -771,9 +771,9 @@ translate_tex(struct fd2_compile_context *ctx,
 		 */
 		instr = ir2_instr_create_alu_v(ctx->so->ir, MAXv);
 
-		add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 		add_src_reg(ctx, instr, &tmp_src);
 		add_src_reg(ctx, instr, &tmp_src);
+		add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 		add_vector_clamp(inst, instr);
 	}
 }
@@ -821,17 +821,17 @@ translate_sge_slt_seq_sne(struct fd2_compile_context *ctx,
 	get_internal_temp(ctx, &tmp_dst, &tmp_src);
 
 	instr = ir2_instr_create_alu_v(ctx->so->ir, ADDv);
-	add_dst_reg(ctx, instr, &tmp_dst);
 	add_src_reg(ctx, instr, &inst->Src[0].Register)->flags |= IR2_REG_NEGATE;
 	add_src_reg(ctx, instr, &inst->Src[1].Register);
+	add_dst_reg(ctx, instr, &tmp_dst);
 
 	instr = ir2_instr_create_alu_v(ctx->so->ir, vopc);
-	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 	add_src_reg(ctx, instr, &tmp_src);
 	get_immediate(ctx, &tmp_const, fui(c1));
 	add_src_reg(ctx, instr, &tmp_const);
 	get_immediate(ctx, &tmp_const, fui(c0));
 	add_src_reg(ctx, instr, &tmp_const);
+	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 }
 
 /* LRP(a,b,c) = (a * b) + ((1 - a) * c) */
@@ -852,27 +852,27 @@ translate_lrp(struct fd2_compile_context *ctx,
 
 	/* tmp1 = (a * b) */
 	instr = ir2_instr_create_alu_v(ctx->so->ir, MULv);
-	add_dst_reg(ctx, instr, &tmp_dst1);
 	add_src_reg(ctx, instr, &inst->Src[0].Register);
 	add_src_reg(ctx, instr, &inst->Src[1].Register);
+	add_dst_reg(ctx, instr, &tmp_dst1);
 
 	/* tmp2 = (1 - a) */
 	instr = ir2_instr_create_alu_v(ctx->so->ir, ADDv);
-	add_dst_reg(ctx, instr, &tmp_dst2);
 	add_src_reg(ctx, instr, &tmp_const);
 	add_src_reg(ctx, instr, &inst->Src[0].Register)->flags |= IR2_REG_NEGATE;
+	add_dst_reg(ctx, instr, &tmp_dst2);
 
 	/* tmp2 = tmp2 * c */
 	instr = ir2_instr_create_alu_v(ctx->so->ir, MULv);
-	add_dst_reg(ctx, instr, &tmp_dst2);
 	add_src_reg(ctx, instr, &tmp_src2);
 	add_src_reg(ctx, instr, &inst->Src[2].Register);
+	add_dst_reg(ctx, instr, &tmp_dst2);
 
 	/* dst = tmp1 + tmp2 */
 	instr = ir2_instr_create_alu_v(ctx->so->ir, ADDv);
-	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 	add_src_reg(ctx, instr, &tmp_src1);
 	add_src_reg(ctx, instr, &tmp_src2);
+	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 }
 
 static void
@@ -904,29 +904,29 @@ translate_trig(struct fd2_compile_context *ctx,
 			tmp_src.SwizzleZ = tmp_src.SwizzleW = TGSI_SWIZZLE_X;
 
 	instr = ir2_instr_create_alu_v(ctx->so->ir, MULADDv);
-	add_dst_reg(ctx, instr, &tmp_dst);
 	add_src_reg(ctx, instr, &inst->Src[0].Register);
 	get_immediate(ctx, &tmp_const, fui(0.159155));
 	add_src_reg(ctx, instr, &tmp_const);
 	get_immediate(ctx, &tmp_const, fui(0.5));
 	add_src_reg(ctx, instr, &tmp_const);
+	add_dst_reg(ctx, instr, &tmp_dst);
 
 	instr = ir2_instr_create_alu_v(ctx->so->ir, FRACv);
-	add_dst_reg(ctx, instr, &tmp_dst);
 	add_src_reg(ctx, instr, &tmp_src);
 	add_src_reg(ctx, instr, &tmp_src);
+	add_dst_reg(ctx, instr, &tmp_dst);
 
 	instr = ir2_instr_create_alu_v(ctx->so->ir, MULADDv);
-	add_dst_reg(ctx, instr, &tmp_dst);
 	add_src_reg(ctx, instr, &tmp_src);
 	get_immediate(ctx, &tmp_const, fui(6.283185));
 	add_src_reg(ctx, instr, &tmp_const);
 	get_immediate(ctx, &tmp_const, fui(-3.141593));
 	add_src_reg(ctx, instr, &tmp_const);
+	add_dst_reg(ctx, instr, &tmp_dst);
 
 	instr = ir2_instr_create_alu_s(ctx->so->ir, op);
-	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 	add_src_reg(ctx, instr, &tmp_src);
+	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 }
 
 static void
@@ -939,11 +939,11 @@ translate_dp2(struct fd2_compile_context *ctx,
 	/* DP2ADD c,a,b -> dot2(a,b) + c */
 	/* for c we use the constant 0.0 */
 	instr = ir2_instr_create_alu_v(ctx->so->ir, DOT2ADDv);
-	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 	add_src_reg(ctx, instr, &inst->Src[0].Register);
 	add_src_reg(ctx, instr, &inst->Src[1].Register);
 	get_immediate(ctx, &tmp_const, fui(0.0f));
 	add_src_reg(ctx, instr, &tmp_const);
+	add_dst_reg(ctx, instr, &inst->Dst[0].Register);
 	add_vector_clamp(inst, instr);
 }
 
diff --git a/src/gallium/drivers/freedreno/a2xx/ir-a2xx.c b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.c
index af9811864f..57625b2110 100644
--- a/src/gallium/drivers/freedreno/a2xx/ir-a2xx.c
+++ b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.c
@@ -653,39 +653,50 @@ static int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
 struct ir2_dst_register * ir2_dst_create(struct ir2_instruction *instr,
 		int num, const char *swizzle, int flags)
 {
+	struct ir2_shader *shader = instr->shader;
+	int idx;
+
 	if (!(flags & IR2_REG_EXPORT)) {
-		struct ir2_register *reg = &instr->shader->reg[num];
+		idx = shader->tgsi_reg_map[num];
+		if (!idx || (!strcmp(swizzle, "xyzw") && !instr->pred)) {
+			idx = shader->max_reg + 1;
+			/* start indices at IR2_REG_TEMP0 */
+			if (idx <= IR2_REG_TEMP0)
+				idx = IR2_REG_TEMP0;
 
-		unsigned i;
-		for (i = instr->shader->max_reg + 1; i <= num; i++)
-			instr->shader->reg[i].write_idx = -1;
-		instr->shader->max_reg = i - 1;
+			shader->tgsi_reg_map[num] = idx;
+			shader->max_reg = idx;
 
-		if (reg->write_idx < 0)
-            reg->write_idx = instr->idx;
-		reg->write_idx2 = instr->idx;
+			shader->reg[idx].write_idx = instr->idx;
+		}
+		num = idx;
+		shader->reg[idx].write_idx2 = instr->idx;
 	}
 
 	struct ir2_dst_register *reg = &instr->dst_reg;
 	reg->flags = flags;
 	reg->num = num;
-	reg->swizzle = ir2_strdup(instr->shader, swizzle);
+	reg->swizzle = ir2_strdup(shader, swizzle);
 	return reg;
 }
 
 struct ir2_src_register * ir2_reg_create(struct ir2_instruction *instr,
 		int num, const char *swizzle, int flags)
 {
+	struct ir2_shader *shader = instr->shader;
+	int idx;
+
 	assert(instr->src_reg_count + 1 <= ARRAY_SIZE(instr->src_reg));
 	if (!(flags & IR2_REG_CONST)) {
-		struct ir2_register *reg = &instr->shader->reg[num];
-
-		reg->read_idx = instr->idx;
-
-		unsigned i;
-		for (i = instr->shader->max_reg + 1; i <= num; i++)
-			instr->shader->reg[i].write_idx = -1;
-		instr->shader->max_reg = i - 1;
+		if (!(flags & IR2_REG_INPUT)) {
+			idx = shader->tgsi_reg_map[num];
+			assert(idx);
+			num = idx;
+		} else {
+			shader->reg[num].write_idx = -1;
+			shader->reg[num].write_idx2 = -1;
+		}
+		shader->reg[num].read_idx = instr->idx;
 	}
 
 	struct ir2_src_register *reg = &instr->src_reg[instr->src_reg_count++];
diff --git a/src/gallium/drivers/freedreno/a2xx/ir-a2xx.h b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.h
index ac2931266d..27fe16f944 100644
--- a/src/gallium/drivers/freedreno/a2xx/ir-a2xx.h
+++ b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.h
@@ -115,11 +115,20 @@ struct ir2_instruction {
 	};
 };
 
+enum {
+	IR2_REG_INPUT0 = 0,
+	IR2_REG_VERT_ID = 15, /* vertex id generated for a20x binning */
+	IR2_REG_TEMP0 = 16,
+};
+
 struct ir2_shader {
 	unsigned instr_count;
 	int max_reg;
 	struct ir2_register reg[REG_MASK+1];
 
+	/* table to translate TGSI ids to our ids */
+	int tgsi_reg_map[256];
+
 	struct ir2_instruction *instr[0x200];
 	uint32_t heap[100 * 4096];
 	unsigned heap_idx;
-- 
2.17.1



More information about the mesa-dev mailing list