[Piglit] [PATCH] shader_runner: add ARB_shader_subroutine support (v2)
Dave Airlie
airlied at gmail.com
Mon Apr 6 22:44:46 PDT 2015
From: Dave Airlie <airlied at 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 <airlied at 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
More information about the Piglit
mailing list