diff options
author | Eric Anholt <[email protected]> | 2012-05-01 13:34:04 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2012-07-20 10:43:42 -0700 |
commit | 093b20666d73f8fc410dc7bf168ab7197756b1f5 (patch) | |
tree | 96465b8d40f52dec6d657f859f602b531498e975 | |
parent | 9f1a4a6340824786142be9bc14f0c3418f14a69f (diff) |
glsl: Set the uniform_block index for the linked shader variables.
At this point in the linking, we've totally lost track of the struct
gl_uniform_buffer that this pointed to in the original unlinked
shader, so we do a nasty n^2 walk to find it the new one based on the
variable name.
Note that these point into the shader's list of gl_uniform_buffers,
not the linked program's.
Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r-- | src/glsl/link_uniforms.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index dddac43c316..ff75b8919e9 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -27,6 +27,7 @@ #include "ir_uniform.h" #include "glsl_symbol_table.h" #include "program/hash_table.h" +#include "program.h" /** * \file link_uniforms.cpp @@ -377,6 +378,42 @@ link_cross_validate_uniform_block(void *mem_ctx, return linked_block_index; } +/** + * Walks the IR and update the references to uniform blocks in the + * ir_variables to point at linked shader's list (previously, they + * would point at the uniform block list in one of the pre-linked + * shaders). + */ +static bool +link_update_uniform_buffer_variables(struct gl_shader *shader) +{ + foreach_list(node, shader->ir) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if ((var == NULL) || (var->uniform_block == -1)) + continue; + + assert(var->mode == ir_var_uniform); + + bool found = false; + 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)) { + found = true; + var->uniform_block = i; + var->location = j; + break; + } + } + if (found) + break; + } + assert(found); + } + + return true; +} + void link_assign_uniform_locations(struct gl_shader_program *prog) { @@ -401,6 +438,14 @@ 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; + + if (!link_update_uniform_buffer_variables(prog->_LinkedShaders[i])) + return; + } + /* 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. |