From 5ee7d99f6482ca77d017abe59b233613fa65911f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Thu, 12 Feb 2026 11:25:20 +0100 Subject: [PATCH] r300: handle polygon-mode points in point sprite path arb_point_sprite-mipmap renders polygons with polygon mode set to POINT. However, r300 point-sprite setup only treated MESA_PRIM_POINTS as point draws, so sprite coord replacement was disabled for polygon primitives that were rasterized as points. This produced wrong texcoord orientation and failed the piglit test. Detect point rasterization from the primitive plus rasterizer fill/cull state and use that in both HWTCL and SWTCL draw paths when updating is_point flag. The test now pass on RV370 and fails with the rest of the CI HW, but the remaining issues seem to be some LOD boundary mismatch at point size 22, the hardware samples level 0 where test expects level 1. In total only 4 cases now fail instead of 82 before. Part-of: --- src/gallium/drivers/r300/r300_render.c | 49 ++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 1033e4c14ff..d4f0e2b6a4d 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -799,6 +799,39 @@ r300_update_clip_discard_distance(struct r300_context *r300, unsigned prim) } } +static bool +r300_rasterizer_emits_points(struct r300_context *r300, unsigned prim) +{ + struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state; + + if (prim == MESA_PRIM_POINTS) + return true; + + switch (prim) { + case MESA_PRIM_TRIANGLES: + case MESA_PRIM_TRIANGLE_STRIP: + case MESA_PRIM_TRIANGLE_FAN: + case MESA_PRIM_QUADS: + case MESA_PRIM_QUAD_STRIP: + case MESA_PRIM_POLYGON: + break; + default: + return false; + } + + if (!rs) + return false; + + bool front_rasterized = !(rs->rs.cull_face & PIPE_FACE_FRONT); + bool back_rasterized = !(rs->rs.cull_face & PIPE_FACE_BACK); + + if (front_rasterized && rs->rs.fill_front != PIPE_POLYGON_MODE_POINT) + return false; + if (back_rasterized && rs->rs.fill_back != PIPE_POLYGON_MODE_POINT) + return false; + + return front_rasterized || back_rasterized; +} static void r300_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_info *dinfo, @@ -823,11 +856,13 @@ static void r300_draw_vbo(struct pipe_context* pipe, r300_update_clip_discard_distance(r300, info.mode); - if (r300->sprite_coord_enable != 0) - if ((info.mode == MESA_PRIM_POINTS) != r300->is_point) { - r300->is_point = !r300->is_point; + if (r300->sprite_coord_enable != 0) { + bool is_point = r300_rasterizer_emits_points(r300, info.mode); + if (is_point != r300->is_point) { + r300->is_point = is_point; r300_mark_atom_dirty(r300, &r300->rs_block_state); } + } r300_update_derived_state(r300); @@ -910,11 +945,13 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, info->index_size, ~0); } - if (r300->sprite_coord_enable != 0) - if ((info->mode == MESA_PRIM_POINTS) != r300->is_point) { - r300->is_point = !r300->is_point; + if (r300->sprite_coord_enable != 0) { + bool is_point = r300_rasterizer_emits_points(r300, info->mode); + if (is_point != r300->is_point) { + r300->is_point = is_point; r300_mark_atom_dirty(r300, &r300->rs_block_state); } + } r300_update_derived_state(r300);