[Mesa-dev] [PATCH shader-db 1/2] run: Add separate shader objects support.
Timothy Arceri
timothy.arceri at collabora.com
Tue Jul 26 03:07:57 UTC 2016
On Mon, 2016-07-25 at 16:54 -0700, Kenneth Graunke wrote:
> With this patch, if a .shader_test file contains
>
> [require]
> ...
> SSO ENABLED
>
> then we'll set GL_PROGRAM_SEPARABLE to compile the shaders into
> separate
> shader objects. This prevents the linker from removing unused inputs
> and outputs. Drivers may also choose to lay out interfaces of SSO
> programs differently, resulting in different code.
>
> v2:
> - Actually initialize use_separate_shader_objects
> - Fix memcmp length parameter (thanks to Matt)
>
> v3:
> - Search for "SSO ENABLED" instead of
> "GL_ARB_separate_shader_objects",
> to match what Timothy did in shader_runner.
> - Use GL_PROGRAM_SEPARABLE (suggested by Tapani). This allows
> multi-stage SSO programs to optimize internal interfaces, while
> still making the end-stages separable.
When using SSO ENABLED in shader_runner each stage is linked as a
separte program here you are creating multi-stage SSO programs. Unless
you are combining the program with another SSO program enabling SSO
doesn't seem very useful. Ideally we would capture and combine specific
stages but that would get complicated which is why I just linked
everything as separate programs in shader_runner.
> ---
> run.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/run.c b/run.c
> index 0e6e248..024c8e9 100644
> --- a/run.c
> +++ b/run.c
> @@ -73,12 +73,14 @@ static struct shader *
> get_shaders(const struct context_info *core, const struct
> context_info *compat,
> const char *text, size_t text_size,
> enum shader_type *type, unsigned *num_shaders,
> + bool *use_separate_shader_objects,
> const char *shader_name)
> {
> static const char *req = "[require]";
> static const char *glsl_req = "\nGLSL >= ";
> static const char *fp_req = "\nGL_ARB_fragment_program";
> static const char *vp_req = "\nGL_ARB_vertex_program";
> + static const char *sso_req = "SSO ENABLED";
> static const char *gs = "geometry shader]\n";
> static const char *fs = "fragment ";
> static const char *vs = "vertex ";
> @@ -90,6 +92,8 @@ get_shaders(const struct context_info *core, const
> struct context_info *compat,
> static const char *test = "test]\n";
> const char *end_text = text + text_size;
>
> + *use_separate_shader_objects = false;
> +
> /* Find the [require] block and parse it first. */
> text = memmem(text, end_text - text, req, strlen(req)) +
> strlen(req);
>
> @@ -137,6 +141,9 @@ get_shaders(const struct context_info *core,
> const struct context_info *compat,
> shader_name, (int)(newline - extension_text),
> extension_text);
> return NULL;
> }
> + if (memcmp(extension_text, sso_req, strlen(sso_req)) == 0) {
> + *use_separate_shader_objects = true;
> + }
> }
>
> /* Find the shaders. */
> @@ -606,9 +613,11 @@ main(int argc, char **argv)
>
> enum shader_type type;
> unsigned num_shaders;
> + bool use_separate_shader_objects;
> struct shader *shader = get_shaders(&core, &compat,
> text,
> shader_test[i].filesize,
> &type, &num_shaders,
> + &use_separate_shader
> _objects,
> current_shader_name)
> ;
> if (unlikely(shader == NULL)) {
> continue;
> @@ -627,6 +636,9 @@ main(int argc, char **argv)
> if (type == TYPE_CORE || type == TYPE_COMPAT) {
> GLuint prog = glCreateProgram();
>
> + if (use_separate_shader_objects)
> + glProgramParameteri(prog, GL_PROGRAM_SEPARABLE,
> GL_TRUE);
> +
> for (unsigned i = 0; i < num_shaders; i++) {
> GLuint s = glCreateShader(shader[i].type);
> glShaderSource(s, 1, &shader[i].text,
> &shader[i].length);
More information about the mesa-dev
mailing list