nir: Move compute system value lowering to a separate pass
authorJesse Natalie <jenatali@microsoft.com>
Fri, 21 Aug 2020 17:18:14 +0000 (10:18 -0700)
committerMarge Bot <eric+marge@anholt.net>
Fri, 21 Aug 2020 22:07:05 +0000 (22:07 +0000)
The actual variable -> intrinsic lowering stays where it is, but
ops which convert one intrinsic to be implemented in terms of
another have moved.

Reviewed-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5891>

13 files changed:
src/amd/vulkan/radv_shader.c
src/broadcom/compiler/vir.c
src/compiler/nir/nir.h
src/compiler/nir/nir_lower_system_values.c
src/freedreno/vulkan/tu_shader.c
src/gallium/auxiliary/nir/tgsi_to_nir.c
src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
src/gallium/frontends/clover/nir/invocation.cpp
src/gallium/frontends/vallium/val_pipeline.c
src/intel/compiler/brw_nir.c
src/mesa/state_tracker/st_glsl_to_nir.cpp
src/mesa/state_tracker/st_nir_builtins.c
src/mesa/state_tracker/st_program.c

index 03cfe993bebc83776e1e881c1ffd7e42099e0d44..01a22b7a7579319b5673a38617f9d750b25e87b9 100644 (file)
@@ -540,6 +540,8 @@ radv_shader_compile_to_nir(struct radv_device *device,
                NIR_PASS_V(nir, nir_propagate_invariant);
 
                NIR_PASS_V(nir, nir_lower_system_values);
+               NIR_PASS_V(nir, nir_lower_compute_system_values);
+
                NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
 
                if (device->instance->debug_flags & RADV_DEBUG_DISCARD_TO_DEMOTE)
index d06f789161fab09e4589e14889d24c16702b86c5..83eb4d14b384dd131383ff52775a543b48145cb1 100644 (file)
@@ -586,6 +586,7 @@ v3d_lower_nir(struct v3d_compile *c)
 
         NIR_PASS_V(c->s, nir_lower_tex, &tex_options);
         NIR_PASS_V(c->s, nir_lower_system_values);
+        NIR_PASS_V(c->s, nir_lower_compute_system_values);
 
         NIR_PASS_V(c->s, nir_lower_vars_to_scratch,
                    nir_var_function_temp,
index bb43ab18a9de157e7c18597ba6e69a2413124931..7432afd8d94051260a8d2eb78080bb3264ae01c9 100644 (file)
@@ -4276,6 +4276,8 @@ bool nir_lower_subgroups(nir_shader *shader,
 
 bool nir_lower_system_values(nir_shader *shader);
 
+bool nir_lower_compute_system_values(nir_shader *shader);
+
 enum PACKED nir_lower_tex_packing {
    nir_lower_tex_packing_none = 0,
    /* The sampler returns up to 2 32-bit words of half floats or 16-bit signed
index bc6a39317674083ee91540ec8f967373a73bb528..bc80d184f721348e85dbaf3c01b02ec060011656 100644 (file)
@@ -92,6 +92,150 @@ lower_system_value_instr(nir_builder *b, nir_instr *instr, void *_state)
          return NULL;
       }
 
+   case nir_intrinsic_load_helper_invocation:
+      if (b->shader->options->lower_helper_invocation) {
+         nir_ssa_def *tmp;
+         tmp = nir_ishl(b, nir_imm_int(b, 1),
+                           nir_load_sample_id_no_per_sample(b));
+         tmp = nir_iand(b, nir_load_sample_mask_in(b), tmp);
+         return nir_inot(b, nir_i2b(b, tmp));
+      } else {
+         return NULL;
+      }
+
+   case nir_intrinsic_load_local_invocation_id:
+   case nir_intrinsic_load_local_invocation_index:
+   case nir_intrinsic_load_local_group_size:
+      return sanitize_32bit_sysval(b, intrin);
+
+   case nir_intrinsic_load_deref: {
+      nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
+      if (deref->mode != nir_var_system_value)
+         return NULL;
+
+      if (deref->deref_type != nir_deref_type_var) {
+         /* The only one system value that is an array and that is
+          * gl_SampleMask which is always an array of one element.
+          */
+         assert(deref->deref_type == nir_deref_type_array);
+         deref = nir_deref_instr_parent(deref);
+         assert(deref->deref_type == nir_deref_type_var);
+         assert(deref->var->data.location == SYSTEM_VALUE_SAMPLE_MASK_IN);
+      }
+      nir_variable *var = deref->var;
+
+      switch (var->data.location) {
+      case SYSTEM_VALUE_INSTANCE_INDEX:
+         return nir_iadd(b, nir_load_instance_id(b),
+                            nir_load_base_instance(b));
+
+      case SYSTEM_VALUE_SUBGROUP_EQ_MASK:
+      case SYSTEM_VALUE_SUBGROUP_GE_MASK:
+      case SYSTEM_VALUE_SUBGROUP_GT_MASK:
+      case SYSTEM_VALUE_SUBGROUP_LE_MASK:
+      case SYSTEM_VALUE_SUBGROUP_LT_MASK: {
+         nir_intrinsic_op op =
+            nir_intrinsic_from_system_value(var->data.location);
+         nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, op);
+         nir_ssa_dest_init_for_type(&load->instr, &load->dest,
+                                    var->type, NULL);
+         load->num_components = load->dest.ssa.num_components;
+         nir_builder_instr_insert(b, &load->instr);
+         return &load->dest.ssa;
+      }
+
+      case SYSTEM_VALUE_DEVICE_INDEX:
+         if (b->shader->options->lower_device_index_to_zero)
+            return nir_imm_int(b, 0);
+         break;
+
+      case SYSTEM_VALUE_GLOBAL_GROUP_SIZE:
+         return build_global_group_size(b, bit_size);
+
+      case SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_pixel,
+                                     INTERP_MODE_NOPERSPECTIVE);
+
+      case SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_centroid,
+                                     INTERP_MODE_NOPERSPECTIVE);
+
+      case SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_sample,
+                                     INTERP_MODE_NOPERSPECTIVE);
+
+      case SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_pixel,
+                                     INTERP_MODE_SMOOTH);
+
+      case SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_centroid,
+                                     INTERP_MODE_SMOOTH);
+
+      case SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_sample,
+                                     INTERP_MODE_SMOOTH);
+
+      case SYSTEM_VALUE_BARYCENTRIC_PULL_MODEL:
+         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_model,
+                                     INTERP_MODE_NONE);
+
+      default:
+         break;
+      }
+
+      nir_intrinsic_op sysval_op =
+         nir_intrinsic_from_system_value(var->data.location);
+      return nir_load_system_value(b, sysval_op, 0,
+                                      intrin->dest.ssa.num_components,
+                                      intrin->dest.ssa.bit_size);
+   }
+
+   default:
+      return NULL;
+   }
+}
+
+bool
+nir_lower_system_values(nir_shader *shader)
+{
+   bool progress = nir_shader_lower_instructions(shader,
+                                                 lower_system_value_filter,
+                                                 lower_system_value_instr,
+                                                 NULL);
+
+   /* We're going to delete the variables so we need to clean up all those
+    * derefs we left lying around.
+    */
+   if (progress)
+      nir_remove_dead_derefs(shader);
+
+   nir_foreach_variable_with_modes_safe(var, shader, nir_var_system_value)
+      exec_node_remove(&var->node);
+
+   return progress;
+}
+
+static bool
+lower_compute_system_value_filter(const nir_instr *instr, const void *_options)
+{
+   return instr->type == nir_instr_type_intrinsic;
+}
+
+static nir_ssa_def *
+lower_compute_system_value_instr(nir_builder *b,
+                                 nir_instr *instr, void *_options)
+{
+   nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+
+   /* All the intrinsics we care about are loads */
+   if (!nir_intrinsic_infos[intrin->intrinsic].has_dest)
+      return NULL;
+
+   assert(intrin->dest.is_ssa);
+   const unsigned bit_size = intrin->dest.ssa.bit_size;
+
+   switch (intrin->intrinsic) {
    case nir_intrinsic_load_local_invocation_id:
       /* If lower_cs_local_id_from_index is true, then we derive the local
        * index from the local id.
@@ -215,121 +359,20 @@ lower_system_value_instr(nir_builder *b, nir_instr *instr, void *_state)
       return index;
    }
 
-   case nir_intrinsic_load_helper_invocation:
-      if (b->shader->options->lower_helper_invocation) {
-         nir_ssa_def *tmp;
-         tmp = nir_ishl(b, nir_imm_int(b, 1),
-                           nir_load_sample_id_no_per_sample(b));
-         tmp = nir_iand(b, nir_load_sample_mask_in(b), tmp);
-         return nir_inot(b, nir_i2b(b, tmp));
-      } else {
-         return NULL;
-      }
-
-   case nir_intrinsic_load_deref: {
-      nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
-      if (deref->mode != nir_var_system_value)
-         return NULL;
-
-      if (deref->deref_type != nir_deref_type_var) {
-         /* The only one system value that is an array and that is
-          * gl_SampleMask which is always an array of one element.
-          */
-         assert(deref->deref_type == nir_deref_type_array);
-         deref = nir_deref_instr_parent(deref);
-         assert(deref->deref_type == nir_deref_type_var);
-         assert(deref->var->data.location == SYSTEM_VALUE_SAMPLE_MASK_IN);
-      }
-      nir_variable *var = deref->var;
-
-      switch (var->data.location) {
-      case SYSTEM_VALUE_INSTANCE_INDEX:
-         return nir_iadd(b, nir_load_instance_id(b),
-                            nir_load_base_instance(b));
-
-      case SYSTEM_VALUE_SUBGROUP_EQ_MASK:
-      case SYSTEM_VALUE_SUBGROUP_GE_MASK:
-      case SYSTEM_VALUE_SUBGROUP_GT_MASK:
-      case SYSTEM_VALUE_SUBGROUP_LE_MASK:
-      case SYSTEM_VALUE_SUBGROUP_LT_MASK: {
-         nir_intrinsic_op op =
-            nir_intrinsic_from_system_value(var->data.location);
-         nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, op);
-         nir_ssa_dest_init_for_type(&load->instr, &load->dest,
-                                    var->type, NULL);
-         load->num_components = load->dest.ssa.num_components;
-         nir_builder_instr_insert(b, &load->instr);
-         return &load->dest.ssa;
-      }
-
-      case SYSTEM_VALUE_DEVICE_INDEX:
-         if (b->shader->options->lower_device_index_to_zero)
-            return nir_imm_int(b, 0);
-         break;
-
-      case SYSTEM_VALUE_GLOBAL_GROUP_SIZE:
-         return build_global_group_size(b, bit_size);
-
-      case SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_pixel,
-                                     INTERP_MODE_NOPERSPECTIVE);
-
-      case SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_centroid,
-                                     INTERP_MODE_NOPERSPECTIVE);
-
-      case SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_sample,
-                                     INTERP_MODE_NOPERSPECTIVE);
-
-      case SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_pixel,
-                                     INTERP_MODE_SMOOTH);
-
-      case SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_centroid,
-                                     INTERP_MODE_SMOOTH);
-
-      case SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_sample,
-                                     INTERP_MODE_SMOOTH);
-
-      case SYSTEM_VALUE_BARYCENTRIC_PULL_MODEL:
-         return nir_load_barycentric(b, nir_intrinsic_load_barycentric_model,
-                                     INTERP_MODE_NONE);
-
-      default:
-         break;
-      }
-
-      nir_intrinsic_op sysval_op =
-         nir_intrinsic_from_system_value(var->data.location);
-      return nir_load_system_value(b, sysval_op, 0,
-                                      intrin->dest.ssa.num_components,
-                                      intrin->dest.ssa.bit_size);
-   }
-
    default:
       return NULL;
    }
 }
 
 bool
-nir_lower_system_values(nir_shader *shader)
+nir_lower_compute_system_values(nir_shader *shader)
 {
-   bool progress = nir_shader_lower_instructions(shader,
-                                                 lower_system_value_filter,
-                                                 lower_system_value_instr,
-                                                 NULL);
-
-   /* We're going to delete the variables so we need to clean up all those
-    * derefs we left lying around.
-    */
-   if (progress)
-      nir_remove_dead_derefs(shader);
-
-   nir_foreach_variable_with_modes_safe(var, shader, nir_var_system_value)
-      exec_node_remove(&var->node);
-
-   return progress;
+   if (shader->info.stage != MESA_SHADER_COMPUTE &&
+       shader->info.stage != MESA_SHADER_KERNEL)
+      return false;
+
+   return nir_shader_lower_instructions(shader,
+                                        lower_compute_system_value_filter,
+                                        lower_compute_system_value_instr,
+                                        NULL);
 }
index ec8e2661e8a6772037aceea26dbfb4694e833bac..aca5ea02f71dfb1e9963d8425c7b73470a114fad 100644 (file)
@@ -765,6 +765,8 @@ tu_shader_create(struct tu_device *dev,
    nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs, stage);
 
    NIR_PASS_V(nir, nir_lower_system_values);
+   NIR_PASS_V(nir, nir_lower_compute_system_values);
+
    NIR_PASS_V(nir, nir_lower_frexp);
 
    if (stage == MESA_SHADER_FRAGMENT) {
index 3035f5460a578bcc2b970243dd3d19ef6bdb92c8..7b1b055af370799fd3c2b691d3d0b918b48e9c2b 100644 (file)
@@ -2559,6 +2559,7 @@ ttn_finalize_nir(struct ttn_compile *c, struct pipe_screen *screen)
    NIR_PASS_V(nir, nir_split_var_copies);
    NIR_PASS_V(nir, nir_lower_var_copies);
    NIR_PASS_V(nir, nir_lower_system_values);
+   NIR_PASS_V(nir, nir_lower_compute_system_values);
 
    if (c->cap_packed_uniforms)
       NIR_PASS_V(nir, nir_lower_uniforms_to_ubo, 16);
index 5dad4da11d21cc6817cd05e165e83d06cb3e5540..54227e4886d792f85ef92d25b5c3ad99ed924d60 100644 (file)
@@ -185,6 +185,8 @@ load_glsl(unsigned num_files, char* const* files, gl_shader_stage stage)
                        ir3_glsl_type_size);
 
        NIR_PASS_V(nir, nir_lower_system_values);
+       NIR_PASS_V(nir, nir_lower_compute_system_values);
+
        NIR_PASS_V(nir, nir_lower_frexp);
        NIR_PASS_V(nir, nir_lower_io,
                   nir_var_shader_in | nir_var_shader_out | nir_var_uniform,
@@ -401,6 +403,7 @@ main(int argc, char **argv)
                /* TODO do this somewhere else */
                nir_lower_int64(nir);
                nir_lower_system_values(nir);
+               nir_lower_compute_system_values(nir);
        } else if (num_files > 0) {
                nir = load_glsl(num_files, filenames, stage);
        } else {
index 032fb03cfd8bf84e4468cd255f9783d2f52f1652..f57472052222bed771774668b5833b31ac7ebf1f 100644 (file)
@@ -169,6 +169,8 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev,
                  spirv_options.global_addr_format);
 
       NIR_PASS_V(nir, nir_lower_system_values);
+      NIR_PASS_V(nir, nir_lower_compute_system_values);
+
       if (compiler_options->lower_int64_options)
          NIR_PASS_V(nir, nir_lower_int64);
 
index 136ac93fbc3b720aae4092ef472b50ccfba567de..779e2ecdc5f2f6cfea93a5daea135bc249600e26 100644 (file)
@@ -562,6 +562,7 @@ val_shader_compile_to_ir(struct val_pipeline *pipeline,
    if (stage == MESA_SHADER_FRAGMENT)
       val_lower_input_attachments(nir, false);
    NIR_PASS_V(nir, nir_lower_system_values);
+   NIR_PASS_V(nir, nir_lower_compute_system_values);
 
    NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
    nir_remove_dead_variables(nir, nir_var_uniform, NULL);
index 567bb42c805c7d29b9b6fb7165c30e871a021073..024cea7df5bfd0f1c6da35304f46e00db46ddcf7 100644 (file)
@@ -709,6 +709,7 @@ brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir,
    }
 
    OPT(nir_lower_system_values);
+   OPT(nir_lower_compute_system_values);
 
    const nir_lower_subgroups_options subgroups_options = {
       .ballot_bit_size = 32,
index 99bbbef79db16f969cc4953cf6cef328fa3fa2fb..b5b85ae46c05c9eb3325f3522a8f3bfcd7300960 100644 (file)
@@ -771,6 +771,8 @@ st_link_nir(struct gl_context *ctx,
                  st->pipe->screen);
 
       NIR_PASS_V(nir, nir_lower_system_values);
+      NIR_PASS_V(nir, nir_lower_compute_system_values);
+
       NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
 
       st_shader_gather_info(nir, shader->Program);
index 77ec8725ff7b28b1dc9712f37ddb3406164c1fa7..cd078f3a5617d56055cd1416d8ce0b6906a2cb8a 100644 (file)
@@ -43,6 +43,7 @@ st_nir_finish_builtin_shader(struct st_context *st,
    NIR_PASS_V(nir, nir_split_var_copies);
    NIR_PASS_V(nir, nir_lower_var_copies);
    NIR_PASS_V(nir, nir_lower_system_values);
+   NIR_PASS_V(nir, nir_lower_compute_system_values);
 
    if (nir->options->lower_to_scalar) {
       nir_variable_mode mask =
index 7e7373dc85e91b5950153df40ab4ebcf08d6bc90..7ba6344051c0edb3819baa962effc6dd2b5045ef 100644 (file)
@@ -388,6 +388,7 @@ st_translate_prog_to_nir(struct st_context *st, struct gl_program *prog,
 
    NIR_PASS_V(nir, st_nir_lower_wpos_ytransform, prog, screen);
    NIR_PASS_V(nir, nir_lower_system_values);
+   NIR_PASS_V(nir, nir_lower_compute_system_values);
 
    /* Optimise NIR */
    NIR_PASS_V(nir, nir_opt_constant_folding);