From 538472e27925dd7d88b0511c76bea67b99838837 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 8 Apr 2022 12:07:26 -0400 Subject: [PATCH] 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 Part-of: --- 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 7cf7f02..a445bfd 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 da42871..36b3a3c 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 531a729..dbd2ce4 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 { -- 2.7.4