|
|
@@ -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); |