summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-10-10 11:54:05 -0700
committerEric Anholt <eric@anholt.net>2010-10-11 11:52:01 -0700
commit90c402204018c78f4a0b8a79515cf8c582092963 (patch)
treee832a1dba9594ca21072855f6c594cdf5b74c53d /src
parent986cb9d5cf60bc11c7facc19017b5432b17240f7 (diff)
i965: Split FS_OPCODE_DISCARD into two steps.
Having the single opcode write then read the reg meant that single instruction opcodes had to consider their source regs to interfere with their dest regs.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 11a5a4acef..f41e8783e6 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -73,7 +73,8 @@ enum fs_opcodes {
FS_OPCODE_TEX,
FS_OPCODE_TXB,
FS_OPCODE_TXL,
- FS_OPCODE_DISCARD,
+ FS_OPCODE_DISCARD_NOT,
+ FS_OPCODE_DISCARD_AND,
};
static int using_new_fs = -1;
@@ -475,7 +476,8 @@ public:
struct brw_reg *src);
void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src);
- void generate_discard(fs_inst *inst, struct brw_reg temp);
+ void generate_discard_not(fs_inst *inst, struct brw_reg temp);
+ void generate_discard_and(fs_inst *inst, struct brw_reg temp);
void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
@@ -1548,7 +1550,8 @@ fs_visitor::visit(ir_discard *ir)
assert(ir->condition == NULL); /* FINISHME */
- emit(fs_inst(FS_OPCODE_DISCARD, temp, temp));
+ emit(fs_inst(FS_OPCODE_DISCARD_NOT, temp, reg_null));
+ emit(fs_inst(FS_OPCODE_DISCARD_AND, reg_null, temp));
kill_emitted = true;
}
@@ -2217,15 +2220,23 @@ fs_visitor::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
}
void
-fs_visitor::generate_discard(fs_inst *inst, struct brw_reg temp)
+fs_visitor::generate_discard_not(fs_inst *inst, struct brw_reg mask)
+{
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_NOT(p, mask, brw_mask_reg(1)); /* IMASK */
+ brw_pop_insn_state(p);
+}
+
+void
+fs_visitor::generate_discard_and(fs_inst *inst, struct brw_reg mask)
{
struct brw_reg g0 = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
- temp = brw_uw1_reg(temp.file, temp.nr, 0);
+ mask = brw_uw1_reg(mask.file, mask.nr, 0);
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE);
- brw_NOT(p, temp, brw_mask_reg(1)); /* IMASK */
- brw_AND(p, g0, temp, g0);
+ brw_AND(p, g0, mask, g0);
brw_pop_insn_state(p);
}
@@ -3011,8 +3022,11 @@ fs_visitor::generate_code()
case FS_OPCODE_TXL:
generate_tex(inst, dst, src[0]);
break;
- case FS_OPCODE_DISCARD:
- generate_discard(inst, dst /* src0 == dst */);
+ case FS_OPCODE_DISCARD_NOT:
+ generate_discard_not(inst, dst);
+ break;
+ case FS_OPCODE_DISCARD_AND:
+ generate_discard_and(inst, src[0]);
break;
case FS_OPCODE_DDX:
generate_ddx(inst, dst, src[0]);