[Piglit] [PATCH 1/2] gl-2.0: Verify results of program validation when a conflicting sampler configuration is used.

Anuj Phogat anuj.phogat at gmail.com
Mon Apr 14 12:20:45 PDT 2014


On Fri, Mar 14, 2014 at 5:25 PM, Ian Romanick <idr at freedesktop.org> wrote:
> From: Ian Romanick <ian.d.romanick at intel.com>
>
> Section 2.15.4 (Shader Execution), subheading "Validation" of the OpenGL
> 2.0 spec says:
>
>     "[INVALID_OPERATION] is generated by Begin, RasterPos, or any
>     command that performs an implicit Begin if:
>
>         - any two active samplers in the current program object are of
>           different types, but refer to the same texture image unit,"
>
> This test verifies this behavior several ways.  First, an invalid
> configuration is constructed.  When the program is in the invalid
> configuration, glValidateProgram is used to determine the status.
>
> The program is then transitioned to a valid configuration, and
> glValidateProgram is called again.
>
> The program is then transitioned back to the invalid configuration.
> Without calling glValidateProgram, glBegin is called.  This should
> generate the aforementioned error.  While still in the invalid state
> glValidateProgram is called a third time.
>
> Finally, the program is transitioned back to the valid configuration.
> Without calling glValidateProgram, glBegin is called.  This should not
> generate any error.
>
> All of the state flip-flopping is done in an attempt to catch
> implementations that latch state in glValidateProgram and do not
> re-validate in glBegin.
>
> NOTE: Mesa fails this test because it does not generate
> GL_INVALID_OPERATION the first time glBegin is called.
>
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> Cc: Eric Anholt <eric at anholt.net>
> ---
>  tests/all.py                                    |   1 +
>  tests/spec/gl-2.0/api/CMakeLists.gl.txt         |   1 +
>  tests/spec/gl-2.0/api/active-sampler-conflict.c | 207 ++++++++++++++++++++++++
>  3 files changed, 209 insertions(+)
>  create mode 100644 tests/spec/gl-2.0/api/active-sampler-conflict.c
>
> diff --git a/tests/all.py b/tests/all.py
> index 84b9728..e0a6c91 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -1029,6 +1029,7 @@ gl20['incomplete-texture-glsl'] = concurrent_test('incomplete-texture -auto glsl
>  add_plain_test(gl20, 'tex3d-npot')
>  add_concurrent_test(gl20, 'max-samplers')
>  add_concurrent_test(gl20, 'max-samplers border')
> +add_concurrent_test(gl20, "gl-2.0-active-sampler-conflict")
>
>  gl21 = Group()
>  spec['!OpenGL 2.1'] = gl21
> diff --git a/tests/spec/gl-2.0/api/CMakeLists.gl.txt b/tests/spec/gl-2.0/api/CMakeLists.gl.txt
> index 77b0f93..9968b13 100644
> --- a/tests/spec/gl-2.0/api/CMakeLists.gl.txt
> +++ b/tests/spec/gl-2.0/api/CMakeLists.gl.txt
> @@ -9,6 +9,7 @@ link_libraries (
>         ${OPENGL_glu_LIBRARY}
>  )
>
> +piglit_add_executable (gl-2.0-active-sampler-conflict active-sampler-conflict.c)
>  piglit_add_executable (attrib-assignments attrib-assignments.c)
>  piglit_add_executable (getattriblocation-conventional getattriblocation-conventional.c)
>  piglit_add_executable (clip-flag-behavior clip-flag-behavior.c)
> diff --git a/tests/spec/gl-2.0/api/active-sampler-conflict.c b/tests/spec/gl-2.0/api/active-sampler-conflict.c
> new file mode 100644
> index 0000000..b35cc89
> --- /dev/null
> +++ b/tests/spec/gl-2.0/api/active-sampler-conflict.c
> @@ -0,0 +1,207 @@
> +/*
> + * Copyright © 2014 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 active-sampler-conflict.c
> + * Verify results of program validation when a conflicting sampler
> + * configuration is used.
> + *
> + * Section 2.15.4 (Shader Execution), subheading "Validation" of the OpenGL
> + * 2.0 spec says:
> + *
> + *     "[INVALID_OPERATION] is generated by Begin, RasterPos, or any
> + *     command that performs an implicit Begin if:
> + *
> + *         - any two active samplers in the current program object are
> + *           of different types, but refer to the same texture image
> + *           unit,"
> + *
> + * This test verifies this behavior several ways.  First, an invalid
> + * configuration is constructed.  When the program is in the invalid
> + * configuration, glValidateProgram is used to determine the status.
> + *
> + * The program is then transitioned to a valid configuration, and
> + * glValidateProgram is called again.
> + *
> + * The program is then transitioned back to the invalid configuration.
> + * Without calling glValidateProgram, glBegin is called.  This should generate
> + * the aforementioned error.  While still in the invalid state
> + * glValidateProgram is called a third time.
> + *
> + * Finally, the program is transitioned back to the valid configuration.
> + * Without calling glValidateProgram, glBegin is called.  This should not
> + * generate any error.
> + *
> + * All of the state flip-flopping is done in an attempt to catch
> + * implementations that latch state in glValidateProgram and do not
> + * re-validate in glBegin.
> + */
> +#include "piglit-util-gl-common.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +       config.supports_gl_compat_version = 20;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +static const char *fs_code =
> +       "uniform sampler2D s2;\n"
> +       "uniform sampler3D s3;\n"
> +       "\n"
> +       "void main()\n"
> +       "{\n"
> +       "    gl_FragColor = texture2D(s2, vec2(0)) + texture3D(s3, vec3(0));\n"
> +       "}\n"
> +       ;
> +
> +static bool
> +program_check_status(GLuint prog)
> +{
> +        GLchar *info = NULL;
> +        GLint size;
> +        GLint ok;
> +
> +        glValidateProgram(prog);
> +        glGetProgramiv(prog, GL_VALIDATE_STATUS, &ok);
> +
> +        /* Some drivers return a size of 1 for an empty log.  This is the size
> +         * of a log that contains only a terminating NUL character.
> +         */
> +        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
> +        if (size > 1) {
> +                info = malloc(size);
> +                glGetProgramInfoLog(prog, size, NULL, info);
> +        }
> +
> +        if (!ok) {
> +                printf("Failed to validate the program: %s\n",
> +                      (info != NULL) ? info : "<empty log>");
> +        }
> +        else if (0 && info != NULL) {
> +                /* Enable this to get extra linking info.
> +                 * Even if there's no link errors, the info log may
> +                 * have some remarks.
> +                 */
> +                printf("Program validation warning: %s\n", info);
> +        }
> +
> +        free(info);
> +
> +        return ok;
> +}
> +
> +
> +void piglit_init(int argc, char **argv)
> +{
> +       GLuint prog;
> +       GLint s2_loc;
> +       GLint s3_loc;
> +       bool pass = true;
> +
> +       prog = piglit_build_simple_program(NULL, fs_code);
> +
> +       s2_loc = glGetUniformLocation(prog, "s2");
> +       if (s2_loc == -1) {
> +               fprintf(stderr, "Failed to get uniform location for s2.\n");
> +               pass = false;
> +       }
> +
> +       s3_loc = glGetUniformLocation(prog, "s3");
> +       if (s3_loc == -1) {
> +               fprintf(stderr, "Failed to get uniform location for s3.\n");
> +               pass = false;
> +       }
> +
> +       glUseProgram(prog);
> +
> +       /* First, try an invalid configuration.
> +        */
> +       glUniform1i(s2_loc, 1);
> +       glUniform1i(s3_loc, 1);
> +       if (program_check_status(prog)) {
> +               fprintf(stderr,
> +                       "Program was validated with conflicting "
> +                       "sampler configuration.\n");
> +               pass = false;
> +       }
> +
> +       /* Now try a valid configuration.
> +        */
> +       glUniform1i(s2_loc, 1);
> +       glUniform1i(s3_loc, 2);
> +       if (!program_check_status(prog)) {
> +               fprintf(stderr,
> +                       "Program was not validated with non-conflicting "
> +                       "sampler configuration.\n");
> +               pass = false;
> +       }
> +
> +       /* Switch back to the invalid configuration.  Without first calling
> +        * glValidateProgramPipeline, try to draw something.  Verify that
> +        * GL_INVALID_OPERATION is generated.
> +        */
> +       glUniform1i(s2_loc, 1);
> +       glUniform1i(s3_loc, 1);
> +
> +       glBegin(GL_POINTS);
> +       glVertex2f(0.0, 0.0);
> +       glEnd();
> +
> +       pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
> +
> +       /* Re-validate the program.
> +        */
> +       if (program_check_status(prog)) {
> +               fprintf(stderr,
> +                       "Program was validated with conflicting "
> +                       "sampler configuration (second attempt).\n");
> +               pass = false;
> +       }
> +
> +       /* Switch back to the valid configuration.  Without first calling
> +        * glValidateProgramPipeline, try to draw something.  Verify that
> +        * no error is generated.
> +        */
> +       glUniform1i(s2_loc, 1);
> +       glUniform1i(s3_loc, 2);
> +
> +       glBegin(GL_POINTS);
> +       glVertex2f(0.0, 0.0);
> +       glEnd();
> +
> +       pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
> +
> +       /* Clean up.
> +        */
> +       glUseProgram(0);
> +       glDeleteProgram(prog);
> +
> +       piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +       /* Not reached */
> +       return PIGLIT_FAIL;
> +}
> --
> 1.8.1.4
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit


Both tests are Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>

Tests expose the wrong behavior of NVIDIA. Here is what I get with proprietary
NVIDIA linux drivers:
$ ./bin/gl-2.0-active-sampler-conflict
Program was validated with conflicting sampler configuration.
Unexpected GL error: GL_NO_ERROR 0x0
(Error at /home/anuj/projects/piglit/tests/spec/gl-2.0/api/active-sampler-conflict.c:170)
Expected GL error: GL_INVALID_OPERATION 0x502
Program was validated with conflicting sampler configuration (second attempt).
PIGLIT: {'result': 'fail' }


More information about the Piglit mailing list