[Mesa-dev] [PATCH 5/7] nir/lower_tex: Add lowering for some min_lod cases

Jason Ekstrand jason at jlekstrand.net
Thu Oct 11 21:32:56 UTC 2018


---
 src/compiler/nir/nir.h           | 18 ++++++
 src/compiler/nir/nir_lower_tex.c | 98 ++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 2896de58743..132a7b8ffbc 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2928,6 +2928,24 @@ typedef struct nir_lower_tex_options {
     * Implies lower_txd_cube_map and lower_txd_shadow.
     */
    bool lower_txd;
+
+   /**
+    * If true, lower nir_texop_txb that try to use shadow compare and min_lod
+    * at the same time to a nir_texop_lod, some math, and nir_texop_tex.
+    */
+   bool lower_txb_shadow_clamp;
+
+   /**
+    * If true, lower nir_texop_txd on shadow samplers when it uses min_lod
+    * with nir_texop_txl.  This includes cube maps.
+    */
+   bool lower_txd_shadow_clamp;
+
+   /**
+    * If true, lower nir_texop_txd on when it uses both offset and min_lod
+    * with nir_texop_txl.  This includes cube maps.
+    */
+   bool lower_txd_offset_clamp;
 } nir_lower_tex_options;
 
 bool nir_lower_tex(nir_shader *shader,
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index 5fd6d922732..9e1651beae5 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -150,6 +150,54 @@ get_texture_size(nir_builder *b, nir_tex_instr *tex)
    return nir_i2f32(b, &txs->dest.ssa);
 }
 
+static nir_ssa_def *
+get_texture_lod(nir_builder *b, nir_tex_instr *tex)
+{
+   b->cursor = nir_before_instr(&tex->instr);
+
+   nir_tex_instr *tql;
+
+   unsigned num_srcs = 0;
+   for (unsigned i = 0; i < tex->num_srcs; i++) {
+      if (tex->src[i].src_type == nir_tex_src_coord ||
+          tex->src[i].src_type == nir_tex_src_texture_deref ||
+          tex->src[i].src_type == nir_tex_src_sampler_deref ||
+          tex->src[i].src_type == nir_tex_src_texture_offset ||
+          tex->src[i].src_type == nir_tex_src_sampler_offset)
+         num_srcs++;
+   }
+
+   tql = nir_tex_instr_create(b->shader, num_srcs);
+   tql->op = nir_texop_lod;
+   tql->coord_components = tex->coord_components;
+   tql->sampler_dim = tex->sampler_dim;
+   tql->is_array = tex->is_array;
+   tql->is_shadow = tex->is_shadow;
+   tql->is_new_style_shadow = tex->is_new_style_shadow;
+   tql->texture_index = tex->texture_index;
+   tql->sampler_index = tex->sampler_index;
+   tql->dest_type = nir_type_float;
+
+   unsigned idx = 0;
+   for (unsigned i = 0; i < tex->num_srcs; i++) {
+      if (tex->src[i].src_type == nir_tex_src_coord ||
+          tex->src[i].src_type == nir_tex_src_texture_deref ||
+          tex->src[i].src_type == nir_tex_src_sampler_deref ||
+          tex->src[i].src_type == nir_tex_src_texture_offset ||
+          tex->src[i].src_type == nir_tex_src_sampler_offset) {
+         nir_src_copy(&tql->src[idx].src, &tex->src[i].src, tql);
+         tql->src[idx].src_type = tex->src[i].src_type;
+         idx++;
+      }
+   }
+
+   nir_ssa_dest_init(&tql->instr, &tql->dest, 2, 32, NULL);
+   nir_builder_instr_insert(b, &tql->instr);
+
+   /* The LOD is the y component of the result */
+   return nir_channel(b, &tql->dest.ssa, 1);
+}
+
 static bool
 lower_offset(nir_builder *b, nir_tex_instr *tex)
 {
@@ -227,6 +275,36 @@ lower_rect(nir_builder *b, nir_tex_instr *tex)
    tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
 }
 
+static void
+lower_implicit_lod(nir_builder *b, nir_tex_instr *tex)
+{
+   assert(tex->op == nir_texop_tex || tex->op == nir_texop_txb);
+   assert(nir_tex_instr_src_index(tex, nir_tex_src_lod) < 0);
+   assert(nir_tex_instr_src_index(tex, nir_tex_src_ddx) < 0);
+   assert(nir_tex_instr_src_index(tex, nir_tex_src_ddy) < 0);
+
+   b->cursor = nir_before_instr(&tex->instr);
+
+   nir_ssa_def *lod = get_texture_lod(b, tex);
+
+   int bias_idx = nir_tex_instr_src_index(tex, nir_tex_src_bias);
+   if (bias_idx >= 0) {
+      /* If we have a bias, add it in */
+      lod = nir_fadd(b, lod, nir_ssa_for_src(b, tex->src[bias_idx].src, 1));
+      nir_tex_instr_remove_src(tex, bias_idx);
+   }
+
+   int min_lod_idx = nir_tex_instr_src_index(tex, nir_tex_src_min_lod);
+   if (min_lod_idx >= 0) {
+      /* If we have a minimum LOD, clamp LOD accordingly */
+      lod = nir_fmax(b, lod, nir_ssa_for_src(b, tex->src[min_lod_idx].src, 1));
+      nir_tex_instr_remove_src(tex, min_lod_idx);
+   }
+
+   nir_tex_instr_add_src(tex, nir_tex_src_lod, nir_src_for_ssa(lod));
+   tex->op = nir_texop_txl;
+}
+
 static nir_ssa_def *
 sample_plane(nir_builder *b, nir_tex_instr *tex, int plane)
 {
@@ -355,6 +433,13 @@ replace_gradient_with_lod(nir_builder *b, nir_ssa_def *lod, nir_tex_instr *tex)
    nir_tex_instr_remove_src(tex, nir_tex_instr_src_index(tex, nir_tex_src_ddx));
    nir_tex_instr_remove_src(tex, nir_tex_instr_src_index(tex, nir_tex_src_ddy));
 
+   int min_lod_idx = nir_tex_instr_src_index(tex, nir_tex_src_min_lod);
+   if (min_lod_idx >= 0) {
+      /* If we have a minimum LOD, clamp LOD accordingly */
+      lod = nir_fmax(b, lod, nir_ssa_for_src(b, tex->src[min_lod_idx].src, 1));
+      nir_tex_instr_remove_src(tex, min_lod_idx);
+   }
+
    nir_tex_instr_add_src(tex, nir_tex_src_lod, nir_src_for_ssa(lod));
    tex->op = nir_texop_txl;
 }
@@ -779,9 +864,22 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
          progress = true;
       }
 
+      const bool has_min_lod =
+         nir_tex_instr_src_index(tex, nir_tex_src_min_lod) >= 0;
+      const bool has_offset =
+         nir_tex_instr_src_index(tex, nir_tex_src_offset) >= 0;
+
+      if (tex->op == nir_texop_txb && tex->is_shadow && has_min_lod &&
+          options->lower_txb_shadow_clamp) {
+         lower_implicit_lod(b, tex);
+         progress = true;
+      }
+
       if (tex->op == nir_texop_txd &&
           (options->lower_txd ||
            (options->lower_txd_shadow && tex->is_shadow) ||
+           (options->lower_txd_shadow_clamp && tex->is_shadow && has_min_lod) ||
+           (options->lower_txd_offset_clamp && has_offset && has_min_lod) ||
            (options->lower_txd_cube_map &&
             tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE))) {
          lower_gradient(b, tex);
-- 
2.19.1



More information about the mesa-dev mailing list