[Piglit] [PATCH] shader_runner: Add basic SSO support to shader runner
Timothy Arceri
t_arceri at yahoo.com.au
Wed Dec 2 22:47:56 PST 2015
On Thu, 2015-12-03 at 17:41 +1100, Timothy Arceri wrote:
> This sets up the basics for using SSO with shader runner. This will
> only support vertex and fragment shaders but is easily extended.
>
> Example shader:
>
> [require]
> GLSL >= 1.50
>
> [vertex sso]
Git commit ate the version and extensions
#version 150
#extension GL_ARB_explicit_attrib_location: require
#extension GL_ARB_separate_shader_objects: require
here and for frag shader below.
>
> layout(location = 0) in vec4 piglit_vertex;
>
> layout(location = 2) out vec3 a;
> layout(location = 3) out vec3 b;
>
> void main()
> {
> gl_Position = piglit_vertex;
> a = vec3(0, 0, 1);
> b = vec3(1, 0, 0);
> }
>
> [fragment sso]
>
> layout(location = 0) out vec4 out_color;
>
> layout(location = 2) in vec3 b; /* should get vec3(0, 0, 1) */
> layout(location = 3) in vec3 a; /* should get vec3(1, 0, 0) */
>
> void main()
> {
> out_color = vec4(cross(b, a), 1);
> }
>
> [test]
> draw rect -1 -1 2 2
> probe all rgb 0 1 0
> ---
> tests/shaders/shader_runner.c | 78
> ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 77 insertions(+), 1 deletion(-)
>
> diff --git a/tests/shaders/shader_runner.c
> b/tests/shaders/shader_runner.c
> index eeb1aac..6010ae2 100644
> --- a/tests/shaders/shader_runner.c
> +++ b/tests/shaders/shader_runner.c
> @@ -123,10 +123,12 @@ GLint shader_string_size;
> const char *vertex_data_start = NULL;
> const char *vertex_data_end = NULL;
> GLuint prog;
> +GLuint pipeline;
> size_t num_vbo_rows = 0;
> bool vbo_present = false;
> bool link_ok = false;
> bool prog_in_use = false;
> +bool sso_in_use = false;
> GLchar *prog_err_info = NULL;
> GLuint vao = 0;
> GLuint fbo = 0;
> @@ -137,12 +139,14 @@ enum states {
> requirements,
> vertex_shader,
> vertex_shader_passthrough,
> + vertex_sso,
> vertex_program,
> tess_ctrl_shader,
> tess_eval_shader,
> geometry_shader,
> geometry_layout,
> fragment_shader,
> + fragment_sso,
> fragment_program,
> compute_shader,
> vertex_data,
> @@ -480,6 +484,48 @@ compile_and_bind_program(GLenum target, const
> char *start, int len)
> prog_in_use = true;
> }
>
> +void
> +create_sso(GLenum target, const char *start, int len)
> +{
> + GLuint prog;
> + GLint ok;
> + char *source;
> +
> + piglit_require_extension("GL_ARB_separate_shader_objects");
> +
> + source = malloc(len + 1);
> + memcpy(source, start, len);
> + source[len] = 0;
> + prog = glCreateShaderProgramv(target, 1,
> + (const GLchar *const *)
> &source);
> +
> + glGetProgramiv(prog, GL_LINK_STATUS, &ok);
> + if (ok) {
> + link_ok = true;
> + } else {
> + GLint size;
> +
> + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
> + prog_err_info = malloc(size);
> +
> + glGetProgramInfoLog(prog, size, NULL,
> prog_err_info);
> +
> + return;
> + }
> +
> + switch (target) {
> + case GL_VERTEX_SHADER:
> + glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT,
> prog);
> + break;
> + case GL_FRAGMENT_SHADER:
> + glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT,
> prog);
> + break;
> + }
> +
> + sso_in_use = true;
> + prog_in_use = true;
> +}
> +
> /**
> * Compare two values given a specified comparison operator
> */
> @@ -846,6 +892,13 @@ leave_state(enum states state, const char *line)
> compile_glsl(GL_VERTEX_SHADER);
> break;
>
> + case vertex_sso:
> + shader_string_size = line - shader_string;
> + create_sso(GL_VERTEX_SHADER,
> + shader_string,
> + line - shader_string);
> + break;
> +
> case vertex_program:
> compile_and_bind_program(GL_VERTEX_PROGRAM_ARB,
> shader_string,
> @@ -875,6 +928,12 @@ leave_state(enum states state, const char *line)
> compile_glsl(GL_FRAGMENT_SHADER);
> break;
>
> + case fragment_sso:
> + create_sso(GL_FRAGMENT_SHADER,
> + shader_string,
> + line - shader_string);
> + break;
> +
> case fragment_program:
> compile_and_bind_program(GL_FRAGMENT_PROGRAM_ARB,
> shader_string,
> @@ -1043,6 +1102,9 @@ process_test_script(const char *script_name)
> } else if (string_match("[vertex program]",
> line)) {
> state = vertex_program;
> shader_string = NULL;
> + } else if (string_match("[vertex sso]",
> line)) {
> + state = vertex_sso;
> + shader_string = NULL;
> } else if (string_match("[vertex shader
> passthrough]", line)) {
> state = vertex_shader_passthrough;
> shader_string =
> @@ -1063,6 +1125,9 @@ process_test_script(const char *script_name)
> } else if (string_match("[fragment shader]",
> line)) {
> state = fragment_shader;
> shader_string = NULL;
> + } else if (string_match("[fragment sso]",
> line)) {
> + state = fragment_sso;
> + shader_string = NULL;
> } else if (string_match("[fragment
> program]", line)) {
> state = fragment_program;
> shader_string = NULL;
> @@ -1098,11 +1163,13 @@ process_test_script(const char *script_name)
> break;
>
> case vertex_shader:
> + case vertex_sso:
> case vertex_program:
> case tess_ctrl_shader:
> case tess_eval_shader:
> case geometry_shader:
> case fragment_shader:
> + case fragment_sso:
> case fragment_program:
> case compute_shader:
> if (shader_string == NULL)
> @@ -3094,8 +3161,10 @@ piglit_display(void)
> glDeleteProgram(prog);
> glUseProgram(0);
> } else {
> - glDeleteProgramsARB(1, &prog);
> + if (!sso_in_use)
> + glDeleteProgramsARB(1, &prog);
> }
> + glGenProgramPipelines(1, &pipeline);
> }
>
> return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> @@ -3138,6 +3207,9 @@ piglit_init(int argc, char **argv)
> glGetIntegerv(GL_MAX_VARYING_COMPONENTS,
> &gl_max_varying_components);
> glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max_clip_planes);
> +
> + if
> (piglit_is_extension_supported("GL_ARB_separate_shader_objects"))
> + glGenProgramPipelines(1, &pipeline);
> #else
> glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
> &gl_max_fragment_uniform_components);
> @@ -3157,6 +3229,10 @@ piglit_init(int argc, char **argv)
>
> process_test_script(argv[1]);
> link_and_use_shaders();
> +
> + if (sso_in_use)
> + glBindProgramPipeline(pipeline);
> +
> if (link_ok && vertex_data_start != NULL) {
> program_must_be_in_use();
> bind_vao_if_supported();
More information about the Piglit
mailing list