From: Dave Airlie <airl...@redhat.com> This adds basic support for executing shader subroutine tests.
it comes with two intro tests, and probably a lot of bugs. tested against NVIDIA, for some reason -auto fails here. v2: add support for other shader types (Ilia) Signed-off-by: Dave Airlie <airl...@redhat.com> --- tests/shaders/shader_runner.c | 138 +++++++++++++++++++++ .../execution/simple-subroutine.shader_test | 42 +++++++ .../execution/two-subroutines.shader_test | 59 +++++++++ 3 files changed, 239 insertions(+) create mode 100644 tests/spec/arb_shader_subroutine/execution/simple-subroutine.shader_test create mode 100644 tests/spec/arb_shader_subroutine/execution/two-subroutines.shader_test diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c index 20eb26c..d8a91cb 100644 --- a/tests/shaders/shader_runner.c +++ b/tests/shaders/shader_runner.c @@ -113,6 +113,14 @@ GLenum geometry_layout_output_type = GL_TRIANGLE_STRIP; GLint geometry_layout_vertices_out = 0; GLuint atomics_bo = 0; +struct subroutine_uniform { + GLuint uniform_location; + GLuint uniform_index; +}; + +#define SHADER_TYPES 6 +static struct subroutine_uniform subuniforms[SHADER_TYPES][64]; +static int num_subuniforms[SHADER_TYPES]; char *shader_string; GLint shader_string_size; const char *vertex_data_start = NULL; @@ -1642,6 +1650,131 @@ set_uniform(const char *line, int ubo_array_index) return; } +static GLenum lookup_shader_type(GLuint idx) +{ + switch (idx) { + case 0: + return GL_VERTEX_SHADER; + case 1: + return GL_FRAGMENT_SHADER; + case 2: + return GL_GEOMETRY_SHADER; + case 3: + return GL_TESS_CONTROL_SHADER; + case 4: + return GL_TESS_EVALUATION_SHADER; + case 5: + return GL_COMPUTE_SHADER; + default: + return 0; + } +} + +static GLenum get_shader_from_string(const char *name, int *idx) +{ + if (string_match("GL_VERTEX_SHADER", name)) { + *idx = 0; + return GL_VERTEX_SHADER; + } + if (string_match("GL_FRAGMENT_SHADER", name)) { + *idx = 1; + return GL_FRAGMENT_SHADER; + } + if (string_match("GL_GEOMETRY_SHADER", name)) { + *idx = 2; + return GL_GEOMETRY_SHADER; + } + if (string_match("GL_TESS_CONTROL_SHADER", name)) { + *idx = 3; + return GL_TESS_CONTROL_SHADER; + } + if (string_match("GL_TESS_EVALUATION_SHADER", name)) { + *idx = 4; + return GL_TESS_EVALUATION_SHADER; + } + if (string_match("GL_COMPUTE_SHADER", name)) { + *idx = 5; + return GL_COMPUTE_SHADER; + } + return 0; +} + +void +program_subroutine_uniforms(void) +{ + int i, sidx; + GLuint uniformidx[64]; + int stype; + for (sidx = 0; sidx < 4; sidx++) { + + if (num_subuniforms[sidx] == 0) + continue; + stype = lookup_shader_type(sidx); + if (!stype) + continue; + + for (i = 0; i < num_subuniforms[sidx]; i++) + uniformidx[i] = subuniforms[sidx][i].uniform_index; + + glUniformSubroutinesuiv(stype, num_subuniforms[sidx], uniformidx); + } +} + +void +set_subroutine_uniform(const char *line) +{ + GLuint prog; + char name[512]; + char subname[512]; + const char *type; + GLint loc; + GLuint idx; + GLenum ptype = 0; + int sidx = 0, i; + + type = eat_whitespace(line); + line = eat_text(type); + + line = strcpy_to_space(name, eat_whitespace(line)); + line = strcpy_to_space(subname, eat_whitespace(line)); + + ptype = get_shader_from_string(type, &sidx); + if (ptype == 0) { + printf("illegal type in subroutine uniform\n"); + piglit_report_result(PIGLIT_FAIL); + } + + glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *) &prog); + + loc = glGetSubroutineUniformLocation(prog, ptype, name); + if (loc < 0) { + printf("cannot get location of uniform \"%s\"\n", + name); + piglit_report_result(PIGLIT_FAIL); + } + + idx = glGetSubroutineIndex(prog, ptype, subname); + if (idx == GL_INVALID_INDEX) { + printf("cannot get index of subroutine uniform \"%s\"\n", + subname); + piglit_report_result(PIGLIT_FAIL); + } + + for (i = 0; i < num_subuniforms[sidx]; i++) { + if (subuniforms[sidx][i].uniform_location == loc) { + subuniforms[sidx][i].uniform_index = idx; + break; + } + } + if (i == num_subuniforms[sidx]) { + num_subuniforms[sidx]++; + subuniforms[sidx][i].uniform_location = loc; + subuniforms[sidx][i].uniform_index = idx; + } + + return; +} + /** * Query a uniform using glGetActiveUniformsiv * @@ -2300,11 +2433,13 @@ piglit_display(void) glMemoryBarrier(GL_ALL_BARRIER_BITS); } else if (string_match("draw rect tex", line)) { program_must_be_in_use(); + program_subroutine_uniforms(); get_floats(line + 13, c, 8); piglit_draw_rect_tex(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]); } else if (string_match("draw rect", line)) { program_must_be_in_use(); + program_subroutine_uniforms(); get_floats(line + 9, c, 4); piglit_draw_rect(c[0], c[1], c[2], c[3]); } else if (string_match("draw instanced rect", line)) { @@ -2614,6 +2749,9 @@ piglit_display(void) } else if (string_match("uniform", line)) { program_must_be_in_use(); set_uniform(line + 7, ubo_array_index); + } else if (string_match("subuniform", line)) { + program_must_be_in_use(); + set_subroutine_uniform(line + 10); } else if (string_match("parameter ", line)) { set_parameter(line + strlen("parameter ")); } else if (string_match("patch parameter ", line)) { diff --git a/tests/spec/arb_shader_subroutine/execution/simple-subroutine.shader_test b/tests/spec/arb_shader_subroutine/execution/simple-subroutine.shader_test new file mode 100644 index 0000000..ae5925f --- /dev/null +++ b/tests/spec/arb_shader_subroutine/execution/simple-subroutine.shader_test @@ -0,0 +1,42 @@ +[require] +GLSL >= 1.50 +GL_ARB_shader_subroutine + +[vertex shader passthrough] + +[fragment shader] +#version 150 +#extension GL_ARB_shader_subroutine: enable + +out vec4 color; + +subroutine vec4 getcolor(); +subroutine uniform getcolor GetColor; + +subroutine(getcolor) +vec4 color_red() +{ + return vec4(1.0, 0.0, 0.0, 1.0); +} + +subroutine(getcolor) +vec4 color_green() +{ + return vec4(0.0, 1.0, 0.0, 1.0); +} + +void main() +{ + color = GetColor(); +} + + +[test] +clear color 0.0 0.0 1.0 0.0 +clear +subuniform GL_FRAGMENT_SHADER GetColor color_red +draw rect -1 -1 2 2 +probe all rgba 1.0 0.0 0.0 1.0 +subuniform GL_FRAGMENT_SHADER GetColor color_green +draw rect -1 -1 2 2 +probe all rgba 0.0 1.0 0.0 1.0 diff --git a/tests/spec/arb_shader_subroutine/execution/two-subroutines.shader_test b/tests/spec/arb_shader_subroutine/execution/two-subroutines.shader_test new file mode 100644 index 0000000..a38b695 --- /dev/null +++ b/tests/spec/arb_shader_subroutine/execution/two-subroutines.shader_test @@ -0,0 +1,59 @@ +[require] +GLSL >= 1.50 +GL_ARB_shader_subroutine + +[vertex shader passthrough] + +[fragment shader] +#version 150 +#extension GL_ARB_shader_subroutine: enable + +out vec4 color; + +subroutine float getchan1(); +subroutine uniform getchan1 GetChan1; + +subroutine float getchan2(); +subroutine uniform getchan2 GetChan2; + +subroutine(getchan1) +float chan1_full() +{ + return 1.0; +} + +subroutine(getchan1) +float chan1_empty() +{ + return 0.0; +} + +subroutine(getchan2) +float chan2_full() +{ + return 1.0; +} + +subroutine(getchan2) +float chan2_empty() +{ + return 0.0; +} + +void main() +{ + color = vec4(GetChan1(), GetChan2(), 0.0, 1.0); +} + + +[test] +clear color 0.0 0.0 1.0 0.0 +clear +subuniform GL_FRAGMENT_SHADER GetChan1 chan1_full +subuniform GL_FRAGMENT_SHADER GetChan2 chan2_empty +draw rect -1 -1 2 2 +probe all rgba 1.0 0.0 0.0 1.0 +subuniform GL_FRAGMENT_SHADER GetChan1 chan1_empty +subuniform GL_FRAGMENT_SHADER GetChan2 chan2_full +draw rect -1 -1 2 2 +probe all rgba 0.0 1.0 0.0 1.0 -- 1.8.3.1 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit