i965: Handle ir_triop_csel in emit_bool_to_cond_code().
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 22 Aug 2014 19:19:49 +0000 (12:19 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 4 Sep 2014 00:12:03 +0000 (17:12 -0700)
ir_triop_csel can return a boolean expression, so we need to handle it
here; we simply forgot when we added it.

Fixes Piglit's EXT_shader_integer_mix/{vs,fs}-mix-if-bool.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Cc: mesa-stable@lists.freedesktop.org
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 2fa90a484a5eae66768d752ed6bdce23500d69b6..ba163ecddc311b39fae135719ef52b8776b2b4c0 100644 (file)
@@ -2243,10 +2243,10 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
       return;
    }
 
-   fs_reg op[2];
+   fs_reg op[3];
    fs_inst *inst;
 
-   assert(expr->get_num_operands() <= 2);
+   assert(expr->get_num_operands() <= 3);
    for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
       assert(expr->operands[i]->type->is_scalar());
 
@@ -2333,6 +2333,22 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
                brw_conditional_for_comparison(expr->operation)));
       break;
 
+   case ir_triop_csel: {
+      /* Expand the boolean condition into the flag register. */
+      inst = emit(MOV(reg_null_d, op[0]));
+      inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+      /* Select which boolean to return. */
+      fs_reg temp(this, expr->operands[1]->type);
+      inst = emit(SEL(temp, op[1], op[2]));
+      inst->predicate = BRW_PREDICATE_NORMAL;
+
+      /* Expand the result to a condition code. */
+      inst = emit(MOV(reg_null_d, temp));
+      inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      break;
+   }
+
    default:
       unreachable("not reached");
    }
index fbf3d0135481e77c0a13c03d9dabab3a1f76f422..7de77557a517f9576918f695054ce11ce62d60ef 100644 (file)
@@ -777,10 +777,10 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir,
    *predicate = BRW_PREDICATE_NORMAL;
 
    if (expr) {
-      src_reg op[2];
+      src_reg op[3];
       vec4_instruction *inst;
 
-      assert(expr->get_num_operands() <= 2);
+      assert(expr->get_num_operands() <= 3);
       for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
         expr->operands[i]->accept(this);
         op[i] = this->result;
@@ -852,6 +852,22 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir,
                  brw_conditional_for_comparison(expr->operation)));
         break;
 
+      case ir_triop_csel: {
+         /* Expand the boolean condition into the flag register. */
+         inst = emit(MOV(dst_null_d(), op[0]));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+         /* Select which boolean to return. */
+         dst_reg temp(this, expr->operands[1]->type);
+         inst = emit(BRW_OPCODE_SEL, temp, op[1], op[2]);
+         inst->predicate = BRW_PREDICATE_NORMAL;
+
+         /* Expand the result to a condition code. */
+         inst = emit(MOV(dst_null_d(), src_reg(temp)));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+         break;
+      }
+
       default:
         unreachable("not reached");
       }