From 41c6148c0d2158ac643164198f32125018aea2b7 Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Fri, 20 Dec 2024 18:46:44 -0800 Subject: [PATCH] panvk: handle sample mask writes on 1-sample targets In OpenGL, non-multisample targets always have full coverage, and shader writes to gl_SampleMask are ignored. On Vulkan, sample mask writes on single-sample targets are treated the same way as writes with >1 sample. Fixes dEQP-VK.pipeline.*.multisample_shader_builtin.write_sample_mask.1_samples Signed-off-by: Benjamin Lee Reviewed-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/panfrost/pan_shader.c | 30 +++++++++++++++++++++++ src/panfrost/ci/panfrost-g52-fails.txt | 6 ----- src/panfrost/ci/panfrost-g610-fails.txt | 5 ---- src/panfrost/compiler/bifrost_compile.c | 4 +-- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_shader.c b/src/gallium/drivers/panfrost/pan_shader.c index 979a693ddc5..d9de7e191e9 100644 --- a/src/gallium/drivers/panfrost/pan_shader.c +++ b/src/gallium/drivers/panfrost/pan_shader.c @@ -80,6 +80,33 @@ lower_load_poly_line_smooth_enabled(nir_builder *b, nir_intrinsic_instr *intrin, return true; } +/* From the OpenGL 4.6 spec 14.3.1: + * + * If MULTISAMPLE is disabled, multisample rasterization of all primitives + * is equivalent to single-sample (fragment-center) rasterization, except + * that the fragment coverage value is set to full coverage. + * + * So always use the original sample mask when multisample is disabled */ +static bool +lower_sample_mask_writes(nir_builder *b, nir_intrinsic_instr *intrin, + void *data) +{ + if (intrin->intrinsic != nir_intrinsic_store_output) + return false; + + if (nir_intrinsic_io_semantics(intrin).location != FRAG_RESULT_SAMPLE_MASK) + return false; + + b->cursor = nir_before_instr(&intrin->instr); + + nir_def *orig = nir_load_sample_mask(b); + nir_def *new = nir_b32csel(b, nir_load_multisampled_pan(b), + intrin->src[0].ssa, orig); + nir_src_rewrite(&intrin->src[0], new); + + return true; +} + static void panfrost_shader_compile(struct panfrost_screen *screen, const nir_shader *ir, struct util_debug_callback *dbg, @@ -148,6 +175,9 @@ panfrost_shader_compile(struct panfrost_screen *screen, const nir_shader *ir, nir_metadata_control_flow, key); NIR_PASS(_, s, nir_lower_alu); } + + NIR_PASS(_, s, nir_shader_intrinsics_pass, + lower_sample_mask_writes, nir_metadata_control_flow, NULL); } if (dev->arch <= 5 && s->info.stage == MESA_SHADER_FRAGMENT) { diff --git a/src/panfrost/ci/panfrost-g52-fails.txt b/src/panfrost/ci/panfrost-g52-fails.txt index 92607dad88c..ce2c08cf6f2 100644 --- a/src/panfrost/ci/panfrost-g52-fails.txt +++ b/src/panfrost/ci/panfrost-g52-fails.txt @@ -2743,12 +2743,6 @@ dEQP-VK.wsi.wayland.swapchain.simulate_oom.min_image_count,Crash dEQP-VK.wsi.wayland.swapchain.simulate_oom.pre_transform,Crash dEQP-VK.wsi.wayland.swapchain.simulate_oom.present_mode,Crash - -# New with sampleRateShading -dEQP-VK.pipeline.monolithic.multisample_shader_builtin.write_sample_mask.1_samples,Fail -dEQP-VK.pipeline.fast_linked_library.multisample_shader_builtin.write_sample_mask.1_samples,Fail -dEQP-VK.pipeline.pipeline_library.multisample_shader_builtin.write_sample_mask.1_samples,Fail - dEQP-VK.dynamic_rendering.primary_cmd_buff.basic.2_cmdbuffers_resuming,Fail dEQP-VK.dynamic_rendering.primary_cmd_buff.basic.2_secondary_2_primary_cmdbuffers_resuming,Fail dEQP-VK.dynamic_rendering.primary_cmd_buff.basic.2_secondary_cmdbuffers_resuming,Fail diff --git a/src/panfrost/ci/panfrost-g610-fails.txt b/src/panfrost/ci/panfrost-g610-fails.txt index f92b25b8cc0..b4cb9e0a993 100644 --- a/src/panfrost/ci/panfrost-g610-fails.txt +++ b/src/panfrost/ci/panfrost-g610-fails.txt @@ -278,12 +278,9 @@ dEQP-VK.glsl.limits.near_max.fragment_input.components_123,Fail dEQP-VK.glsl.limits.near_max.fragment_input.components_124,Fail dEQP-VK.pipeline.monolithic.max_varyings.test_vertex_io_between_vertex_fragment,Fail -dEQP-VK.pipeline.monolithic.multisample_shader_builtin.write_sample_mask.1_samples,Fail dEQP-VK.pipeline.pipeline_library.max_varyings.test_vertex_io_between_vertex_fragment,Fail -dEQP-VK.pipeline.pipeline_library.multisample_shader_builtin.write_sample_mask.1_samples,Fail - dEQP-VK.renderpass.suballocation.attachment_allocation.input_output.63,Fail dEQP-VK.renderpass.multiple_subpasses_multiple_command_buffers.test,Fail dEQP-VK.renderpass2.suballocation.attachment_allocation.input_output.63,Fail @@ -295,8 +292,6 @@ dEQP-VK.spirv_assembly.instruction.graphics.opquantize.too_small_vert,Fail dEQP-VK.pipeline.fast_linked_library.max_varyings.test_vertex_io_between_vertex_fragment,Fail -dEQP-VK.pipeline.fast_linked_library.multisample_shader_builtin.write_sample_mask.1_samples,Fail - dEQP-VK.glsl.loops.special.do_while_dynamic_iterations.dowhile_trap_vertex,Crash dEQP-VK.rasterization.rasterization_order_attachment_access.depth.samples_1.multi_draw_barriers,Crash diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index 589705bcf4a..185a438a0b3 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -5105,9 +5105,7 @@ bi_lower_sample_mask_writes(nir_builder *b, nir_intrinsic_instr *intr, nir_def *orig = nir_load_sample_mask(b); - nir_src_rewrite(&intr->src[0], - nir_b32csel(b, nir_load_multisampled_pan(b), - nir_iand(b, orig, intr->src[0].ssa), orig)); + nir_src_rewrite(&intr->src[0], nir_iand(b, orig, intr->src[0].ssa)); return true; }