[Mesa-dev] [PATCH 3/4] i965/fs: Implement integer quotient and remainder math operations.

Kenneth Graunke kenneth at whitecape.org
Thu Aug 11 17:38:37 PDT 2011


Prior to this patch, POW was the only two-operand math operation, so a
few cases needed to be updated.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_eu_emit.c            |    2 ++
 src/mesa/drivers/dri/i965/brw_fs.cpp               |    5 +++++
 src/mesa/drivers/dri/i965/brw_fs.h                 |    4 ++++
 src/mesa/drivers/dri/i965/brw_fs_emit.cpp          |   10 ++++++++++
 .../dri/i965/brw_fs_schedule_instructions.cpp      |    2 ++
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp       |   10 ++++++++--
 6 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index e7370f3..b591324 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1481,6 +1481,7 @@ void brw_math( struct brw_compile *p,
       assert(!src.abs);
 
       if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
+	  function != BRW_MATH_FUNCTION_INT_DIV_REMAINDER &&
 	  function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
 	 assert(src.type == BRW_REGISTER_TYPE_F);
       }
@@ -1541,6 +1542,7 @@ void brw_math2(struct brw_compile *p,
    assert(src1.hstride == BRW_HORIZONTAL_STRIDE_1);
 
    if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
+       function != BRW_MATH_FUNCTION_INT_DIV_REMAINDER &&
        function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
       assert(src0.type == BRW_REGISTER_TYPE_F);
       assert(src1.type == BRW_REGISTER_TYPE_F);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index fd0d522..a24cef7 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -152,6 +152,8 @@ fs_visitor::implied_mrf_writes(fs_inst *inst)
    case FS_OPCODE_COS:
       return 1 * c->dispatch_width / 8;
    case FS_OPCODE_POW:
+   case FS_OPCODE_INT_QUOTIENT:
+   case FS_OPCODE_INT_REMAINDER:
       return 2 * c->dispatch_width / 8;
    case FS_OPCODE_TEX:
    case FS_OPCODE_TXB:
@@ -577,6 +579,9 @@ fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src0, fs_reg src1)
    switch (opcode) {
    case FS_OPCODE_POW:
       break;
+   case FS_OPCODE_INT_QUOTIENT:
+   case FS_OPCODE_INT_REMAINDER:
+      break;
    default:
       assert(!"not reached: unsupported binary math opcode");
       return NULL;
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 4ec6490..1ce9797 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -65,6 +65,8 @@ enum fs_opcodes {
    FS_OPCODE_POW,
    FS_OPCODE_SIN,
    FS_OPCODE_COS,
+   FS_OPCODE_INT_QUOTIENT,
+   FS_OPCODE_INT_REMAINDER,
    FS_OPCODE_DDX,
    FS_OPCODE_DDY,
    FS_OPCODE_PIXEL_X,
@@ -328,6 +330,8 @@ public:
 	      opcode == FS_OPCODE_LOG2 ||
 	      opcode == FS_OPCODE_SIN ||
 	      opcode == FS_OPCODE_COS ||
+	      opcode == FS_OPCODE_INT_QUOTIENT ||
+	      opcode == FS_OPCODE_INT_REMAINDER ||
 	      opcode == FS_OPCODE_POW);
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 679bf05..71ff513 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -175,6 +175,14 @@ fs_visitor::generate_math(fs_inst *inst,
    case FS_OPCODE_COS:
       op = BRW_MATH_FUNCTION_COS;
       break;
+   case FS_OPCODE_INT_QUOTIENT:
+      op = BRW_MATH_FUNCTION_INT_DIV_QUOTIENT;
+      num_operands = 2;
+      break;
+   case FS_OPCODE_INT_REMAINDER:
+      op = BRW_MATH_FUNCTION_INT_DIV_REMAINDER;
+      num_operands = 2;
+      break;
    default:
       assert(!"not reached: unknown math function");
       op = 0;
@@ -779,6 +787,8 @@ fs_visitor::generate_code()
       case FS_OPCODE_POW:
       case FS_OPCODE_SIN:
       case FS_OPCODE_COS:
+      case FS_OPCODE_INT_QUOTIENT:
+      case FS_OPCODE_INT_REMAINDER:
 	 generate_math(inst, dst, src);
 	 break;
       case FS_OPCODE_PIXEL_X:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp
index f1a88fc..062b408 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp
@@ -100,6 +100,8 @@ public:
 	 this->latency = 4 * chans * math_latency;
 	 break;
       case FS_OPCODE_POW:
+      case FS_OPCODE_INT_QUOTIENT:
+      case FS_OPCODE_INT_REMAINDER:
 	 this->latency = 8 * chans * math_latency;
 	 break;
       case FS_OPCODE_SIN:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 2e3f9be..560956c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -290,10 +290,16 @@ fs_visitor::visit(ir_expression *ir)
       emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
       break;
    case ir_binop_div:
-      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
+      /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */
+      assert(ir->type->is_integer());
+
+      emit_math(FS_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]);
       break;
    case ir_binop_mod:
-      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
+      /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */
+      assert(ir->type->is_integer());
+
+      emit_math(FS_OPCODE_INT_REMAINDER, this->result, op[0], op[1]);
       break;
 
    case ir_binop_less:
-- 
1.7.6



More information about the mesa-dev mailing list