glsl: Factor out code that generates block of index comparisons
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
@@ -69,3 +69,7 @@ bool lower_variable_index_to_cond_assign(exec_list *instructions,
|
|||||||
bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform);
|
bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform);
|
||||||
bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz);
|
bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz);
|
||||||
bool optimize_redundant_jumps(exec_list *instructions);
|
bool optimize_redundant_jumps(exec_list *instructions);
|
||||||
|
|
||||||
|
ir_rvalue *
|
||||||
|
compare_index_block(exec_list *instructions, ir_variable *index,
|
||||||
|
unsigned base, unsigned components, void *mem_ctx);
|
||||||
|
@@ -52,6 +52,70 @@
|
|||||||
#include "glsl_types.h"
|
#include "glsl_types.h"
|
||||||
#include "main/macros.h"
|
#include "main/macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a comparison value for a block of indices
|
||||||
|
*
|
||||||
|
* Lowering passes for non-constant indexing of arrays, matrices, or vectors
|
||||||
|
* can use this to generate blocks of index comparison values.
|
||||||
|
*
|
||||||
|
* \param instructions List where new instructions will be appended
|
||||||
|
* \param index \c ir_variable containing the desired index
|
||||||
|
* \param base Base value for this block of comparisons
|
||||||
|
* \param components Number of unique index values to compare. This must
|
||||||
|
* be on the range [1, 4].
|
||||||
|
* \param mem_ctx ralloc memory context to be used for all allocations.
|
||||||
|
*
|
||||||
|
* \returns
|
||||||
|
* An \c ir_rvalue that \b must be cloned for each use in conditional
|
||||||
|
* assignments, etc.
|
||||||
|
*/
|
||||||
|
ir_rvalue *
|
||||||
|
compare_index_block(exec_list *instructions, ir_variable *index,
|
||||||
|
unsigned base, unsigned components, void *mem_ctx)
|
||||||
|
{
|
||||||
|
ir_rvalue *broadcast_index = new(mem_ctx) ir_dereference_variable(index);
|
||||||
|
|
||||||
|
assert(index->type->is_scalar());
|
||||||
|
assert(index->type->base_type == GLSL_TYPE_INT);
|
||||||
|
assert(components >= 1 && components <= 4);
|
||||||
|
|
||||||
|
if (components > 1) {
|
||||||
|
const ir_swizzle_mask m = { 0, 0, 0, 0, components, false };
|
||||||
|
broadcast_index = new(mem_ctx) ir_swizzle(broadcast_index, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare the desired index value with the next block of four indices.
|
||||||
|
*/
|
||||||
|
ir_constant_data test_indices_data;
|
||||||
|
memset(&test_indices_data, 0, sizeof(test_indices_data));
|
||||||
|
test_indices_data.i[0] = base;
|
||||||
|
test_indices_data.i[1] = base + 1;
|
||||||
|
test_indices_data.i[2] = base + 2;
|
||||||
|
test_indices_data.i[3] = base + 3;
|
||||||
|
|
||||||
|
ir_constant *const test_indices =
|
||||||
|
new(mem_ctx) ir_constant(broadcast_index->type,
|
||||||
|
&test_indices_data);
|
||||||
|
|
||||||
|
ir_rvalue *const condition_val =
|
||||||
|
new(mem_ctx) ir_expression(ir_binop_equal,
|
||||||
|
&glsl_type::bool_type[components - 1],
|
||||||
|
broadcast_index,
|
||||||
|
test_indices);
|
||||||
|
|
||||||
|
ir_variable *const condition =
|
||||||
|
new(mem_ctx) ir_variable(condition_val->type,
|
||||||
|
"dereference_condition",
|
||||||
|
ir_var_temporary);
|
||||||
|
instructions->push_tail(condition);
|
||||||
|
|
||||||
|
ir_rvalue *const cond_deref =
|
||||||
|
new(mem_ctx) ir_dereference_variable(condition);
|
||||||
|
instructions->push_tail(new(mem_ctx) ir_assignment(cond_deref, condition_val, 0));
|
||||||
|
|
||||||
|
return cond_deref;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_array_or_matrix(const ir_instruction *ir)
|
is_array_or_matrix(const ir_instruction *ir)
|
||||||
{
|
{
|
||||||
@@ -204,54 +268,17 @@ struct switch_generator
|
|||||||
for (unsigned i = first; i < end; i += 4) {
|
for (unsigned i = first; i < end; i += 4) {
|
||||||
const unsigned comps = MIN2(condition_components, end - i);
|
const unsigned comps = MIN2(condition_components, end - i);
|
||||||
|
|
||||||
ir_rvalue *broadcast_index =
|
|
||||||
new(this->mem_ctx) ir_dereference_variable(index);
|
|
||||||
|
|
||||||
if (comps) {
|
|
||||||
const ir_swizzle_mask m = { 0, 0, 0, 0, comps, false };
|
|
||||||
broadcast_index = new(this->mem_ctx) ir_swizzle(broadcast_index, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare the desired index value with the next block of four indices.
|
|
||||||
*/
|
|
||||||
ir_constant_data test_indices_data;
|
|
||||||
memset(&test_indices_data, 0, sizeof(test_indices_data));
|
|
||||||
test_indices_data.i[0] = i;
|
|
||||||
test_indices_data.i[1] = i + 1;
|
|
||||||
test_indices_data.i[2] = i + 2;
|
|
||||||
test_indices_data.i[3] = i + 3;
|
|
||||||
ir_constant *const test_indices =
|
|
||||||
new(this->mem_ctx) ir_constant(broadcast_index->type,
|
|
||||||
&test_indices_data);
|
|
||||||
|
|
||||||
ir_rvalue *const condition_val =
|
|
||||||
new(this->mem_ctx) ir_expression(ir_binop_equal,
|
|
||||||
&glsl_type::bool_type[comps - 1],
|
|
||||||
broadcast_index,
|
|
||||||
test_indices);
|
|
||||||
|
|
||||||
ir_variable *const condition =
|
|
||||||
new(this->mem_ctx) ir_variable(condition_val->type,
|
|
||||||
"dereference_array_condition",
|
|
||||||
ir_var_temporary);
|
|
||||||
list->push_tail(condition);
|
|
||||||
|
|
||||||
ir_rvalue *const cond_deref =
|
ir_rvalue *const cond_deref =
|
||||||
new(this->mem_ctx) ir_dereference_variable(condition);
|
compare_index_block(list, index, i, comps, this->mem_ctx);
|
||||||
list->push_tail(new(this->mem_ctx) ir_assignment(cond_deref,
|
|
||||||
condition_val, 0));
|
|
||||||
|
|
||||||
if (comps == 1) {
|
if (comps == 1) {
|
||||||
ir_rvalue *const cond_deref =
|
this->generator.generate(i, cond_deref->clone(this->mem_ctx, NULL),
|
||||||
new(this->mem_ctx) ir_dereference_variable(condition);
|
list);
|
||||||
|
|
||||||
this->generator.generate(i, cond_deref, list);
|
|
||||||
} else {
|
} else {
|
||||||
for (unsigned j = 0; j < comps; j++) {
|
for (unsigned j = 0; j < comps; j++) {
|
||||||
ir_rvalue *const cond_deref =
|
|
||||||
new(this->mem_ctx) ir_dereference_variable(condition);
|
|
||||||
ir_rvalue *const cond_swiz =
|
ir_rvalue *const cond_swiz =
|
||||||
new(this->mem_ctx) ir_swizzle(cond_deref, j, 0, 0, 0, 1);
|
new(this->mem_ctx) ir_swizzle(cond_deref->clone(this->mem_ctx, NULL),
|
||||||
|
j, 0, 0, 0, 1);
|
||||||
|
|
||||||
this->generator.generate(i + j, cond_swiz, list);
|
this->generator.generate(i + j, cond_swiz, list);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user