mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
glsl: Compare vector indices in blocks
Just like the non-constant array index lowering pass, compare all N indices at once. For accesses to a vec4, this saves 3 comparison instructions on a vector architecture. Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
90cc372400
commit
6c8f1f483a
1 changed files with 39 additions and 23 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -189,24 +200,29 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
|
|||
assign = new(ir) ir_assignment(deref, ir->rhs, NULL);
|
||||
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);
|
||||
assign = new(ir) ir_assignment(swizzle, deref, condition_swizzle);
|
||||
list.push_tail(assign);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue