Mesa (main): zink: handle multisampled fbfetch

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Apr 8 18:34:32 UTC 2022


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Apr  8 12:07:26 2022 -0400

zink: handle multisampled fbfetch

this uses a shader key to flag the fbfetch as per-sample

it doesn't work, but at least it doesn't error anymore?

Acked-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15823>

---

 src/gallium/drivers/zink/zink_compiler.c    | 22 ++++++++++++++--------
 src/gallium/drivers/zink/zink_context.c     |  4 ++++
 src/gallium/drivers/zink/zink_shader_keys.h |  1 +
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c
index 7cf7f02746b..a445bfdcc09 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -447,16 +447,17 @@ optimize_nir(struct nir_shader *s)
 static bool
 lower_fbfetch_instr(nir_builder *b, nir_instr *instr, void *data)
 {
+   bool ms = data != NULL;
    if (instr->type != nir_instr_type_intrinsic)
       return false;
    nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
    if (intr->intrinsic != nir_intrinsic_load_deref)
       return false;
    nir_variable *var = nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0]));
-   if (var != data)
+   if (!var->data.fb_fetch_output)
       return false;
    b->cursor = nir_after_instr(instr);
-   nir_variable *fbfetch = nir_variable_clone(data, b->shader);
+   nir_variable *fbfetch = nir_variable_clone(var, b->shader);
    /* If Dim is SubpassData, ... Image Format must be Unknown
     * - SPIRV OpTypeImage specification
     */
@@ -464,10 +465,14 @@ lower_fbfetch_instr(nir_builder *b, nir_instr *instr, void *data)
    fbfetch->data.index = 0; /* fix this if more than 1 fbfetch target is supported */
    fbfetch->data.mode = nir_var_uniform;
    fbfetch->data.binding = ZINK_FBFETCH_BINDING;
-   fbfetch->type = glsl_image_type(GLSL_SAMPLER_DIM_SUBPASS, false, GLSL_TYPE_FLOAT);
+   fbfetch->data.binding = ZINK_FBFETCH_BINDING;
+   fbfetch->data.sample = ms;
+   enum glsl_sampler_dim dim = ms ? GLSL_SAMPLER_DIM_SUBPASS_MS : GLSL_SAMPLER_DIM_SUBPASS;
+   fbfetch->type = glsl_image_type(dim, false, GLSL_TYPE_FLOAT);
    nir_shader_add_variable(b->shader, fbfetch);
    nir_ssa_def *deref = &nir_build_deref_var(b, fbfetch)->dest.ssa;
-   nir_ssa_def *load = nir_image_deref_load(b, 4, 32, deref, nir_imm_vec4(b, 0, 0, 0, 1), nir_ssa_undef(b, 1, 32), nir_imm_int(b, 0));
+   nir_ssa_def *sample = ms ? nir_load_sample_id(b) : nir_ssa_undef(b, 1, 32);
+   nir_ssa_def *load = nir_image_deref_load(b, 4, 32, deref, nir_imm_vec4(b, 0, 0, 0, 1), sample, nir_imm_int(b, 0));
    unsigned swiz[4] = {2, 1, 0, 3};
    nir_ssa_def *swizzle = nir_swizzle(b, load, swiz, 4);
    nir_ssa_def_rewrite_uses(&intr->dest.ssa, swizzle);
@@ -475,7 +480,7 @@ lower_fbfetch_instr(nir_builder *b, nir_instr *instr, void *data)
 }
 
 static bool
-lower_fbfetch(nir_shader *shader, nir_variable **fbfetch)
+lower_fbfetch(nir_shader *shader, nir_variable **fbfetch, bool ms)
 {
    nir_foreach_shader_out_variable(var, shader) {
       if (var->data.fb_fetch_output) {
@@ -486,7 +491,7 @@ lower_fbfetch(nir_shader *shader, nir_variable **fbfetch)
    assert(*fbfetch);
    if (!*fbfetch)
       return false;
-   return nir_shader_instructions_pass(shader, lower_fbfetch_instr, nir_metadata_dominance, *fbfetch);
+   return nir_shader_instructions_pass(shader, lower_fbfetch_instr, nir_metadata_dominance, (void*)ms);
 }
 
 /* check for a genuine gl_PointSize output vs one from nir_lower_point_size_mov */
@@ -1350,14 +1355,15 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad
             NIR_PASS_V(nir, nir_lower_texcoord_replace, zink_fs_key(key)->coord_replace_bits,
                      false, zink_fs_key(key)->coord_replace_yinvert);
          }
-         if (zink_fs_key(key)->force_persample_interp) {
+         if (zink_fs_key(key)->force_persample_interp || zink_fs_key(key)->fbfetch_ms) {
             nir_foreach_shader_in_variable(var, nir)
                var->data.sample = true;
             nir->info.fs.uses_sample_qualifier = true;
+            nir->info.fs.uses_sample_shading = true;
          }
          if (nir->info.fs.uses_fbfetch_output) {
             nir_variable *fbfetch = NULL;
-            NIR_PASS_V(nir, lower_fbfetch, &fbfetch);
+            NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key(key)->fbfetch_ms);
             /* old variable must be deleted to avoid spirv errors */
             fbfetch->data.mode = nir_var_shader_temp;
             nir_fixup_deref_modes(nir);
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index da42871119e..36b3a3cf8bf 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -1954,6 +1954,10 @@ zink_update_fbfetch(struct zink_context *ctx)
          return;
       changed |= fbfetch != ctx->di.fbfetch.imageView;
       ctx->di.fbfetch.imageView = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
+
+      bool fbfetch_ms = ctx->fb_state.cbufs[0]->texture->nr_samples > 1;
+      if (zink_get_fs_key(ctx)->fbfetch_ms != fbfetch_ms)
+         zink_set_fs_key(ctx)->fbfetch_ms = fbfetch_ms;
    }
    ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
    if (changed) {
diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h
index 531a729416a..dbd2ce417ef 100644
--- a/src/gallium/drivers/zink/zink_shader_keys.h
+++ b/src/gallium/drivers/zink/zink_shader_keys.h
@@ -61,6 +61,7 @@ struct zink_fs_key {
    bool samples;
    bool force_dual_color_blend;
    bool force_persample_interp;
+   bool fbfetch_ms;
 };
 
 struct zink_tcs_key {



More information about the mesa-commit mailing list