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 <itoral@igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39826>
This commit is contained in:
Juan A. Suarez Romero 2026-02-05 22:27:10 +01:00 committed by Marge Bot
parent 0df50e8ed1
commit 56258f4cfd
3 changed files with 26 additions and 18 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}