Selaa lähdekoodia

glsl: Fix structure and array comparisions.

We were trying to emit a single ir_expression to compare the whole
thing.  The backends (ir_to_mesa.cpp and brw_fs.cpp so far) expected
ir_binop_any_nequal or ir_binop_all_equal to apply to at most a vector
(with matrices broken down by the lowering pass).  Break them down to
a bunch of ORed or ANDed any_nequals/all_equals.

Fixes:
glsl-array-compare
glsl-array-compare-02
glsl-fs-struct-equal
glsl-fs-struct-notequal
Bug #31909
tags/android-x86-2.2
Eric Anholt 15 vuotta sitten
vanhempi
commit
ff79633d9f
1 muutettua tiedostoa jossa 70 lisäystä ja 2 poistoa
  1. 70
    2
      src/glsl/ast_to_hir.cpp

+ 70
- 2
src/glsl/ast_to_hir.cpp Näytä tiedosto

@@ -745,6 +745,75 @@ ast_node::hir(exec_list *instructions,
return NULL;
}

static ir_rvalue *
do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
{
int join_op;

if (operation == ir_binop_all_equal)
join_op = ir_binop_logic_and;
else
join_op = ir_binop_logic_or;

switch (op0->type->base_type) {
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
case GLSL_TYPE_BOOL:
return new(mem_ctx) ir_expression(operation, op0, op1);

case GLSL_TYPE_ARRAY: {
ir_rvalue *last = NULL;

for (unsigned int i = 0; i < op0->type->length; i++) {
ir_rvalue *e0, *e1, *result;

e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
new(mem_ctx) ir_constant(i));
e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
new(mem_ctx) ir_constant(i));
result = do_comparison(mem_ctx, operation, e0, e1);

if (last) {
last = new(mem_ctx) ir_expression(join_op, last, result);
} else {
last = result;
}
}
return last;
}

case GLSL_TYPE_STRUCT: {
ir_rvalue *last = NULL;

for (unsigned int i = 0; i < op0->type->length; i++) {
ir_rvalue *e0, *e1, *result;
const char *field_name = op0->type->fields.structure[i].name;

e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
field_name);
e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
field_name);
result = do_comparison(mem_ctx, operation, e0, e1);

if (last) {
last = new(mem_ctx) ir_expression(join_op, last, result);
} else {
last = result;
}
}
return last;
}

case GLSL_TYPE_ERROR:
case GLSL_TYPE_VOID:
case GLSL_TYPE_SAMPLER:
/* I assume a comparison of a struct containing a sampler just
* ignores the sampler present in the type.
*/
return new(mem_ctx) ir_constant(true);
}
}

ir_rvalue *
ast_expression::hir(exec_list *instructions,
@@ -941,8 +1010,7 @@ ast_expression::hir(exec_list *instructions,
error_emitted = true;
}

result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
op[0], op[1]);
result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
type = glsl_type::bool_type;

assert(result->type == glsl_type::bool_type);

Loading…
Peruuta
Tallenna