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