ir_to_mesa: Refactor code for emitting DP instructions
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 10 Nov 2010 01:01:14 +0000 (17:01 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 10 Nov 2010 02:09:41 +0000 (18:09 -0800)
src/mesa/program/ir_to_mesa.cpp

index bdd3fd92ffc7cdc5f261c9f442f5916c6ea4df1d..f45bbf55821914a322e6f36edbd3337f14856cbf 100644 (file)
@@ -260,6 +260,17 @@ public:
                                               ir_to_mesa_src_reg src1,
                                               ir_to_mesa_src_reg src2);
 
+   /**
+    * Emit the correct dot-product instruction for the type of arguments
+    *
+    * \sa ir_to_mesa_emit_op2
+    */
+   void ir_to_mesa_emit_dp(ir_instruction *ir,
+                          ir_to_mesa_dst_reg dst,
+                          ir_to_mesa_src_reg src0,
+                          ir_to_mesa_src_reg src1,
+                          unsigned elements);
+
    void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
                                   enum prog_opcode op,
                                   ir_to_mesa_dst_reg dst,
@@ -393,6 +404,21 @@ ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
                              ir_to_mesa_undef);
 }
 
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_dp(ir_instruction *ir,
+                                      ir_to_mesa_dst_reg dst,
+                                      ir_to_mesa_src_reg src0,
+                                      ir_to_mesa_src_reg src1,
+                                      unsigned elements)
+{
+   static const gl_inst_opcode dot_opcodes[] = {
+      OPCODE_DP2, OPCODE_DP3, OPCODE_DP4
+   };
+
+   ir_to_mesa_emit_op3(ir, dot_opcodes[elements - 2],
+                      dst, src0, src1, ir_to_mesa_undef);
+}
+
 inline ir_to_mesa_dst_reg
 ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
 {
@@ -832,9 +858,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    struct ir_to_mesa_src_reg op[2];
    struct ir_to_mesa_src_reg result_src;
    struct ir_to_mesa_dst_reg result_dst;
-   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
-   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
-   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
 
    /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
     */
@@ -976,12 +999,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
         ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
         ir_to_mesa_emit_op2(ir, OPCODE_SNE,
                             ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
-        if (vector_elements == 4)
-           ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
-        else if (vector_elements == 3)
-           ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, temp, temp);
-        else
-           ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, temp, temp);
+        ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements);
         ir_to_mesa_emit_op2(ir, OPCODE_SEQ,
                             result_dst, result_src, src_reg_for_float(0.0));
       } else {
@@ -995,12 +1013,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
         ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
         ir_to_mesa_emit_op2(ir, OPCODE_SNE,
                             ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
-        if (vector_elements == 4)
-           ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
-        else if (vector_elements == 3)
-           ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, temp, temp);
-        else
-           ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, temp, temp);
+        ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements);
         ir_to_mesa_emit_op2(ir, OPCODE_SNE,
                             result_dst, result_src, src_reg_for_float(0.0));
       } else {
@@ -1009,20 +1022,9 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       break;
 
    case ir_unop_any:
-      switch (ir->operands[0]->type->vector_elements) {
-      case 4:
-        ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]);
-        break;
-      case 3:
-        ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]);
-        break;
-      case 2:
-        ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]);
-        break;
-      default:
-        assert(!"unreached: ir_unop_any of non-bvec");
-        break;
-      }
+      assert(ir->operands[0]->type->is_vector());
+      ir_to_mesa_emit_dp(ir, result_dst, op[0], op[0],
+                        ir->operands[0]->type->vector_elements);
       ir_to_mesa_emit_op2(ir, OPCODE_SNE,
                          result_dst, result_src, src_reg_for_float(0.0));
       break;
@@ -1050,22 +1052,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       break;
 
    case ir_binop_dot:
-      if (ir->operands[0]->type == vec4_type) {
-        assert(ir->operands[1]->type == vec4_type);
-        ir_to_mesa_emit_op2(ir, OPCODE_DP4,
-                            result_dst,
-                            op[0], op[1]);
-      } else if (ir->operands[0]->type == vec3_type) {
-        assert(ir->operands[1]->type == vec3_type);
-        ir_to_mesa_emit_op2(ir, OPCODE_DP3,
-                            result_dst,
-                            op[0], op[1]);
-      } else if (ir->operands[0]->type == vec2_type) {
-        assert(ir->operands[1]->type == vec2_type);
-        ir_to_mesa_emit_op2(ir, OPCODE_DP2,
-                            result_dst,
-                            op[0], op[1]);
-      }
+      assert(ir->operands[0]->type->is_vector());
+      assert(ir->operands[0]->type == ir->operands[1]->type);
+      ir_to_mesa_emit_dp(ir, result_dst, op[0], op[1],
+                        ir->operands[0]->type->vector_elements);
       break;
 
    case ir_binop_cross: