[Piglit] [PATCH 3/4] vertex-program-two-side: New test for VERTEX_PROGRAM_TWO_SIDE.

Eric Anholt eric at anholt.net
Mon Sep 19 11:41:53 PDT 2011


On Mon, 12 Sep 2011 13:56:28 -0700, Paul Berry <stereotype441 at gmail.com> wrote:
Non-text part: multipart/alternative
> On 8 September 2011 23:07, Eric Anholt <eric at anholt.net> wrote:
> 
> > ---
> >  tests/all.tests                             |   15 ++
> >  tests/spec/gl-2.0/CMakeLists.gl.txt         |   16 ++
> >  tests/spec/gl-2.0/CMakeLists.txt            |    1 +
> >  tests/spec/gl-2.0/vertex-program-two-side.c |  235
> > +++++++++++++++++++++++++++
> >  4 files changed, 267 insertions(+), 0 deletions(-)
> >  create mode 100644 tests/spec/gl-2.0/CMakeLists.gl.txt
> >  create mode 100644 tests/spec/gl-2.0/vertex-program-two-side.c
> >
> > diff --git a/tests/all.tests b/tests/all.tests
> > index fc66ff6..cbd40d0 100644
> > --- a/tests/all.tests
> > +++ b/tests/all.tests
> > @@ -729,6 +729,21 @@ add_texwrap_test3(gl20, '2D', 'npot', 'proj')
> >  add_texwrap_test2(gl20, '3D', 'npot')
> >  add_texwrap_test3(gl20, '3D', 'npot', 'proj')
> >  add_plain_test(gl20, 'getattriblocation-conventional')
> > +gl20['vertex-program-two-side '] =
> > concurrent_test('vertex-program-two-side')
> > +gl20['vertex-program-two-side front'] =
> > concurrent_test('vertex-program-two-side front')
> > +gl20['vertex-program-two-side back'] =
> > concurrent_test('vertex-program-two-side back')
> > +gl20['vertex-program-two-side primary'] =
> > concurrent_test('vertex-program-two-side primary')
> > +gl20['vertex-program-two-side primary front'] =
> > concurrent_test('vertex-program-two-side primary front')
> > +gl20['vertex-program-two-side primary back'] =
> > concurrent_test('vertex-program-two-side primary back')
> > +gl20['vertex-program-two-side secondary'] =
> > concurrent_test('vertex-program-two-side secondary')
> > +gl20['vertex-program-two-side secondary front'] =
> > concurrent_test('vertex-program-two-side secondary front')
> > +gl20['vertex-program-two-side secondary back'] =
> > concurrent_test('vertex-program-two-side secondary back')
> > +gl20['vertex-program-two-side disabled'] =
> > concurrent_test('vertex-program-two-side disabled')
> > +gl20['vertex-program-two-side disabled front'] =
> > concurrent_test('vertex-program-two-side disabled front')
> > +gl20['vertex-program-two-side disabled primary'] =
> > concurrent_test('vertex-program-two-side disabled primary')
> > +gl20['vertex-program-two-side disabled primary front'] =
> > concurrent_test('vertex-program-two-side disabled primary front')
> > +gl20['vertex-program-two-side disabled secondary'] =
> > concurrent_test('vertex-program-two-side disabled secondary')
> > +gl20['vertex-program-two-side disabled secondary front'] =
> > concurrent_test('vertex-program-two-side disabled secondary front')
> >
> 
> I found the meaning of the arguments to be hard to follow:
> - "front" sets the global variable "back" to false, which means the VS
> doesn't set gl_BackColor or gl_BackSecondaryColor.
> - "back" sets "front" to false, which means the VS doesn't set gl_FrontColor
> or gl_FrontSecondaryColor.
> - "primary" sets "secondary" to false, which means the VS doesn't set
> gl_FrontSecondaryColor or gl_BackSecondaryColor.
> - "secondary" sets "primary" to false, which means the VS doesn't set
> gl_BackSecondaryColor or gl_FrontSecondaryColor.
> 
> So, for example, concurrent_test('vertex-program-two-side') causes the VS to
> set all four color outputs, where a naive reader might have expected none of
> them to be set.  Also, concurrent_test('vertex-program-two-side front back
> primary') would cause nothing to be tested, where a naive reader would
> probably have expected it to test both front and back.  It would be way
> easier to reason about this code if the globals "front", "back", "primary",
> and "secondary" all started out false, and the presence of arguments set
> them to true.
> 
> Also, a few cases aren't tested:
> - VS sets all colors except gl_BackSecondaryColor.
> - VS sets all colors except gl_FrontSecondaryColor.
> - VS sets all colors except gl_BackColor.
> - VS sets all colors except gl_FrontColor.
> - VS sets only gl_FrontColor and gl_BackSecondaryColor.
> - VS sets only gl_BackColor and gl_FrontSecondaryColor.

I was trying to make things a bit more concise so that the test name
for the likely most relevant test wasn't "vertex-program-two-side
gl_FrontColor gl_BackColor gl_FrontSecondaryColor
gl_BackSecondaryColor".  I think what you're saying makes more sense,
so the no-arguments version ends up undefined.

> Granted, the standard doesn't specify the meaning of these cases, but it
> doesn't specify that their behavior is undefined either, so I think it's
> reasonable to verify that the undefined behavior is confined to the variable
> that wasn't set.  For instance, in the case where the VS sets all colors
> except gl_BackSecondaryColor, we should test that primary color works
> properly, and that secondary color works properly when you look at the front
> side of a triangle.  Considering some of the primary/secondary color code I
> ran across in my recent refactor of i965 VUE setup on Mesa, I would not be
> surprised if in some of these cases, the "undefined" behavior bleeds over
> between primary and secondary colors, or between front and back.  It might
> even cause mesa to abort with an assertion.  Considering the standard's
> vagueness on what exactly is undefined in these cases, I think it's
> reasonable to err on the side of testing more cases rather than fewer.
> 
> (Note: of course, to test these additional cases we would have to further
> change the meaning of the command-line options.  You might consider just
> having one flag per VS output variable, plus of course the enable/disable
> flag for VERTEX_PROGRAM_TWO_SIDE).

> 
> 
> >
> >  # Group spec/glsl-1.00
> >  spec['glsl-1.00'] = Group()
> > diff --git a/tests/spec/gl-2.0/CMakeLists.gl.txt
> > b/tests/spec/gl-2.0/CMakeLists.gl.txt
> > new file mode 100644
> > index 0000000..bc771e7
> > --- /dev/null
> > +++ b/tests/spec/gl-2.0/CMakeLists.gl.txt
> > @@ -0,0 +1,16 @@
> > +include_directories(
> > +       ${GLEXT_INCLUDE_DIR}
> > +       ${OPENGL_INCLUDE_PATH}
> > +       ${GLUT_INCLUDE_DIR}
> > +       ${piglit_SOURCE_DIR}/tests/mesa/util
> > +       ${piglit_SOURCE_DIR}/tests/util
> > +)
> > +
> > +link_libraries (
> > +       piglitutil
> > +       ${OPENGL_gl_LIBRARY}
> > +       ${OPENGL_glu_LIBRARY}
> > +       ${GLUT_glut_LIBRARY}
> > +)
> > +
> > +add_executable (vertex-program-two-side vertex-program-two-side.c)
> > diff --git a/tests/spec/gl-2.0/CMakeLists.txt
> > b/tests/spec/gl-2.0/CMakeLists.txt
> > index 9a13702..6903d88 100644
> > --- a/tests/spec/gl-2.0/CMakeLists.txt
> > +++ b/tests/spec/gl-2.0/CMakeLists.txt
> > @@ -1 +1,2 @@
> >  add_subdirectory (api)
> > +piglit_include_target_api()
> > \ No newline at end of file
> > diff --git a/tests/spec/gl-2.0/vertex-program-two-side.c
> > b/tests/spec/gl-2.0/vertex-program-two-side.c
> > new file mode 100644
> > index 0000000..b2038e9
> > --- /dev/null
> > +++ b/tests/spec/gl-2.0/vertex-program-two-side.c
> > @@ -0,0 +1,235 @@
> > +/*
> > + * Copyright © 2011 Intel Corporation
> > + *
> > + * 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 vertex-program-two-side.c
> > + *
> > + * Tests two-sided lighting behavior.
> > + *
> > + * From the GL 2.1 spec, page 63 (page 77 of the PDF):
> > + *
> > + *     "Additionally, vertex shaders can operate in two-sided color
> > + *      mode. When a vertex shader is active, front and back colors
> > + *      can be computed by the vertex shader and written to the
> > + *      gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor and
> > + *      gl_BackSecondaryColor outputs. If VERTEX PROGRAM TWO SIDE is
> > + *      enabled, the GL chooses between front and back colors, as
> > + *      described below. Otherwise, the front color output is always
> > + *      selected. Two-sided color mode is enabled and disabled by
> > + *      calling Enable or Disable with the symbolic value VERTEX
> > + *      PROGRAM TWO SIDE."
> > + *
> > + * This appears to override the text in the GLSL 1.10 spec which
> > + * implies that two-sided behavior always occurs.
> > + */
> > +
> > +#define _GNU_SOURCE
> > +#include "piglit-util.h"
> > +
> > +int piglit_width = 100, piglit_height = 100;
> > +int piglit_window_mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE;
> > +
> > +static GLint prog;
> > +
> > +static bool primary = true;
> > +static bool secondary = true;
> > +static bool enabled = true;
> > +static bool front = true;
> > +static bool back = true;
> > +static float frontcolor[4] = {0.0, 0.5, 0.0, 0.0};
> > +static float backcolor[4] = {0.0, 0.0, 0.5, 0.0};
> > +static float secondary_frontcolor[4] = {0.0, 0.25, 0.0, 0.0};
> > +static float secondary_backcolor[4] = {0.0, 0.0, 0.25, 0.0};
> > +
> > +static const char *fs_source_primary =
> > +       "void main()\n"
> > +       "{\n"
> > +       "       gl_FragColor = gl_Color;\n"
> > +       "}\n";
> > +
> > +static const char *fs_source_secondary =
> > +       "void main()\n"
> > +       "{\n"
> > +       "       gl_FragColor = gl_SecondaryColor;\n"
> > +       "}\n";
> > +
> > +static const char *fs_source_both =
> > +       "void main()\n"
> > +       "{\n"
> > +       "       gl_FragColor = gl_Color + gl_SecondaryColor;\n"
> > +       "}\n";
> >
> 
> Rather than add the colors in this case, consider having a uniform variable
> to tell the FS whether to use gl_Color or gl_SecondaryColor, and having the
> program draw four rectangles instead of two.  This would make it easier to
> inspect the test results manually (since it's diffucult to mentally add RGB
> color values when viewing on screen), and it would have the advantage
> allowing some of the partially-undefined cases to be tested (e.g. where the
> VS sets only gl_FrontColor and gl_BackSecondaryColor).

Fair enough.

> > +
> > +void
> > +add(float *values, float *a)
> > +{
> > +       int i;
> > +
> > +       for (i = 0; i < 4; i++)
> > +               values[i] += a[i];
> > +}
> > +
> > +void
> > +get_expected(float *values, bool drew_front)
> > +{
> > +       int i;
> > +
> > +       for (i = 0; i < 4; i++)
> > +               values[i] = 0.0;
> > +
> > +       if (drew_front || !enabled) {
> > +               if (primary)
> > +                       add(values, frontcolor);
> > +               if (secondary)
> > +                       add(values, secondary_frontcolor);
> > +       }
> > +
> > +       if (!drew_front && enabled) {
> > +               if (primary)
> > +                       add(values, backcolor);
> > +               if (secondary)
> > +                       add(values, secondary_backcolor);
> > +       }
> >
> 
> Minor nit: it's not immediately obvious on first reading that: (a) exactly
> one or the other of these if tests will always execute, and (b) the
> condition indicates whether we expect to see front colors or back colors.
> Consider changing this to something like:
> 
> bool front_colors_expected = enabled ? draw_front : true;
> 
> ...
> 
> if (front_colors_expected) {
>     ...
> } else {
>     ...
> }

Agreed.

> > +}
> > +
> > +enum piglit_result
> > +piglit_display(void)
> > +{
> > +       int front_x = 10;
> > +       int front_y = 10;
> > +       int front_w = piglit_width / 2 - 20;
> > +       int front_h = piglit_height - 20;
> > +       int back_x = piglit_width - 10;
> > +       int back_y = 10;
> > +       int back_w = -(front_w);
> >
> +       int back_h = piglit_height - 20;
> >
> +       bool pass = true;
> > +       float expected[4];
> > +
> > +       piglit_ortho_projection(piglit_width, piglit_height, false);
> > +
> > +       glClearColor(0.5, 0.5, 0.5, 0.5);
> > +       glClear(GL_COLOR_BUFFER_BIT);
> > +
> > +       if (front) {
> > +               piglit_draw_rect(front_x, front_y, front_w, front_h);
> > +               get_expected(expected, true);
> > +               pass = pass && piglit_probe_rect_rgba(front_x, front_y,
> > +                                                     front_w, front_h,
> > +                                                     expected);
> > +       }
> > +
> > +       if (back || !enabled) {
> > +               piglit_draw_rect(back_x, back_y, back_w, back_h);
> > +               get_expected(expected, false);
> > +               pass = pass && piglit_probe_rect_rgba(back_x + back_w,
> > back_y,
> > +                                                     -back_w, back_h,
> > +                                                     expected);
> > +       }
> >
> 
> Another minor nit: usually the one-letter abbreviations x, y, w, and h are
> intuitively clear, but the fact that we're cleverly negating w in order to
> get a peek at the back side of the rectangle makes the second call to
> piglit_probe_rect_rgba() hard to follow.  Consider doing something more
> explicit.  Also a comment would be nice to explain the cleverness of
> negating the width to see the back side of the rectangle.  For example,
> perhaps something like this:
> 
> int back_x_right = piglit_width - 10;
> int back_w = front_w;
> int back_x = back_x_right - back_w;
> 
> ...
> 
> if (back || !enabled) {
>     /* Draw a reversed rectangle so we see its back side */
>     piglit_draw_rect(back_x_right, back_y, -back_w, back_h);
>     get_expected(expected, false);
>     pass = pass && piglit_probe_rect_rgba(back_x, back_y, back_w, back_h,
> expected);
> }

OK.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20110919/eb2cae5b/attachment.pgp>


More information about the Piglit mailing list