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

vlj vljn at ovi.com
Fri Sep 23 06:53:12 PDT 2011


---
 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;
+}
+
+void merge_intrastage_ubo ( gl_shader_program* prog,struct gl_shader& merged_shader,
+struct gl_shader **shader_list,
+unsigned num_shaders)
+{
+   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++)
+   {
+      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>
+
+
+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)
+{
+   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
-- 
1.7.6.3



More information about the mesa-dev mailing list