[Freedreno] [PATCH] freedreno/ir3: fix array count returned by TXQ

Ilia Mirkin imirkin at alum.mit.edu
Sat Mar 7 14:42:29 PST 2015


Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
 src/gallium/drivers/freedreno/ir3/ir3_compiler.c | 44 ++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index c4fae45..dc4fd98 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
@@ -1591,6 +1591,7 @@ trans_txq(const struct instr_translater *t,
 	struct tgsi_dst_register *dst = &inst->Dst[0].Register;
 	struct tgsi_src_register *level = &inst->Src[0].Register;
 	struct tgsi_src_register *samp = &inst->Src[1].Register;
+	const struct target_info *tgt = &tex_targets[inst->Texture.Texture];
 	struct tex_info tinf;
 
 	memset(&tinf, 0, sizeof(tinf));
@@ -1604,8 +1605,47 @@ trans_txq(const struct instr_translater *t,
 	instr->cat5.tex  = samp->Index;
 	instr->flags |= tinf.flags;
 
-	add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask);
-	add_src_reg_wrmask(ctx, instr, level, level->SwizzleX, 0x1);
+	if (tgt->array && (dst->WriteMask & (1 << tgt->dims))) {
+		/* Array size actually ends up in .w rather than .z. This doesn't
+		 * matter for miplevel 0, but for higher mips the value in z is
+		 * minified whereas w stays. Also, the value in TEX_CONST_3_DEPTH is
+		 * returned, which means that we have to add 1 to it for arrays.
+		 */
+		struct tgsi_dst_register tmp_dst;
+		struct tgsi_src_register *tmp_src;
+		type_t type_mov = get_utype(ctx);
+
+		tmp_src = get_internal_temp(ctx, &tmp_dst);
+		add_dst_reg_wrmask(ctx, instr, &tmp_dst, 0,
+						   dst->WriteMask | TGSI_WRITEMASK_W);
+		add_src_reg_wrmask(ctx, instr, level, level->SwizzleX, 0x1);
+
+		if (dst->WriteMask & TGSI_WRITEMASK_X) {
+			instr = instr_create(ctx, 1, 0);
+			instr->cat1.src_type = type_mov;
+			instr->cat1.dst_type = type_mov;
+			add_dst_reg(ctx, instr, dst, 0);
+			add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 0));
+		}
+
+		if (tgt->dims == 2) {
+			if (dst->WriteMask & TGSI_WRITEMASK_Y) {
+				instr = instr_create(ctx, 1, 0);
+				instr->cat1.src_type = type_mov;
+				instr->cat1.dst_type = type_mov;
+				add_dst_reg(ctx, instr, dst, 1);
+				add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 1));
+			}
+		}
+
+		instr = instr_create(ctx, 2, OPC_ADD_U);
+		add_dst_reg(ctx, instr, dst, tgt->dims);
+		add_src_reg(ctx, instr, tmp_src, src_swiz(tmp_src, 3));
+		ir3_reg_create(instr, 0, IR3_REG_IMMED)->iim_val = 1;
+	} else {
+		add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask);
+		add_src_reg_wrmask(ctx, instr, level, level->SwizzleX, 0x1);
+	}
 }
 
 /* DDX/DDY */
-- 
2.0.5



More information about the Freedreno mailing list