etnaviv: nir: support intrinsic used for txs lowering
authorChristian Gmeiner <cgmeiner@igalia.com>
Tue, 11 Jul 2023 13:41:36 +0000 (15:41 +0200)
committerMarge Bot <emma+marge@anholt.net>
Fri, 21 Jul 2023 08:52:03 +0000 (08:52 +0000)
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24217>

src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c
src/gallium/drivers/etnaviv/etnaviv_compiler_nir.h
src/gallium/drivers/etnaviv/etnaviv_context.h
src/gallium/drivers/etnaviv/etnaviv_uniforms.c

index cde517b..c6bc457 100644 (file)
@@ -221,6 +221,7 @@ src_swizzle(hw_src src, unsigned swizzle)
 #define CONST(x) CONST_VAL(ETNA_UNIFORM_CONSTANT, x)
 #define UNIFORM(x) CONST_VAL(ETNA_UNIFORM_UNIFORM, x)
 #define TEXSCALE(x, i) CONST_VAL(ETNA_UNIFORM_TEXRECT_SCALE_X + (i), x)
+#define TEXSIZE(x, i) CONST_VAL(ETNA_UNIFORM_TEXTURE_WIDTH + (i), x)
 
 static int
 const_add(uint64_t *c, uint64_t value)
@@ -380,6 +381,16 @@ get_src(struct etna_compile *c, nir_src *src)
 
          return src_swizzle(const_src(c, values, 2), SWIZZLE(X,Y,X,X));
       }
+      case nir_intrinsic_load_texture_size_etna: {
+         int sampler = nir_src_as_int(intr->src[0]);
+         nir_const_value values[] = {
+            TEXSIZE(sampler, 0),
+            TEXSIZE(sampler, 1),
+            TEXSIZE(sampler, 2),
+         };
+
+         return src_swizzle(const_src(c, values, 3), SWIZZLE(X,Y,Z,X));
+      }
       default:
          compile_error(c, "Unhandled NIR intrinsic type: %s\n",
                        nir_intrinsic_infos[intr->intrinsic].name);
@@ -601,6 +612,7 @@ emit_intrinsic(struct etna_compile *c, nir_intrinsic_instr * intr)
    case nir_intrinsic_load_input:
    case nir_intrinsic_load_instance_id:
    case nir_intrinsic_load_texture_scale:
+   case nir_intrinsic_load_texture_size_etna:
       break;
    default:
       compile_error(c, "Unhandled NIR intrinsic type: %s\n",
index 5f72002..2260f90 100644 (file)
@@ -218,7 +218,8 @@ dest_for_instr(nir_instr *instr)
           intr->intrinsic == nir_intrinsic_load_ubo ||
           intr->intrinsic == nir_intrinsic_load_input ||
           intr->intrinsic == nir_intrinsic_load_instance_id ||
-          intr->intrinsic == nir_intrinsic_load_texture_scale)
+          intr->intrinsic == nir_intrinsic_load_texture_scale ||
+          intr->intrinsic == nir_intrinsic_load_texture_size_etna)
          dest = &intr->dest;
    } break;
    case nir_instr_type_deref:
index e08157b..874867d 100644 (file)
@@ -96,6 +96,9 @@ enum etna_uniform_contents {
    ETNA_UNIFORM_UNIFORM,
    ETNA_UNIFORM_TEXRECT_SCALE_X,
    ETNA_UNIFORM_TEXRECT_SCALE_Y,
+   ETNA_UNIFORM_TEXTURE_WIDTH,
+   ETNA_UNIFORM_TEXTURE_HEIGHT,
+   ETNA_UNIFORM_TEXTURE_DEPTH,
    ETNA_UNIFORM_UBO0_ADDR,
    ETNA_UNIFORM_UBOMAX_ADDR = ETNA_UNIFORM_UBO0_ADDR + ETNA_MAX_CONST_BUF - 1,
 };
index 92d5665..2e1cc44 100644 (file)
@@ -60,6 +60,53 @@ get_texrect_scale(const struct etna_context *ctx, bool frag,
    return fui(1.0f / dim);
 }
 
+static inline bool
+is_array_texture(enum pipe_texture_target target)
+{
+   switch (target) {
+   case PIPE_TEXTURE_1D_ARRAY:
+   case PIPE_TEXTURE_2D_ARRAY:
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      return true;
+   default:
+      return false;
+   }
+}
+
+static uint32_t
+get_texture_size(const struct etna_context *ctx, bool frag,
+                  enum etna_uniform_contents contents, uint32_t data)
+{
+   unsigned index = get_const_idx(ctx, frag, data);
+   struct pipe_sampler_view *texture = ctx->sampler_view[index];
+
+   switch (contents) {
+   case ETNA_UNIFORM_TEXTURE_WIDTH:
+      if (texture->target == PIPE_BUFFER) {
+         return texture->u.buf.size / util_format_get_blocksize(texture->format);
+      } else {
+         return u_minify(texture->texture->width0, texture->u.tex.first_level);
+      }
+   case ETNA_UNIFORM_TEXTURE_HEIGHT:
+      return u_minify(texture->texture->height0, texture->u.tex.first_level);
+   case ETNA_UNIFORM_TEXTURE_DEPTH:
+      assert(texture->target != PIPE_BUFFER);
+
+      if (is_array_texture(texture->target)) {
+         if (texture->target != PIPE_TEXTURE_CUBE_ARRAY) {
+            return texture->texture->array_size;
+         } else {
+            assert(texture->texture->array_size % 6 == 0);
+            return texture->texture->array_size / 6;
+         }
+      }
+
+      return u_minify(texture->texture->depth0, texture->u.tex.first_level);
+   default:
+      unreachable("Bad texture size field");
+   }
+}
+
 void
 etna_uniforms_write(const struct etna_context *ctx,
                     const struct etna_shader_variant *sobj,
@@ -97,6 +144,13 @@ etna_uniforms_write(const struct etna_context *ctx,
             get_texrect_scale(ctx, frag, uinfo->contents[i], val));
          break;
 
+      case ETNA_UNIFORM_TEXTURE_WIDTH:
+      case ETNA_UNIFORM_TEXTURE_HEIGHT:
+      case ETNA_UNIFORM_TEXTURE_DEPTH:
+         etna_cmd_stream_emit(stream,
+            get_texture_size(ctx, frag, uinfo->contents[i], val));
+         break;
+
       case ETNA_UNIFORM_UBO0_ADDR ... ETNA_UNIFORM_UBOMAX_ADDR:
          idx = uinfo->contents[i] - ETNA_UNIFORM_UBO0_ADDR;
          etna_cmd_stream_reloc(stream, &(struct etna_reloc) {