summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-12-07 14:50:50 -0800
committerEric Anholt <[email protected]>2010-12-07 15:11:27 -0800
commit7ca7e9b626389dd6dac683c6664b8478e6d5c3b9 (patch)
tree8d0ed8169c05221f9e4f9ea0b5e4f0fb3f70fc4e
parent2d7dfb8446df87f11494a2a079cf4e0e8d1da030 (diff)
i965: Work around gen6 ignoring source modifiers on math instructions.
With the change of extended math from having the arguments moved into mrfs and handed off through message passing to being directly hooked up to the EU, it looks like the piece for doing source modifiers (negate and abs) was left out. Fixes: fog-modes glean/fp1-ARB_fog_exp test glean/fp1-ARB_fog_exp2 test glean/fp1-Computed fog exp test glean/fp1-Computed fog exp2 test ext_fog_coord-modes
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c14
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp7
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c8
3 files changed, 26 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 96aa046b64f..f62fc7ebfb5 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1272,6 +1272,10 @@ void brw_math( struct brw_compile *p,
assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
assert(src.hstride == BRW_HORIZONTAL_STRIDE_1);
+ /* Source modifiers are ignored for extended math instructions. */
+ assert(!src.negate);
+ assert(!src.abs);
+
if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
assert(src.type == BRW_REGISTER_TYPE_F);
@@ -1338,6 +1342,12 @@ void brw_math2(struct brw_compile *p,
assert(src1.type == BRW_REGISTER_TYPE_F);
}
+ /* Source modifiers are ignored for extended math instructions. */
+ assert(!src0.negate);
+ assert(!src0.abs);
+ assert(!src1.negate);
+ assert(!src1.abs);
+
/* Math is the same ISA format as other opcodes, except that CondModifier
* becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
*/
@@ -1374,6 +1384,10 @@ void brw_math_16( struct brw_compile *p,
insn->header.destreg__conditionalmod = function;
insn->header.saturate = saturate;
+ /* Source modifiers are ignored for extended math instructions. */
+ assert(!src.negate);
+ assert(!src.abs);
+
brw_set_dest(p, insn, dest);
brw_set_src0(insn, src);
brw_set_src1(insn, brw_null_reg());
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index a956453dbf5..8840b6d6f73 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -600,8 +600,13 @@ fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src)
* might be able to do better by doing execsize = 1 math and then
* expanding that result out, but we would need to be careful with
* masking.
+ *
+ * The hardware ignores source modifiers (negate and abs) on math
+ * instructions, so we also move to a temp to set those up.
*/
- if (intel->gen >= 6 && src.file == UNIFORM) {
+ if (intel->gen >= 6 && (src.file == UNIFORM ||
+ src.abs ||
+ src.negate)) {
fs_reg expanded = fs_reg(this, glsl_type::float_type);
emit(fs_inst(BRW_OPCODE_MOV, expanded, src));
src = expanded;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 6e8f08c14d8..24e10632aa0 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -896,10 +896,14 @@ void emit_math1(struct brw_wm_compile *c,
BRW_MATH_SATURATE_NONE);
struct brw_reg src;
- if (intel->gen >= 6 && (arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
- arg0[0].file != BRW_GENERAL_REGISTER_FILE)) {
+ if (intel->gen >= 6 && ((arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
+ arg0[0].file != BRW_GENERAL_REGISTER_FILE) ||
+ arg0[0].negate || arg0[0].abs)) {
/* Gen6 math requires that source and dst horizontal stride be 1,
* and that the argument be in the GRF.
+ *
+ * The hardware ignores source modifiers (negate and abs) on math
+ * instructions, so we also move to a temp to set those up.
*/
src = dst[dst_chan];
brw_MOV(p, src, arg0[0]);