diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu.c | 22 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 21 |
3 files changed, 45 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu.c b/src/mesa/drivers/dri/i965/brw_eu.c index 3b5c4c071e3..b59d6b251e6 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.c +++ b/src/mesa/drivers/dri/i965/brw_eu.c @@ -34,6 +34,28 @@ #include "brw_defines.h" #include "brw_eu.h" +/* Returns the corresponding conditional mod for swapping src0 and + * src1 in e.g. CMP. + */ +uint32_t +brw_swap_cmod(uint32_t cmod) +{ + switch (cmod) { + case BRW_CONDITIONAL_Z: + case BRW_CONDITIONAL_NZ: + return cmod; + case BRW_CONDITIONAL_G: + return BRW_CONDITIONAL_LE; + case BRW_CONDITIONAL_GE: + return BRW_CONDITIONAL_L; + case BRW_CONDITIONAL_L: + return BRW_CONDITIONAL_GE; + case BRW_CONDITIONAL_LE: + return BRW_CONDITIONAL_G; + default: + return ~0; + } +} /* How does predicate control work when execution_size != 8? Do I diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 2d2ed9de985..c2e59c1be13 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -1017,6 +1017,8 @@ void brw_set_src1( struct brw_instruction *insn, void brw_set_uip_jip(struct brw_compile *p); +uint32_t brw_swap_cmod(uint32_t cmod); + /* brw_optimize.c */ void brw_optimize(struct brw_compile *p); void brw_remove_duplicate_mrf_moves(struct brw_compile *p); diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 99cd8f833a7..128bbe93a32 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2938,12 +2938,33 @@ fs_visitor::propagate_constants() progress = true; } break; + case BRW_OPCODE_CMP: + if (i == 1) { + scan_inst->src[i] = inst->src[0]; + progress = true; + } else if (i == 0 && scan_inst->src[1].file != IMM) { + uint32_t new_cmod; + + new_cmod = brw_swap_cmod(scan_inst->conditional_mod); + if (new_cmod != ~0u) { + /* Fit this constant in by swapping the operands and + * flipping the test + */ + scan_inst->src[0] = scan_inst->src[1]; + scan_inst->src[1] = inst->src[0]; + scan_inst->conditional_mod = new_cmod; + progress = true; + } + } + break; + case BRW_OPCODE_SEL: if (i == 1) { scan_inst->src[i] = inst->src[0]; progress = true; } + break; } } |