diff options
author | Matt Turner <mattst88@gmail.com> | 2015-02-03 11:57:33 -0800 |
---|---|---|
committer | Matt Turner <mattst88@gmail.com> | 2015-02-17 20:45:54 -0800 |
commit | 9ea83d65d20da0e2a0c601e10820d33248006010 (patch) | |
tree | e763f6cb6ac086d9b2c4d4ca5b71d283ebe2515e | |
parent | 37a72b705520301c727423df7eee30955165c9a1 (diff) |
match immwip/const-vf
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp index dd519dc7cb6..fe9d8a67e00 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp @@ -190,6 +190,63 @@ compare(const void *_a, const void *_b) return a->first_use_ip - b->first_use_ip; } +static void +match_immediates(fs_visitor *v, struct table *table, + const float value[8], float multiplicand, + const uint8_t first_4_vf[4], const uint8_t second_4_vf[4]) +{ + int block_num = -1; + int found = 0; + int idx[8]; + + for (int i = 0; i < table->len && found < 8; i++) { + for (int j = 0; j < 8; j++) { + if (table->imm[i].val == value[j]) { + if (block_num == -1) { + block_num = table->imm[i].block->num; + } else if (table->imm[i].block->num != block_num) { + return; + } + idx[j] = i; + found++; + break; + } + } + } + + if (found != 8) + return; + + fs_reg result(GRF, v->virtual_grf_alloc(1)); + fs_reg reg(GRF, v->virtual_grf_alloc(1)); + reg.width = 4; + + for (int i = 0; i < 8; i++) { + table->imm[idx[i]].reg = result.reg; + table->imm[idx[i]].subreg_offset = i * sizeof(float); + table->imm[idx[i]].inserted = true; + } + + fs_inst *res = v->MUL(result, reg, fs_reg(multiplicand)); + fs_inst *_1 = v->MOV(reg, fs_reg(first_4_vf)); + reg.subreg_offset = 16; + fs_inst *_2 = v->MOV(reg, fs_reg(second_4_vf)); + + bblock_t *block = v->cfg->blocks[block_num]; + backend_instruction *inst = block->first_non_control_flow_inst(); + inst->insert_before(block, _1); + inst->insert_before(block, _2); + inst->insert_before(block, res); + + for (int i = 0; i < table->len; i++) { + if (table->imm[i].val == multiplicand) { + if (table->imm[i].inserted) + break; + table->imm[i].block = cfg_t::intersect(block, table->imm[i].block); + } + } +} + bool fs_visitor::opt_combine_constants() { @@ -266,6 +323,23 @@ fs_visitor::opt_combine_constants() if (cfg->num_blocks != 1) qsort(table.imm, table.len, sizeof(struct imm), compare); + static const float ninths[8] = { + 1/9., 2/9., 3/9., 4/9., 5/9., 6/9., 7/9., 8/9. + }; + static const uint8_t one_to_four_vf[4] = { 0x30, 0x40, 0x48, 0x50 }; + static const uint8_t five_to_eight_vf[4] = { 0x54, 0x58, 0x5c, 0x60 }; + + match_immediates(this, &table, ninths, 1.0f / 9.0f, + one_to_four_vf, five_to_eight_vf); + + static const float tenths[8] = { + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 + }; + static const uint8_t two_to_five_vf[4] = { 0x40, 0x48, 0x50, 0x54 }; + static const uint8_t six_to_nine_vf[4] = { 0x58, 0x5c, 0x60, 0x62 }; + + match_immediates(this, &table, tenths, 0.1f, + two_to_five_vf, six_to_nine_vf); /* Insert MOVs to load the constant values into GRFs. */ fs_reg reg(GRF, alloc.allocate(dispatch_width / 8)); @@ -284,6 +358,9 @@ fs_visitor::opt_combine_constants() count = 0; } + if (table.imm[i].inserted) + continue; + int vf = brw_float_to_vf(table.imm[i].val); if (vf == -1) continue; |