--- src/glsl/linker.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/mtypes.h | 9 ++++ 2 files changed, 107 insertions(+), 0 deletions(-)
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 5ae928d..0c8a2c2 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1193,6 +1193,99 @@ create_storage_type(const struct glsl_type *const type, void *ctx=NULL) return storage_tree; } + +/** + * Generate structures for declared and implicit (eg, array element/struct field) variables in UBO. + */ +static void expand_gl_ubo(struct gl_shader_program *sh, const struct gl_uniform_buffer_object *source,struct gl_uniform_buffer_object *dest) +{ + dest->Name = strdup(source->Name); + dest->MatrixLayout = source->MatrixLayout; + dest->Layout = source->Layout; + dest->NumberOfVariables = source->NumberOfVariables; + dest->Variables = (struct gl_shader_ubo_variable*) + malloc(dest->NumberOfVariables * sizeof(gl_shader_ubo_variable)); + + for (unsigned i = 0; i < dest->NumberOfVariables; i++) { + struct gl_shader_ubo_variable& sourcevar = source->Variables[i]; + struct gl_shader_ubo_variable& destvar = dest->Variables[i]; + destvar.Name = strdup(sourcevar.Name); + destvar.Type = sourcevar.Type; + } + + dest->ReferencedByFS = dest->ReferencedByGS = dest->ReferencedByVS = 0; +} + +/** + * At interstage this function extract UBOs from shaders to populate programs UBOs + * It also performs checks coherency between UBOs with same name. + */ +static 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 = prog->UBOCount = 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++) { + + struct gl_uniform_buffer_object* current_ubo = &(shader->UniformBufferObjects[ubo_idx]); + struct gl_uniform_buffer_object* ubo_model = (struct gl_uniform_buffer_object*) hash_table_find(ht,current_ubo->Name); + if(!ubo_model) { + if (index == 0) + prog->UniformBufferObject = (struct gl_uniform_buffer_object*) malloc(sizeof(struct gl_uniform_buffer_object)); + else + prog->UniformBufferObject = (struct gl_uniform_buffer_object*) realloc(prog->UniformBufferObject, (index + 1) * sizeof(struct gl_uniform_buffer_object)); + expand_gl_ubo(prog,current_ubo,&(prog->UniformBufferObject[index])); + prog->UniformBufferObject[index].Index = index; + + 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); + } + switch(shader->Type) { + case GL_FRAGMENT_SHADER: + prog->UniformBufferObject[index - 1].ReferencedByFS = 1; + break; + case GL_VERTEX_SHADER: + prog->UniformBufferObject[index - 1].ReferencedByVS = 1; + break; + case GL_GEOMETRY_SHADER_ARB: + prog->UniformBufferObject[index - 1].ReferencedByGS = 1; + break; + } + + } + for (unsigned i = 0; i < prog->UBOCount; i++) { + const gl_uniform_buffer_object& ubo = prog->UniformBufferObject[i]; + for (unsigned j = 0; j < ubo.NumberOfVariables; j++) { + for (unsigned k = 0; k < MESA_SHADER_TYPES; k++) { + struct gl_shader *shader = prog->_LinkedShaders[k]; + if (!shader) + continue; + ir_variable* var = shader->symbols->get_variable(ubo.Variables[j].Name); + if (!var) + continue; + var->location = i + 1; + } + } + } + + } + + hash_table_dtor(ht); +} + + #endif @@ -2333,6 +2426,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) link_assign_uniform_locations(prog); store_fragdepth_layout(prog); +#ifdef FEATURE_ARB_uniform_buffer_object + merge_interstage_ubo(prog); +#endif + + if (!check_resources(ctx, prog)) goto done; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 865b6dc..269e433 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2194,6 +2194,9 @@ struct gl_uniform_buffer_object GLuint Layout; /** packed, shared or std140 */ GLuint MatrixLayout; /** rowmajor or columnmajor */ GLuint NumberOfVariables; /**< number of UBOVariableInfo in StorageLayout */ + unsigned ReferencedByVS:1; /** Is it present in VS ? Set at link time */ + unsigned ReferencedByGS:1; /** Is it present in GS ? Set at link time */ + unsigned ReferencedByFS:1; /** Is it present in FS ? Set at link time */ }; @@ -2346,6 +2349,12 @@ struct gl_shader_program * \c NULL. */ struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES]; + /** + * Program Scope UBO + */ + struct gl_uniform_buffer_object *UniformBufferObject; + unsigned UBOCount; + }; -- 1.7.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev