From ece07bdeaa82ea59e74bcfc588bcabe5e47567c1 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 26 Jul 2011 08:58:05 +0200 Subject: libX11 libXext mesa pixman xserver xkeyboard-config git update 26 July 2011 --- .../src/glsl/lower_vec_index_to_cond_assign.cpp | 91 +++++++++++++++------- 1 file changed, 63 insertions(+), 28 deletions(-) (limited to 'mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp') diff --git a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp index 3c4d93201..fce9c3424 100644 --- a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -71,8 +71,6 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue ir_assignment *assign; ir_variable *index, *var; ir_dereference *deref; - ir_expression *condition; - ir_swizzle *swizzle; int i; if (!orig_deref) @@ -86,39 +84,52 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); + exec_list list; + /* Store the index to a temporary to avoid reusing its tree. */ index = new(base_ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i", ir_var_temporary); - base_ir->insert_before(index); + list.push_tail(index); deref = new(base_ir) ir_dereference_variable(index); assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL); - base_ir->insert_before(assign); + list.push_tail(assign); /* Temporary where we store whichever value we swizzle out. */ var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v", ir_var_temporary); - base_ir->insert_before(var); + list.push_tail(var); + + /* Generate a single comparison condition "mask" for all of the components + * in the vector. + */ + ir_rvalue *const cond_deref = + compare_index_block(&list, index, 0, + orig_deref->array->type->vector_elements, + mem_ctx); /* Generate a conditional move of each vector element to the temp. */ for (i = 0; i < orig_deref->array->type->vector_elements; i++) { - deref = new(base_ir) ir_dereference_variable(index); - condition = new(base_ir) ir_expression(ir_binop_equal, - glsl_type::bool_type, - deref, - new(base_ir) ir_constant(i)); + ir_rvalue *condition_swizzle = + new(base_ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1); /* Just clone the rest of the deref chain when trying to get at the * underlying variable. */ - swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), - i, 0, 0, 0, 1); + ir_rvalue *swizzle = + new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), + i, 0, 0, 0, 1); deref = new(base_ir) ir_dereference_variable(var); - assign = new(base_ir) ir_assignment(deref, swizzle, condition); - base_ir->insert_before(assign); + assign = new(base_ir) ir_assignment(deref, swizzle, condition_swizzle); + list.push_tail(assign); } + /* Put all of the new instructions in the IR stream before the old + * instruction. + */ + base_ir->insert_before(&list); + this->progress = true; return new(base_ir) ir_dereference_variable(var); } @@ -171,42 +182,66 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); + exec_list list; + /* Store the index to a temporary to avoid reusing its tree. */ index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i", ir_var_temporary); - ir->insert_before(index); + list.push_tail(index); deref = new(ir) ir_dereference_variable(index); assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL); - ir->insert_before(assign); + list.push_tail(assign); /* Store the RHS to a temporary to avoid reusing its tree. */ var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v", ir_var_temporary); - ir->insert_before(var); + list.push_tail(var); deref = new(ir) ir_dereference_variable(var); assign = new(ir) ir_assignment(deref, ir->rhs, NULL); - ir->insert_before(assign); + list.push_tail(assign); + + /* Generate a single comparison condition "mask" for all of the components + * in the vector. + */ + ir_rvalue *const cond_deref = + compare_index_block(&list, index, 0, + orig_deref->array->type->vector_elements, + mem_ctx); /* Generate a conditional move of each vector element to the temp. */ for (i = 0; i < orig_deref->array->type->vector_elements; i++) { - ir_rvalue *condition, *swizzle; + ir_rvalue *condition_swizzle = + new(ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1); - deref = new(ir) ir_dereference_variable(index); - condition = new(ir) ir_expression(ir_binop_equal, - glsl_type::bool_type, - deref, - new(ir) ir_constant(i)); /* Just clone the rest of the deref chain when trying to get at the * underlying variable. */ - swizzle = new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), - i, 0, 0, 0, 1); + ir_rvalue *swizzle = + new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), + i, 0, 0, 0, 1); deref = new(ir) ir_dereference_variable(var); - assign = new(ir) ir_assignment(swizzle, deref, condition); - ir->insert_before(assign); + assign = new(ir) ir_assignment(swizzle, deref, condition_swizzle); + list.push_tail(assign); } + + /* If the original assignment has a condition, respect that original + * condition! This is acomplished by wrapping the new conditional + * assignments in an if-statement that uses the original condition. + */ + if (ir->condition != NULL) { + /* No need to clone the condition because the IR that it hangs on is + * going to be removed from the instruction sequence. + */ + ir_if *if_stmt = new(mem_ctx) ir_if(ir->condition); + + list.move_nodes_to(&if_stmt->then_instructions); + ir->insert_before(if_stmt); + } else { + ir->insert_before(&list); + } + ir->remove(); this->progress = true; -- cgit v1.2.3