[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