From 56258f4cfd6acf28e573cd028f4327cd85385aa4 Mon Sep 17 00:00:00 2001 From: "Juan A. Suarez Romero" Date: Thu, 5 Feb 2026 22:27:10 +0100 Subject: [PATCH] v3d,v3dv: emit always set point size On V3D 4.2 (Raspberry Pi 4), there is a hardware bug where the binner can trigger a GPU reset in some situations where primitives are discarded, such as due to primitive restarts. The way to avoid this is to force the binner to do always something, by emitting the proper CL. In this case we decided to always set point size, as it is a very simple and fast operation. This fixes resets caused by dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.*. Reviewed-by: Iago Toral Quiroga Signed-off-by: Juan A. Suarez Romero Part-of: --- src/broadcom/ci/broadcom-rpi4-skips.txt | 15 --------------- src/broadcom/vulkan/v3dv_cmd_buffer.c | 14 ++++++++++++-- src/gallium/drivers/v3d/v3dx_emit.c | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/broadcom/ci/broadcom-rpi4-skips.txt b/src/broadcom/ci/broadcom-rpi4-skips.txt index 45de96e2c6c..e5ec49eb8c0 100644 --- a/src/broadcom/ci/broadcom-rpi4-skips.txt +++ b/src/broadcom/ci/broadcom-rpi4-skips.txt @@ -68,18 +68,3 @@ dEQP-VK.transform_feedback.* # avoid interferences when running with other tests in parallel dEQP-VK.api.device_init.create_instance_device_intentional_alloc_fail.basic dEQP-VK.api.object_management.alloc_callback_fail.* - - -# These tests cause GPU resets -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_triangle_list_dynamic_topo -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_extra_draw_triangle_list -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_extra_draw_triangle_list_large_non_indexed_draw -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_extra_draw_triangle_list_dynamic_topo -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_extra_draw_triangle_list_dynamic_topo_large_non_indexed_draw -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_triangle_list -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_triangle_list_large_non_indexed_draw -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_extra_draw_dynamic_topo -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_extra_draw -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_triangle_list_dynamic_topo_large_non_indexed_draw -dEQP-VK.pipeline.monolithic.input_assembly.primitive_restart.restart_mix.restart_mix_dynamic_topo diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 2b34cd5aaff..17521a02c20 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -3067,8 +3067,18 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer, if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH)) v3d_X((&device->devinfo), cmd_buffer_emit_line_width)(cmd_buffer); - if (dyn->ia.primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && - !job->emitted_default_point_size) { + /* There is a bug in V3D 4.2 hardware where a FIFO in the binner may + * overflow in some scenarios where geometry is dropped in the pipeline + * (for example, if using primitive discards). The work around requires the + * driver to emit any CLE command, which will trigger the binner to flush + * the FIFO. The recommendation is to emit a very small packet that is fast + * to process by the CLE hardware such as PointSize in between all draw + * calls to ensure this flush always happens and there is never a chance of + * overflowing the binner. + */ + if ((dyn->ia.primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && + !job->emitted_default_point_size) || + device->devinfo.ver == 42) { v3d_X((&device->devinfo), cmd_buffer_emit_default_point_size)(cmd_buffer); } diff --git a/src/gallium/drivers/v3d/v3dx_emit.c b/src/gallium/drivers/v3d/v3dx_emit.c index ebb3c8d0ce7..0980707cb77 100644 --- a/src/gallium/drivers/v3d/v3dx_emit.c +++ b/src/gallium/drivers/v3d/v3dx_emit.c @@ -416,11 +416,24 @@ v3dX(emit_state)(struct pipe_context *pctx) } } - if (v3d->dirty & V3D_DIRTY_RASTERIZER) { + /* There is a bug in V3D 4.2 hardware where a FIFO in the binner may + * overflow in some scenarios where geometry is dropped in the + * pipeline (for example, if using primitive discards). The work + * around requires the driver to emit any CLE command, which will + * trigger the binner to flush the FIFO. The recommendation is to emit + * a very small packet that is fast to process by the CLE hardware + * such as PointSize in between all draw calls to ensure this flush + * always happens and there is never a chance of overflowing the + * binner. + */ + if (v3d->dirty & V3D_DIRTY_RASTERIZER || + v3d->screen->devinfo.ver == 42) { cl_emit(&job->bcl, POINT_SIZE, point_size) { point_size.point_size = v3d->rasterizer->point_size; } + } + if (v3d->dirty & V3D_DIRTY_RASTERIZER) { cl_emit(&job->bcl, LINE_WIDTH, line_width) { line_width.line_width = v3d_get_real_line_width(v3d); }