[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