i965/vec4: Combine all the math emitters.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 11 Nov 2014 22:40:08 +0000 (14:40 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 14 Nov 2014 04:55:41 +0000 (20:55 -0800)
17 insertions(+), 102 deletions(-).  Works just as well.

v2: Make emit_math take const references (suggested by Matt),
    drop redundant WRITEMASK_XYZW setting (Matt and Curro).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index ebbf882968e25ac0860f831dcf0159e01951316d..8e7dfe16c7d54baff89195b0ab991359661e53b6 100644 (file)
@@ -503,12 +503,8 @@ public:
 
    src_reg fix_3src_operand(src_reg src);
 
-   void emit_math1_gen6(enum opcode opcode, dst_reg dst, src_reg src);
-   void emit_math1_gen4(enum opcode opcode, dst_reg dst, src_reg src);
-   void emit_math(enum opcode opcode, dst_reg dst, src_reg src);
-   void emit_math2_gen6(enum opcode opcode, dst_reg dst, src_reg src0, src_reg src1);
-   void emit_math2_gen4(enum opcode opcode, dst_reg dst, src_reg src0, src_reg src1);
-   void emit_math(enum opcode opcode, dst_reg dst, src_reg src0, src_reg src1);
+   void emit_math(enum opcode opcode, const dst_reg &dst, const src_reg &src0,
+                  const src_reg &src1 = src_reg());
    src_reg fix_math_operand(src_reg src);
 
    void emit_pack_half_2x16(dst_reg dst, src_reg src0);
index a8ce4981073988075a6836ae272b9d3910a58440..af7ca0c2ead31075af6d957ff5709fab6dbc34bc 100644 (file)
@@ -310,6 +310,9 @@ vec4_visitor::fix_3src_operand(src_reg src)
 src_reg
 vec4_visitor::fix_math_operand(src_reg src)
 {
+   if (brw->gen < 6 || brw->gen >= 8 || src.file == BAD_FILE)
+      return src;
+
    /* The gen6 math instruction ignores the source modifiers --
     * swizzle, abs, negate, and at least some parts of the register
     * region description.
@@ -330,108 +333,22 @@ vec4_visitor::fix_math_operand(src_reg src)
    return src_reg(expanded);
 }
 
-void
-vec4_visitor::emit_math1_gen6(enum opcode opcode, dst_reg dst, src_reg src)
-{
-   src = fix_math_operand(src);
-
-   if (brw->gen == 6 && dst.writemask != WRITEMASK_XYZW) {
-      /* The gen6 math instruction must be align1, so we can't do
-       * writemasks.
-       */
-      dst_reg temp_dst = dst_reg(this, glsl_type::vec4_type);
-
-      emit(opcode, temp_dst, src);
-
-      emit(MOV(dst, src_reg(temp_dst)));
-   } else {
-      emit(opcode, dst, src);
-   }
-}
-
-void
-vec4_visitor::emit_math1_gen4(enum opcode opcode, dst_reg dst, src_reg src)
-{
-   vec4_instruction *inst = emit(opcode, dst, src);
-   inst->base_mrf = 1;
-   inst->mlen = 1;
-}
-
-void
-vec4_visitor::emit_math(opcode opcode, dst_reg dst, src_reg src)
-{
-   switch (opcode) {
-   case SHADER_OPCODE_RCP:
-   case SHADER_OPCODE_RSQ:
-   case SHADER_OPCODE_SQRT:
-   case SHADER_OPCODE_EXP2:
-   case SHADER_OPCODE_LOG2:
-   case SHADER_OPCODE_SIN:
-   case SHADER_OPCODE_COS:
-      break;
-   default:
-      unreachable("not reached: bad math opcode");
-   }
-
-   if (brw->gen >= 8) {
-      emit(opcode, dst, src);
-   } else if (brw->gen >= 6) {
-      emit_math1_gen6(opcode, dst, src);
-   } else {
-      emit_math1_gen4(opcode, dst, src);
-   }
-}
-
-void
-vec4_visitor::emit_math2_gen6(enum opcode opcode,
-                             dst_reg dst, src_reg src0, src_reg src1)
-{
-   src0 = fix_math_operand(src0);
-   src1 = fix_math_operand(src1);
-
-   if (brw->gen == 6 && dst.writemask != WRITEMASK_XYZW) {
-      /* The gen6 math instruction must be align1, so we can't do
-       * writemasks.
-       */
-      dst_reg temp_dst = dst_reg(this, glsl_type::vec4_type);
-      temp_dst.type = dst.type;
-
-      emit(opcode, temp_dst, src0, src1);
-
-      emit(MOV(dst, src_reg(temp_dst)));
-   } else {
-      emit(opcode, dst, src0, src1);
-   }
-}
-
-void
-vec4_visitor::emit_math2_gen4(enum opcode opcode,
-                             dst_reg dst, src_reg src0, src_reg src1)
-{
-   vec4_instruction *inst = emit(opcode, dst, src0, src1);
-   inst->base_mrf = 1;
-   inst->mlen = 2;
-}
-
 void
 vec4_visitor::emit_math(enum opcode opcode,
-                       dst_reg dst, src_reg src0, src_reg src1)
+                        const dst_reg &dst,
+                        const src_reg &src0, const src_reg &src1)
 {
-   switch (opcode) {
-   case SHADER_OPCODE_POW:
-   case SHADER_OPCODE_INT_QUOTIENT:
-   case SHADER_OPCODE_INT_REMAINDER:
-      break;
-   default:
-      unreachable("not reached: unsupported binary math opcode");
-   }
+   vec4_instruction *math =
+      emit(opcode, dst, fix_math_operand(src0), fix_math_operand(src1));
 
-   if (brw->gen >= 8) {
-      emit(opcode, dst, src0, src1);
-   } else if (brw->gen >= 6) {
-      emit_math2_gen6(opcode, dst, src0, src1);
-   } else {
-      emit_math2_gen4(opcode, dst, src0, src1);
+   if (brw->gen == 6 && dst.writemask != WRITEMASK_XYZW) {
+      /* MATH on Gen6 must be align1, so we can't do writemasks. */
+      math->dst = dst_reg(this, glsl_type::vec4_type);
+      math->dst.type = dst.type;
+      emit(MOV(dst, src_reg(math->dst)));
+   } else if (brw->gen < 6) {
+      math->base_mrf = 1;
+      math->mlen = src1.file == BAD_FILE ? 1 : 2;
    }
 }