[Piglit] [PATCH v5 6/6] program_interface_query: add tests for getprogramresourceiv

Martin Peres martin.peres at linux.intel.com
Thu Apr 2 04:25:26 PDT 2015



On 02/04/15 14:10, Tapani Pälli wrote:
>
>
> On 04/01/2015 01:56 PM, Martin Peres wrote:
>> Tested on NVIDIA's proprietary driver version 346.35.
>>
>> Signed-off-by: Martin Peres <martin.peres at linux.intel.com>
>> ---
>>   .../arb_program_interface_query/CMakeLists.gl.txt  |    1 +
>>   .../getprogramresourceiv.c                         | 1063 
>> ++++++++++++++++++++
>>   2 files changed, 1064 insertions(+)
>>   create mode 100755 
>> tests/spec/arb_program_interface_query/getprogramresourceiv.c
>>
>> diff --git a/tests/spec/arb_program_interface_query/CMakeLists.gl.txt 
>> b/tests/spec/arb_program_interface_query/CMakeLists.gl.txt
>> index 2508342..91da8ac 100755
>> --- a/tests/spec/arb_program_interface_query/CMakeLists.gl.txt
>> +++ b/tests/spec/arb_program_interface_query/CMakeLists.gl.txt
>> @@ -14,3 +14,4 @@ piglit_add_executable 
>> (arb_program_interface_query-resource-query resource-query
>>   piglit_add_executable 
>> (arb_program_interface_query-getprograminterfaceiv 
>> getprograminterfaceiv.c)
>>   piglit_add_executable 
>> (arb_program_interface_query-getprogramresourceindex 
>> getprogramresourceindex.c)
>>   piglit_add_executable 
>> (arb_program_interface_query-getprogramresourcename 
>> getprogramresourcename.c)
>> +piglit_add_executable 
>> (arb_program_interface_query-getprogramresourceiv 
>> getprogramresourceiv.c)
>> diff --git 
>> a/tests/spec/arb_program_interface_query/getprogramresourceiv.c 
>> b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
>> new file mode 100755
>> index 0000000..0f6239c
>> --- /dev/null
>> +++ b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
>> @@ -0,0 +1,1063 @@
>> +/*
>> + * Copyright © 2015 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
>
> --- 8< ---
>
>> +};
>> +
>> +/* WARNING: ATOMIC_COUNTER_BUFFER is left untested because it is 
>> impossible to
>> + * fetch the index of variables which means we cannot reliably test 
>> anything
>> + */
>
> One can fetch indices but do you mean it is impossible to verify the 
> these indices later? You could cross-check indices against 
> glGetActiveAtomicCounterBufferiv, not sure if this is worth it though 
> because it will call the very same functionality anyway.

I meant that it is impossible to fetch the index of a atomic variable 
from its name. I can however compare the index with 
glGetActiveAtomicCounterBufferiv. Will do!

>
>> +
>> +static bool
>> +check_extensions_prop(GLenum prop)
>> +{
>> +    /* First check the availability of the extensions */
>> +    if (prop == GL_ATOMIC_COUNTER_BUFFER_INDEX &&
>> + !piglit_is_extension_supported("GL_ARB_shader_atomic_counters")) {
>> +        return false;
>> +    }
>> +
>> +    if ((prop == GL_TOP_LEVEL_ARRAY_SIZE ||
>> +        prop == GL_TOP_LEVEL_ARRAY_STRIDE) &&
>> + 
>> !piglit_is_extension_supported("GL_ARB_shader_storage_buffer_object")) {
>> +        return false;
>> +    }
>> +
>> +    if ((prop == GL_NUM_COMPATIBLE_SUBROUTINES ||
>> +         prop == GL_COMPATIBLE_SUBROUTINES) &&
>> + !piglit_is_extension_supported("GL_ARB_shader_subroutine")) {
>> +         return false;
>> +    }
>> +
>> +    if ((prop == GL_REFERENCED_BY_TESS_CONTROL_SHADER ||
>> +         prop == GL_REFERENCED_BY_TESS_EVALUATION_SHADER) &&
>> + !piglit_is_extension_supported("GL_ARB_tessellation_shader")) {
>> +         return false;
>> +    }
>> +
>> +    if ((prop == GL_REFERENCED_BY_COMPUTE_SHADER ||
>> +         prop == GL_COMPUTE_SUBROUTINE_UNIFORM ||
>> +         prop == GL_IS_PER_PATCH) &&
>> + !piglit_is_extension_supported("GL_ARB_compute_shader") &&
>> + !piglit_is_extension_supported("GL_ARB_shader_image_load_store")) {
>> +         return false;
>> +    }
>> +
>> +    return true;
>> +}
>> +
>> +static bool
>> +is_resource_in_list(const char **list, const char *resource, int index,
>> +            bool check_order)
>> +{
>> +    int i = 0;
>> +    while (list && list[i]) {
>> +        if (strcmp(list[i], resource) == 0) {
>> +            return !check_order || index == i;
>> +        }
>> +        i++;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +static void
>> +basic_check(const char *subsubtest, int value, int expected_value, 
>> bool *pass)
>> +{
>> +    /* no real check can be done other than checking that
>> +     * the index or offset is not invalid when it was
>> +     * supposed to be valid (or the other way round).
>> +     */
>> +    if ((value >= 0  && expected_value == -1) ||
>> +        (value == -1 && expected_value >= 0)) {
>> +        const char *validity = expected_value == -1 ?
>> +                       "an invalid" : "a valid";
>> +        fprintf(stderr, "'%s' expected %s offset or index but "
>> +                "got %i\n", subsubtest, validity, value);
>> +        *pass = false;
>> +    }
>> +}
>> +
>> +static void
>> +check_prop(GLuint prog, GLenum programInterface, int index, const 
>> char *name,
>> +       void *inputs, struct check_t c, bool *pass)
>> +{
>> +    int values[10], parent_idx, i;
>> +    char subsubtest[150];
>> +    GLsizei length, tmp = -1;
>> +    char buf[21];
>> +    GLenum pif;
>> +    GLuint loc;
>> +
>> +    /* skip the test if it is not supported */
>> +    if(!check_extensions_prop(c.prop)) {
>> +        return;
>> +    }
>> +
>> +    /* generate the name of the subsubtest for error-reporting 
>> purposes */
>> +    snprintf(subsubtest, sizeof(subsubtest), "%s: %s on %s",
>> +         name, piglit_get_gl_enum_name(c.prop),
>> +         piglit_get_gl_enum_name(programInterface));
>> +
>> +    /* retrieve the property */
>> +    glGetProgramResourceiv(prog, programInterface, index, 1, 
>> &c.prop, 10,
>> +                   &length, values);
>> +    if (!piglit_check_gl_error(GL_NO_ERROR)) {
>> +        printf("    Latest error generated while running '%s'\n",
>> +               subsubtest);
>> +        *pass = false;
>> +        return;
>> +    }
>> +
>> +    /* check the return value */
>> +    switch (c.prop) {
>> +    case GL_OFFSET:
>> +    case GL_ARRAY_STRIDE:
>> +    case GL_ATOMIC_COUNTER_BUFFER_INDEX:
>> +        basic_check(subsubtest, values[0], c.values[0], pass);
>> +        break;
>> +
>> +    case GL_BLOCK_INDEX:
>> +        /* check that the index of the parent matches the name
>> +         * of the parent
>> +         */
>> +        switch (programInterface) {
>> +        case GL_UNIFORM: pif = GL_UNIFORM_BLOCK; break;
>> +        case GL_BUFFER_VARIABLE: pif = GL_SHADER_STORAGE_BLOCK; break;
>
> Please be consistent with the style and move the breaks on their own 
> lines.

Ok.

>
>> +        }
>> +
>> +        parent_idx = glGetProgramResourceIndex(prog, pif,
>> +                               (char*)inputs);
>> +        piglit_check_gl_error(GL_NO_ERROR);
>> +        if (parent_idx != values[0]) {
>> +            glGetProgramResourceName(prog, programInterface,
>> +                         values[0], sizeof(buf), NULL,
>> +                         buf);
>> +
>> +            fprintf(stderr, "'%s' expected parent name to be %s"
>> +                "(idx = %i) but got parent name %s(idx = %i)\n",
>> +                subsubtest, (char*)inputs, parent_idx, buf,
>> +                values[0]);
>> +            *pass = false;
>> +        }
>> +        break;
>> +
>> +    case GL_BUFFER_BINDING:
>> +        if (values[0] < 0) {
>> +            fprintf(stderr, "'%s' invalid buffer binding point\n",
>> +                subsubtest);
>> +            *pass = false;
>> +        }
>> +
>> +        /* check against another API call */
>> +        if (programInterface != GL_UNIFORM_BLOCK) {
>> +            break;
>> +        }
>> +
>> +        glGetActiveUniformBlockiv(prog, index, 
>> GL_UNIFORM_BLOCK_BINDING,
>> +                      &tmp);
>> +        piglit_check_gl_error(GL_NO_ERROR);
>> +        if (tmp != values[0]) {
>> +            fprintf(stderr, "'%s' inconsitent buffer binding point"
>
> inconsistent

Good catch!
>
>> +                    "(%i) with glGetActiveUniformBlockiv"
>> +                    "(%i)\n", subsubtest, values[0], tmp);
>> +            *pass = false;
>> +        }
>> +
>> +        /* TODO: Create a more complete program where we actually bind
>> +         * buffers to some bind points to check this.
>> +         */
>
> IMO this is fine to be left as a 'future task'.

You mean I should change TODO to FIXMELATER?
>
>> +        break;
>> +
>> +    case GL_ACTIVE_VARIABLES:
>> +    case GL_COMPATIBLE_SUBROUTINES:
>> +        switch (programInterface) {
>> +        case GL_UNIFORM_BLOCK:
>> +            pif = GL_UNIFORM;
>> +            break;
>> +        case GL_SHADER_STORAGE_BLOCK:
>> +            pif = GL_BUFFER_VARIABLE;
>> +            break;
>> +        case GL_VERTEX_SUBROUTINE_UNIFORM:
>> +            pif = GL_VERTEX_SUBROUTINE;
>> +            break;
>> +        case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
>> +            pif = GL_TESS_CONTROL_SUBROUTINE;
>> +            break;
>> +        case GL_COMPUTE_SUBROUTINE_UNIFORM:
>> +            pif = GL_COMPUTE_SUBROUTINE;
>> +            break;
>> +        }
>> +
>> +        /* check that the return count is as expected */
>> +        if (c.count != length) {
>> +            fprintf(stderr, "'%s' expected %zu entries but got %i"
>> +                    "\n", subsubtest, c.count, length);
>> +            length = 1;
>> +            *pass = false;
>> +            break;
>> +        }
>> +
>> +        for (i = 0; i < length; i++) {
>> +            buf[0] = '\0';
>> +            glGetProgramResourceName(prog, pif, values[i],
>> +                         sizeof(buf), NULL, buf);
>> +            piglit_check_gl_error(GL_NO_ERROR);
>> +            if (!is_resource_in_list(inputs, buf, i, false)) {
>> +                fprintf(stderr, "'%s' could not find active "
>> +                    "resource '%s' (idx = %i) in the active"
>> +                    " list\n", subsubtest, buf, values[i]);
>> +                *pass = false;
>> +            }
>> +        }
>> +        break;
>> +
>> +    case GL_BUFFER_DATA_SIZE:
>> +        /* Nothing we can check here... */
>> +        break;
>> +
>> +    case GL_LOCATION:
>> +        loc = glGetProgramResourceLocation(prog, programInterface,
>> +                           name);
>> +        piglit_check_gl_error(GL_NO_ERROR);
>> +        if (loc != values[0]) {
>> +            fprintf(stderr, "'%s' inconsistent value between "
>> +                    "glGetProgramResourceiv(%i) and "
>> +                    "glGetProgramResourceLocation(%i).\n",
>> +                subsubtest, values[0], loc);
>> +            *pass = false;
>> +            break;
>> +        }
>> +
>> +        if (prog == prog_loc && values[0] != c.values[0]) {
>> +            fprintf(stderr, "'%s' expected location %i but got "
>> +                    "%i\n", subsubtest, c.values[0],
>> +                    values[0]);
>> +            *pass = false;
>> +            break;
>> +        }
>> +
>> +        /* continue by testing the (in)validity of the index */
>> +        basic_check(subsubtest, values[0], c.values[0], pass);
>> +        break;
>> +
>> +    case GL_LOCATION_INDEX:
>> +        loc = glGetProgramResourceLocationIndex(prog, programInterface,
>> +                            name);
>> +        piglit_check_gl_error(GL_NO_ERROR);
>> +        if (loc != values[0]) {
>> +            fprintf(stderr, "'%s' inconsistent value between "
>> +                    "glGetProgramResourceiv(%i) and "
>> +                    "glGetProgramResourceLocationIndex(%i)."
>> +                    "\n", subsubtest, values[0], loc);
>> +            *pass = false;
>> +            break;
>> +        }
>> +
>> +        /* continue by testing the (in)validity of the index */
>> +        basic_check(subsubtest, values[0], c.values[0], pass);
>> +        break;
>> +
>> +    default:
>> +        /* check that the return count is as expected */
>> +        if (c.count != length) {
>> +            fprintf(stderr, "'%s' expected %zu entries but got %i"
>> +                    "\n", subsubtest, c.count, length);
>> +            length = 1;
>> +            *pass = false;
>> +            break;
>> +        }
>> +
>> +        /* go through all the values returned */
>> +        for (i = 0; i < length; i++) {
>> +            if (values[i] != c.values[i]) {
>> +                fprintf(stderr, "'%s' expected %i but got %i at"
>> +                    " index %i\n", subsubtest, c.values[i],
>> +                    values[i], i);
>> +                *pass = false;
>> +            }
>> +        }
>> +
>> +        break;
>> +    }
>> +}
>> +
>> +static bool
>> +check_extensions(GLuint prog, GLenum programInterface)
>> +{
>> +    /* First check the availability of the extensions */
>> +    if ((programInterface == GL_BUFFER_VARIABLE ||
>> +        programInterface == GL_SHADER_STORAGE_BLOCK ||
>> +        prog == prog_stor) &&
>> + 
>> !piglit_is_extension_supported("GL_ARB_shader_storage_buffer_object")) {
>> +        return false;
>> +    }
>> +
>> +    if ((programInterface == GL_VERTEX_SUBROUTINE ||
>> +         programInterface == GL_GEOMETRY_SUBROUTINE ||
>> +         programInterface == GL_FRAGMENT_SUBROUTINE ||
>> +         programInterface == GL_COMPUTE_SUBROUTINE ||
>> +         programInterface == GL_VERTEX_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_GEOMETRY_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_FRAGMENT_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_COMPUTE_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_TESS_CONTROL_SUBROUTINE ||
>> +         programInterface == GL_TESS_EVALUATION_SUBROUTINE ||
>> +         programInterface == GL_TESS_CONTROL_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_TESS_EVALUATION_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_COMPUTE_SUBROUTINE_UNIFORM ||
>> +         prog == prog_sub || prog == prog_sub_tess) &&
>> + !piglit_is_extension_supported("GL_ARB_shader_subroutine")) {
>> +         return false;
>> +    }
>> +
>> +    if ((programInterface == GL_TESS_CONTROL_SUBROUTINE ||
>> +         programInterface == GL_TESS_EVALUATION_SUBROUTINE ||
>> +         programInterface == GL_TESS_CONTROL_SUBROUTINE_UNIFORM ||
>> +         programInterface == GL_TESS_EVALUATION_SUBROUTINE_UNIFORM ||
>> +         prog == prog_sub_tess) &&
>> + !piglit_is_extension_supported("GL_ARB_tessellation_shader")) {
>> +         return false;
>> +    }
>> +
>> +    if ((programInterface == GL_COMPUTE_SUBROUTINE ||
>> +         programInterface == GL_COMPUTE_SUBROUTINE_UNIFORM ||
>> +         prog == prog_cs) &&
>> + !piglit_is_extension_supported("GL_ARB_compute_shader") &&
>> + !piglit_is_extension_supported("GL_ARB_shader_image_load_store")) {
>> +         return false;
>> +    }
>> +
>> +    return true;
>> +}
>> +
>> +static void
>> +run_subtest(const struct subtest_t st, bool *pass)
>> +{
>> +    enum piglit_result result;
>> +    bool local_pass = true;
>> +    int index, i = 0;
>> +
>> +    if (*st.prog == -1 || !check_extensions(*st.prog, 
>> st.programInterface)) {
>> +        result = PIGLIT_SKIP;
>> +        goto report_result;
>> +    }
>> +
>> +    index = glGetProgramResourceIndex(*st.prog, st.programInterface,
>> +                      st.name);
>> +    piglit_check_gl_error(GL_NO_ERROR);
>> +    if (index < 0) {
>> +        printf("    Could not find resource '%s' in program %u\n",
>> +               st.name, *st.prog);
>> +        result = PIGLIT_FAIL;
>> +        goto report_result;
>> +    }
>> +
>> +    while (st.props[i].prop != 0) {
>> +        check_prop(*st.prog, st.programInterface, index, st.name,
>> +               st.inputs, st.props[i], &local_pass);
>> +        i++;
>> +    }
>> +
>> +    *pass = *pass && local_pass;
>> +    result = local_pass ? PIGLIT_PASS : PIGLIT_FAIL;
>> +
>> +report_result:
>> +    piglit_report_subtest_result(result, "%s on %s", st.name,
>> + piglit_get_gl_enum_name(st.programInterface));
>> +}
>> +
>> +void
>> +piglit_init(int argc, char **argv)
>> +{
>> +    static const char *st_r_tf_varying[] = {"gs_output0", NULL};
>> +
>> +    piglit_require_extension("GL_ARB_program_interface_query");
>
> please require GL_ARB_separate_shader_objects :)

Oops!

>
>> +
>> +    /* Allocate the different programs */
>> +    prog_std = piglit_build_simple_program_unlinked_multiple_shaders(
>> +                    GL_VERTEX_SHADER, vs_std,
>> +                    GL_GEOMETRY_SHADER, gs_std,
>> +                    GL_FRAGMENT_SHADER, fs_std,
>> +                    0);
>> +    glTransformFeedbackVaryings(prog_std, 1, st_r_tf_varying,
>> +                    GL_INTERLEAVED_ATTRIBS);
>> +    piglit_check_gl_error(GL_NO_ERROR);
>
> There was additional linker validation code added which makes the 
> shader above fail. As we use it also for some SSO cases in other tests 
> let's just mark it separable to pass validation:
>
> glProgramParameteri(prog_std, GL_PROGRAM_SEPARABLE, GL_TRUE);

Oh, right! Will do, thanks for the review!
>
>> +
>> +    glLinkProgram(prog_std);
>> +    if (!piglit_link_check_status(prog_std)) {
>> +        glDeleteProgram(prog_std);
>> +        piglit_report_result(PIGLIT_FAIL);
>> +    }
>> +
>> +    if 
>> (piglit_is_extension_supported("GL_ARB_shader_storage_buffer_object")) {
>> +        prog_stor = piglit_build_simple_program_multiple_shaders(
>> +                        GL_VERTEX_SHADER, vs_stor,
>> +                        GL_GEOMETRY_SHADER, gs_stor,
>> +                        GL_FRAGMENT_SHADER, fs_stor,
>> +                        0);
>> +        if (!piglit_link_check_status(prog_stor)) {
>> +            glDeleteProgram(prog_stor);
>> +            piglit_report_result(PIGLIT_FAIL);
>> +        }
>> +    }
>> +
>> +    if 
>> (piglit_is_extension_supported("GL_ARB_explicit_attrib_location") &&
>> + piglit_is_extension_supported("GL_ARB_explicit_uniform_location")) {
>> +        prog_loc = piglit_build_simple_program_multiple_shaders(
>> +                        GL_VERTEX_SHADER, vs_loc,
>> +                        GL_FRAGMENT_SHADER, fs_loc,
>> +                        0);
>> +        if (!piglit_link_check_status(prog_loc)) {
>> +            glDeleteProgram(prog_loc);
>> +            piglit_report_result(PIGLIT_FAIL);
>> +        }
>> +    }
>> +
>> +    if (!piglit_is_extension_supported("GL_ARB_shader_subroutine")) {
>> +        return;
>> +    }
>> +
>> +    prog_sub = piglit_build_simple_program_multiple_shaders(
>> +                GL_VERTEX_SHADER, vs_sub,
>> +                GL_GEOMETRY_SHADER, gs_sub,
>> +                GL_FRAGMENT_SHADER, fs_sub,
>> +                0);
>> +    if (!piglit_link_check_status(prog_sub)) {
>> +        glDeleteProgram(prog_sub);
>> +        piglit_report_result(PIGLIT_FAIL);
>> +    }
>> +
>> +    if (piglit_is_extension_supported("GL_ARB_tessellation_shader")) {
>> +        prog_sub_tess =
>> + piglit_build_simple_program_unlinked_multiple_shaders(
>> +                    GL_TESS_CONTROL_SHADER, tcs_sub,
>> +                    0);
>> +        /* force the compiler not to optimise away inputs/outputs */
>> +        glProgramParameteri(prog_sub_tess, GL_PROGRAM_SEPARABLE,
>> +                    GL_TRUE);
>> +        piglit_check_gl_error(GL_NO_ERROR);
>> +
>> +        glLinkProgram(prog_sub_tess);
>> +        if (!piglit_link_check_status(prog_sub_tess)) {
>> +            glDeleteProgram(prog_sub_tess);
>> +            piglit_report_result(PIGLIT_FAIL);
>> +        }
>> +    }
>> +
>> +    if (piglit_is_extension_supported("GL_ARB_compute_shader")) {
>> +        prog_cs = piglit_build_simple_program_multiple_shaders(
>> +                        GL_COMPUTE_SHADER, cs_sub,
>> +                        0);
>> +        if (!piglit_link_check_status(prog_cs)) {
>> +            glDeleteProgram(prog_cs);
>> +            piglit_report_result(PIGLIT_FAIL);
>> +        }
>> +    }
>> +}
>> +
>> +static void
>> +test_error_cases(bool *pass)
>> +{
>> +    GLenum props[] = {GL_NAME_LENGTH};
>> +    GLenum props_invalid[] = {GL_NAME_LENGTH, GL_TRUE, GL_TYPE};
>> +    GLenum props_error[] = {GL_NAME_LENGTH, GL_OFFSET, GL_TYPE};
>> +    int values[10];
>> +    GLuint shader;
>> +    bool prg_tst;
>> +
>> +    /* test using an unexisting program ID */
>> +    glGetProgramResourceiv(1337, GL_UNIFORM, 0, 1, props, 10, NULL, 
>> values);
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "Invalid program (undefined ID)");
>> +
>> +    /* test using a shader ID */
>> +    shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_empty);
>> +    glGetProgramResourceIndex(shader, GL_UNIFORM, "resource");
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "Invalid program (call on shader)");
>> +
>> +    /* invalid index. This is unspecified but let's check it is 
>> consistent
>> +     * with GetProgramResourceName.
>> +     */
>> +    glGetProgramResourceiv(prog_std, GL_UNIFORM, 1337, 0, props, 10, 
>> NULL,
>> +                   values);
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "Invalid index");
>> +
>> +    /* test propcount == 0 */
>> +    glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 0, props, 10, NULL,
>> +                   values);
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "<propcount> == 0");
>> +
>> +    /* test propcount < 0 */
>> +    glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, -1, props, 10, 
>> NULL,
>> +                   values);
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "<propcount> < 0");
>> +
>> +    /* one invalid property */
>> +    glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 3, 
>> props_invalid, 10,
>> +                   NULL, values);
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_ENUM);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "prop == GL_TRUE");
>> +
>> +    /* property not acceptable for one program interface */
>> +    glGetProgramResourceiv(prog_std, GL_PROGRAM_INPUT, 0, 3, 
>> props_error,
>> +                   10, NULL, values);
>> +    prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION);
>> +    *pass = *pass && prg_tst;
>> +    piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
>> +                     "GL_OFFSET on GL_PROGRAM_INPUT");
>> +}
>> +
>> +static void
>> +glDeleteProgramSafe(GLuint prog)
>> +{
>> +    if (prog != -1)
>> +        glDeleteProgram(prog);
>> +}
>> +
>> +enum piglit_result
>> +piglit_display(void)
>> +{
>> +    bool pass = true;
>> +    int i;
>> +
>> +    test_error_cases(&pass);
>> +
>> +    /* run all the getprogramresourceiv tests */
>> +    for (i = 0; i < sizeof(subtests) / sizeof(struct subtest_t); i++) {
>> +        run_subtest(subtests[i], &pass);
>> +    }
>> +
>> +    glDeleteProgramSafe(prog_loc);
>> +    glDeleteProgramSafe(prog_cs);
>> +    glDeleteProgramSafe(prog_sub_tess);
>> +    glDeleteProgramSafe(prog_sub);
>> +    glDeleteProgramSafe(prog_stor);
>> +    glDeleteProgramSafe(prog_std);
>> +
>> +    return pass ? PIGLIT_PASS : PIGLIT_FAIL;
>> +}
>>



More information about the Piglit mailing list