summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2013-01-22 01:09:16 -0500
committerIan Romanick <[email protected]>2013-01-25 09:07:36 -0500
commit514f8c7ec7cc1ab18be93cebb5b9bf970b1955a9 (patch)
tree7dd462bc3360ff2fced2186fc65550ccb6603fda /src
parent0ab7399822b480f6e07cc566a2e50fabedc8258d (diff)
glsl: Calculate UBO data at link-time
Use the function added in the previous commit. This temporarily causes gles3conform uniform_buffer_object_index_of_not_active_block, uniform_buffer_object_inherit_and_override_layouts, and uniform_buffer_object_repeat_global_scope_layouts to assertion fail. This is fixed in the next commit. Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ast_to_hir.cpp56
-rw-r--r--src/glsl/link_uniforms.cpp42
-rw-r--r--src/glsl/linker.cpp23
3 files changed, 44 insertions, 77 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index bf4130fa8c6..3272868ee83 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -4187,25 +4187,6 @@ ast_struct_specifier::hir(exec_list *instructions,
return NULL;
}
-static struct gl_uniform_block *
-get_next_uniform_block(struct _mesa_glsl_parse_state *state)
-{
- if (state->num_uniform_blocks >= state->uniform_block_array_size) {
- state->uniform_block_array_size *= 2;
- if (state->uniform_block_array_size <= 4)
- state->uniform_block_array_size = 4;
-
- state->uniform_blocks = reralloc(state,
- state->uniform_blocks,
- struct gl_uniform_block,
- state->uniform_block_array_size);
- }
-
- memset(&state->uniform_blocks[state->num_uniform_blocks],
- 0, sizeof(*state->uniform_blocks));
- return &state->uniform_blocks[state->num_uniform_blocks++];
-}
-
ir_rvalue *
ast_uniform_block::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
@@ -4216,17 +4197,15 @@ ast_uniform_block::hir(exec_list *instructions,
* need to turn those into ir_variables with an association
* with this uniform block.
*/
- struct gl_uniform_block *ubo = get_next_uniform_block(state);
- ubo->Name = ralloc_strdup(state->uniform_blocks, this->block_name);
-
+ enum glsl_interface_packing packing;
if (this->layout.flags.q.shared) {
- ubo->_Packing = ubo_packing_shared;
+ packing = GLSL_INTERFACE_PACKING_SHARED;
} else if (this->layout.flags.q.packed) {
- ubo->_Packing = ubo_packing_packed;
+ packing = GLSL_INTERFACE_PACKING_PACKED;
} else {
/* The default layout is std140.
*/
- ubo->_Packing = ubo_packing_std140;
+ packing = GLSL_INTERFACE_PACKING_STD140;
}
bool block_row_major = this->layout.flags.q.row_major;
@@ -4241,17 +4220,10 @@ ast_uniform_block::hir(exec_list *instructions,
true,
block_row_major);
- STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140)
- == unsigned(ubo_packing_std140));
- STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED)
- == unsigned(ubo_packing_shared));
- STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED)
- == unsigned(ubo_packing_packed));
-
const glsl_type *block_type =
glsl_type::get_interface_instance(fields,
num_variables,
- (enum glsl_interface_packing) ubo->_Packing,
+ packing,
this->block_name);
if (!state->symbols->add_type(block_type->name, block_type)) {
@@ -4310,24 +4282,6 @@ ast_uniform_block::hir(exec_list *instructions,
}
}
- /* FINISHME: Eventually the rest of this code needs to be moved into the
- * FINISHME: linker.
- */
- ubo->Uniforms = rzalloc_array(state->uniform_blocks,
- struct gl_uniform_buffer_variable,
- num_variables);
-
- for (unsigned i = 0; i < num_variables; i++) {
- struct gl_uniform_buffer_variable *ubo_var =
- &ubo->Uniforms[ubo->NumUniforms++];
-
- ubo_var->Name = ralloc_strdup(state->uniform_blocks, fields[i].name);
- ubo_var->IndexName = ubo_var->Name;
- ubo_var->Type = fields[i].type;
- ubo_var->Offset = 0; /* Assigned at link time. */
- ubo_var->RowMajor = fields[i].row_major;
- }
-
return NULL;
}
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 68cafbf3946..3e24842a026 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -539,10 +539,41 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
assert(var->mode == ir_var_uniform);
+ if (var->is_interface_instance()) {
+ var->location = 0;
+ continue;
+ }
+
bool found = false;
+ char sentinel = '\0';
+
+ if (var->type->is_record()) {
+ sentinel = '.';
+ } else if (var->type->is_array()
+ && var->type->fields.array->is_record()) {
+ sentinel = '[';
+ }
+
+ const unsigned l = strlen(var->name);
for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
for (unsigned j = 0; j < shader->UniformBlocks[i].NumUniforms; j++) {
- if (!strcmp(var->name, shader->UniformBlocks[i].Uniforms[j].Name)) {
+ if (sentinel) {
+ const char *begin = shader->UniformBlocks[i].Uniforms[j].Name;
+ const char *end = strchr(begin, sentinel);
+
+ if (end == NULL)
+ continue;
+
+ if (l != (end - begin))
+ continue;
+
+ if (strncmp(var->name, begin, l) == 0) {
+ found = true;
+ var->location = j;
+ break;
+ }
+ } else if (!strcmp(var->name,
+ shader->UniformBlocks[i].Uniforms[j].Name)) {
found = true;
var->uniform_block = i;
var->location = j;
@@ -614,13 +645,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
*/
memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
- for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
- if (prog->_LinkedShaders[i] == NULL)
- continue;
-
- link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
- }
-
/* First pass: Count the uniform resources used by the user-defined
* uniforms. While this happens, each active uniform will have an index
* assigned to it.
@@ -633,6 +657,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
+ link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
+
/* Reset various per-shader target counts.
*/
uniform_size.start_shader();
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index a480dd0523f..63ce178f44c 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -873,7 +873,6 @@ link_intrastage_shaders(void *mem_ctx,
unsigned num_shaders)
{
struct gl_uniform_block *uniform_blocks = NULL;
- unsigned num_uniform_blocks = 0;
/* Check that global variables defined in multiple shaders are consistent.
*/
@@ -881,23 +880,11 @@ link_intrastage_shaders(void *mem_ctx,
return NULL;
/* Check that uniform blocks between shaders for a stage agree. */
- for (unsigned i = 0; i < num_shaders; i++) {
- struct gl_shader *sh = shader_list[i];
-
- for (unsigned j = 0; j < sh->NumUniformBlocks; j++) {
- link_assign_uniform_block_offsets(sh);
-
- int index = link_cross_validate_uniform_block(mem_ctx,
- &uniform_blocks,
- &num_uniform_blocks,
- &sh->UniformBlocks[j]);
- if (index == -1) {
- linker_error(prog, "uniform block `%s' has mismatching definitions",
- sh->UniformBlocks[j].Name);
- return NULL;
- }
- }
- }
+ const int num_uniform_blocks =
+ link_uniform_blocks(mem_ctx, prog, shader_list, num_shaders,
+ &uniform_blocks);
+ if (num_uniform_blocks < 0)
+ return NULL;
/* Check that there is only a single definition of each function signature
* across all shaders.