Mesa (main): i915g: Make sure we consider negates/swizzles on bias/shadow coords.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Nov 1 21:07:21 UTC 2021
Module: Mesa
Branch: main
Commit: fa4fd67f7824727d92e52c816543b0233eacd932
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=fa4fd67f7824727d92e52c816543b0233eacd932
Author: Emma Anholt <emma at anholt.net>
Date: Thu Sep 30 21:12:00 2021 -0700
i915g: Make sure we consider negates/swizzles on bias/shadow coords.
Caught by imirkin while debugging #4986.
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13133>
---
src/gallium/drivers/i915/i915_fpc.h | 4 +--
src/gallium/drivers/i915/i915_fpc_emit.c | 33 ++++++++---------------
src/gallium/drivers/i915/i915_fpc_optimize.c | 33 ++---------------------
src/gallium/drivers/i915/i915_fpc_translate.c | 38 +++++++++++++++++----------
4 files changed, 39 insertions(+), 69 deletions(-)
diff --git a/src/gallium/drivers/i915/i915_fpc.h b/src/gallium/drivers/i915/i915_fpc.h
index c223599400c..a8426f7b88b 100644
--- a/src/gallium/drivers/i915/i915_fpc.h
+++ b/src/gallium/drivers/i915/i915_fpc.h
@@ -185,7 +185,7 @@ extern void i915_release_utemps(struct i915_fp_compile *p);
extern uint32_t i915_emit_texld(struct i915_fp_compile *p, uint32_t dest,
uint32_t destmask, uint32_t sampler,
uint32_t coord, uint32_t op,
- uint32_t num_coord);
+ uint32_t coord_mask);
extern uint32_t i915_emit_arith(struct i915_fp_compile *p, uint32_t op,
uint32_t dest, uint32_t mask, uint32_t saturate,
@@ -285,7 +285,7 @@ extern struct i915_token_list *i915_optimize(const struct tgsi_token *tokens);
extern void i915_optimize_free(struct i915_token_list *tokens);
-extern uint32_t i915_num_coords(uint32_t tex);
+extern uint32_t i915_coord_mask(enum tgsi_opcode opcode, enum tgsi_texture_type tex);
extern bool i915_nir_lower_sincos(struct nir_shader *s);
diff --git a/src/gallium/drivers/i915/i915_fpc_emit.c b/src/gallium/drivers/i915/i915_fpc_emit.c
index 9d4e17d713c..9c7e55b477a 100644
--- a/src/gallium/drivers/i915/i915_fpc_emit.c
+++ b/src/gallium/drivers/i915/i915_fpc_emit.c
@@ -176,32 +176,21 @@ i915_emit_arith(struct i915_fp_compile *p, uint32_t op, uint32_t dest,
uint32_t
i915_emit_texld(struct i915_fp_compile *p, uint32_t dest, uint32_t destmask,
uint32_t sampler, uint32_t coord, uint32_t opcode,
- uint32_t num_coord)
+ uint32_t coord_mask)
{
const uint32_t k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
int temp = -1;
- uint32_t ignore = 0;
-
- /* Eliminate the useless texture coordinates. Otherwise we end up generating
- * a swizzle for no reason below. */
- switch (num_coord) {
- case 1:
- /* For 1D textures, make sure that the Y coordinate is actually
- * initialized. It seems that if the channel is never written during the
- * program, texturing returns undefined results (even if the Y wrap is
- * REPEAT).
- */
- coord = swizzle(coord, X, X, Z, W);
- FALLTHROUGH;
- case 2:
- ignore |= (0xf << UREG_CHANNEL_Z_SHIFT);
- FALLTHROUGH;
- case 3:
- ignore |= (0xf << UREG_CHANNEL_W_SHIFT);
- }
- if ((coord & ~ignore) != (k & ~ignore) ||
+ uint32_t coord_used = 0xf << UREG_CHANNEL_X_SHIFT;
+ if (coord_mask & TGSI_WRITEMASK_Y)
+ coord_used |= 0xf << UREG_CHANNEL_Y_SHIFT;
+ if (coord_mask & TGSI_WRITEMASK_Z)
+ coord_used |= 0xf << UREG_CHANNEL_Z_SHIFT;
+ if (coord_mask & TGSI_WRITEMASK_W)
+ coord_used |= 0xf << UREG_CHANNEL_W_SHIFT;
+
+ if ((coord & coord_used) != (k & coord_used) ||
GET_UREG_TYPE(coord) == REG_TYPE_CONST) {
/* texcoord is swizzled or negated. Need to allocate a new temporary
* register (a utemp / unpreserved temp) won't do.
@@ -226,7 +215,7 @@ i915_emit_texld(struct i915_fp_compile *p, uint32_t dest, uint32_t destmask,
/* if not writing to XYZW... */
uint32_t tmp = i915_get_utemp(p);
i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode,
- num_coord);
+ coord_mask);
i915_emit_arith(p, A0_MOV, dest, destmask, 0, tmp, 0, 0);
/* XXX release utemp here? */
} else {
diff --git a/src/gallium/drivers/i915/i915_fpc_optimize.c b/src/gallium/drivers/i915/i915_fpc_optimize.c
index 9dd7bdfb5a9..85b6cfaf822 100644
--- a/src/gallium/drivers/i915/i915_fpc_optimize.c
+++ b/src/gallium/drivers/i915/i915_fpc_optimize.c
@@ -148,26 +148,6 @@ op_commutes(unsigned opcode)
return op_table[opcode].commutes;
}
-static unsigned
-mask_for_unswizzled(int num_components)
-{
- unsigned mask = 0;
- switch (num_components) {
- case 4:
- mask |= TGSI_WRITEMASK_W;
- FALLTHROUGH;
- case 3:
- mask |= TGSI_WRITEMASK_Z;
- FALLTHROUGH;
- case 2:
- mask |= TGSI_WRITEMASK_Y;
- FALLTHROUGH;
- case 1:
- mask |= TGSI_WRITEMASK_X;
- }
- return mask;
-}
-
static bool
is_unswizzled(struct i915_full_src_register *r, unsigned write_mask)
{
@@ -385,17 +365,8 @@ unused_from(struct i915_optimize_context *ctx,
static unsigned
i915_tex_mask(union i915_full_token *instr)
{
- unsigned mask;
-
- /* Get the number of coords */
- mask = mask_for_unswizzled(
- i915_num_coords(instr->FullInstruction.Texture.Texture));
-
- /* Add the W component if projective */
- if (instr->FullInstruction.Instruction.Opcode == TGSI_OPCODE_TXP)
- mask |= TGSI_WRITEMASK_W;
-
- return mask;
+ return i915_coord_mask(instr->FullInstruction.Instruction.Opcode,
+ instr->FullInstruction.Texture.Texture);
}
static bool
diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c
index 93e95c16ac0..345f8609805 100644
--- a/src/gallium/drivers/i915/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915/i915_fpc_translate.c
@@ -326,26 +326,28 @@ translate_tex_src_target(struct i915_fp_compile *p, uint32_t tex)
* Return the number of coords needed to access a given TGSI_TEXTURE_*
*/
uint32_t
-i915_num_coords(uint32_t tex)
+i915_coord_mask(enum tgsi_opcode opcode, enum tgsi_texture_type tex)
{
- switch (tex) {
- case TGSI_TEXTURE_SHADOW1D:
- case TGSI_TEXTURE_1D:
- return 1;
+ uint32_t coord_mask = 0;
- case TGSI_TEXTURE_SHADOW2D:
+ if (opcode == TGSI_OPCODE_TXP || opcode == TGSI_OPCODE_TXB)
+ coord_mask |= TGSI_WRITEMASK_W;
+
+ switch (tex) {
+ case TGSI_TEXTURE_1D: /* See the 1D coord swizzle below. */
case TGSI_TEXTURE_2D:
- case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_RECT:
- return 2;
+ return coord_mask | TGSI_WRITEMASK_XY;
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
- return 3;
+ return coord_mask | TGSI_WRITEMASK_XYZ;
default:
- debug_printf("Unknown texture target for num coords");
- return 2;
+ unreachable("bad texture target");
}
}
@@ -362,9 +364,17 @@ emit_tex(struct i915_fp_compile *p, const struct i915_full_instruction *inst,
uint32_t sampler = i915_emit_decl(p, REG_TYPE_S, unit, tex);
uint32_t coord = src_vector(p, &inst->Src[0], fs);
+ /* For 1D textures, make sure that the Y coordinate is actually
+ * initialized. It seems that if the channel is never written during the
+ * program, texturing returns undefined results (even if the Y wrap is
+ * REPEAT).
+ */
+ if (texture == TGSI_TEXTURE_1D || texture == TGSI_TEXTURE_SHADOW1D)
+ coord = swizzle(coord, X, X, Z, W);
+
i915_emit_texld(p, get_result_vector(p, &inst->Dst[0]),
get_result_flags(inst), sampler, coord, opcode,
- i915_num_coords(texture));
+ i915_coord_mask(inst->Instruction.Opcode, texture));
}
/**
@@ -521,7 +531,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
0, /* sampler */
src0, /* coord*/
T0_TEXKILL, /* opcode */
- 4); /* num_coord */
+ TGSI_WRITEMASK_XYZW);/* coord_mask */
break;
case TGSI_OPCODE_KILL:
@@ -534,7 +544,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
negate(swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE),
1, 1, 1, 1), /* coord */
T0_TEXKILL, /* opcode */
- 1); /* num_coord */
+ TGSI_WRITEMASK_X); /* coord_mask */
break;
case TGSI_OPCODE_LG2:
More information about the mesa-commit
mailing list