[Piglit] [PATCH 2/3] gl-3.0: Verify linking errors to due invalid glBindFragDataLocation assignments

Paul Berry stereotype441 at gmail.com
Tue Nov 8 09:07:29 PST 2011


On 4 November 2011 16:34, Ian Romanick <idr at freedesktop.org> wrote:

> From: Ian Romanick <ian.d.romanick at intel.com>
>
> This test fails on AMD's closed-source driver and NVIDIA's
> closed-source driver because they both allow an array to be assigned
> to location GL_MAX_DRAW_BUFFERS-1.  See comments in the test for the
> reasons this should be rejected.
>
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> ---
>  tests/all.tests                                 |    1 +
>  tests/spec/gl-3.0/api/CMakeLists.gl.txt         |    1 +
>  tests/spec/gl-3.0/api/bindfragdata-link-error.c |  172
> +++++++++++++++++++++++
>  3 files changed, 174 insertions(+), 0 deletions(-)
>  create mode 100644 tests/spec/gl-3.0/api/bindfragdata-link-error.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index 429f65a..9641281 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -789,6 +789,7 @@ add_concurrent_test(gl20, 'vertex-program-two-side')
>  gl30 = Group()
>  spec['!OpenGL 3.0'] = gl30
>  add_concurrent_test(gl30, 'bindfragdata-invalid-location')
> +add_concurrent_test(gl30, 'bindfragdata-link-error')
>  add_concurrent_test(gl30, 'clearbuffer-depth-stencil')
>  add_concurrent_test(gl30, 'clearbuffer-invalid-drawbuffer')
>  add_concurrent_test(gl30, 'clearbuffer-invalid-buffer')
> diff --git a/tests/spec/gl-3.0/api/CMakeLists.gl.txt
> b/tests/spec/gl-3.0/api/CMakeLists.gl.txt
> index 2e9f190..51fbce4 100644
> --- a/tests/spec/gl-3.0/api/CMakeLists.gl.txt
> +++ b/tests/spec/gl-3.0/api/CMakeLists.gl.txt
> @@ -13,6 +13,7 @@ link_libraries (
>  )
>
>  add_executable (bindfragdata-invalid-parameters
> bindfragdata-invalid-parameters.c)
> +add_executable (bindfragdata-link-error bindfragdata-link-error.c)
>  add_executable (clearbuffer-depth clearbuffer-common.c
> clearbuffer-depth.c)
>  add_executable (clearbuffer-depth-stencil clearbuffer-common.c
> clearbuffer-depth-stencil.c)
>  add_executable (clearbuffer-invalid-drawbuffer
> clearbuffer-invalid-drawbuffer.c)
> diff --git a/tests/spec/gl-3.0/api/bindfragdata-link-error.c
> b/tests/spec/gl-3.0/api/bindfragdata-link-error.c
> new file mode 100644
> index 0000000..70e44ca
> --- /dev/null
> +++ b/tests/spec/gl-3.0/api/bindfragdata-link-error.c
> @@ -0,0 +1,172 @@
> +/* 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 bindfragdata-link-error.c
> + *
> + * \author Ian Romanick
> + */
> +#include "piglit-util.h"
> +
> +int piglit_width = 100, piglit_height = 100;
> +int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;
> +
> +static const char *vs_text =
> +       "#version 130\n"
> +       "in vec4 vertex;\n"
> +       "void main() { gl_Position = vertex; }\n"
> +       ;
> +
> +static const char *fs_text =
> +       "#version 130\n"
> +       "out vec4 v;\n"
> +       "out vec4 a[2];\n"
> +       "void main() {\n"
> +       "    v = vec4(0.0);\n"
> +       "    a[0] = vec4(1.0);\n"
> +       "    a[1] = vec4(2.0);\n"
> +       "}\n"
> +       ;
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +       return PIGLIT_FAIL;
> +}
> +
> +void piglit_init(int argc, char **argv)
> +{
> +       GLint max_draw_buffers;
> +       GLuint prog;
> +       GLuint vs;
> +       GLuint fs;
> +
> +       piglit_require_gl_version(30);
> +
> +       /* This test needs some number of draw buffers, so make sure the
> +        * implementation isn't broken.  This enables the test to generate
> a
> +        * useful failure message.
> +        */
> +       glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
> +       if (max_draw_buffers < 8) {
> +               fprintf(stderr,
> +                       "OpenGL 3.0 requires GL_MAX_DRAW_BUFFERS >= 8.  "
> +                       "Only got %d!\n",
> +                       max_draw_buffers);
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       prog = glCreateProgram();
> +       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
> +       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       /* First, verify that the program will link without making any
> +        * location assignments through the API.
> +        */
> +       printf("Basic test...\n");
> +
> +       glAttachShader(prog, vs);
> +       glAttachShader(prog, fs);
> +       glLinkProgram(prog);
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       if (!piglit_link_check_status(prog)) {
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       /* Page 237 (page 253 of the PDF) of the OpenGL 3.0 spec says:
> +        *
> +        *     "LinkProgram will fail if the assigned binding of a varying
> out
> +        *     variable would cause the GL to reference a non-existant
> +        *     fragment color number (one greater than or equal to MAX DRAW
> +        *     BUFFERS)."
> +        *
> +        * The array output has two elements.  Binding it to
> +        * GL_MAX_DRAW_BUFFERS - 1 causes a[0] to have a valid location but
> +        * a[1] to have an invalid location.
> +        *
> +        * This should not generate a GL error.  It should only cause
> linking
> +        * to fail.
> +        */
> +       printf("Assigning `a' to GL_MAX_DRAW_BUFFERS - 1...\n");
> +
> +       glBindFragDataLocation(prog, 0, "v");
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +       glBindFragDataLocation(prog, max_draw_buffers - 1, "a");
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       glLinkProgram(prog);
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       if (piglit_link_check_status(prog)) {
> +               fprintf(stderr,
> +                       "Linking was successful when it should have
> failed.\n");
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       /* Page 237 (page 253 of the PDF) of the OpenGL 3.0 spec says:
> +        *
> +        *     "LinkProgram will also fail if more than one varying out
> +        *     variable is bound to the same number. This type of aliasing
> is
> +        *     not allowed."
> +        *
> +        * Try this by assiging 'a[0]' and 'v' to the same slot, and also
> try
> +        * assigning 'a[1]' and 'v' to the same slot.
> +        *
> +        * This should not generate a GL error.  It should only cause
> linking
> +        * to fail.
> +        */
> +       printf("Assigning `a[0]' to `v' to the same slot...\n");
>

"Assigning `a[0]' and `v' to the same slot"


> +
> +       glBindFragDataLocation(prog, 0, "v");
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +       glBindFragDataLocation(prog, 0, "a");
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       glLinkProgram(prog);
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       if (piglit_link_check_status(prog)) {
> +               fprintf(stderr,
> +                       "Linking was successful when it should have
> failed.\n");
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       printf("Assigning `a[1]' to `v' to the same slot...\n");
> +
> +       glBindFragDataLocation(prog, 1, "v");
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +       glBindFragDataLocation(prog, 0, "a");
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       glLinkProgram(prog);
> +       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);
> +
> +       if (piglit_link_check_status(prog)) {
> +               fprintf(stderr,
> +                       "Linking was successful when it should have
> failed.\n");
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
>

For good measure, it might be worth assigning 'a' to 0 and 'v' to 2, and
doing a final link, to verify that:
- The implementation correctly computes how many slots 'a' takes up
- The implementation is capable of clearing the link error once the
assignments are fixed
- Linking is successful when locations are assigned in a non-overlapping
way.


> +       piglit_report_result(PIGLIT_PASS);
> +}
> --
> 1.7.6.4
>
>
In any case, this patch is:

Reviewed-by: Paul Berry <stereotype441 at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20111108/17ab9eb0/attachment-0001.htm>


More information about the Piglit mailing list