summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2015-02-03 11:57:33 -0800
committerMatt Turner <mattst88@gmail.com>2015-02-17 20:45:54 -0800
commit9ea83d65d20da0e2a0c601e10820d33248006010 (patch)
treee763f6cb6ac086d9b2c4d4ca5b71d283ebe2515e
parent37a72b705520301c727423df7eee30955165c9a1 (diff)
match immwip/const-vf
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp77
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;