diff options
author | Glenn Kennard <[email protected]> | 2014-08-17 22:26:19 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2014-08-19 16:30:13 +0200 |
commit | dfa10ed2640a350a84e6e31edd22560155cd5016 (patch) | |
tree | 1fe5c1378d50b757ab4446de2944239bd092e451 /src/gallium/drivers/r600/sb/sb_bc_finalize.cpp | |
parent | ef1cf69cd34701ea005a244909c71357a3dddb06 (diff) |
r600g: Fix missing SET_TEXTURE_OFFSETS
SB needs a bit of special handling to handle
instructions without obvious side effects, to
avoid it deleting them.
Fixes failing non-const ARB_gpu_shader5
textureOffsets piglits with sb enabled.
Signed-off-by: Glenn Kennard <[email protected]>
Signed-off-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/sb/sb_bc_finalize.cpp')
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_bc_finalize.cpp | 119 |
1 files changed, 68 insertions, 51 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp index 99a20eb00c8..5c22f964690 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp @@ -394,81 +394,96 @@ void bc_finalizer::finalize_alu_src(alu_group_node* g, alu_node* a) { } } -void bc_finalizer::emit_set_grad(fetch_node* f) { +void bc_finalizer::copy_fetch_src(fetch_node &dst, fetch_node &src, unsigned arg_start) +{ + int reg = -1; - assert(f->src.size() == 12); - unsigned ops[2] = { FETCH_OP_SET_GRADIENTS_V, FETCH_OP_SET_GRADIENTS_H }; + for (unsigned chan = 0; chan < 4; ++chan) { - unsigned arg_start = 0; + dst.bc.dst_sel[chan] = SEL_MASK; - for (unsigned op = 0; op < 2; ++op) { - fetch_node *n = sh.create_fetch(); - n->bc.set_op(ops[op]); + unsigned sel = SEL_MASK; - // FIXME extract this loop into a separate method and reuse it + value *v = src.src[arg_start + chan]; - int reg = -1; + if (!v || v->is_undef()) { + sel = SEL_MASK; + } else if (v->is_const()) { + literal l = v->literal_value; + if (l == literal(0)) + sel = SEL_0; + else if (l == literal(1.0f)) + sel = SEL_1; + else { + sblog << "invalid fetch constant operand " << chan << " "; + dump::dump_op(&src); + sblog << "\n"; + abort(); + } - arg_start += 4; + } else if (v->is_any_gpr()) { + unsigned vreg = v->gpr.sel(); + unsigned vchan = v->gpr.chan(); - for (unsigned chan = 0; chan < 4; ++chan) { + if (reg == -1) + reg = vreg; + else if ((unsigned)reg != vreg) { + sblog << "invalid fetch source operand " << chan << " "; + dump::dump_op(&src); + sblog << "\n"; + abort(); + } - n->bc.dst_sel[chan] = SEL_MASK; + sel = vchan; - unsigned sel = SEL_MASK; + } else { + sblog << "invalid fetch source operand " << chan << " "; + dump::dump_op(&src); + sblog << "\n"; + abort(); + } - value *v = f->src[arg_start + chan]; + dst.bc.src_sel[chan] = sel; + } - if (!v || v->is_undef()) { - sel = SEL_MASK; - } else if (v->is_const()) { - literal l = v->literal_value; - if (l == literal(0)) - sel = SEL_0; - else if (l == literal(1.0f)) - sel = SEL_1; - else { - sblog << "invalid fetch constant operand " << chan << " "; - dump::dump_op(f); - sblog << "\n"; - abort(); - } + if (reg >= 0) + update_ngpr(reg); - } else if (v->is_any_gpr()) { - unsigned vreg = v->gpr.sel(); - unsigned vchan = v->gpr.chan(); + dst.bc.src_gpr = reg >= 0 ? reg : 0; +} - if (reg == -1) - reg = vreg; - else if ((unsigned)reg != vreg) { - sblog << "invalid fetch source operand " << chan << " "; - dump::dump_op(f); - sblog << "\n"; - abort(); - } +void bc_finalizer::emit_set_grad(fetch_node* f) { - sel = vchan; + assert(f->src.size() == 12); + unsigned ops[2] = { FETCH_OP_SET_GRADIENTS_V, FETCH_OP_SET_GRADIENTS_H }; - } else { - sblog << "invalid fetch source operand " << chan << " "; - dump::dump_op(f); - sblog << "\n"; - abort(); - } + unsigned arg_start = 0; - n->bc.src_sel[chan] = sel; - } + for (unsigned op = 0; op < 2; ++op) { + fetch_node *n = sh.create_fetch(); + n->bc.set_op(ops[op]); - if (reg >= 0) - update_ngpr(reg); + arg_start += 4; - n->bc.src_gpr = reg >= 0 ? reg : 0; + copy_fetch_src(*n, *f, arg_start); f->insert_before(n); } } +void bc_finalizer::emit_set_texture_offsets(fetch_node &f) { + assert(f.src.size() == 8); + + fetch_node *n = sh.create_fetch(); + + n->bc.set_op(FETCH_OP_SET_TEXTURE_OFFSETS); + + copy_fetch_src(*n, f, 4); + + f.insert_before(n); +} + void bc_finalizer::finalize_fetch(fetch_node* f) { int reg = -1; @@ -483,6 +498,8 @@ void bc_finalizer::finalize_fetch(fetch_node* f) { src_count = 1; } else if (flags & FF_USEGRAD) { emit_set_grad(f); + } else if (flags & FF_USE_TEXTURE_OFFSETS) { + emit_set_texture_offsets(*f); } for (unsigned chan = 0; chan < src_count; ++chan) { |