i965/vec4: Simplify opt_reduce_swizzle() using the swizzle utils.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_visitor.cpp
index f6f589d71b4da3f72b5d4df68e660ef38d6fb68e..05bda43bb2be8128af794f9062b8ac6cef66494c 100644 (file)
@@ -1159,21 +1159,16 @@ vec4_visitor::try_emit_mad(ir_expression *ir)
    if (ir->type->base_type != GLSL_TYPE_FLOAT)
       return false;
 
-   ir_rvalue *nonmul = ir->operands[1];
-   ir_expression *mul = ir->operands[0]->as_expression();
+   ir_rvalue *nonmul;
+   ir_expression *mul;
+   bool mul_negate, mul_abs;
 
-   bool mul_negate = false, mul_abs = false;
-   if (mul && mul->operation == ir_unop_abs) {
-      mul = mul->operands[0]->as_expression();
-      mul_abs = true;
-   } else if (mul && mul->operation == ir_unop_neg) {
-      mul = mul->operands[0]->as_expression();
-      mul_negate = true;
-   }
+   for (int i = 0; i < 2; i++) {
+      mul_negate = false;
+      mul_abs = false;
 
-   if (!mul || mul->operation != ir_binop_mul) {
-      nonmul = ir->operands[0];
-      mul = ir->operands[1]->as_expression();
+      mul = ir->operands[i]->as_expression();
+      nonmul = ir->operands[1 - i];
 
       if (mul && mul->operation == ir_unop_abs) {
          mul = mul->operands[0]->as_expression();
@@ -1183,10 +1178,13 @@ vec4_visitor::try_emit_mad(ir_expression *ir)
          mul_negate = true;
       }
 
-      if (!mul || mul->operation != ir_binop_mul)
-         return false;
+      if (mul && mul->operation == ir_binop_mul)
+         break;
    }
 
+   if (!mul || mul->operation != ir_binop_mul)
+      return false;
+
    nonmul->accept(this);
    src_reg src0 = fix_3src_operand(this->result);
 
@@ -1307,7 +1305,7 @@ void
 vec4_visitor::visit(ir_expression *ir)
 {
    unsigned int operand;
-   src_reg op[Elements(ir->operands)];
+   src_reg op[ARRAY_SIZE(ir->operands)];
    vec4_instruction *inst;
 
    if (ir->operation == ir_binop_add) {
@@ -1557,6 +1555,11 @@ vec4_visitor::visit(ir_expression *ir)
    }
 
    case ir_binop_all_equal:
+      if (brw->gen <= 5) {
+         resolve_bool_comparison(ir->operands[0], &op[0]);
+         resolve_bool_comparison(ir->operands[1], &op[1]);
+      }
+
       /* "==" operator producing a scalar boolean. */
       if (ir->operands[0]->type->is_vector() ||
          ir->operands[1]->type->is_vector()) {
@@ -1569,6 +1572,11 @@ vec4_visitor::visit(ir_expression *ir)
       }
       break;
    case ir_binop_any_nequal:
+      if (brw->gen <= 5) {
+         resolve_bool_comparison(ir->operands[0], &op[0]);
+         resolve_bool_comparison(ir->operands[1], &op[1]);
+      }
+
       /* "!=" operator producing a scalar boolean. */
       if (ir->operands[0]->type->is_vector() ||
          ir->operands[1]->type->is_vector()) {
@@ -1583,6 +1591,9 @@ vec4_visitor::visit(ir_expression *ir)
       break;
 
    case ir_unop_any:
+      if (brw->gen <= 5) {
+         resolve_bool_comparison(ir->operands[0], &op[0]);
+      }
       emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
       emit(MOV(result_dst, src_reg(0)));
 
@@ -1655,7 +1666,7 @@ vec4_visitor::visit(ir_expression *ir)
       emit(CMP(result_dst, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
       break;
    case ir_unop_i2b:
-      emit(AND(result_dst, op[0], src_reg(1)));
+      emit(CMP(result_dst, op[0], src_reg(0), BRW_CONDITIONAL_NZ));
       break;
 
    case ir_unop_trunc:
@@ -1772,6 +1783,15 @@ vec4_visitor::visit(ir_expression *ir)
 
       if (brw->gen >= 7) {
          dst_reg grf_offset = dst_reg(this, glsl_type::int_type);
+
+         /* We have to use a message header on Skylake to get SIMD4x2 mode.
+          * Reserve space for the register.
+          */
+         if (brw->gen >= 9) {
+            grf_offset.reg_offset++;
+            alloc.sizes[grf_offset.reg] = 2;
+         }
+
          grf_offset.type = offset.type;
 
          emit(MOV(grf_offset, offset));
@@ -3466,6 +3486,15 @@ vec4_visitor::emit_pull_constant_load(bblock_t *block, vec4_instruction *inst,
 
    if (brw->gen >= 7) {
       dst_reg grf_offset = dst_reg(this, glsl_type::int_type);
+
+      /* We have to use a message header on Skylake to get SIMD4x2 mode.
+       * Reserve space for the register.
+       */
+      if (brw->gen >= 9) {
+         grf_offset.reg_offset++;
+         alloc.sizes[grf_offset.reg] = 2;
+      }
+
       grf_offset.type = offset.type;
       emit_before(block, inst, MOV(grf_offset, offset));
 
@@ -3642,7 +3671,8 @@ vec4_visitor::vec4_visitor(struct brw_context *brw,
     */
    this->uniform_array_size = 1;
    if (prog_data) {
-      this->uniform_array_size = MAX2(stage_prog_data->nr_params, 1);
+      this->uniform_array_size =
+         MAX2(DIV_ROUND_UP(stage_prog_data->nr_params, 4), 1);
    }
 
    this->uniform_size = rzalloc_array(mem_ctx, int, this->uniform_array_size);