Optional binding of variables can be processed before linking shader objects for creating shader program. It is activated by adding lines with a keyword "BindAttribLoc" followed by name and index as,
"BindAttribLoc name_str1 <index1>" For example, [require] ...... BindAttrbLoc vertex 1 BindAttrbLoc coord 2 BindAttrbLoc col 3 This makes the shader-db run glBindAttribLocation(p, 1, "vertex"); glBindAttribLocation(p, 2, "coord"); glBindAttribLocation(p, 3, "col"); before glLinkProgram() to include these binding info in binary shader program. Signed-off-by: Dongwon Kim <dongwon....@intel.com> --- run.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/run.c b/run.c index bbab5d9..fe2a97a 100644 --- a/run.c +++ b/run.c @@ -76,6 +76,12 @@ struct shader { int type; }; +struct binding_var { + char *name; + GLint index; + struct binding_var *next; +}; + static bool extension_in_string(const char *haystack, const char *needle) { @@ -105,6 +111,10 @@ extension_in_string(const char *haystack, const char *needle) return false; } +#define SKIP_SPACES(str) while (*(str) == ' ') str++ + +struct binding_var binding_head = {"NULL", -1, NULL}; + static struct shader * get_shaders(const struct context_info *core, const struct context_info *compat, const struct context_info *es, @@ -120,6 +130,7 @@ get_shaders(const struct context_info *core, const struct context_info *compat, 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 *binding = "\nBindAttribLoc"; static const char *gs = "geometry shader]\n"; static const char *fs = "fragment "; static const char *vs = "vertex "; @@ -186,11 +197,13 @@ get_shaders(const struct context_info *core, const struct context_info *compat, const struct context_info *info = *type == TYPE_CORE ? core : compat; const char *extension_text = text; + while ((extension_text = memmem(extension_text, end_text - extension_text, "\nGL_", strlen("\nGL_"))) != NULL) { extension_text += 1; const char *newline = memchr(extension_text, '\n', end_text - extension_text); + if (memmem(info->extension_string, info->extension_string_len, extension_text, newline - extension_text) == NULL) { fprintf(stderr, "SKIP: %s requires unavailable extension %.*s\n", @@ -202,6 +215,62 @@ get_shaders(const struct context_info *core, const struct context_info *compat, } } + /* process binding */ + struct binding_var *binding_prev = &binding_head; + const char *pre_binding_text = text; + + while ((pre_binding_text = memmem(pre_binding_text, end_text - pre_binding_text, + binding, strlen(binding))) != NULL) { + pre_binding_text += strlen(binding); + + const char *newline = memchr(pre_binding_text, '\n', end_text - pre_binding_text); + + SKIP_SPACES(pre_binding_text); + + char *endword = memchr(pre_binding_text, ' ', newline - pre_binding_text); + + /* if there's no more space in the same line */ + if (!endword) { + fprintf(stderr, "SKIP: can't find attr index for this binding\n"); + continue; + } + + char *binding_name = (char *)calloc(1, endword - pre_binding_text + 1); + + strncpy(binding_name, pre_binding_text, endword - pre_binding_text); + + pre_binding_text = endword; + + SKIP_SPACES(pre_binding_text); + if (*pre_binding_text == '\n') { + fprintf(stderr, "SKIP: can't find attr variable name for this binding\n"); + continue; + } + + endword = memchr(pre_binding_text, ' ', newline - pre_binding_text); + + if (!endword) + endword = (char *)newline; + + char *index_string = calloc(1, endword - pre_binding_text + 1); + strncpy(index_string, pre_binding_text, endword - pre_binding_text); + + struct binding_var *binding_new = malloc(sizeof(struct binding_var)); + + binding_new->index = strtol(index_string, NULL, 10); + binding_new->name = binding_name; + binding_new->next = NULL; + + free(index_string); + + fprintf(stdout, + "LOG: glBindAttribLocation(prog, %d, \"%s\") will be executed before linking\n", + binding_new->index, binding_new->name); + + binding_prev->next = binding_new; + binding_prev = binding_new; + } + /* Find the shaders. */ unsigned shader_size = 3; struct shader *shader = malloc(shader_size * sizeof(struct shader)); @@ -887,6 +956,16 @@ main(int argc, char **argv) glDeleteShader(s); } + /* takes care of pre-bindings */ + struct binding_var *binding_curr = binding_head.next; + while (binding_curr != NULL) { + struct binding_var *binding_next = binding_curr->next; + glBindAttribLocation(prog, binding_curr->index, binding_curr->name); + free(binding_curr->name); + free(binding_curr); + binding_curr = binding_next; + } + glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, ¶m); -- 2.16.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev