agx: Implement txd
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Fri, 9 Sep 2022 18:32:32 +0000 (14:32 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 13 Sep 2022 16:04:29 +0000 (16:04 +0000)
Handles all cases except for cube maps, which don't seem to work
properly, so those are lowered.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18525>

src/asahi/compiler/agx_compile.c
src/asahi/compiler/agx_compiler.h
src/asahi/compiler/agx_pack.c

index 57764f5..1fa225d 100644 (file)
@@ -997,6 +997,7 @@ agx_lod_mode_for_nir(nir_texop op)
    switch (op) {
    case nir_texop_tex: return AGX_LOD_MODE_AUTO_LOD;
    case nir_texop_txb: return AGX_LOD_MODE_AUTO_LOD_BIAS;
+   case nir_texop_txd: return AGX_LOD_MODE_LOD_GRAD;
    case nir_texop_txl: return AGX_LOD_MODE_LOD_MIN;
    case nir_texop_txf: return AGX_LOD_MODE_LOD_MIN;
    default: unreachable("Unhandled texture op");
@@ -1011,6 +1012,7 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
    case nir_texop_txf:
    case nir_texop_txl:
    case nir_texop_txb:
+   case nir_texop_txd:
       break;
    default:
       unreachable("Unhandled texture op");
@@ -1111,6 +1113,32 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
          break;
       }
 
+      case nir_tex_src_ddx:
+      {
+         int y_idx = nir_tex_instr_src_index(instr, nir_tex_src_ddy);
+         assert(y_idx >= 0 && "we only handle gradients");
+
+         unsigned n = nir_tex_instr_src_size(instr, y_idx);
+         assert((n == 2 || n == 3) && "other sizes not supported");
+
+         agx_index index2 = agx_src_index(&instr->src[y_idx].src);
+
+         /* We explicitly don't cache about the split cache for this */
+         lod = agx_temp(b->shader, AGX_SIZE_32);
+         agx_instr *I = agx_p_combine_to(b, lod, 2 * n);
+
+         for (unsigned i = 0; i < n; ++i) {
+            I->src[(2 * i) + 0] = agx_emit_extract(b, index, i);
+            I->src[(2 * i) + 1] = agx_emit_extract(b, index2, i);
+         }
+
+         break;
+      }
+
+      case nir_tex_src_ddy:
+         /* handled above */
+         break;
+
       case nir_tex_src_ms_index:
       case nir_tex_src_texture_offset:
       case nir_tex_src_sampler_offset:
@@ -1782,6 +1810,11 @@ agx_compile_shader_nir(nir_shader *nir,
       .lower_txs_lod = true,
       .lower_txp = ~0,
       .lower_invalid_implicit_lod = true,
+
+      /* XXX: Metal seems to handle just like 3D txd, so why doesn't it work?
+       * TODO: Stop using this lowering
+       */
+      .lower_txd_cube_map = true,
    };
 
    nir_tex_src_type_constraints tex_constraints = {
index 8ac605a..f5e613d 100644 (file)
@@ -256,8 +256,8 @@ enum agx_lod_mode {
    AGX_LOD_MODE_AUTO_LOD = 0,
    AGX_LOD_MODE_AUTO_LOD_BIAS = 5,
    AGX_LOD_MODE_LOD_MIN = 6,
-   AGX_LOD_GRAD = 8,
-   AGX_LOD_GRAD_MIN = 12
+   AGX_LOD_MODE_LOD_GRAD = 4,
+   AGX_LOD_MODE_LOD_GRAD_MIN = 12
 };
 
 enum agx_dim {
index 557a50e..e206603 100644 (file)
@@ -95,9 +95,8 @@ agx_pack_lod(agx_index index)
    if (index.type == AGX_INDEX_IMMEDIATE && index.value == 0)
       return 0;
 
-   /* Otherwise must be a 16-bit float immediate */
+   /* Otherwise must be registers. Type implicitly specified by LOD mode. */
    assert(index.type == AGX_INDEX_REGISTER);
-   assert(index.size == AGX_SIZE_16);
    assert(index.value < 0x100);
 
    return index.value;