[Mesa-dev] [PATCH 06/92] nir/lower_system_values: add support for the FRAG_COORD system value

Nicolai Hähnle nhaehnle at gmail.com
Mon Jun 26 14:09:45 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Arguably this could convert to a load intrinsic, but other code paths
already expect this as a fragment shader input.
---
 src/compiler/nir/nir_lower_system_values.c | 36 ++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c
index 810100a..64a1354 100644
--- a/src/compiler/nir/nir_lower_system_values.c
+++ b/src/compiler/nir/nir_lower_system_values.c
@@ -21,22 +21,46 @@
  * IN THE SOFTWARE.
  *
  * Authors:
  *    Connor Abbott (cwabbott0 at gmail.com)
  *
  */
 
 #include "nir.h"
 #include "nir_builder.h"
 
+static nir_ssa_def *
+get_frag_coord(nir_builder *b, nir_shader *shader, nir_variable *orig)
+{
+   nir_variable *pos = NULL;
+
+   assert(shader->stage == MESA_SHADER_FRAGMENT);
+
+   nir_foreach_variable(var, &shader->inputs) {
+      if (var->data.location == VARYING_SLOT_POS) {
+         pos = var;
+         break;
+      }
+   }
+
+   if (!pos) {
+      pos = nir_variable_create(shader, nir_var_shader_in, glsl_vec4_type(), "gl_FragCoord");
+      pos->data.location = VARYING_SLOT_POS;
+      pos->data.pixel_center_integer = orig->data.pixel_center_integer;
+      pos->data.origin_upper_left = orig->data.origin_upper_left;
+   }
+
+   return nir_load_var(b, pos);
+}
+
 static bool
-convert_block(nir_block *block, nir_builder *b)
+convert_block(nir_block *block, nir_builder *b, nir_shader *shader)
 {
    bool progress = false;
 
    nir_foreach_instr_safe(instr, block) {
       if (instr->type != nir_instr_type_intrinsic)
          continue;
 
       nir_intrinsic_instr *load_var = nir_instr_as_intrinsic(instr);
 
       if (load_var->intrinsic != nir_intrinsic_load_var)
@@ -109,59 +133,63 @@ convert_block(nir_block *block, nir_builder *b)
             sysval = nir_load_vertex_id(b);
          }
          break;
 
       case SYSTEM_VALUE_INSTANCE_INDEX:
          sysval = nir_iadd(b,
                            nir_load_instance_id(b),
                            nir_load_base_instance(b));
          break;
 
+      case SYSTEM_VALUE_FRAG_COORD:
+         sysval = get_frag_coord(b, shader, var);
+         break;
+
       default:
          break;
       }
 
       if (sysval == NULL) {
          nir_intrinsic_op sysval_op =
             nir_intrinsic_from_system_value(var->data.location);
          sysval = nir_load_system_value(b, sysval_op, 0);
       }
 
       nir_ssa_def_rewrite_uses(&load_var->dest.ssa, nir_src_for_ssa(sysval));
       nir_instr_remove(&load_var->instr);
 
       progress = true;
    }
 
    return progress;
 }
 
 static bool
-convert_impl(nir_function_impl *impl)
+convert_impl(nir_function_impl *impl, nir_shader *shader)
 {
    bool progress = false;
    nir_builder builder;
    nir_builder_init(&builder, impl);
 
    nir_foreach_block(block, impl) {
-      progress |= convert_block(block, &builder);
+      progress |= convert_block(block, &builder, shader);
    }
 
    nir_metadata_preserve(impl, nir_metadata_block_index |
                                nir_metadata_dominance);
    return progress;
 }
 
 bool
 nir_lower_system_values(nir_shader *shader)
 {
    bool progress = false;
 
    nir_foreach_function(function, shader) {
       if (function->impl)
-         progress = convert_impl(function->impl) || progress;
+         progress = convert_impl(function->impl, shader) || progress;
    }
 
    exec_list_make_empty(&shader->system_values);
 
    return progress;
 }
-- 
2.9.3



More information about the mesa-dev mailing list