From 9b96be595b93544266436ec3b22b2cbd349d180c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 8 Jan 2014 17:19:41 +0000 Subject: [PATCH] llvmpipe: Honour pipe_rasterizer::point_quad_rasterization. Commit eda21d2a3010d9fc5a68b55a843c5e44b2abf8dd fixed the rasterization of points for Direct3D but ended up breaking the rasterization of OpenGL non-sprite points, in particular conform's pntrast.c test. The only way to get both working is to properly honour pipe_rasterizer::point_quad_rasterization, and follow the weird OpenGL rule when it is false. Reviewed-by: Roland Scheidegger --- src/gallium/drivers/llvmpipe/lp_setup_point.c | 67 ++++++++++++++++--- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index 988e0c59f21..3610c5c6a24 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -338,9 +338,13 @@ try_setup_point( struct lp_setup_context *setup, int fixed_width = MAX2(FIXED_ONE, (subpixel_snap(size) + FIXED_ONE/2 - 1) & ~(FIXED_ONE-1)); - const int x0 = subpixel_snap(v0[0][0] - setup->pixel_offset) - fixed_width/2; - const int y0 = subpixel_snap(v0[0][1] - setup->pixel_offset) - fixed_width/2; - + /* Yes this is necessary to accurately calculate bounding boxes + * with the two fill-conventions we support. GL (normally) ends + * up needing a bottom-left fill convention, which requires + * slightly different rounding. + */ + int adj = (setup->bottom_edge_rule != 0) ? 1 : 0; + struct lp_scene *scene = setup->scene; struct lp_rast_triangle *point; unsigned bytes; @@ -363,13 +367,14 @@ try_setup_point( struct lp_setup_context *setup, print_point(setup, v0); /* Bounding rectangle (in pixels) */ - { - /* Yes this is necessary to accurately calculate bounding boxes - * with the two fill-conventions we support. GL (normally) ends - * up needing a bottom-left fill convention, which requires - * slightly different rounding. + if (!lp_context->rasterizer || + lp_context->rasterizer->point_quad_rasterization) { + /* + * Rasterize points as quads. */ - int adj = (setup->bottom_edge_rule != 0) ? 1 : 0; + + const int x0 = subpixel_snap(v0[0][0] - setup->pixel_offset) - fixed_width/2; + const int y0 = subpixel_snap(v0[0][1] - setup->pixel_offset) - fixed_width/2; bbox.x0 = (x0 + (FIXED_ONE-1)) >> FIXED_ORDER; bbox.x1 = (x0 + fixed_width + (FIXED_ONE-1)) >> FIXED_ORDER; @@ -380,8 +385,50 @@ try_setup_point( struct lp_setup_context *setup, */ bbox.x1--; bbox.y1--; + } else { + /* + * OpenGL legacy rasterization rules for non-sprite points. + * + * Per OpenGL 2.1 spec, section 3.3.1, "Basic Point Rasterization". + * + * This type of point rasterization is only available in pre 3.0 contexts + * (or compatibilility contexts which we don't support) anyway. + */ + + const int x0 = subpixel_snap(v0[0][0]); + const int y0 = subpixel_snap(v0[0][1]) - adj; + + int int_width = fixed_width >> FIXED_ORDER; + + assert(setup->pixel_offset != 0); + + if (int_width == 1) { + bbox.x0 = x0 >> FIXED_ORDER; + bbox.y0 = y0 >> FIXED_ORDER; + bbox.x1 = bbox.x0; + bbox.y1 = bbox.y0; + } else { + if (int_width & 1) { + /* Odd width */ + bbox.x0 = (x0 >> FIXED_ORDER) - (int_width - 1)/2; + bbox.y0 = (y0 >> FIXED_ORDER) - (int_width - 1)/2; + } else { + /* Even width */ + bbox.x0 = ((x0 + FIXED_ONE/2) >> FIXED_ORDER) - int_width/2; + bbox.y0 = ((y0 + FIXED_ONE/2) >> FIXED_ORDER) - int_width/2; + } + + bbox.x1 = bbox.x0 + int_width - 1; + bbox.y1 = bbox.y0 + int_width - 1; + } } - + + if (0) { + debug_printf(" bbox: (%i, %i) - (%i, %i)\n", + bbox.x0, bbox.y0, + bbox.x1, bbox.y1); + } + if (!u_rect_test_intersection(&setup->draw_regions[viewport_index], &bbox)) { if (0) debug_printf("offscreen\n"); LP_COUNT(nr_culled_tris); -- 2.30.2