[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