[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