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