* we do retain the vector types in that case.
*/
-extern "C" {
-#include "main/core.h"
-#include "brw_wm.h"
-}
-#include "../glsl/ir.h"
-#include "../glsl/ir_expression_flattening.h"
-#include "../glsl/glsl_types.h"
+#include "compiler/glsl/ir.h"
+#include "compiler/glsl/ir_expression_flattening.h"
+#include "compiler/glsl_types.h"
class ir_channel_expressions_visitor : public ir_hierarchical_visitor {
public:
if (!expr)
return false;
+ switch (expr->operation) {
+ case ir_unop_pack_half_2x16:
+ case ir_unop_pack_snorm_2x16:
+ case ir_unop_pack_snorm_4x8:
+ case ir_unop_pack_unorm_2x16:
+ case ir_unop_pack_unorm_4x8:
+ return false;
+
+ /* these opcodes need to act on the whole vector,
+ * just like texturing.
+ */
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
+ case ir_unop_pack_double_2x32:
+ return false;
+ default:
+ break;
+ }
+
for (i = 0; i < expr->get_num_operands(); i++) {
if (expr->operands[i]->type->is_vector())
return true;
return false;
}
-extern "C" {
-GLboolean
+bool
brw_do_channel_expressions(exec_list *instructions)
{
ir_channel_expressions_visitor v;
return v.progress;
}
-}
ir_rvalue *
ir_channel_expressions_visitor::get_element(ir_variable *var, unsigned int elem)
{
ir_dereference *lhs = ir->lhs->clone(mem_ctx, NULL);
ir_assignment *assign;
- ir_swizzle *val_swiz;
/* This assign-of-expression should have been generated by the
* expression flattening visitor (since we never short circit to
*/
assert(ir->write_mask == (1 << ir->lhs->type->components()) - 1);
- /* Smear the float across all the channels for the masked write. */
- val_swiz = new(mem_ctx) ir_swizzle(val, 0, 0, 0, 0,
- ir->lhs->type->components());
- assign = new(mem_ctx) ir_assignment(lhs, val_swiz, NULL, (1 << elem));
+ assign = new(mem_ctx) ir_assignment(lhs, val, NULL, (1 << elem));
ir->insert_before(assign);
}
ir_expression *expr = ir->rhs->as_expression();
bool found_vector = false;
unsigned int i, vector_elements = 1;
- ir_variable *op_var[2];
+ ir_variable *op_var[4];
if (!expr)
return visit_continue;
if (!this->mem_ctx)
- this->mem_ctx = talloc_parent(ir);
+ this->mem_ctx = ralloc_parent(ir);
for (i = 0; i < expr->get_num_operands(); i++) {
if (expr->operands[i]->type->is_vector()) {
if (!found_vector)
return visit_continue;
+ switch (expr->operation) {
+ case ir_unop_pack_half_2x16:
+ case ir_unop_pack_snorm_2x16:
+ case ir_unop_pack_snorm_4x8:
+ case ir_unop_pack_unorm_2x16:
+ case ir_unop_pack_unorm_4x8:
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
+ /* We scalarize these in NIR, so no need to do it here */
+ case ir_unop_pack_double_2x32:
+ return visit_continue;
+
+ default:
+ break;
+ }
+
/* Store the expression operands in temps so we can use them
* multiple times.
*/
case ir_unop_log:
case ir_unop_exp2:
case ir_unop_log2:
+ case ir_unop_bitcast_i2f:
+ case ir_unop_bitcast_f2i:
+ case ir_unop_bitcast_f2u:
+ case ir_unop_bitcast_u2f:
+ case ir_unop_i2u:
+ case ir_unop_u2i:
case ir_unop_f2i:
+ case ir_unop_f2u:
case ir_unop_i2f:
case ir_unop_f2b:
case ir_unop_b2f:
case ir_unop_i2b:
case ir_unop_b2i:
case ir_unop_u2f:
+ case ir_unop_d2f:
+ case ir_unop_f2d:
+ case ir_unop_d2i:
+ case ir_unop_i2d:
+ case ir_unop_d2u:
+ case ir_unop_u2d:
+ case ir_unop_d2b:
case ir_unop_trunc:
case ir_unop_ceil:
case ir_unop_floor:
case ir_unop_fract:
+ case ir_unop_round_even:
case ir_unop_sin:
case ir_unop_cos:
case ir_unop_dFdx:
+ case ir_unop_dFdx_coarse:
+ case ir_unop_dFdx_fine:
case ir_unop_dFdy:
+ case ir_unop_dFdy_coarse:
+ case ir_unop_dFdy_fine:
+ case ir_unop_bitfield_reverse:
+ case ir_unop_bit_count:
+ case ir_unop_find_msb:
+ case ir_unop_find_lsb:
+ case ir_unop_saturate:
+ case ir_unop_subroutine_to_int:
for (i = 0; i < vector_elements; i++) {
ir_rvalue *op0 = get_element(op_var[0], i);
case ir_binop_add:
case ir_binop_sub:
case ir_binop_mul:
+ case ir_binop_imul_high:
case ir_binop_div:
+ case ir_binop_carry:
+ case ir_binop_borrow:
case ir_binop_mod:
case ir_binop_min:
case ir_binop_max:
case ir_binop_bit_and:
case ir_binop_bit_xor:
case ir_binop_bit_or:
+ case ir_binop_logic_and:
+ case ir_binop_logic_xor:
+ case ir_binop_logic_or:
+ case ir_binop_less:
+ case ir_binop_greater:
+ case ir_binop_lequal:
+ case ir_binop_gequal:
+ case ir_binop_equal:
+ case ir_binop_nequal:
+ case ir_binop_ldexp:
for (i = 0; i < vector_elements; i++) {
ir_rvalue *op0 = get_element(op_var[0], i);
ir_rvalue *op1 = get_element(op_var[1], i);
}
break;
- case ir_unop_any: {
- ir_expression *temp;
- temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
- element_type,
- get_element(op_var[0], 0),
- get_element(op_var[0], 1));
-
- for (i = 2; i < vector_elements; i++) {
- temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
- element_type,
- get_element(op_var[0], i),
- temp);
- }
- assign(ir, 0, temp);
- break;
- }
-
case ir_binop_dot: {
ir_expression *last = NULL;
for (i = 0; i < vector_elements; i++) {
break;
}
- case ir_binop_cross: {
- for (i = 0; i < vector_elements; i++) {
- int swiz0 = (i + 1) % 3;
- int swiz1 = (i + 2) % 3;
- ir_expression *temp1, *temp2;
-
- temp1 = new(mem_ctx) ir_expression(ir_binop_mul,
- element_type,
- get_element(op_var[0], swiz0),
- get_element(op_var[1], swiz1));
-
- temp2 = new(mem_ctx) ir_expression(ir_binop_mul,
- element_type,
- get_element(op_var[1], swiz0),
- get_element(op_var[0], swiz1));
-
- temp2 = new(mem_ctx) ir_expression(ir_unop_neg,
- element_type,
- temp2,
- NULL);
-
- assign(ir, i, new(mem_ctx) ir_expression(ir_binop_add,
- element_type,
- temp1, temp2));
- }
- break;
- }
-
- case ir_binop_less:
- case ir_binop_greater:
- case ir_binop_lequal:
- case ir_binop_gequal:
- case ir_binop_logic_and:
- case ir_binop_logic_xor:
- case ir_binop_logic_or:
- ir->print();
- printf("\n");
- assert(!"not reached: expression operates on scalars only");
- break;
- case ir_binop_equal:
- case ir_binop_nequal: {
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal: {
ir_expression *last = NULL;
for (i = 0; i < vector_elements; i++) {
ir_rvalue *op0 = get_element(op_var[0], i);
ir_expression *temp;
ir_expression_operation join;
- if (expr->operation == ir_binop_equal)
+ if (expr->operation == ir_binop_all_equal)
join = ir_binop_logic_and;
else
join = ir_binop_logic_or;
assign(ir, 0, last);
break;
}
+ case ir_unop_noise:
+ unreachable("noise should have been broken down to function call");
+
+ case ir_binop_ubo_load:
+ case ir_unop_get_buffer_size:
+ unreachable("not yet supported");
+
+ case ir_triop_fma:
+ case ir_triop_lrp:
+ case ir_triop_csel:
+ case ir_triop_bitfield_extract:
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op0 = get_element(op_var[0], i);
+ ir_rvalue *op1 = get_element(op_var[1], i);
+ ir_rvalue *op2 = get_element(op_var[2], i);
+
+ assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0,
+ op1,
+ op2));
+ }
+ break;
+
+ case ir_quadop_bitfield_insert:
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op0 = get_element(op_var[0], i);
+ ir_rvalue *op1 = get_element(op_var[1], i);
+ ir_rvalue *op2 = get_element(op_var[2], i);
+ ir_rvalue *op3 = get_element(op_var[3], i);
+
+ assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0,
+ op1,
+ op2,
+ op3));
+ }
+ break;
+
+ case ir_unop_pack_snorm_2x16:
+ case ir_unop_pack_snorm_4x8:
+ case ir_unop_pack_unorm_2x16:
+ case ir_unop_pack_unorm_4x8:
+ case ir_unop_pack_half_2x16:
+ case ir_unop_unpack_snorm_2x16:
+ case ir_unop_unpack_snorm_4x8:
+ case ir_unop_unpack_unorm_2x16:
+ case ir_unop_unpack_unorm_4x8:
+ case ir_unop_unpack_half_2x16:
+ case ir_binop_vector_extract:
+ case ir_triop_vector_insert:
+ case ir_quadop_vector:
+ case ir_unop_ssbo_unsized_array_length:
+ unreachable("should have been lowered");
+
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
+ case ir_unop_unpack_double_2x32:
+ unreachable("not reached: expression operates on scalars only");
+
+ case ir_unop_pack_double_2x32:
+ unreachable("not reached: to be lowered in NIR, should've been skipped");
+
+ case ir_unop_frexp_sig:
+ case ir_unop_frexp_exp:
+ unreachable("should have been lowered by lower_instructions");
}
ir->remove();