diff options
author | Ian Romanick <[email protected]> | 2011-01-25 10:41:20 -0800 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2011-03-29 13:21:08 -0700 |
commit | 89d81ab16c05818b290ed735c1343d3abde449bf (patch) | |
tree | 256104ebb7bdcc721ff0d70178047acb8c83ed21 /src/glsl | |
parent | 92e412e788931ad464125113a64eec8a8223cda3 (diff) |
glsl: Calcluate Mesa state slots in front-end instead of back-end
This should be the last bit of infrastructure changes before
generating GLSL IR for assembly shaders.
This commit leaves some odd code formatting in ir_to_mesa and brw_fs.
This was done to minimize whitespace changes / reindentation in some
loops. The following commit will restore formatting sanity.
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: Chad Versace <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ir.h | 26 | ||||
-rw-r--r-- | src/glsl/ir_clone.cpp | 12 | ||||
-rw-r--r-- | src/glsl/ir_variable.cpp | 46 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 13 |
4 files changed, 94 insertions, 3 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 39d4ebc7107..a41984310b3 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -253,6 +253,16 @@ enum ir_depth_layout { const char* depth_layout_string(ir_depth_layout layout); +/** + * Description of built-in state associated with a uniform + * + * \sa ir_variable::state_slots + */ +struct ir_state_slot { + int tokens[5]; + int swizzle; +}; + class ir_variable : public ir_instruction { public: ir_variable(const struct glsl_type *, const char *, ir_variable_mode); @@ -386,6 +396,22 @@ public: int location; /** + * Built-in state that backs this uniform + * + * Once set at variable creation, \c state_slots must remain invariant. + * This is because, ideally, this array would be shared by all clones of + * this variable in the IR tree. In other words, we'd really like for it + * to be a fly-weight. + * + * If the variable is not a uniform, \c num_state_slots will be zero and + * \c state_slots will be \c NULL. + */ + /*@{*/ + unsigned num_state_slots; /**< Number of state slots used */ + ir_state_slot *state_slots; /**< State descriptors. */ + /*@}*/ + + /** * Emit a warning if this variable is accessed. */ const char *warn_extension; diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 2c0574dc6bf..069bb85e8de 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -53,6 +53,18 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const var->origin_upper_left = this->origin_upper_left; var->pixel_center_integer = this->pixel_center_integer; var->explicit_location = this->explicit_location; + + var->num_state_slots = this->num_state_slots; + if (this->state_slots) { + /* FINISHME: This really wants to use something like talloc_reference, but + * FINISHME: ralloc doesn't have any similar function. + */ + var->state_slots = ralloc_array(var, ir_state_slot, + this->num_state_slots); + memcpy(var->state_slots, this->state_slots, + sizeof(this->state_slots[0]) * var->num_state_slots); + } + if (this->explicit_location) var->location = this->location; diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index c2715254a59..f3577175691 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -327,7 +327,43 @@ static ir_variable * add_uniform(exec_list *instructions, glsl_symbol_table *symtab, const char *name, const glsl_type *type) { - return add_variable(instructions, symtab, name, type, ir_var_uniform, -1); + ir_variable *const uni = + add_variable(instructions, symtab, name, type, ir_var_uniform, -1); + + unsigned i; + for (i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) { + if (strcmp(_mesa_builtin_uniform_desc[i].name, name) == 0) { + break; + } + } + + assert(_mesa_builtin_uniform_desc[i].name != NULL); + const struct gl_builtin_uniform_desc* const statevar = + &_mesa_builtin_uniform_desc[i]; + + const unsigned array_count = type->is_array() ? type->length : 1; + uni->num_state_slots = array_count * statevar->num_elements; + + ir_state_slot *slots = + ralloc_array(uni, ir_state_slot, uni->num_state_slots); + + uni->state_slots = slots; + + for (unsigned a = 0; a < array_count; a++) { + for (unsigned j = 0; j < statevar->num_elements; j++) { + struct gl_builtin_uniform_element *element = &statevar->elements[j]; + + memcpy(slots->tokens, element->tokens, sizeof(element->tokens)); + if (type->is_array()) { + slots->tokens[1] = a; + } + + slots->swizzle = element->swizzle; + slots++; + } + } + + return uni; } static void @@ -341,8 +377,12 @@ add_builtin_variable(exec_list *instructions, glsl_symbol_table *symtab, assert(type != NULL); - add_variable(instructions, symtab, proto->name, type, proto->mode, - proto->slot); + if (proto->mode == ir_var_uniform) { + add_uniform(instructions, symtab, proto->name, type); + } else { + add_variable(instructions, symtab, proto->name, type, proto->mode, + proto->slot); + } } static void diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 7db5c5e8d53..17492357f2d 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -994,6 +994,19 @@ update_array_sizes(struct gl_shader_program *prog) } if (size + 1 != var->type->fields.array->length) { + /* If this is a built-in uniform (i.e., it's backed by some + * fixed-function state), adjust the number of state slots to + * match the new array size. The number of slots per array entry + * is not known. It seems saft to assume that the total number of + * slots is an integer multiple of the number of array elements. + * Determine the number of slots per array element by dividing by + * the old (total) size. + */ + if (var->num_state_slots > 0) { + var->num_state_slots = (size + 1) + * (var->num_state_slots / var->type->length); + } + var->type = glsl_type::get_array_instance(var->type->fields.array, size + 1); /* FINISHME: We should update the types of array |