Mesa (main): nir_to_tgsi: Extract const components of atomic counter offsets into Index.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Apr 8 21:30:38 UTC 2022


Module: Mesa
Branch: main
Commit: 664f69a4d5601a46031ebd003ecc917aa7e48773
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=664f69a4d5601a46031ebd003ecc917aa7e48773

Author: Emma Anholt <emma at anholt.net>
Date:   Tue Apr  5 09:45:36 2022 -0700

nir_to_tgsi: Extract const components of atomic counter offsets into Index.

virglrenderer maps atomic accesses to atomic counter declarations using
the .Index field.  We were previously emitting a .Index of 0 for array
accesses, so virglrenderer would emit
atomicIncrement(first_counter[counter_offset+array_index]).  This would
mostly work because hardware doesn't care about the bounds of counter
declarations, but if the first counter was a non-array, then the [] GLSL
emit gets dropped (can't array access a scalar!) and you'd access the
non-array first_counter instead.

Acked-by: Marek Olšák <marek.olsak at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15824>

---

 src/gallium/auxiliary/nir/nir_to_tgsi.c | 79 ++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 12 deletions(-)

diff --git a/src/gallium/auxiliary/nir/nir_to_tgsi.c b/src/gallium/auxiliary/nir/nir_to_tgsi.c
index 78e2eb6c14d..d23887389e5 100644
--- a/src/gallium/auxiliary/nir/nir_to_tgsi.c
+++ b/src/gallium/auxiliary/nir/nir_to_tgsi.c
@@ -523,6 +523,59 @@ ntt_allocate_regs(struct ntt_compile *c, nir_function_impl *impl)
    }
 }
 
+/**
+ * Try to find an iadd of a constant value with a non-constant value in the
+ * nir_src's first component, returning the constant offset and replacing *src
+ * with the non-constant component.
+ */
+static const uint32_t
+ntt_extract_const_src_offset(nir_src *src)
+{
+   if (!src->is_ssa)
+      return 0;
+
+   nir_ssa_scalar s = nir_get_ssa_scalar(src->ssa, 0);
+
+   while (nir_ssa_scalar_is_alu(s)) {
+      nir_alu_instr *alu = nir_instr_as_alu(s.def->parent_instr);
+
+      for (int i = 0; i < nir_op_infos[alu->op].num_inputs; i++) {
+         if (!alu->src[i].src.is_ssa)
+            return 0;
+      }
+
+      if (alu->op == nir_op_iadd) {
+         for (int i = 0; i < 2; i++) {
+            nir_const_value *v = nir_src_as_const_value(alu->src[i].src);
+            if (v && !alu->src[i].negate && !alu->src[i].abs) {
+               *src = alu->src[1 - i].src;
+               return v[alu->src[i].swizzle[s.comp]].u32;
+            }
+         }
+
+         return 0;
+      }
+
+      /* We'd like to reuse nir_ssa_scalar_chase_movs(), but it assumes SSA and that
+       * seems reasonable for something used in inner loops of the compiler.
+       */
+      if (!nir_alu_instr_is_copy(alu))
+         return 0;
+
+      if (alu->op == nir_op_mov) {
+         s.def = alu->src[0].src.ssa;
+         s.comp = alu->src[0].swizzle[s.comp];
+      } else if (nir_op_is_vec(alu->op)) {
+         s.def = alu->src[s.comp].src.ssa;
+         s.comp = alu->src[s.comp].swizzle[0];
+      } else {
+         return 0;
+      }
+   }
+
+   return 0;
+}
+
 static const struct glsl_type *
 ntt_shader_input_type(struct ntt_compile *c,
                       struct nir_variable *var)
@@ -1839,7 +1892,7 @@ ntt_emit_mem(struct ntt_compile *c, nir_intrinsic_instr *instr,
    unsigned opcode;
    struct ureg_src src[4];
    int num_src = 0;
-   int nir_src;
+   int next_src;
    struct ureg_dst addr_temp = ureg_dst_undef();
 
    struct ureg_src memory;
@@ -1847,24 +1900,26 @@ ntt_emit_mem(struct ntt_compile *c, nir_intrinsic_instr *instr,
    case nir_var_mem_ssbo:
       memory = ntt_ureg_src_indirect(c, ureg_src_register(TGSI_FILE_BUFFER, 0),
                                      instr->src[is_store ? 1 : 0]);
-      nir_src = 1;
+      next_src = 1;
       break;
    case nir_var_mem_shared:
       memory = ureg_src_register(TGSI_FILE_MEMORY, 0);
-      nir_src = 0;
+      next_src = 0;
       break;
    case nir_var_uniform: { /* HW atomic buffers */
-      memory = ureg_src_register(TGSI_FILE_HW_ATOMIC, 0);
+      nir_src src = instr->src[0];
+      uint32_t offset = ntt_extract_const_src_offset(&src) / 4;
+      memory = ureg_src_register(TGSI_FILE_HW_ATOMIC, offset);
       /* ntt_ureg_src_indirect, except dividing by 4 */
-      if (nir_src_is_const(instr->src[0])) {
-         memory.Index += nir_src_as_uint(instr->src[0]) / 4;
+      if (nir_src_is_const(src)) {
+         memory.Index += nir_src_as_uint(src) / 4;
       } else {
          addr_temp = ntt_temp(c);
-         ntt_USHR(c, addr_temp, ntt_get_src(c, instr->src[0]), ureg_imm1i(c->ureg, 2));
+         ntt_USHR(c, addr_temp, ntt_get_src(c, src), ureg_imm1i(c->ureg, 2));
          memory = ureg_src_indirect(memory, ntt_reladdr(c, ureg_src(addr_temp), 2));
       }
       memory = ureg_src_dimension(memory, nir_intrinsic_base(instr));
-      nir_src = 0;
+      next_src = 0;
       break;
    }
 
@@ -1873,12 +1928,12 @@ ntt_emit_mem(struct ntt_compile *c, nir_intrinsic_instr *instr,
    }
 
    if (is_store) {
-      src[num_src++] = ntt_get_src(c, instr->src[nir_src + 1]); /* offset */
+      src[num_src++] = ntt_get_src(c, instr->src[next_src + 1]); /* offset */
       src[num_src++] = ntt_get_src(c, instr->src[0]); /* value */
    } else {
       src[num_src++] = memory;
       if (instr->intrinsic != nir_intrinsic_get_ssbo_size) {
-         src[num_src++] = ntt_get_src(c, instr->src[nir_src++]); /* offset */
+         src[num_src++] = ntt_get_src(c, instr->src[next_src++]); /* offset */
          switch (instr->intrinsic) {
          case nir_intrinsic_atomic_counter_inc:
             src[num_src++] = ureg_imm1i(c->ureg, 1);
@@ -1888,7 +1943,7 @@ ntt_emit_mem(struct ntt_compile *c, nir_intrinsic_instr *instr,
             break;
          default:
             if (!is_load)
-               src[num_src++] = ntt_get_src(c, instr->src[nir_src++]); /* value */
+               src[num_src++] = ntt_get_src(c, instr->src[next_src++]); /* value */
             break;
          }
       }
@@ -1949,7 +2004,7 @@ ntt_emit_mem(struct ntt_compile *c, nir_intrinsic_instr *instr,
    case nir_intrinsic_ssbo_atomic_comp_swap:
    case nir_intrinsic_shared_atomic_comp_swap:
       opcode = TGSI_OPCODE_ATOMCAS;
-      src[num_src++] = ntt_get_src(c, instr->src[nir_src++]);
+      src[num_src++] = ntt_get_src(c, instr->src[next_src++]);
       break;
    case nir_intrinsic_atomic_counter_read:
    case nir_intrinsic_load_ssbo:



More information about the mesa-commit mailing list