Mesa (master): compiler/nir: add texcoord replace lowering pass

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 25 17:57:08 UTC 2021


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

Author: Erik Faye-Lund <erik.faye-lund at collabora.com>
Date:   Thu Aug 27 13:25:15 2020 +0200

compiler/nir: add texcoord replace lowering pass

This lowering pass allows us to replace point-sprites to gl_PointCoord,
which better match what modern hardware does.

Reviewed-by: Eric Anholt <eric at anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6473>

---

 src/compiler/Makefile.sources                 |   1 +
 src/compiler/nir/meson.build                  |   1 +
 src/compiler/nir/nir.h                        |   3 +
 src/compiler/nir/nir_lower_texcoord_replace.c | 147 ++++++++++++++++++++++++++
 4 files changed, 152 insertions(+)

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 7464e972c1b..e2c1403a221 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -299,6 +299,7 @@ NIR_FILES = \
 	nir/nir_lower_subgroups.c \
 	nir/nir_lower_system_values.c \
 	nir/nir_lower_tex.c \
+	nir/nir_lower_texcoord_replace.c \
 	nir/nir_lower_to_source_mods.c \
 	nir/nir_lower_two_sided_color.c \
 	nir/nir_lower_ubo_vec4.c \
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
index 05670fbd98c..8df22adb3f6 100644
--- a/src/compiler/nir/meson.build
+++ b/src/compiler/nir/meson.build
@@ -187,6 +187,7 @@ files_libnir = files(
   'nir_lower_subgroups.c',
   'nir_lower_system_values.c',
   'nir_lower_tex.c',
+  'nir_lower_texcoord_replace.c',
   'nir_lower_to_source_mods.c',
   'nir_lower_two_sided_color.c',
   'nir_lower_undef_to_zero.c',
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index ffa32fb18da..1a27f5ccf10 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -4868,6 +4868,9 @@ void nir_lower_mediump_outputs(nir_shader *nir);
 
 bool nir_lower_point_size(nir_shader *shader, float min, float max);
 
+void nir_lower_texcoord_replace(nir_shader *s, unsigned coord_replace,
+                                bool point_coord_is_sysval);
+
 typedef enum {
    nir_lower_interpolation_at_sample = (1 << 1),
    nir_lower_interpolation_at_offset = (1 << 2),
diff --git a/src/compiler/nir/nir_lower_texcoord_replace.c b/src/compiler/nir/nir_lower_texcoord_replace.c
new file mode 100644
index 00000000000..f0a03e8cef8
--- /dev/null
+++ b/src/compiler/nir/nir_lower_texcoord_replace.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright © 2020 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Erik Faye-Lund <erik.faye-lund at collabora.com>
+ */
+
+#include "nir.h"
+#include "nir_builder.h"
+#include "nir_deref.h"
+
+static nir_ssa_def *
+get_io_index(nir_builder *b, nir_deref_instr *deref)
+{
+   nir_deref_path path;
+   nir_deref_path_init(&path, deref, NULL);
+
+   assert(path.path[0]->deref_type == nir_deref_type_var);
+   nir_deref_instr **p = &path.path[1];
+
+   /* Just emit code and let constant-folding go to town */
+   nir_ssa_def *offset = nir_imm_int(b, 0);
+
+   for (; *p; p++) {
+      if ((*p)->deref_type == nir_deref_type_array) {
+         unsigned size = glsl_get_length((*p)->type);
+
+         nir_ssa_def *mul =
+            nir_amul_imm(b, nir_ssa_for_src(b, (*p)->arr.index, 1), size);
+
+         offset = nir_iadd(b, offset, mul);
+      } else
+         unreachable("Unsupported deref type");
+   }
+
+   nir_deref_path_finish(&path);
+
+   return offset;
+}
+
+static void
+nir_lower_texcoord_replace_impl(nir_function_impl *impl,
+                                unsigned coord_replace,
+                                bool point_coord_is_sysval)
+{
+   nir_builder b;
+
+   nir_builder_init(&b, impl);
+   b.cursor = nir_before_cf_list(&impl->body);
+
+   nir_ssa_def *new_coord;
+   if (point_coord_is_sysval) {
+      new_coord = nir_load_system_value(&b, nir_intrinsic_load_point_coord,
+                                        0, 2, 32);
+   } else {
+      /* find or create pntc */
+      nir_variable *pntc = nir_find_variable_with_location(b.shader,
+                                                           nir_var_shader_in,
+                                                           VARYING_SLOT_PNTC);
+      if (!pntc) {
+         pntc = nir_variable_create(b.shader, nir_var_shader_in,
+                                    glsl_vec_type(2), "gl_PointCoord");
+         pntc->data.location = VARYING_SLOT_PNTC;
+      }
+
+      new_coord = nir_load_var(&b, pntc);
+   }
+
+   /* point-coord is two-component, need to add two implicit ones in case of
+    * projective texturing etc.
+    */
+   nir_ssa_def *zero = nir_imm_zero(&b, 1, new_coord->bit_size);
+   nir_ssa_def *one = nir_imm_floatN_t(&b, 1.0, new_coord->bit_size);
+   new_coord = nir_vec4(&b, nir_channel(&b, new_coord, 0),
+                            nir_channel(&b, new_coord, 1),
+                            zero, one);
+
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         if (instr->type != nir_instr_type_intrinsic)
+            continue;
+
+         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+         if (intrin->intrinsic != nir_intrinsic_load_deref)
+            continue;
+
+         nir_variable *var = nir_intrinsic_get_var(intrin, 0);
+         if (var->data.mode != nir_var_shader_in ||
+             var->data.location < VARYING_SLOT_TEX0 ||
+             var->data.location > VARYING_SLOT_TEX7)
+            continue;
+         unsigned base = var->data.location - VARYING_SLOT_TEX0;
+
+         b.cursor = nir_after_instr(instr);
+         nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
+         nir_ssa_def *index = get_io_index(&b, deref);
+         nir_ssa_def *mask =
+            nir_ishl(&b, nir_imm_int(&b, 1),
+                         nir_iadd_imm(&b, index, base));
+
+         nir_ssa_def *cond =
+            nir_i2b(&b, nir_iand_imm(&b, mask, coord_replace));
+         nir_ssa_def *result = nir_bcsel(&b, cond, new_coord,
+                                         &intrin->dest.ssa);
+
+         nir_ssa_def_rewrite_uses_after(&intrin->dest.ssa,
+                                        nir_src_for_ssa(result),
+                                        result->parent_instr);
+      }
+   }
+
+   nir_metadata_preserve(impl, nir_metadata_block_index |
+                               nir_metadata_dominance);
+}
+
+void
+nir_lower_texcoord_replace(nir_shader *s, unsigned coord_replace,
+                           bool point_coord_is_sysval)
+{
+   assert(s->info.stage == MESA_SHADER_FRAGMENT);
+   assert(coord_replace != 0);
+
+   nir_foreach_function(function, s) {
+      if (function->impl)
+         nir_lower_texcoord_replace_impl(function->impl, coord_replace,
+                                         point_coord_is_sysval);
+   }
+}



More information about the mesa-commit mailing list