Commit aa14141c authored by Kenneth Graunke's avatar Kenneth Graunke

run: Add separate shader objects support.

With this patch, if a .shader_test file contains

    [require]
    ...
    SSO ENABLED

then we'll use glCreateShaderProgramv to create each shader, so that
they're compiled as 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.

v4:
- Go back to glCreateShaderProgramv.  Timothy pointed out that Piglit's
  shader_runner compiles each shader separately, and wouldn't optimize
  interfaces between programs.  I want to preserve the same semantics
  between both .shader_test file processors.  Today, it looks like
  multi-stage SSO programs are pretty uncommon (typically every stage
  is separable), so we'll punt on solving that until later.
Acked-by: Ilia Mirkin's avatarIlia Mirkin <imirkin@alum.mit.edu>
Acked-by: default avatarTimothy Arceri <timothy.arceri@collabora.com>
parent 8bbc8ab8
......@@ -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 = "\nSSO 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;
......@@ -624,7 +633,11 @@ main(int argc, char **argv)
}
ctx_is_core = type == TYPE_CORE;
if (type == TYPE_CORE || type == TYPE_COMPAT) {
if (use_separate_shader_objects) {
for (unsigned i = 0; i < num_shaders; i++) {
glCreateShaderProgramv(shader[i].type, 1, &shader[i].text);
}
} else if (type == TYPE_CORE || type == TYPE_COMPAT) {
GLuint prog = glCreateProgram();
for (unsigned i = 0; i < num_shaders; i++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment