On 09/23/2011 07:53 AM, vlj wrote:
---
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;
+}
If this is a placeholder function, please put some comments on it to
explain what's needed in the future.
+
+void merge_intrastage_ubo ( gl_shader_program* prog,struct gl_shader&
merged_shader,
+struct gl_shader **shader_list,
+unsigned num_shaders)
Please indent the parameters there and put a space after commas. And
put a comment on the function explaining what the function does.
Actually, please put comments on every function, unless it's dead
obvious what it does.
+{
+ 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++)
+ {
A loop like that should be:
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>
Use #include "main/hash.h" when including Mesa headers. And put all
#includes at the top of the file.
+
+
+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)
static?
+{
+ 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
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev