[Mesa-dev] [PATCH 10/17] glsl: Linker merges UBO from shaders from different stage into program-scope UBO.
Vincent Lejeune
vljn at ovi.com
Sun Dec 25 10:20:05 PST 2011
---
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
More information about the mesa-dev
mailing list