diff options
author | Emil Velikov <[email protected]> | 2016-01-18 12:16:48 +0200 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2016-01-26 16:08:33 +0000 |
commit | eb63640c1d38a200a7b1540405051d3ff79d0d8a (patch) | |
tree | da46321a41f309b1d02aeb14d5d5487791c45aeb /src/glsl/lower_named_interface_blocks.cpp | |
parent | a39a8fbbaa129f4e52f2a3ad2747182e9a74d910 (diff) |
glsl: move to compiler/
Signed-off-by: Emil Velikov <[email protected]>
Acked-by: Matt Turner <[email protected]>
Acked-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/glsl/lower_named_interface_blocks.cpp')
-rw-r--r-- | src/glsl/lower_named_interface_blocks.cpp | 280 |
1 files changed, 0 insertions, 280 deletions
diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp deleted file mode 100644 index f29eba4f75f..00000000000 --- a/src/glsl/lower_named_interface_blocks.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2013 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file lower_named_interface_blocks.cpp - * - * This lowering pass converts all interface blocks with instance names - * into interface blocks without an instance name. - * - * For example, the following shader: - * - * out block { - * float block_var; - * } inst_name; - * - * main() - * { - * inst_name.block_var = 0.0; - * } - * - * Is rewritten to: - * - * out block { - * float block_var; - * }; - * - * main() - * { - * block_var = 0.0; - * } - * - * This takes place after the shader code has already been verified with - * the interface name in place. - * - * The linking phase will use the interface block name rather than the - * interface's instance name when linking interfaces. - * - * This modification to the ir allows our currently existing dead code - * elimination to work with interface blocks without changes. - */ - -#include "glsl_symbol_table.h" -#include "ir.h" -#include "ir_optimization.h" -#include "ir_rvalue_visitor.h" -#include "program/hash_table.h" - -static const glsl_type * -process_array_type(const glsl_type *type, unsigned idx) -{ - const glsl_type *element_type = type->fields.array; - if (element_type->is_array()) { - const glsl_type *new_array_type = process_array_type(element_type, idx); - return glsl_type::get_array_instance(new_array_type, type->length); - } else { - return glsl_type::get_array_instance( - element_type->fields.structure[idx].type, type->length); - } -} - -static ir_rvalue * -process_array_ir(void * const mem_ctx, - ir_dereference_array *deref_array_prev, - ir_rvalue *deref_var) -{ - ir_dereference_array *deref_array = - deref_array_prev->array->as_dereference_array(); - - if (deref_array == NULL) { - return new(mem_ctx) ir_dereference_array(deref_var, - deref_array_prev->array_index); - } else { - deref_array = (ir_dereference_array *) process_array_ir(mem_ctx, - deref_array, - deref_var); - return new(mem_ctx) ir_dereference_array(deref_array, - deref_array_prev->array_index); - } -} - -namespace { - -class flatten_named_interface_blocks_declarations : public ir_rvalue_visitor -{ -public: - void * const mem_ctx; - hash_table *interface_namespace; - - flatten_named_interface_blocks_declarations(void *mem_ctx) - : mem_ctx(mem_ctx), - interface_namespace(NULL) - { - } - - void run(exec_list *instructions); - - virtual ir_visitor_status visit_leave(ir_assignment *); - virtual void handle_rvalue(ir_rvalue **rvalue); -}; - -} /* anonymous namespace */ - -void -flatten_named_interface_blocks_declarations::run(exec_list *instructions) -{ - interface_namespace = hash_table_ctor(0, hash_table_string_hash, - hash_table_string_compare); - - /* First pass: adjust instance block variables with an instance name - * to not have an instance name. - * - * The interface block variables are stored in the interface_namespace - * hash table so they can be used in the second pass. - */ - foreach_in_list_safe(ir_instruction, node, instructions) { - ir_variable *var = node->as_variable(); - if (!var || !var->is_interface_instance()) - continue; - - /* It should be possible to handle uniforms during this pass, - * but, this will require changes to the other uniform block - * support code. - */ - if (var->data.mode == ir_var_uniform || - var->data.mode == ir_var_shader_storage) - continue; - - const glsl_type * iface_t = var->type->without_array(); - exec_node *insert_pos = var; - - assert (iface_t->is_interface()); - - for (unsigned i = 0; i < iface_t->length; i++) { - const char * field_name = iface_t->fields.structure[i].name; - char *iface_field_name = - ralloc_asprintf(mem_ctx, "%s %s.%s.%s", - var->data.mode == ir_var_shader_in ? "in" : "out", - iface_t->name, var->name, field_name); - - ir_variable *found_var = - (ir_variable *) hash_table_find(interface_namespace, - iface_field_name); - if (!found_var) { - ir_variable *new_var; - char *var_name = - ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name); - if (!var->type->is_array()) { - new_var = - new(mem_ctx) ir_variable(iface_t->fields.structure[i].type, - var_name, - (ir_variable_mode) var->data.mode); - new_var->data.from_named_ifc_block_nonarray = 1; - } else { - const glsl_type *new_array_type = - process_array_type(var->type, i); - new_var = - new(mem_ctx) ir_variable(new_array_type, - var_name, - (ir_variable_mode) var->data.mode); - new_var->data.from_named_ifc_block_array = 1; - } - new_var->data.location = iface_t->fields.structure[i].location; - new_var->data.explicit_location = (new_var->data.location >= 0); - new_var->data.interpolation = - iface_t->fields.structure[i].interpolation; - new_var->data.centroid = iface_t->fields.structure[i].centroid; - new_var->data.sample = iface_t->fields.structure[i].sample; - new_var->data.patch = iface_t->fields.structure[i].patch; - new_var->data.stream = var->data.stream; - new_var->data.how_declared = var->data.how_declared; - - new_var->init_interface_type(iface_t); - hash_table_insert(interface_namespace, new_var, - iface_field_name); - insert_pos->insert_after(new_var); - insert_pos = new_var; - } - } - var->remove(); - } - - /* Second pass: visit all ir_dereference_record instances, and if they - * reference an interface block, then flatten the refererence out. - */ - visit_list_elements(this, instructions); - hash_table_dtor(interface_namespace); - interface_namespace = NULL; -} - -ir_visitor_status -flatten_named_interface_blocks_declarations::visit_leave(ir_assignment *ir) -{ - ir_dereference_record *lhs_rec = ir->lhs->as_dereference_record(); - if (lhs_rec) { - ir_rvalue *lhs_rec_tmp = lhs_rec; - handle_rvalue(&lhs_rec_tmp); - if (lhs_rec_tmp != lhs_rec) { - ir->set_lhs(lhs_rec_tmp); - } - } - return rvalue_visit(ir); -} - -void -flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue) -{ - if (*rvalue == NULL) - return; - - ir_dereference_record *ir = (*rvalue)->as_dereference_record(); - if (ir == NULL) - return; - - ir_variable *var = ir->variable_referenced(); - if (var == NULL) - return; - - if (!var->is_interface_instance()) - return; - - /* It should be possible to handle uniforms during this pass, - * but, this will require changes to the other uniform block - * support code. - */ - if (var->data.mode == ir_var_uniform || var->data.mode == ir_var_shader_storage) - return; - - if (var->get_interface_type() != NULL) { - char *iface_field_name = - ralloc_asprintf(mem_ctx, "%s %s.%s.%s", - var->data.mode == ir_var_shader_in ? "in" : "out", - var->get_interface_type()->name, - var->name, ir->field); - /* Find the variable in the set of flattened interface blocks */ - ir_variable *found_var = - (ir_variable *) hash_table_find(interface_namespace, - iface_field_name); - assert(found_var); - - ir_dereference_variable *deref_var = - new(mem_ctx) ir_dereference_variable(found_var); - - ir_dereference_array *deref_array = - ir->record->as_dereference_array(); - if (deref_array != NULL) { - *rvalue = process_array_ir(mem_ctx, deref_array, - (ir_rvalue *)deref_var); - } else { - *rvalue = deref_var; - } - } -} - -void -lower_named_interface_blocks(void *mem_ctx, gl_shader *shader) -{ - flatten_named_interface_blocks_declarations v_decl(mem_ctx); - v_decl.run(shader->ir); -} - |