diff options
author | Eric Anholt <[email protected]> | 2010-10-10 11:54:05 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2010-10-11 11:52:01 -0700 |
commit | 90c402204018c78f4a0b8a79515cf8c582092963 (patch) | |
tree | e832a1dba9594ca21072855f6c594cdf5b74c53d | |
parent | 986cb9d5cf60bc11c7facc19017b5432b17240f7 (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.
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 32 |
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 11a5a4aceff..f41e8783e67 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]); |