[Piglit] [PATCH 12/18] gl 1.0: Stress test GL_LINE_LOOP.

Brian Paul brianp at vmware.com
Tue Jan 9 18:39:34 UTC 2018


On 01/07/2018 03:14 PM, Fabian Bieler wrote:
> Draw circles with long line loops and check the result.
> 
> In particular, check that the last line segment is drawn and that no
> additional segments in between arbitrary vertices are drawn.
> ---
>   tests/all.py                        |   1 +
>   tests/spec/gl-1.0/CMakeLists.gl.txt |   1 +
>   tests/spec/gl-1.0/long-line-loop.c  | 151 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 153 insertions(+)
>   create mode 100644 tests/spec/gl-1.0/long-line-loop.c
> 
> diff --git a/tests/all.py b/tests/all.py
> index 32ab2b610..6abcb3aa8 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -727,6 +727,7 @@ with profile.test_list.group_manager(
>       g(['gl-1.0-edgeflag-quads'])
>       g(['gl-1.0-empty-begin-end-clause'])
>       g(['gl-1.0-long-dlist'])
> +    g(['gl-1.0-long-line-loop'])
>       g(['gl-1.0-readpixels-oob'])
>       g(['gl-1.0-rendermode-feedback'])
>       g(['gl-1.0-front-invalidate-back'], run_concurrent=False)
> diff --git a/tests/spec/gl-1.0/CMakeLists.gl.txt b/tests/spec/gl-1.0/CMakeLists.gl.txt
> index 355df7472..2df3a8cf4 100644
> --- a/tests/spec/gl-1.0/CMakeLists.gl.txt
> +++ b/tests/spec/gl-1.0/CMakeLists.gl.txt
> @@ -26,6 +26,7 @@ piglit_add_executable (gl-1.0-fpexceptions fpexceptions.c)
>   piglit_add_executable (gl-1.0-front-invalidate-back front-invalidate-back.c)
>   piglit_add_executable (gl-1.0-logicop logicop.c)
>   piglit_add_executable (gl-1.0-long-dlist long-dlist.c)
> +piglit_add_executable (gl-1.0-long-line-loop long-line-loop.c)
>   piglit_add_executable (gl-1.0-ortho-pos orthpos.c)
>   piglit_add_executable (gl-1.0-no-op-paths no-op-paths.c)
>   piglit_add_executable (gl-1.0-polygon-line-aa polygon-line-aa.c)
> diff --git a/tests/spec/gl-1.0/long-line-loop.c b/tests/spec/gl-1.0/long-line-loop.c
> new file mode 100644
> index 000000000..768e1aa85
> --- /dev/null
> +++ b/tests/spec/gl-1.0/long-line-loop.c
> @@ -0,0 +1,151 @@
> +/*
> + * Copyright © 2017 Fabian Bieler
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +/**
> + * @file long-line-loop.c
> + * Draw cricles with line loops and a line strips blended on top of each
> + * other and check that the renderings match.
> + */
> +
> +#include "piglit-util-gl.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +	config.supports_gl_compat_version = 10;
> +	config.window_width = 1024;
> +	config.window_height = 1024;
> +	config.window_visual = PIGLIT_GL_VISUAL_RGB;
> +	config.khr_no_error_support = PIGLIT_NO_ERRORS;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +static int max_vertices;
> +static int probe_location[2];
> +static const float radius = 0.9;
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	/* This isn't a hard limit, but staying below should help performance.
> +	 *
> +	 * XXX: It could be interesting to go beyond this limit to test a
> +	 * different code path in the GL implementation.
> +	 */
> +	glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_vertices);
> +	max_vertices = CLAMP(max_vertices, 0x2000, 0x40000);

I fixed some long line loop issues in Mesa/gallium a few years ago.  I 
_think_ 0x2000 (8192) is enough, but you might want to check more (Note 
that Mesa llvmpipe reports GL_MAX_ELEMENTS_VERTICES = 3000).

Also, I see you're stepping the vertex count by <<=2 in the test loop 
below.  That _might_ skip some magic vertex counts which tickle bugs. 
Off-hand I don't have a good suggesting for how to be thorough about 
this without being really slow.

There's (at least) two places where the vertex buffer limits (the VBO 
module and draw/vbuf code) will trigger splitting/continuing long line 
loops.  This test should try to exceed both those buffer limits.  You 
might set some breakpoints in the Mesa/gallium code to see if they're 
getting hit.

For reference, see Mesa  bdf6cef0333bf7278, b48e16fa2f8b96bb36a6e0, 
d79595bf0230824b2

I wish I'd have had this test back then!

-Brian


> +
> +	glBlendFunc(GL_ONE, GL_ONE);
> +
> +	piglit_ortho_projection(piglit_width, piglit_height, false);
> +}
> +
> +static void
> +draw_circle(int num_vertices)
> +{
> +	/* The first (num_vertices - 1) vertices describe the arc of a circle
> +	 * slice with central angle (360° - alpha).
> +	 * The last vertex is identical to the first vertex.
> +	 * alpha is chosen so that the last line segment covers two pixels.
> +	 */
> +	const float alpha = asinf(2.0 / (piglit_width / 2 * radius));
> +	float *vertex = malloc(sizeof(float) * 2 * num_vertices);
> +
> +	for (int i = 0; i < num_vertices - 1; ++i) {
> +		const float phi = alpha -
> +				  (2 * M_PI - alpha) /
> +				  (float)(num_vertices - 2) *
> +				  (float)i;
> +
> +		vertex[2 * i + 0] = round(piglit_width / 2 *
> +					  (1 + radius * cosf(phi))) + 0.5;
> +		vertex[2 * i + 1] = round(piglit_height / 2 *
> +					  (1 + radius * sinf(phi))) + 0.5;
> +	}
> +	vertex[2 * num_vertices - 2] = vertex[0];
> +	vertex[2 * num_vertices - 1] = vertex[1];
> +
> +	/* Find a pixel in the last line segment: */
> +	for (int i = 0; i < 2; ++i)
> +		probe_location[i] = round((vertex[2 * num_vertices - 4 + i] +
> +					   vertex[2 * num_vertices - 2 + i] -
> +					   1.0) / 2.0);
> +
> +	/* Render twice: */
> +	glClear(GL_COLOR_BUFFER_BIT);
> +
> +	glVertexPointer(2, GL_FLOAT, 0, vertex);
> +
> +	glEnableClientState(GL_VERTEX_ARRAY);
> +
> +	glColor3f(0,1,0);
> +	glDrawArrays(GL_LINE_LOOP, 0, num_vertices - 1);
> +
> +	glEnable(GL_BLEND);
> +	glColor3f(0,0,1);
> +	glDrawArrays(GL_LINE_STRIP, 0, num_vertices);
> +	glDisable(GL_BLEND);
> +
> +	free(vertex);
> +
> +	piglit_present_results();
> +}
> +
> +static bool
> +check_circle(void)
> +{
> +	bool pass = true;
> +	const float teal[] = {0, 1, 1};
> +	const float black[] = {0, 0, 0};
> +
> +	/* check that the two renderings are identical */
> +	pass = piglit_probe_rect_two_rgb(0, 0, piglit_width, piglit_height,
> +					 black, teal) && pass;
> +
> +	/* belt + suspenders: Additionally check that the last line segment
> +	 * was drawn...
> +	 */
> +	pass = piglit_probe_pixel_rgb(probe_location[0], probe_location[1],
> +				      teal) && pass;
> +
> +	/* ...and that the center of the circle is black */
> +	const int x = ceil(piglit_width / 2 * radius / M_SQRT2) + 1;
> +	const int y = ceil(piglit_height / 2 * radius / M_SQRT2) + 1;
> +	pass = piglit_probe_rect_rgb(x, y, piglit_width - 2 * x,
> +				     piglit_height - 2 * y, black) && pass;
> +
> +	return pass;
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	bool pass = true;
> +
> +	for (int vertices = 16; vertices <= max_vertices; vertices <<= 2) {
> +		draw_circle(vertices);
> +		pass = check_circle() && pass;
> +	} > +
> +	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> 



More information about the Piglit mailing list