[Mesa-dev] [PATCH shader-db 4/4] run: handling binding of attribute variable name

Kenneth Graunke kenneth at whitecape.org
Wed Mar 14 22:15:20 UTC 2018


On Friday, March 9, 2018 2:28:36 PM PDT Dongwon Kim wrote:
> 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.kim at intel.com>

Matt, do you have an opinion on this?  This seems like the sort of
commands that would normally go in the [test] block, rather than the
[require] block.  But it looks like shader_runner doesn't have any
syntax for glBindAttribLocation today.

It's definitely a useful thing to have if we're going to use run.c
to produce shader binaries for ARB_get_program_binary...

> ---
>  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, &param);
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180314/960d96de/attachment.sig>


More information about the mesa-dev mailing list