aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-05-17 23:54:25 -0700
committerFrancisco Jerez <[email protected]>2016-05-27 23:19:21 -0700
commit99b5476d33f967ac2a30c3f8f7f958a7169e7123 (patch)
treeebcce452816e95424dd07983ec24c3e187049ded
parente531b7907a6a10922e09c42f9c78d3b59beab2b4 (diff)
i965/fs: Lower math into Gen4-5 send-like instructions in lower_logical_sends.
The benefit is we will be able to use the SIMD lowering pass to unroll math instructions of unsupported width and then remove some cruft from the generator. Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp55
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_builder.h47
2 files changed, 60 insertions, 42 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index d7ae90a8f04..822d863ab1c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -4434,6 +4434,36 @@ lower_varying_pull_constant_logical_send(const fs_builder &bld, fs_inst *inst)
}
}
+static void
+lower_math_logical_send(const fs_builder &bld, fs_inst *inst)
+{
+ assert(bld.shader->devinfo->gen < 6);
+
+ inst->base_mrf = 2;
+ inst->mlen = inst->sources * inst->exec_size / 8;
+
+ if (inst->sources > 1) {
+ /* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13
+ * "Message Payload":
+ *
+ * "Operand0[7]. For the INT DIV functions, this operand is the
+ * denominator."
+ * ...
+ * "Operand1[7]. For the INT DIV functions, this operand is the
+ * numerator."
+ */
+ const bool is_int_div = inst->opcode != SHADER_OPCODE_POW;
+ const fs_reg src0 = is_int_div ? inst->src[1] : inst->src[0];
+ const fs_reg src1 = is_int_div ? inst->src[0] : inst->src[1];
+
+ inst->resize_sources(1);
+ inst->src[0] = src0;
+
+ assert(inst->exec_size == 8);
+ bld.MOV(fs_reg(MRF, inst->base_mrf + 1, src1.type), src1);
+ }
+}
+
bool
fs_visitor::lower_logical_sends()
{
@@ -4543,6 +4573,31 @@ fs_visitor::lower_logical_sends()
lower_varying_pull_constant_logical_send(ibld, inst);
break;
+ 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:
+ case SHADER_OPCODE_POW:
+ case SHADER_OPCODE_INT_QUOTIENT:
+ case SHADER_OPCODE_INT_REMAINDER:
+ /* The math opcodes are overloaded for the send-like and
+ * expression-like instructions which seems kind of icky. Gen6+ has
+ * a native (but rather quirky) MATH instruction so we don't need to
+ * do anything here. On Gen4-5 we'll have to lower the Gen6-like
+ * logical instructions (which we can easily recognize because they
+ * have mlen = 0) into send-like virtual instructions.
+ */
+ if (devinfo->gen < 6 && inst->mlen == 0) {
+ lower_math_logical_send(ibld, inst);
+ break;
+
+ } else {
+ continue;
+ }
+
default:
continue;
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_builder.h b/src/mesa/drivers/dri/i965/brw_fs_builder.h
index 2087e585b06..b50dda421ae 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_builder.h
+++ b/src/mesa/drivers/dri/i965/brw_fs_builder.h
@@ -281,9 +281,8 @@ namespace brw {
case SHADER_OPCODE_LOG2:
case SHADER_OPCODE_SIN:
case SHADER_OPCODE_COS:
- return fix_math_instruction(
- emit(instruction(opcode, dispatch_width(), dst,
- fix_math_operand(src0))));
+ return emit(instruction(opcode, dispatch_width(), dst,
+ fix_math_operand(src0)));
default:
return emit(instruction(opcode, dispatch_width(), dst, src0));
@@ -301,10 +300,9 @@ namespace brw {
case SHADER_OPCODE_POW:
case SHADER_OPCODE_INT_QUOTIENT:
case SHADER_OPCODE_INT_REMAINDER:
- return fix_math_instruction(
- emit(instruction(opcode, dispatch_width(), dst,
- fix_math_operand(src0),
- fix_math_operand(src1))));
+ return emit(instruction(opcode, dispatch_width(), dst,
+ fix_math_operand(src0),
+ fix_math_operand(src1)));
default:
return emit(instruction(opcode, dispatch_width(), dst, src0, src1));
@@ -640,41 +638,6 @@ namespace brw {
}
}
- /**
- * Workaround other weirdness of the math instruction.
- */
- instruction *
- fix_math_instruction(instruction *inst) const
- {
- if (shader->devinfo->gen < 6) {
- inst->base_mrf = 2;
- inst->mlen = inst->sources * dispatch_width() / 8;
-
- if (inst->sources > 1) {
- /* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13
- * "Message Payload":
- *
- * "Operand0[7]. For the INT DIV functions, this operand is the
- * denominator."
- * ...
- * "Operand1[7]. For the INT DIV functions, this operand is the
- * numerator."
- */
- const bool is_int_div = inst->opcode != SHADER_OPCODE_POW;
- const fs_reg src0 = is_int_div ? inst->src[1] : inst->src[0];
- const fs_reg src1 = is_int_div ? inst->src[0] : inst->src[1];
-
- inst->resize_sources(1);
- inst->src[0] = src0;
-
- at(block, inst).MOV(fs_reg(MRF, inst->base_mrf + 1, src1.type),
- src1);
- }
- }
-
- return inst;
- }
-
bblock_t *block;
exec_node *cursor;