Note that there are two slightly different variants of geometry shaders: those supported by GLSL 1.50 and those supported by ARB_geometry_shader4. A principal difference between these two variants is in how geometry shader layout parameters are specified (i.e. input and output primitive types, max number of output vertices). When using GLSL 1.50 style geometry shaders, these layout parameters are specified in the shader source. When using ARB_geometry_shader4 style geometry shaders, these layout parameters are specified by calling glProgramParameteriARB() prior to linking.
In order to support both variants, this patch allows an optional "[geometry layout]" section to shader_runner test files. For example the following [geometry layout] section: [geometry layout] input type GL_POINTS output type GL_LINE_STRIP vertices out 3 Causes shader_runner to make these calls prior to linking: glProgramParameteriARB(prog, GL_GEOMETRY_INPUT_TYPE_ARB, GL_POINTS); glProgramParameteriARB(prog, GL_GEOMETRY_OUTPUT_TYPE_ARB, GL_LINE_STRIP); glProgramParameteriARB(prog, GL_GEOMETRY_VERTICES_OUT_ARB, 3); --- tests/shaders/shader_runner.c | 88 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c index 770f0c8..eae5063 100644 --- a/tests/shaders/shader_runner.c +++ b/tests/shaders/shader_runner.c @@ -41,6 +41,8 @@ static void get_required_versions(const char *script_name, struct piglit_gl_test_config *config); +GLenum +decode_drawing_mode(const char *mode_str); PIGLIT_GL_TEST_CONFIG_BEGIN @@ -85,6 +87,9 @@ GLuint fragment_shaders[256]; unsigned num_fragment_shaders = 0; int num_uniform_blocks; GLuint *uniform_block_bos; +GLenum geometry_layout_input_type = GL_TRIANGLES; +GLenum geometry_layout_output_type = GL_TRIANGLE_STRIP; +GLint geometry_layout_vertices_out = 0; char *shader_string; GLint shader_string_size; @@ -101,6 +106,7 @@ enum states { vertex_program, geometry_shader, geometry_shader_file, + geometry_layout, fragment_shader, fragment_shader_file, fragment_program, @@ -183,6 +189,23 @@ string_match(const char *string, const char *line) return (strncmp(string, line, strlen(string)) == 0); } + +const char * +target_to_short_name(GLenum target) +{ + switch (target) { + case GL_VERTEX_SHADER: + return "VS"; + case GL_FRAGMENT_SHADER: + return "FS"; + case GL_GEOMETRY_SHADER: + return "GS"; + default: + return "???"; + } +} + + void compile_glsl(GLenum target, bool release_text) { @@ -247,7 +270,7 @@ compile_glsl(GLenum target, bool release_text) glGetShaderInfoLog(shader, size, NULL, info); fprintf(stderr, "Failed to compile %s: %s\n", - target == GL_FRAGMENT_SHADER ? "FS" : "VS", + target_to_short_name(target), info); free(info); @@ -619,6 +642,32 @@ process_requirement(const char *line) } +/** + * Process a line from the [geometry layout] section of a test + */ +void +process_geometry_layout(const char *line) +{ + char s[32]; + int x; + + line = eat_whitespace(line); + + if (line[0] == '\0' || line[0] == '\n') { + return; + } else if (sscanf(line, "input type %31s", s) == 1) { + geometry_layout_input_type = decode_drawing_mode(s); + } else if (sscanf(line, "output type %31s", s) == 1) { + geometry_layout_output_type = decode_drawing_mode(s); + } else if (sscanf(line, "vertices out %d", &x) == 1) { + geometry_layout_vertices_out = x; + } else { + printf("Could not parse geometry layout line: %s\n", line); + piglit_report_result(PIGLIT_FAIL); + } +} + + void leave_state(enum states state, const char *line) { @@ -645,6 +694,15 @@ leave_state(enum states state, const char *line) break; case geometry_shader: + shader_string_size = line - shader_string; + compile_glsl(GL_GEOMETRY_SHADER, false); + break; + + case geometry_shader_file: + compile_glsl(GL_GEOMETRY_SHADER, true); + break; + + case geometry_layout: break; case fragment_shader: @@ -701,6 +759,21 @@ link_and_use_shaders(void) glAttachShader(prog, fragment_shaders[i]); } +#ifdef PIGLIT_USE_OPENGL + if (geometry_layout_input_type != GL_TRIANGLES) { + glProgramParameteriARB(prog, GL_GEOMETRY_INPUT_TYPE_ARB, + geometry_layout_input_type); + } + if (geometry_layout_output_type != GL_TRIANGLE_STRIP) { + glProgramParameteriARB(prog, GL_GEOMETRY_OUTPUT_TYPE_ARB, + geometry_layout_output_type); + } + if (geometry_layout_vertices_out != 0) { + glProgramParameteriARB(prog, GL_GEOMETRY_VERTICES_OUT_ARB, + geometry_layout_vertices_out); + } +#endif + glLinkProgram(prog); for (i = 0; i < num_vertex_shaders; i++) { @@ -780,6 +853,15 @@ process_test_script(const char *script_name) } else if (string_match("[vertex shader file]", line)) { state = vertex_shader_file; shader_string = NULL; + } else if (string_match("[geometry shader]", line)) { + state = geometry_shader; + shader_string = NULL; + } else if (string_match("[geometry shader file]", line)) { + state = vertex_shader_file; + shader_string = NULL; + } else if (string_match("[geometry layout]", line)) { + state = geometry_layout; + shader_string = NULL; } else if (string_match("[fragment shader]", line)) { state = fragment_shader; shader_string = NULL; @@ -807,6 +889,10 @@ process_test_script(const char *script_name) process_requirement(line); break; + case geometry_layout: + process_geometry_layout(line); + break; + case vertex_shader: case vertex_program: case geometry_shader: -- 1.8.1.3 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit