Mesa (main): radv: determine the VS output parameters in the shader info pass

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 1 17:36:04 UTC 2021


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Thu Sep 30 11:10:08 2021 +0200

radv: determine the VS output parameters in the shader info pass

This can be determined earlier instead of duplicating code in both
compiler backends.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13119>

---

 .../compiler/aco_instruction_selection_setup.cpp   | 41 -----------
 src/amd/vulkan/radv_nir_to_llvm.c                  | 21 ------
 src/amd/vulkan/radv_shader_info.c                  | 81 ++++++++++++++++++++--
 3 files changed, 74 insertions(+), 69 deletions(-)

diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp
index a2166e5866d..e8bae91ce18 100644
--- a/src/amd/compiler/aco_instruction_selection_setup.cpp
+++ b/src/amd/compiler/aco_instruction_selection_setup.cpp
@@ -278,53 +278,12 @@ void
 setup_vs_output_info(isel_context* ctx, nir_shader* nir, bool export_prim_id,
                      bool export_clip_dists, radv_vs_output_info* outinfo)
 {
-   memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
-          sizeof(outinfo->vs_output_param_offset));
-
-   outinfo->param_exports = 0;
-   int pos_written = 0x1;
-   bool writes_primitive_shading_rate =
-      outinfo->writes_primitive_shading_rate || ctx->options->force_vrs_rates;
-   if (outinfo->writes_pointsize || outinfo->writes_viewport_index || outinfo->writes_layer ||
-       writes_primitive_shading_rate)
-      pos_written |= 1 << 1;
-
-   uint64_t mask = nir->info.outputs_written;
-   while (mask) {
-      int idx = u_bit_scan64(&mask);
-      if (idx >= VARYING_SLOT_VAR0 || idx == VARYING_SLOT_LAYER ||
-          idx == VARYING_SLOT_PRIMITIVE_ID || idx == VARYING_SLOT_VIEWPORT ||
-          ((idx == VARYING_SLOT_CLIP_DIST0 || idx == VARYING_SLOT_CLIP_DIST1) &&
-           export_clip_dists)) {
-         if (outinfo->vs_output_param_offset[idx] == AC_EXP_PARAM_UNDEFINED)
-            outinfo->vs_output_param_offset[idx] = outinfo->param_exports++;
-      }
-   }
-   if (outinfo->writes_layer &&
-       outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] == AC_EXP_PARAM_UNDEFINED) {
-      /* when ctx->options->key.has_multiview_view_index = true, the layer
-       * variable isn't declared in NIR and it's isel's job to get the layer */
-      outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = outinfo->param_exports++;
-   }
-
-   if (export_prim_id) {
-      assert(outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] == AC_EXP_PARAM_UNDEFINED);
-      outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = outinfo->param_exports++;
-   }
-
    ctx->export_clip_dists = export_clip_dists;
    ctx->num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
    ctx->num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
 
    assert(ctx->num_clip_distances + ctx->num_cull_distances <= 8);
 
-   if (ctx->num_clip_distances + ctx->num_cull_distances > 0)
-      pos_written |= 1 << 2;
-   if (ctx->num_clip_distances + ctx->num_cull_distances > 4)
-      pos_written |= 1 << 3;
-
-   outinfo->pos_exports = util_bitcount(pos_written);
-
    /* GFX10+ early rasterization:
     * When there are no param exports in an NGG (or legacy VS) shader,
     * RADV sets NO_PC_EXPORT=1, which means the HW will start clipping and rasterization
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index 2f38ddfe5f0..2bc408c6cc9 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -1197,12 +1197,7 @@ radv_build_param_exports(struct radv_shader_context *ctx, struct radv_shader_out
          continue;
 
       radv_export_param(ctx, param_count, outputs[i].values, usage_mask);
-
-      assert(i < ARRAY_SIZE(outinfo->vs_output_param_offset));
-      outinfo->vs_output_param_offset[slot_name] = param_count++;
    }
-
-   outinfo->param_exports = param_count;
 }
 
 /* Generate export instructions for hardware VS shader stage or NGG GS stage
@@ -1325,11 +1320,6 @@ radv_llvm_export_vs(struct radv_shader_context *ctx, struct radv_shader_output_v
       }
    }
 
-   for (i = 0; i < 4; i++) {
-      if (pos_args[i].out[0])
-         outinfo->pos_exports++;
-   }
-
    /* GFX10 skip POS0 exports if EXEC=0 and DONE=0, causing a hang.
     * Setting valid_mask=1 prevents it and has no other effect.
     */
@@ -1375,10 +1365,6 @@ handle_vs_outputs_post(struct radv_shader_context *ctx, bool export_prim_id, boo
       ctx->output_mask |= 1ull << VARYING_SLOT_LAYER;
    }
 
-   memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
-          sizeof(outinfo->vs_output_param_offset));
-   outinfo->pos_exports = 0;
-
    if (ctx->args->shader_info->so.num_outputs && !ctx->args->is_gs_copy_shader) {
       /* The GS copy shader emission already emits streamout. */
       radv_emit_streamout(ctx, 0);
@@ -1695,9 +1681,6 @@ handle_ngg_outputs_post_2(struct radv_shader_context *ctx)
             values[j] = ctx->ac.f32_0;
 
          radv_export_param(ctx, param_count, values, 0x1);
-
-         outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++;
-         outinfo->param_exports = param_count;
       }
    }
    ac_build_endif(&ctx->ac, 6002);
@@ -1957,10 +1940,6 @@ gfx10_ngg_gs_emit_epilogue_2(struct radv_shader_context *ctx)
       unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_view_index;
       outputs = calloc(num_outputs, sizeof(outputs[0]));
 
-      memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
-             sizeof(outinfo->vs_output_param_offset));
-      outinfo->pos_exports = 0;
-
       tmp = ngg_gs_vertex_ptr(ctx, tid);
       tmp = LLVMBuildLoad(builder, ngg_gs_get_emit_primflag_ptr(ctx, tmp, 1), "");
       tmp = LLVMBuildZExt(builder, tmp, ctx->ac.i32, "");
diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c
index ec3822c3b8a..dd80b740470 100644
--- a/src/amd/vulkan/radv_shader_info.c
+++ b/src/amd/vulkan/radv_shader_info.c
@@ -25,6 +25,8 @@
 #include "radv_private.h"
 #include "radv_shader.h"
 
+#include "ac_exp_param.h"
+
 static void
 mark_sampler_desc(const nir_variable *var, struct radv_shader_info *info)
 {
@@ -459,30 +461,47 @@ gather_info_output_decl_gs(const nir_shader *nir, const nir_variable *var,
    info->gs.output_streams[idx] = stream;
 }
 
+static struct radv_vs_output_info *
+get_vs_output_info(const nir_shader *nir, struct radv_shader_info *info)
+{
+
+   switch (nir->info.stage) {
+   case MESA_SHADER_VERTEX:
+      if (!info->vs.as_ls && !info->vs.as_es)
+         return &info->vs.outinfo;
+      break;
+   case MESA_SHADER_GEOMETRY:
+      return &info->vs.outinfo;
+      break;
+   case MESA_SHADER_TESS_EVAL:
+      if (!info->tes.as_es)
+         return &info->tes.outinfo;
+      break;
+   default:
+      break;
+   }
+
+   return NULL;
+}
+
 static void
 gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
                         struct radv_shader_info *info)
 {
-   struct radv_vs_output_info *vs_info = NULL;
+   struct radv_vs_output_info *vs_info = get_vs_output_info(nir, info);
 
    switch (nir->info.stage) {
    case MESA_SHADER_FRAGMENT:
       gather_info_output_decl_ps(nir, var, info);
       break;
    case MESA_SHADER_VERTEX:
-      if (!info->vs.as_ls && !info->vs.as_es)
-         vs_info = &info->vs.outinfo;
-
       if (!info->vs.as_ls && info->is_ngg)
          gather_info_output_decl_gs(nir, var, info);
       break;
    case MESA_SHADER_GEOMETRY:
-      vs_info = &info->vs.outinfo;
       gather_info_output_decl_gs(nir, var, info);
       break;
    case MESA_SHADER_TESS_EVAL:
-      if (!info->tes.as_es)
-         vs_info = &info->tes.outinfo;
       break;
    default:
       break;
@@ -603,6 +622,54 @@ radv_nir_shader_info_pass(struct radv_device *device, const struct nir_shader *n
       }
    }
 
+   struct radv_vs_output_info *outinfo = get_vs_output_info(nir, info);
+   if (outinfo) {
+      bool writes_primitive_shading_rate =
+         outinfo->writes_primitive_shading_rate || device->force_vrs != RADV_FORCE_VRS_NONE;
+      int pos_written = 0x1;
+
+      if (outinfo->writes_pointsize || outinfo->writes_viewport_index || outinfo->writes_layer ||
+          writes_primitive_shading_rate)
+         pos_written |= 1 << 1;
+
+      unsigned num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
+      unsigned num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
+
+      if (num_clip_distances + num_cull_distances > 0)
+         pos_written |= 1 << 2;
+      if (num_clip_distances + num_cull_distances > 4)
+         pos_written |= 1 << 3;
+
+      outinfo->pos_exports = util_bitcount(pos_written);
+
+      memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
+             sizeof(outinfo->vs_output_param_offset));
+      outinfo->param_exports = 0;
+
+      uint64_t mask = nir->info.outputs_written;
+      while (mask) {
+         int idx = u_bit_scan64(&mask);
+         if (idx >= VARYING_SLOT_VAR0 || idx == VARYING_SLOT_LAYER ||
+             idx == VARYING_SLOT_PRIMITIVE_ID || idx == VARYING_SLOT_VIEWPORT ||
+             ((idx == VARYING_SLOT_CLIP_DIST0 || idx == VARYING_SLOT_CLIP_DIST1) &&
+              outinfo->export_clip_dists)) {
+            if (outinfo->vs_output_param_offset[idx] == AC_EXP_PARAM_UNDEFINED)
+               outinfo->vs_output_param_offset[idx] = outinfo->param_exports++;
+         }
+      }
+      if (outinfo->writes_layer &&
+          outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] == AC_EXP_PARAM_UNDEFINED) {
+         /* when ctx->options->key.has_multiview_view_index = true, the layer
+          * variable isn't declared in NIR and it's isel's job to get the layer */
+         outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = outinfo->param_exports++;
+      }
+
+      if (outinfo->export_prim_id) {
+         assert(outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] == AC_EXP_PARAM_UNDEFINED);
+         outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = outinfo->param_exports++;
+      }
+   }
+
    if (nir->info.stage == MESA_SHADER_FRAGMENT)
       info->ps.num_interp = nir->num_inputs;
 



More information about the mesa-commit mailing list