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

Author: Alyssa Rosenzweig <[email protected]>
Date:   Mon Nov 27 09:40:50 2023 -0400

nir/lower_tex: Add 1D lowering

>From amd/common.

Signed-off-by: Alyssa Rosenzweig <[email protected]>
Reviewed-by: Faith Ekstrand <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26377>

---

 src/compiler/nir/nir.h           |  9 +++++
 src/compiler/nir/nir_lower_tex.c | 78 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 76502c7f5e1..47d1795b02d 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -5694,6 +5694,15 @@ typedef struct nir_lower_tex_options {
     */
    bool lower_rect;
 
+   /**
+    * If true, lower 1D textures to 2D. This requires the GL/VK driver to map 
1D
+    * textures to 2D textures with height=1.
+    *
+    * lower_1d_shadow does this lowering for shadow textures only.
+    */
+   bool lower_1d;
+   bool lower_1d_shadow;
+
    /**
     * If true, convert yuv to rgb.
     */
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index 716c5dda7a8..2865fd14647 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright © 2023 Valve Corporation
  * Copyright © 2015 Broadcom
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -246,6 +247,77 @@ lower_rect_tex_scale(nir_builder *b, nir_tex_instr *tex)
    }
 }
 
+static void
+lower_1d(nir_builder *b, nir_tex_instr *tex)
+{
+   b->cursor = nir_before_instr(&tex->instr);
+
+   nir_def *coords = nir_steal_tex_src(tex, nir_tex_src_coord);
+   nir_def *offset = nir_steal_tex_src(tex, nir_tex_src_offset);
+   nir_def *ddx = nir_steal_tex_src(tex, nir_tex_src_ddx);
+   nir_def *ddy = nir_steal_tex_src(tex, nir_tex_src_ddy);
+
+   /* Add in 2D sources to become a 2D operation */
+   tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
+
+   if (coords) {
+      /* We want to fetch texel 0 along the Y-axis. To do so, we sample at 0.5
+       * to get texel 0 with correct handling of wrap modes.
+       */
+      nir_def *y = nir_imm_floatN_t(b, tex->op == nir_texop_txf ? 0.0 : 0.5,
+                                    coords->bit_size);
+
+      tex->coord_components++;
+
+      if (tex->is_array && tex->op != nir_texop_lod) {
+         assert(tex->coord_components == 3);
+
+         nir_def *x = nir_channel(b, coords, 0);
+         nir_def *idx = nir_channel(b, coords, 1);
+         coords = nir_vec3(b, x, y, idx);
+      } else {
+         assert(tex->coord_components == 2);
+         coords = nir_vec2(b, coords, y);
+      }
+
+      nir_tex_instr_add_src(tex, nir_tex_src_coord, coords);
+   }
+
+   if (offset) {
+      nir_tex_instr_add_src(tex, nir_tex_src_offset,
+                            nir_pad_vector_imm_int(b, offset, 0, 2));
+   }
+
+   if (ddx || ddy) {
+      nir_tex_instr_add_src(tex, nir_tex_src_ddx,
+                            nir_pad_vector_imm_int(b, ddx, 0, 2));
+
+      nir_tex_instr_add_src(tex, nir_tex_src_ddy,
+                            nir_pad_vector_imm_int(b, ddy, 0, 2));
+   }
+
+   /* Handle destination component mismatch for txs. */
+   if (tex->op == nir_texop_txs) {
+      b->cursor = nir_after_instr(&tex->instr);
+
+      nir_def *dst;
+      if (tex->is_array) {
+         assert(tex->def.num_components == 2);
+         tex->def.num_components = 3;
+
+         /* For array, we take .xz to skip the newly added height */
+         dst = nir_channels(b, &tex->def, (1 << 0) | (1 << 2));
+      } else {
+         assert(tex->def.num_components == 1);
+         tex->def.num_components = 2;
+
+         dst = nir_channel(b, &tex->def, 0);
+      }
+
+      nir_def_rewrite_uses_after(&tex->def, dst, dst->parent_instr);
+   }
+}
+
 static void
 lower_lod(nir_builder *b, nir_tex_instr *tex, nir_def *lod)
 {
@@ -1497,6 +1569,12 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
          progress = true;
       }
 
+      if (tex->sampler_dim == GLSL_SAMPLER_DIM_1D &&
+          (options->lower_1d || (tex->is_shadow && options->lower_1d_shadow))) 
{
+         lower_1d(b, tex);
+         progress = true;
+      }
+
       unsigned texture_index = tex->texture_index;
       uint32_t texture_mask = 1u << texture_index;
       int tex_index = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);

Reply via email to