[Mesa-dev] [PATCH 7/9] glsl: linker supports UBO

Brian Paul brianp at vmware.com
Fri Sep 23 13:45:45 PDT 2011


On 09/23/2011 07:53 AM, vlj wrote:
> ---
>   src/glsl/linker.cpp |  154 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>   1 files changed, 152 insertions(+), 2 deletions(-)
>
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index ba81c59..8dcc0d4 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -784,6 +784,47 @@ get_main_function_signature(gl_shader *sh)
>      return NULL;
>   }
>
> +bool validate_separate_ubo(const ubo&  first, const ubo&  second)
> +{
> +   return true;
> +}

If this is a placeholder function, please put some comments on it to 
explain what's needed in the future.


> +
> +void merge_intrastage_ubo ( gl_shader_program* prog,struct gl_shader&  merged_shader,
> +struct gl_shader **shader_list,
> +unsigned num_shaders)

Please indent the parameters there and put a space after commas.  And 
put a comment on the function explaining what the function does. 
Actually, please put comments on every function, unless it's dead 
obvious what it does.


> +{
> +   hash_table *ht = hash_table_ctor(0, hash_table_string_hash,
> +                            hash_table_string_compare);
> +   merged_shader.UBOCount = 0;
> +   unsigned&  index =    merged_shader.UBOCount;
> +   for(unsigned shad_id=0;shad_id<num_shaders;shad_id++)
> +   {

A loop like that should be:

for (unsigned shad_id = 0; shad_id < num_shaders; shad_id++) {


> +      for(unsigned ubo_id=0;ubo_id<shader_list[shad_id]->UBOCount;ubo_id++)
> +      {
> +         ubo* current_ubo =&(shader_list[shad_id]->UniformBufferObjects[ubo_id]);
> +         ubo* sh = (ubo*) hash_table_find(ht,current_ubo->name);
> +         if(!sh)
> +         {
> +            ubo&  tmp = merged_shader.UniformBufferObjects[index];
> +            tmp = *current_ubo;
> +            tmp.name = strdup(current_ubo->name);
> +            tmp.storage_layout = (UBOVariableInfo*) malloc(tmp.number_of_variables * sizeof(UBOVariableInfo));
> +            for(unsigned i = 0; i<  current_ubo->number_of_variables; i++) {
> +               tmp.storage_layout[i] = current_ubo->storage_layout[i];
> +               tmp.storage_layout[i].name = strdup(current_ubo->storage_layout[i].name);
> +            }
> +            hash_table_insert(ht,current_ubo,current_ubo->name);
> +            index++;
> +         }
> +         else
> +         {
> +            if(!validate_separate_ubo(*current_ubo,*sh))
> +               linker_error(prog,"Uniform Buffer Object '%s definition mismatch",sh->name);
> +         }
> +      }
> +   }
> +   hash_table_dtor(ht);
> +}
>
>   /**
>    * Combine a group of shaders for a single stage to generate a linked shader
> @@ -955,6 +996,8 @@ link_intrastage_shaders(void *mem_ctx,
>         v.run(linked->ir);
>      }
>
> +   merge_intrastage_ubo(prog,*linked,shader_list,num_shaders);
> +
>      return linked;
>   }
>
> @@ -1181,6 +1224,111 @@ assign_uniform_locations(struct gl_shader_program *prog)
>      prog->Uniforms = ul;
>   }
>
> +#include<main/hash.h>

Use #include "main/hash.h" when including Mesa headers.  And put all 
#includes at the top of the file.


> +
> +
> +void set_standard_uniform_block_layout(ubo* prog_ubo,GLenum shaderType)
> +{
> +   exec_list uniforms;
> +   unsigned total_uniforms = 0;
> +   hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
> +                            hash_table_string_compare);
> +   void *mem_ctx = ralloc_context(NULL);
> +
> +
> +
> +      unsigned next_position = 0;
> +
> +      for(unsigned i=0;i<prog_ubo->number_of_variables;i++) {
> +         UBOVariableInfo&  var = prog_ubo->storage_layout[i];
> +
> +         //var.location_in_ubo = next_position;
> +         add_uniform(mem_ctx,&uniforms, ht, var.name, var.Type,
> +                shaderType,
> +&next_position,&total_uniforms);
> +      }
> +
> +
> +   ralloc_free(mem_ctx);
> +
> +   unsigned idx = 0;
> +   uniform_node *next;
> +   for (uniform_node *node = (uniform_node *) uniforms.head
> +         ; node->link.next != NULL
> +         ; node = next) {
> +      next = (uniform_node *) node->link.next;
> +
> +      node->link.remove();
> +      prog_ubo->storage_layout[idx].offset = node->u->VertPos;
> +      prog_ubo->storage_layout[idx].size = node->u->Type->component_slots();
> +      idx++;
> +
> +      free(node->u);
> +      free(node);
> +   }
> +
> +   hash_table_dtor(ht);
> +}
> +
> +void merge_interstage_ubo(gl_shader_program* prog)

static?


> +{
> +   hash_table *ht = hash_table_ctor(0, hash_table_string_hash,
> +                            hash_table_string_compare);
> +
> +   unsigned index = 0;
> +    for (unsigned k = 0; k<  MESA_SHADER_TYPES; k++) {
> +       gl_shader* shader = prog->_LinkedShaders[k];
> +       if(shader==NULL)
> +          continue;
> +
> +       for(unsigned ubo_idx = 0;ubo_idx<  shader->UBOCount;ubo_idx++) {
> +
> +          ubo* current_ubo =&(shader->UniformBufferObjects[ubo_idx]);
> +          ubo* ubo_model = (ubo*) hash_table_find(ht,current_ubo->name);
> +          if(!ubo_model)
> +          {
> +             // Map pointer
> +             prog->UniformBufferObjects[prog->ubo_count] = current_ubo;
> +             current_ubo->bound_buffer = -1;
> +             current_ubo->index = index;
> +
> +             // Set variables info in current_ubo
> +             set_standard_uniform_block_layout(current_ubo,shader->Type);
> +
> +             prog->ubo_count = prog->ubo_count + 1;
> +             hash_table_insert(ht,current_ubo,current_ubo->name);
> +             index++;
> +          }
> +          else
> +          {
> +             if(!validate_separate_ubo(*current_ubo,*ubo_model))
> +                linker_error(prog,"Uniform Buffer Object '%s definition mismatch",ubo_model->name);
> +          }
> +       }
> +    }
> +
> +   /* Mirror the changes to ir_variable */
> +   for(unsigned i = 0; i<  prog->ubo_count; i++) {
> +
> +      const ubo* current_ubo = prog->UniformBufferObjects[i];
> +      for(unsigned j = 0;j<  current_ubo->number_of_variables; j++) {
> +
> +         for (unsigned k = 0; k<  MESA_SHADER_TYPES; k++) {
> +
> +            gl_shader* shader = prog->_LinkedShaders[k];
> +            if(shader==NULL)
> +               continue;
> +            ir_variable* var = shader->symbols->get_variable(current_ubo->storage_layout[j].name);
> +            if(var==NULL)
> +               continue;
> +            var->UBO =&(current_ubo->storage_layout[j]);
> +         }
> +      }
> +   }
> +   hash_table_dtor(ht);
> +}
> +
> +
>
>   /**
>    * Find a contiguous set of available bits in a bitmask.
> @@ -1634,12 +1782,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
>       */
>      assert(min_version>= 100);
>      assert(max_version<= 130);
> -   if ((max_version>= 130 || min_version == 100)
> +   /*if ((max_version>= 130 || min_version == 100)
>          &&  min_version != max_version) {
>         linker_error(prog, "all shaders must use same shading "
>   		   "language version\n");
>         goto done;
> -   }
> +   }*/
>
>      prog->Version = max_version;
>
> @@ -1732,6 +1880,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
>
>      assign_uniform_locations(prog);
>
> +   merge_interstage_ubo(prog);
> +
>      /* FINISHME: The value of the max_attribute_index parameter is
>       * FINISHME: implementation dependent based on the value of
>       * FINISHME: GL_MAX_VERTEX_ATTRIBS.  GL_MAX_VERTEX_ATTRIBS must be



More information about the mesa-dev mailing list