Mesa (main): nir/lower_tex: add lower_to_fragment_fetch_amd

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Oct 7 17:52:54 UTC 2021


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

Author: Rhys Perry <pendingchaos02 at gmail.com>
Date:   Wed Aug  4 16:17:39 2021 +0100

nir/lower_tex: add lower_to_fragment_fetch_amd

Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12214>

---

 src/compiler/nir/nir.h           |  6 ++++
 src/compiler/nir/nir_lower_tex.c | 76 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 3a4a439b461..5d076c75487 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -5222,6 +5222,12 @@ typedef struct nir_lower_tex_options {
     */
    bool lower_tg4_offsets;
 
+   /**
+    * Lower txf_ms to fragment_mask_fetch and fragment_fetch and samples_identical to
+    * fragment_mask_fetch.
+    */
+   bool lower_to_fragment_fetch_amd;
+
    /**
     * To lower packed sampler return formats.
     *
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index b19f671623b..30aa1e75249 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -1191,6 +1191,70 @@ nir_lower_txs_cube_array(nir_builder *b, nir_tex_instr *tex)
    nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, size, size->parent_instr);
 }
 
+static void
+nir_lower_ms_txf_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
+{
+   lower_offset(b, tex);
+
+   b->cursor = nir_before_instr(&tex->instr);
+
+   /* Create FMASK fetch. */
+   assert(tex->texture_index == 0);
+   nir_tex_instr *fmask_fetch = nir_tex_instr_create(b->shader, tex->num_srcs - 1);
+   fmask_fetch->op = nir_texop_fragment_mask_fetch_amd;
+   fmask_fetch->coord_components = tex->coord_components;
+   fmask_fetch->sampler_dim = tex->sampler_dim;
+   fmask_fetch->is_array = tex->is_array;
+   fmask_fetch->texture_non_uniform = tex->texture_non_uniform;
+   fmask_fetch->dest_type = nir_type_uint32;
+   nir_ssa_dest_init(&fmask_fetch->instr, &fmask_fetch->dest, 1, 32, NULL);
+
+   fmask_fetch->num_srcs = 0;
+   for (unsigned i = 0; i < tex->num_srcs; i++) {
+      if (tex->src[i].src_type == nir_tex_src_ms_index)
+         continue;
+      nir_tex_src *src = &fmask_fetch->src[fmask_fetch->num_srcs++];
+      src->src = nir_src_for_ssa(tex->src[i].src.ssa);
+      src->src_type = tex->src[i].src_type;
+   }
+
+   nir_builder_instr_insert(b, &fmask_fetch->instr);
+
+   /* Obtain new sample index. */
+   int ms_index = nir_tex_instr_src_index(tex, nir_tex_src_ms_index);
+   assert(ms_index >= 0);
+   nir_src sample = tex->src[ms_index].src;
+   nir_ssa_def *new_sample = NULL;
+   if (nir_src_is_const(sample) && (nir_src_as_uint(sample) == 0 || nir_src_as_uint(sample) == 7)) {
+      if (nir_src_as_uint(sample) == 7)
+         new_sample = nir_ushr(b, &fmask_fetch->dest.ssa, nir_imm_int(b, 28));
+      else
+         new_sample = nir_iand_imm(b, &fmask_fetch->dest.ssa, 0xf);
+   } else {
+      new_sample = nir_ubitfield_extract(b, &fmask_fetch->dest.ssa,
+                                         nir_imul_imm(b, sample.ssa, 4), nir_imm_int(b, 4));
+   }
+
+   /* Update instruction. */
+   tex->op = nir_texop_fragment_fetch_amd;
+   nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[ms_index].src, new_sample);
+}
+
+static void
+nir_lower_samples_identical_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
+{
+   b->cursor = nir_after_instr(&tex->instr);
+
+   nir_tex_instr *fmask_fetch = nir_instr_as_tex(nir_instr_clone(b->shader, &tex->instr));
+   fmask_fetch->op = nir_texop_fragment_mask_fetch_amd;
+   fmask_fetch->dest_type = nir_type_uint32;
+   nir_ssa_dest_init(&fmask_fetch->instr, &fmask_fetch->dest, 1, 32, NULL);
+   nir_builder_instr_insert(b, &fmask_fetch->instr);
+
+   nir_ssa_def_rewrite_uses(&tex->dest.ssa, nir_ieq_imm(b, &fmask_fetch->dest.ssa, 0));
+   nir_instr_remove_v(&tex->instr);
+}
+
 static bool
 nir_lower_tex_block(nir_block *block, nir_builder *b,
                     const nir_lower_tex_options *options,
@@ -1400,6 +1464,18 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
          progress |= lower_tg4_offsets(b, tex);
          continue;
       }
+
+      if (options->lower_to_fragment_fetch_amd && tex->op == nir_texop_txf_ms) {
+         nir_lower_ms_txf_to_fragment_fetch(b, tex);
+         progress = true;
+         continue;
+      }
+
+      if (options->lower_to_fragment_fetch_amd && tex->op == nir_texop_samples_identical) {
+         nir_lower_samples_identical_to_fragment_fetch(b, tex);
+         progress = true;
+         continue;
+      }
    }
 
    return progress;



More information about the mesa-commit mailing list