diff options
author | Ilia Mirkin <[email protected]> | 2015-03-07 17:41:47 -0500 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2015-03-11 18:12:14 +0000 |
commit | d8ed6aa4742b37d2fda95fa7e6bea584582569e4 (patch) | |
tree | 2c5b984ef4dda457bf92ee5ed0f574d8db85d089 | |
parent | 5b1bd4fc9e442568bacdec3a7e9697a87968158d (diff) |
freedreno/ir3: fix array count returned by TXQ
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Rob Clark <[email protected]>
Cc: "10.4 10.5" <[email protected]>
(cherry picked from commit 8ac957a51c67fc095db9539df6482b9533b1d05c)
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_compiler.c | 44 |
1 files 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 8c88bf7db47..7555f5c6baf 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c @@ -1537,6 +1537,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)); @@ -1550,8 +1551,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 */ |