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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev