[Mesa-dev] [PATCH 08/17] glsl: Linker merges UBO from different shaders at intrastage step

Vincent Lejeune vljn at ovi.com
Sun Dec 25 10:17:07 PST 2011


This patch makes the linker checks UBO from several shader compatibility, and merges
them if necessary, at intrastage step.
---
 src/glsl/linker.cpp |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 036e4b9..289a398 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -65,6 +65,7 @@
  */
 
 #include "main/core.h"
+#include "main/hash.h"
 #include "glsl_symbol_table.h"
 #include "ir.h"
 #include "program.h"
@@ -847,6 +848,81 @@ get_main_function_signature(gl_shader *sh)
    return NULL;
 }
 
+/**
+ * This function duplicates content of a ubo source into shader ubo array.
+ */
+static struct gl_uniform_buffer_object*
+append_ubo (const struct gl_uniform_buffer_object& source, struct gl_shader* merged_shader)
+{
+   /* Use shorter alias */
+   unsigned& current_ubo_count = merged_shader->UBOCount;
+   struct gl_uniform_buffer_object*& ubo_array = merged_shader->UniformBufferObjects;
+
+   if (current_ubo_count == 0)
+      ubo_array = (gl_uniform_buffer_object*) ralloc_array_size(merged_shader,sizeof(gl_uniform_buffer_object),current_ubo_count + 1);
+   else
+      ubo_array = (gl_uniform_buffer_object*) reralloc_array_size(merged_shader,ubo_array,sizeof(gl_uniform_buffer_object),current_ubo_count + 1);
+   struct gl_uniform_buffer_object& dest = ubo_array[current_ubo_count];
+   dest = source; // copy everything, but need to duplicate ptr afterward
+   dest.Name = ralloc_strdup(merged_shader,source.Name);
+   dest.Variables = (gl_shader_ubo_variable*) ralloc_array_size(merged_shader,sizeof(gl_shader_ubo_variable),source.NumberOfVariables);
+   for (unsigned i = 0; i < dest.NumberOfVariables; i++) {
+      dest.Variables[i] = source.Variables[i];
+      dest.Variables[i].Name = ralloc_strdup(merged_shader,source.Variables[i].Name);
+   }
+   current_ubo_count++;
+   return &dest;
+}
+
+/**
+ * TODO : write the function
+ * This function should check consistency between 2 UBO having same name
+ * from different shaders :
+ * - Same layout
+ * - Same variables (name and type) in same order
+ * - Same matrix layout (ie row/column major)
+ */
+static bool validate_separate_ubo(const gl_uniform_buffer_object& first, const gl_uniform_buffer_object& second)
+{
+   return true;
+}
+
+
+#ifdef FEATURE_ARB_uniform_buffer_object
+/**
+ * At intrastage, when several shaders of same type are merged in a single one,
+ * this function generates UBOs of the newly created shader from them and
+ * performs necessary check.
+ */
+static
+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);
+
+   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++)
+      {
+         struct gl_uniform_buffer_object* current_ubo = &(shader_list[shad_id]->UniformBufferObjects[ubo_id]);
+         struct gl_uniform_buffer_object* sh = (struct gl_uniform_buffer_object*) hash_table_find(ht,current_ubo->Name);
+         if(!sh)
+         {
+            append_ubo(*current_ubo,merged_shader);
+            hash_table_insert(ht,current_ubo,current_ubo->Name);
+         }
+         else
+         {
+            if(!validate_separate_ubo(*current_ubo,*sh))
+               linker_error(prog,"Uniform Buffer Object '%s definition mismatch",sh->Name);
+         }
+      }
+   }
+
+   hash_table_dtor(ht);
+}
+#endif
 
 /**
  * Combine a group of shaders for a single stage to generate a linked shader
@@ -1018,6 +1094,9 @@ link_intrastage_shaders(void *mem_ctx,
       v.run(linked->ir);
    }
 
+#if FEATURE_ARB_uniform_buffer_object
+   merge_intrastage_ubo(prog,linked,shader_list,num_shaders);
+#endif
    return linked;
 }
 
-- 
1.7.7



More information about the mesa-dev mailing list