From d998456d21d5d327b63aa9e9d7c16538c1f7fb05 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 29 Apr 2026 14:46:20 -0400 Subject: [PATCH] llvmpipe: fix min_samples + A2C running a2c in its usual loop fails to update the mask for the current sample, which breaks successive operations BUT ONLY WHEN RUNNING PER-SAMPLE cc: mesa-stable Part-of: --- src/gallium/drivers/llvmpipe/lp_state_fs.c | 45 ++++++++++++++++++- .../frontends/lavapipe/ci/lvp-asan-fails.txt | 1 - .../frontends/lavapipe/ci/lvp-fails.txt | 16 ------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index eb8b02ef9d1..b7f85b49750 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -473,6 +473,39 @@ lp_build_sample_alpha_to_coverage(struct gallivm_state *gallivm, } }; +static void +lp_build_sample_alpha_to_coverage_per_sample(struct gallivm_state *gallivm, + struct lp_type type, + struct lp_build_mask_context *mask, + unsigned coverage_samples, + LLVMValueRef num_loop, + LLVMValueRef loop_counter, + LLVMValueRef sample_loop_counter, + LLVMTypeRef coverage_mask_type, + LLVMValueRef coverage_mask_store, + LLVMValueRef alpha) +{ + struct lp_build_context bld; + LLVMBuilderRef builder = gallivm->builder; + float step = 1.0 / coverage_samples; + + lp_build_context_init(&bld, gallivm, type); + LLVMValueRef alpha_ref_value = LLVMBuildFMul(builder, + lp_build_const_float(gallivm, step), + LLVMBuildBitCast(builder, sample_loop_counter, bld.elem_type, ""), + ""); + LLVMValueRef test = lp_build_cmp(&bld, PIPE_FUNC_GREATER, + alpha, lp_build_broadcast_scalar(&bld, alpha_ref_value)); + LLVMValueRef s_mask_idx = LLVMBuildMul(builder, sample_loop_counter, num_loop, ""); + s_mask_idx = LLVMBuildAdd(builder, s_mask_idx, loop_counter, ""); + LLVMValueRef s_mask_ptr = LLVMBuildGEP2(builder, coverage_mask_type, + coverage_mask_store, &s_mask_idx, 1, ""); + LLVMValueRef s_mask = LLVMBuildLoad2(builder, coverage_mask_type, s_mask_ptr, ""); + s_mask = LLVMBuildAnd(builder, s_mask, test, ""); + LLVMBuildStore(builder, s_mask, s_mask_ptr); + lp_build_mask_update(mask, s_mask); +}; + struct lp_build_fs_llvm_iface { struct lp_build_fs_iface base; @@ -1165,8 +1198,18 @@ generate_fs_loop(struct gallivm_state *gallivm, &mask, alpha, key->blend.alpha_to_coverage_dither, (depth_mode & LATE_DEPTH_TEST) != 0); + } else if (key->coverage_samples == key->min_samples) { + /* when running at sample rate, directly update the current sample's mask to avoid mask desync + * PS. I have no idea why this works + */ + lp_build_sample_alpha_to_coverage_per_sample(gallivm, type, &mask, + key->coverage_samples, num_loop, + loop_state.counter, + sample_loop_state.counter, + mask_type, mask_store, alpha); } else { - lp_build_sample_alpha_to_coverage(gallivm, type, key->coverage_samples, num_loop, + lp_build_sample_alpha_to_coverage(gallivm, type, + key->coverage_samples, num_loop, loop_state.counter, mask_type, mask_store, alpha); } diff --git a/src/gallium/frontends/lavapipe/ci/lvp-asan-fails.txt b/src/gallium/frontends/lavapipe/ci/lvp-asan-fails.txt index 1bb54611051..918350129cf 100644 --- a/src/gallium/frontends/lavapipe/ci/lvp-asan-fails.txt +++ b/src/gallium/frontends/lavapipe/ci/lvp-asan-fails.txt @@ -42,7 +42,6 @@ dEQP-VK.shader_object.misc.state.pipeline.vert_tess_geom_frag.rasterization_disc # New failures with VKCTS 1.4.4.0 dEQP-VK.pipeline.monolithic.extended_dynamic_state.cmd_buffer_start.large_stride_with_offset_and_padding,Fail dEQP-VK.pipeline.pipeline_library.extended_dynamic_state.before_good_static.tess_domain_origin_upper_left,Fail -dEQP-VK.pipeline.shader_object_linked_binary.multisample.sample_rate_a2c.dynamic_a2c,Fail dEQP-VK.pipeline.shader_object_linked_spirv.bind_buffers_2.maintenance5.robustness2.triangle_list.buffers9.stride_offset_rnd654.true_size.beyond_size,Fail dEQP-VK.pipeline.shader_object_unlinked_spirv.extended_dynamic_state.cmd_buffer_start.stride_with_offset_and_padding,Fail dEQP-VK.shader_object.misc.state.pipeline.vert_tess_frag.color_write.true,Fail diff --git a/src/gallium/frontends/lavapipe/ci/lvp-fails.txt b/src/gallium/frontends/lavapipe/ci/lvp-fails.txt index 7add341ee1d..ebfe8ba2bb2 100644 --- a/src/gallium/frontends/lavapipe/ci/lvp-fails.txt +++ b/src/gallium/frontends/lavapipe/ci/lvp-fails.txt @@ -854,15 +854,6 @@ nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8 nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_unorm.input.load.dont_care.draw,Fail nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.unused_attachment.loadopdontcare.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail -# New fails in 1.4.1.0 -dEQP-VK.pipeline.pipeline_library.multisample.sample_rate_a2c.static_a2c,Fail -dEQP-VK.pipeline.shader_object_linked_spirv.multisample.sample_rate_a2c.static_a2c,Fail - -# New fails in 1.4.1.1 -dEQP-VK.pipeline.fast_linked_library.multisample.sample_rate_a2c.static_a2c,Fail -dEQP-VK.pipeline.shader_object_linked_binary.multisample.sample_rate_a2c.static_a2c,Fail -dEQP-VK.pipeline.shader_object_unlinked_spirv.multisample.sample_rate_a2c.static_a2c,Fail - dEQP-VK.sparse_resources.image_block_shapes.2d.g8b8g8r8_422_unorm.samples_1,Fail dEQP-VK.sparse_resources.image_block_shapes.2d_array.g8b8g8r8_422_unorm.samples_1,Fail @@ -872,18 +863,11 @@ dEQP-VK.mesh_shader.ext.smoke.fast_lib.depth_only_triangles_position_components, dEQP-VK.mesh_shader.ext.smoke.monolithic.depth_only_points_position_components,Fail dEQP-VK.mesh_shader.ext.smoke.optimized_lib.depth_only_points_position_components,Fail dEQP-VK.mesh_shader.ext.smoke.shader_objects.depth_only_triangles_position_components,Fail -dEQP-VK.pipeline.fast_linked_library.multisample.sample_rate_a2c.dynamic_a2c,Fail -dEQP-VK.pipeline.monolithic.multisample.sample_rate_a2c.static_a2c,Fail -dEQP-VK.pipeline.shader_object_linked_spirv.multisample.sample_rate_a2c.dynamic_a2c,Fail -dEQP-VK.pipeline.shader_object_unlinked_binary.multisample.sample_rate_a2c.dynamic_a2c,Fail -dEQP-VK.pipeline.shader_object_unlinked_binary.multisample.sample_rate_a2c.static_a2c,Fail -dEQP-VK.pipeline.shader_object_unlinked_spirv.multisample.sample_rate_a2c.dynamic_a2c,Fail # New failures with VKCTS 1.4.4.0 dEQP-VK.mesh_shader.ext.smoke.optimized_lib.depth_only_triangles_position_components,Fail dEQP-VK.mesh_shader.ext.smoke.monolithic.depth_only_triangles_position_components,Fail dEQP-VK.mesh_shader.ext.smoke.shader_objects.depth_only_points_position_components,Fail -dEQP-VK.pipeline.pipeline_library.multisample.sample_rate_a2c.dynamic_a2c,Fail dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.dont_care.store.self_dep_clear_draw,Fail dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.load.store.self_dep_clear_draw,Fail dEQP-VK.sparse_resources.image_block_shapes.2d.b8g8r8g8_422_unorm.samples_1,Fail