[Mesa-dev] [PATCH v2] glsl: apply shader storage block member rules when adding program resources

Timothy Arceri t_arceri at yahoo.com.au
Tue Sep 29 08:00:34 PDT 2015


On Tue, 2015-09-29 at 11:02 +0200, Samuel Iglesias Gonsalvez wrote:
> From ARB_program_interface_query:
> 
> "For an active shader storage block member declared as an array, an
>  entry will be generated only for the first array element, regardless
>  of its type. For arrays of aggregate types, the enumeration rules
> are
>  applied recursively for the single enumerated array element."
> 
> v2:
> - Simplify 'if' conditions and return true if it is not a buffer
>   variable, because these rules only apply to buffer variables
> (Timothy).
> 
> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>

Reviewed-by: Timothy Arceri <t_arceri at yahoo.com.au>

> ---
>  src/glsl/linker.cpp | 58
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
> 
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index 87c7d4b..dbf300a 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -3134,6 +3134,60 @@ check_explicit_uniform_locations(struct
> gl_context *ctx,
>  }
>  
>  static bool
> +should_add_buffer_variable(struct gl_shader_program *shProg,
> +                           GLenum type, const char *name)
> +{
> +   bool found_interface = false;
> +   const char *block_name = NULL;
> +
> +   /* These rules only apply to buffer variables. So we return
> +    * true for the rest of types.
> +    */
> +   if (type != GL_BUFFER_VARIABLE)
> +      return true;
> +
> +   for (unsigned i = 0; i < shProg->NumBufferInterfaceBlocks; i++) {
> +      block_name = shProg->UniformBlocks[i].Name;
> +      if (strncmp(block_name, name, strlen(block_name)) == 0) {
> +         found_interface = true;
> +         break;
> +      }
> +   }
> +
> +   /* We remove the interface name from the buffer variable name,
> +    * including the dot that follows it.
> +    */
> +   if (found_interface)
> +      name = name + strlen(block_name) + 1;
> +
> +   /* From: ARB_program_interface_query extension:
> +    *
> +    *  "For an active shader storage block member declared as an
> array, an
> +    *   entry will be generated only for the first array element,
> regardless
> +    *   of its type.  For arrays of aggregate types, the enumeration
> rules are
> +    *   applied recursively for the single enumerated array element.
> +    */
> +   const char *first_dot = strchr(name, '.');
> +   const char *first_square_bracket = strchr(name, '[');
> +
> +   /* The buffer variable is on top level and it is not an array */
> +   if (!first_square_bracket) {
> +      return true;
> +   /* The shader storage block member is a struct, then generate the
> entry */
> +   } else if (first_dot && first_dot < first_square_bracket) {
> +      return true;
> +   } else {
> +      /* Shader storage block member is an array, only generate an
> entry for the
> +       * first array element.
> +       */
> +      if (strncmp(first_square_bracket, "[0]", 3) == 0)
> +         return true;
> +   }
> +
> +   return false;
> +}
> +
> +static bool
>  add_program_resource(struct gl_shader_program *prog, GLenum type,
>                       const void *data, uint8_t stages)
>  {
> @@ -3412,6 +3466,10 @@ build_program_resource_list(struct
> gl_shader_program *shProg)
>  
>        bool is_shader_storage =  shProg
> ->UniformStorage[i].is_shader_storage;
>        GLenum type = is_shader_storage ? GL_BUFFER_VARIABLE :
> GL_UNIFORM;
> +      if (!should_add_buffer_variable(shProg, type,
> +                                      shProg
> ->UniformStorage[i].name))
> +         continue;
> +
>        if (!add_program_resource(shProg, type,
>                                  &shProg->UniformStorage[i],
> stageref))
>           return;


More information about the mesa-dev mailing list