Mesa (main): zink: update psiz handling to fix xfb output

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Feb 28 16:08:50 UTC 2022


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Feb  3 10:22:34 2022 -0500

zink: update psiz handling to fix xfb output

now when gl_PointSize and gl_PointSizeMESA are both present, the former
will be used for xfb with a new location and the latter will be
exported by the shader

fixes (zink):
GTF-GL46.gtf30.GL3Tests.transform_feedback.transform_feedback_builtins

Acked-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15184>

---

 .../drivers/zink/nir_to_spirv/nir_to_spirv.c       |  8 +--
 src/gallium/drivers/zink/zink_compiler.c           | 59 +++++++++++++++++++---
 2 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
index 4026aa7f414..4f5929acf27 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
@@ -601,11 +601,13 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var)
       HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
 
       default:
-         spirv_builder_emit_location(&ctx->builder, var_id,
-                                     var->data.driver_location);
+         /* non-xfb psiz output will have location -1 */
+         if (var->data.location >= 0)
+            spirv_builder_emit_location(&ctx->builder, var_id,
+                                        var->data.driver_location);
       }
       /* tcs can't do xfb */
-      if (ctx->stage != MESA_SHADER_TESS_CTRL) {
+      if (ctx->stage != MESA_SHADER_TESS_CTRL && var->data.location >= 0) {
          unsigned idx = var->data.location << 2 | var->data.location_frac;
          ctx->outputs[idx] = var_id;
          ctx->so_output_gl_types[idx] = var->type;
diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c
index 18266e1a81c..e122398982d 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -460,23 +460,26 @@ lower_fbfetch(nir_shader *shader, nir_variable **fbfetch)
 static bool
 check_psiz(struct nir_shader *s)
 {
+   bool have_psiz = false;
    nir_foreach_shader_out_variable(var, s) {
       if (var->data.location == VARYING_SLOT_PSIZ) {
          /* genuine PSIZ outputs will have this set */
-         return !!var->data.explicit_location;
+         have_psiz |= !!var->data.explicit_location;
       }
    }
-   return false;
+   return have_psiz;
 }
 
 static nir_variable *
-find_var_with_location_frac(nir_shader *nir, unsigned location, unsigned location_frac)
+find_var_with_location_frac(nir_shader *nir, unsigned location, unsigned location_frac, bool have_psiz)
 {
    nir_foreach_shader_out_variable(var, nir) {
       if (var->data.location == location &&
           (var->data.location_frac == location_frac ||
-           glsl_get_vector_elements(var->type) >= location_frac + 1))
-         return var;
+           glsl_get_vector_elements(var->type) >= location_frac + 1)) {
+         if (location != VARYING_SLOT_PSIZ || !have_psiz || var->data.explicit_location)
+            return var;
+      }
    }
    return NULL;
 }
@@ -490,6 +493,18 @@ is_inlined(const bool *inlined, const struct pipe_stream_output *output)
    return true;
 }
 
+static void
+update_psiz_location(nir_shader *nir, nir_variable *psiz)
+{
+   uint32_t last_output = util_last_bit64(nir->info.outputs_written);
+   if (last_output < VARYING_SLOT_VAR0)
+      last_output = VARYING_SLOT_VAR0;
+   else
+      last_output++;
+   /* this should get fixed up by slot remapping */
+   psiz->data.location = last_output;
+}
+
 static void
 update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_info,
                uint64_t outputs_written, bool have_psiz)
@@ -505,8 +520,12 @@ update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_
       reverse_map[slot++] = bit;
    }
 
-   nir_foreach_shader_out_variable(var, zs->nir)
+   bool have_fake_psiz = false;
+   nir_foreach_shader_out_variable(var, zs->nir) {
       var->data.explicit_xfb_buffer = 0;
+      if (var->data.location == VARYING_SLOT_PSIZ && !var->data.explicit_location)
+         have_fake_psiz = true;
+   }
 
    bool inlined[VARYING_SLOT_MAX][4] = {0};
    uint32_t packed = 0;
@@ -514,6 +533,7 @@ update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_
    uint8_t packed_streams[VARYING_SLOT_MAX] = {0};
    uint8_t packed_buffers[VARYING_SLOT_MAX] = {0};
    uint16_t packed_offsets[VARYING_SLOT_MAX][4] = {0};
+   nir_variable *psiz = NULL;
    for (unsigned i = 0; i < so_info->num_outputs; i++) {
       const struct pipe_stream_output *output = &so_info->output[i];
       unsigned slot = reverse_map[output->register_index];
@@ -522,7 +542,9 @@ update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_
       if (zs->nir->info.stage != MESA_SHADER_GEOMETRY || util_bitcount(zs->nir->info.gs.active_stream_mask) == 1) {
          nir_variable *var = NULL;
          while (!var)
-            var = find_var_with_location_frac(zs->nir, slot--, output->start_component);
+            var = find_var_with_location_frac(zs->nir, slot--, output->start_component, have_psiz);
+         if (var->data.location == VARYING_SLOT_PSIZ)
+            psiz = var;
          slot++;
          if (is_inlined(inlined[slot], output))
             continue;
@@ -556,7 +578,7 @@ update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_
       if (zs->nir->info.stage != MESA_SHADER_GEOMETRY || util_bitcount(zs->nir->info.gs.active_stream_mask) == 1) {
          nir_variable *var = NULL;
          while (!var)
-            var = find_var_with_location_frac(zs->nir, slot--, output->start_component);
+            var = find_var_with_location_frac(zs->nir, slot--, output->start_component, have_psiz);
          slot++;
          /* if this was flagged as a packed output before, and if all the components are
           * being output with the same stream on the same buffer, this entire variable
@@ -594,6 +616,9 @@ update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_
       zs->sinfo.so_info_slots[zs->sinfo.so_info.num_outputs++] = reverse_map[output->register_index];
    }
    zs->sinfo.have_xfb = !!zs->sinfo.so_info.num_outputs;
+   /* ensure this doesn't get output in the shader by unsetting location */
+   if (have_fake_psiz && psiz)
+      update_psiz_location(zs->nir, psiz);
 }
 
 struct decompose_state {
@@ -870,6 +895,7 @@ assign_producer_var_io(gl_shader_stage stage, nir_variable *var, unsigned *reser
 {
    unsigned slot = var->data.location;
    switch (var->data.location) {
+   case -1:
    case VARYING_SLOT_POS:
    case VARYING_SLOT_PNTC:
    case VARYING_SLOT_PSIZ:
@@ -1910,6 +1936,23 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
    ret->nir = nir;
    if (so_info && nir->info.outputs_written && nir->info.has_transform_feedback_varyings)
       update_so_info(ret, so_info, nir->info.outputs_written, have_psiz);
+   else if (have_psiz) {
+      bool have_fake_psiz = false;
+      nir_variable *psiz = NULL;
+      nir_foreach_shader_out_variable(var, nir) {
+         if (var->data.location == VARYING_SLOT_PSIZ) {
+            if (!var->data.explicit_location)
+               have_fake_psiz = true;
+            else
+               psiz = var;
+         }
+      }
+      if (have_fake_psiz && psiz) {
+         psiz->data.mode = nir_var_shader_temp;
+         nir_fixup_deref_modes(nir);
+         NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL);
+      }
+   }
 
    return ret;
 }



More information about the mesa-commit mailing list