diff options
Diffstat (limited to 'src/mesa/program')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index bdd3fd92ffc..f45bbf55821 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -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: |