[Mesa-dev] [PATCH 14/16] i965/vs: Add support for bit instructions.

Matt Turner mattst88 at gmail.com
Mon Apr 22 17:08:30 PDT 2013


---
 src/mesa/drivers/dri/i965/brw_vec4.h           |    7 +++
 src/mesa/drivers/dri/i965/brw_vec4_emit.cpp    |   29 ++++++++++++++
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |   48 ++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 697ab86..45c1f7a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -386,6 +386,13 @@ public:
    vec4_instruction *PULL_CONSTANT_LOAD(dst_reg dst, src_reg index);
    vec4_instruction *SCRATCH_READ(dst_reg dst, src_reg index);
    vec4_instruction *SCRATCH_WRITE(dst_reg dst, src_reg src, src_reg index);
+   vec4_instruction *BFREV(dst_reg dst, src_reg value);
+   vec4_instruction *BFE(dst_reg dst, src_reg bits, src_reg offset, src_reg value);
+   vec4_instruction *BFI1(dst_reg dst, src_reg bits, src_reg offset);
+   vec4_instruction *BFI2(dst_reg dst, src_reg bfi1_dst, src_reg insert, src_reg base);
+   vec4_instruction *FBH(dst_reg dst, src_reg value);
+   vec4_instruction *FBL(dst_reg dst, src_reg value);
+   vec4_instruction *CBIT(dst_reg dst, src_reg value);
 
    int implied_mrf_writes(vec4_instruction *inst);
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index c9963bf..6916bd8 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -838,6 +838,35 @@ vec4_generator::generate_code(exec_list *instructions)
          brw_F16TO32(p, dst, src[0]);
          break;
 
+      case BRW_OPCODE_BFREV:
+         /* BFREV only supports UD type for src and dst. */
+         brw_BFREV(p, retype(dst, BRW_REGISTER_TYPE_UD),
+                      retype(src[0], BRW_REGISTER_TYPE_UD));
+         break;
+      case BRW_OPCODE_FBH:
+         /* FBH only supports UD type for dst. */
+         brw_FBH(p, retype(dst, BRW_REGISTER_TYPE_UD), src[0]);
+         break;
+      case BRW_OPCODE_FBL:
+         /* FBL only supports UD type for dst. */
+         brw_FBL(p, retype(dst, BRW_REGISTER_TYPE_UD), src[0]);
+         break;
+      case BRW_OPCODE_CBIT:
+         /* CBIT only supports UD type for dst. */
+         brw_CBIT(p, retype(dst, BRW_REGISTER_TYPE_UD), src[0]);
+         break;
+
+      case BRW_OPCODE_BFE:
+         brw_BFE(p, dst, src[0], src[1], src[2]);
+         break;
+
+      case BRW_OPCODE_BFI1:
+         brw_BFI1(p, dst, src[0], src[1]);
+         break;
+      case BRW_OPCODE_BFI2:
+         brw_BFI2(p, dst, src[0], src[1], src[2]);
+         break;
+
       case BRW_OPCODE_IF:
 	 if (inst->src[0].file != BAD_FILE) {
 	    /* The instruction has an embedded compare (only allowed on gen6) */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 2fb8482..d46c3f7 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -107,6 +107,14 @@ vec4_visitor::emit(enum opcode opcode)
 					   src0, src1);			\
    }
 
+#define ALU3(op)							\
+   vec4_instruction *							\
+   vec4_visitor::op(dst_reg dst, src_reg src0, src_reg src1, src_reg src2)\
+   {									\
+      return new(mem_ctx) vec4_instruction(this, BRW_OPCODE_##op, dst,	\
+					   src0, src1, src2);		\
+   }
+
 ALU1(NOT)
 ALU1(MOV)
 ALU1(FRC)
@@ -127,6 +135,13 @@ ALU2(DPH)
 ALU2(SHL)
 ALU2(SHR)
 ALU2(ASR)
+ALU1(BFREV)
+ALU3(BFE)
+ALU2(BFI1)
+ALU3(BFI2)
+ALU1(FBH)
+ALU1(FBL)
+ALU1(CBIT)
 
 /** Gen4 predicated IF. */
 vec4_instruction *
@@ -1350,6 +1365,19 @@ vec4_visitor::visit(ir_expression *ir)
       assert(!"derivatives not valid in vertex shader");
       break;
 
+   case ir_unop_bitfield_reverse:
+      emit(BFREV(result_dst, op[0]));
+      break;
+   case ir_unop_bit_count:
+      emit(CBIT(result_dst, op[0]));
+      break;
+   case ir_unop_find_msb:
+      emit(FBH(result_dst, op[0]));
+      break;
+   case ir_unop_find_lsb:
+      emit(FBL(result_dst, op[0]));
+      break;
+
    case ir_unop_noise:
       assert(!"not reached: should be handled by lower_noise");
       break;
@@ -1550,6 +1578,10 @@ vec4_visitor::visit(ir_expression *ir)
          inst = emit(SHR(result_dst, op[0], op[1]));
       break;
 
+   case ir_binop_bfm:
+      emit(BFI1(result_dst, op[0], op[1]));
+      break;
+
    case ir_binop_ubo_load: {
       ir_constant *uniform_block = ir->operands[0]->as_constant();
       ir_constant *const_offset_ir = ir->operands[1]->as_constant();
@@ -1599,6 +1631,22 @@ vec4_visitor::visit(ir_expression *ir)
       assert(!"not reached: should be handled by lrp_to_arith");
       break;
 
+   case ir_triop_bfi:
+      emit(BFI2(result_dst, op[0], op[1], op[2]));
+      break;
+
+   case ir_triop_bitfield_extract:
+      /* Note that the instruction's argument order is reversed from GLSL
+       * and the IR.
+       */
+      emit(BFE(result_dst, op[2], op[1], op[0]));
+      break;
+
+   case ir_quadop_bitfield_insert:
+      assert(!"not reached: should be handled by "
+              "bitfield_insert_to_bfm_bfi\n");
+      break;
+
    case ir_quadop_vector:
       assert(!"not reached: should be handled by lower_quadop_vector");
       break;
-- 
1.7.8.6



More information about the mesa-dev mailing list