From: Ian Romanick <[email protected]> This enables querying various aspects of a uniform using glActiveUniformsiv. Future commits will use this feature to test UBO layouts.
Signed-off-by: Ian Romanick <[email protected]> --- tests/shaders/shader_runner.c | 218 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 1 deletion(-) diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c index 3d77db9..310b2d4 100644 --- a/tests/shaders/shader_runner.c +++ b/tests/shaders/shader_runner.c @@ -80,6 +80,8 @@ struct component_version { char _string[100]; }; +#define ENUM_STRING(e) { #e, e } + struct string_to_enum { const char *name; GLenum token; @@ -1614,6 +1616,219 @@ set_uniform(const char *line, int ubo_array_index) return; } +/** + * Query a uniform using glGetActiveUniformsiv + * + * Format of the command: + * + * active uniform uniform_name GL_PNAME_ENUM integer + * + * or + * + * active uniform uniform_name GL_PNAME_ENUM GL_TYPE_ENUM + */ +void +active_uniform(const char *line) +{ + static const struct string_to_enum all_pnames[] = { + ENUM_STRING(GL_UNIFORM_TYPE), + ENUM_STRING(GL_UNIFORM_SIZE), + ENUM_STRING(GL_UNIFORM_NAME_LENGTH), + ENUM_STRING(GL_UNIFORM_BLOCK_INDEX), + ENUM_STRING(GL_UNIFORM_OFFSET), + ENUM_STRING(GL_UNIFORM_ARRAY_STRIDE), + ENUM_STRING(GL_UNIFORM_MATRIX_STRIDE), + ENUM_STRING(GL_UNIFORM_IS_ROW_MAJOR), + ENUM_STRING(GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX), + { NULL, 0 } + }; + + static const struct string_to_enum all_types[] = { + ENUM_STRING(GL_FLOAT), + ENUM_STRING(GL_FLOAT_VEC2), + ENUM_STRING(GL_FLOAT_VEC3), + ENUM_STRING(GL_FLOAT_VEC4), + ENUM_STRING(GL_DOUBLE), + ENUM_STRING(GL_DOUBLE_VEC2), + ENUM_STRING(GL_DOUBLE_VEC3), + ENUM_STRING(GL_DOUBLE_VEC4), + ENUM_STRING(GL_INT), + ENUM_STRING(GL_INT_VEC2), + ENUM_STRING(GL_INT_VEC3), + ENUM_STRING(GL_INT_VEC4), + ENUM_STRING(GL_UNSIGNED_INT), + ENUM_STRING(GL_UNSIGNED_INT_VEC2), + ENUM_STRING(GL_UNSIGNED_INT_VEC3), + ENUM_STRING(GL_UNSIGNED_INT_VEC4), + ENUM_STRING(GL_BOOL), + ENUM_STRING(GL_BOOL_VEC2), + ENUM_STRING(GL_BOOL_VEC3), + ENUM_STRING(GL_BOOL_VEC4), + ENUM_STRING(GL_FLOAT_MAT2), + ENUM_STRING(GL_FLOAT_MAT3), + ENUM_STRING(GL_FLOAT_MAT4), + ENUM_STRING(GL_FLOAT_MAT2x3), + ENUM_STRING(GL_FLOAT_MAT2x4), + ENUM_STRING(GL_FLOAT_MAT3x2), + ENUM_STRING(GL_FLOAT_MAT3x4), + ENUM_STRING(GL_FLOAT_MAT4x2), + ENUM_STRING(GL_FLOAT_MAT4x3), + ENUM_STRING(GL_DOUBLE_MAT2), + ENUM_STRING(GL_DOUBLE_MAT3), + ENUM_STRING(GL_DOUBLE_MAT4), + ENUM_STRING(GL_DOUBLE_MAT2x3), + ENUM_STRING(GL_DOUBLE_MAT2x4), + ENUM_STRING(GL_DOUBLE_MAT3x2), + ENUM_STRING(GL_DOUBLE_MAT3x4), + ENUM_STRING(GL_DOUBLE_MAT4x2), + ENUM_STRING(GL_DOUBLE_MAT4x3), + ENUM_STRING(GL_SAMPLER_1D), + ENUM_STRING(GL_SAMPLER_2D), + ENUM_STRING(GL_SAMPLER_3D), + ENUM_STRING(GL_SAMPLER_CUBE), + ENUM_STRING(GL_SAMPLER_1D_SHADOW), + ENUM_STRING(GL_SAMPLER_2D_SHADOW), + ENUM_STRING(GL_SAMPLER_1D_ARRAY), + ENUM_STRING(GL_SAMPLER_2D_ARRAY), + ENUM_STRING(GL_SAMPLER_1D_ARRAY_SHADOW), + ENUM_STRING(GL_SAMPLER_2D_ARRAY_SHADOW), + ENUM_STRING(GL_SAMPLER_2D_MULTISAMPLE), + ENUM_STRING(GL_SAMPLER_2D_MULTISAMPLE_ARRAY), + ENUM_STRING(GL_SAMPLER_CUBE_SHADOW), + ENUM_STRING(GL_SAMPLER_BUFFER), + ENUM_STRING(GL_SAMPLER_2D_RECT), + ENUM_STRING(GL_SAMPLER_2D_RECT_SHADOW), + ENUM_STRING(GL_INT_SAMPLER_1D), + ENUM_STRING(GL_INT_SAMPLER_2D), + ENUM_STRING(GL_INT_SAMPLER_3D), + ENUM_STRING(GL_INT_SAMPLER_CUBE), + ENUM_STRING(GL_INT_SAMPLER_1D_ARRAY), + ENUM_STRING(GL_INT_SAMPLER_2D_ARRAY), + ENUM_STRING(GL_INT_SAMPLER_2D_MULTISAMPLE), + ENUM_STRING(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY), + ENUM_STRING(GL_INT_SAMPLER_BUFFER), + ENUM_STRING(GL_INT_SAMPLER_2D_RECT), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_1D), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_3D), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_CUBE), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_BUFFER), + ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_RECT), + { NULL, 0 } + }; + + char name[512]; + char name_buf[512]; + char pname_string[512]; + GLenum pname; + GLint expected; + int i; + int num_active_uniforms; + + line = strcpy_to_space(name, eat_whitespace(line)); + + strcpy_to_space(pname_string, eat_whitespace(line)); + pname = lookup_enum_string(all_pnames, &line, "glGetUniformsiv pname"); + + line = eat_whitespace(line); + if (isdigit(line[0])) { + expected = strtol(line, NULL, 0); + } else { + expected = lookup_enum_string(all_types, &line, "type enum"); + } + + glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_active_uniforms); + for (i = 0; i < num_active_uniforms; i++) { + GLint got; + GLint size; + GLenum type; + GLsizei name_len; + bool pass = true; + + glGetActiveUniform(prog, i, sizeof(name_buf), &name_len, + &size, &type, name_buf); + + if (!piglit_check_gl_error(GL_NO_ERROR)) { + fprintf(stderr, "glGetActiveUniform error\n"); + piglit_report_result(PIGLIT_FAIL); + } + + if (strcmp(name, name_buf) != 0) + continue; + + /* If the requested pname is one of the values that + * glGetActiveUniform happens to return, check the value + * returned by that function too. + */ + switch (pname) { + case GL_UNIFORM_TYPE: + got = (GLint) type; + break; + + case GL_UNIFORM_SIZE: + got = size; + break; + + case GL_UNIFORM_NAME_LENGTH: + got = name_len; + break; + + default: + /* This ensures the check below will pass when the + * requested enum is not one of the values already + * returned by glGetActiveUniform. + */ + got = expected; + break; + } + + if (got != expected) { + fprintf(stderr, + "glGetActiveUniform(%s, %s): " + "expected %d (0x%04x), got %d (0x%04x)\n", + name, pname_string, + expected, expected, got, got); + pass = false; + } + + /* Set 'got' to some value in case glGetActiveUniformsiv + * doesn't write to it. That should only be able to occur + * when the function raises a GL error, but "should" is kind + * of a funny word. + */ + got = ~expected; + glGetActiveUniformsiv(prog, 1, (GLuint *) &i, pname, &got); + + if (!piglit_check_gl_error(GL_NO_ERROR)) { + fprintf(stderr, "glGetActiveUniformsiv error\n"); + piglit_report_result(PIGLIT_FAIL); + } + + if (got != expected) { + fprintf(stderr, + "glGetActiveUniformsiv(%s, %s): " + "expected %d, got %d\n", + name, pname_string, + expected, got); + pass = false; + } + + if (!pass) + piglit_report_result(PIGLIT_FAIL); + + return; + } + + + fprintf(stderr, "No active uniform named \"%s\"\n", name); + piglit_report_result(PIGLIT_FAIL); + return; +} + void set_parameter(const char *line) { @@ -1712,7 +1927,6 @@ do_enable_disable(const char *line, bool enable_flag) glDisable(value); } -#define ENUM_STRING(e) { #e, e } static const struct string_to_enum hint_target_table[] = { ENUM_STRING(GL_LINE_SMOOTH_HINT), ENUM_STRING(GL_POLYGON_SMOOTH_HINT), @@ -2375,6 +2589,8 @@ piglit_display(void) program_must_be_in_use(); } else if (string_match("ubo array index ", line)) { get_ints(line + strlen("ubo array index "), &ubo_array_index, 1); + } else if (string_match("active uniform ", line)) { + active_uniform(line + strlen("active uniform ")); } else if ((line[0] != '\n') && (line[0] != '\0') && (line[0] != '#')) { printf("unknown command \"%s\"\n", line); -- 1.8.1.4 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
