aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
diff options
context:
space:
mode:
authorGlenn Kennard <[email protected]>2014-08-17 22:26:19 +0200
committerMarek Olšák <[email protected]>2014-08-19 16:30:13 +0200
commitdfa10ed2640a350a84e6e31edd22560155cd5016 (patch)
tree1fe5c1378d50b757ab4446de2944239bd092e451 /src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
parentef1cf69cd34701ea005a244909c71357a3dddb06 (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.cpp119
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) {