diff options
Diffstat (limited to 'src/gallium/drivers/r600/r600_asm.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_asm.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 61de24b31ae..54e339fbefe 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -602,26 +602,24 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan, return 0; } -static int reserve_cfile(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan) +static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsigned sel, unsigned chan) { - int res, resmatch = -1, resempty = -1; - for (res = 3; res >= 0; --res) { - if (bs->hw_cfile_addr[res] == -1) - resempty = res; - else if (bs->hw_cfile_addr[res] == sel && - bs->hw_cfile_elem[res] == chan) - resmatch = res; + int res, num_res = 4; + if (bc->chiprev >= CHIPREV_R700) { + num_res = 2; + chan /= 2; } - if (resmatch != -1) - return 0; // Read for this scalar element already reserved, nothing to do here. - else if (resempty != -1) { - bs->hw_cfile_addr[resempty] = sel; - bs->hw_cfile_elem[resempty] = chan; - } else { - // All cfile read ports are used, cannot reference vector element - return -1; + for (res = 0; res < num_res; ++res) { + if (bs->hw_cfile_addr[res] == -1) { + bs->hw_cfile_addr[res] = sel; + bs->hw_cfile_elem[res] = chan; + return 0; + } else if (bs->hw_cfile_addr[res] == sel && + bs->hw_cfile_elem[res] == chan) + return 0; // Read for this scalar element already reserved, nothing to do here. } - return 0; + // All cfile read ports are used, cannot reference vector element + return -1; } static int is_gpr(unsigned sel) @@ -667,7 +665,7 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, return r; } } else if (is_cfile(sel)) { - r = reserve_cfile(bs, sel, elem); + r = reserve_cfile(bc, bs, sel, elem); if (r) return r; } @@ -694,7 +692,7 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, const_count++; } if (is_cfile(sel)) { - r = reserve_cfile(bs, sel, elem); + r = reserve_cfile(bc, bs, sel, elem); if (r) return r; } @@ -915,6 +913,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], int i, j, r, src, num_src; int num_once_inst = 0; + int have_mova = 0, have_rel = 0; r = assign_alu_units(bc, alu_prev, prev); if (r) @@ -929,6 +928,12 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], return 0; if (r600_bc_alu_nliterals(bc, prev[i], prev_literal, &prev_nliteral)) return 0; + if (is_alu_mova_inst(bc, prev[i])) { + if (have_rel) + return 0; + have_mova = 1; + } + num_once_inst += is_alu_once_inst(bc, prev[i]); } if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral)) return 0; @@ -936,7 +941,6 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], // let's check used slots if (prev[i] && !slots[i]) { result[i] = prev[i]; - num_once_inst += is_alu_once_inst(bc, prev[i]); continue; } else if (prev[i] && slots[i]) { if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { @@ -962,6 +966,12 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { + if (alu->src[src].rel) { + if (have_mova) + return 0; + have_rel = 1; + } + // constants doesn't matter if (!is_gpr(alu->src[src].sel)) continue; |