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 <glenn.kennard@gmail.com> Signed-off-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
committed by
Marek Olšák
parent
ef1cf69cd3
commit
dfa10ed264
@@ -123,6 +123,9 @@ enum fetch_op_flags
|
||||
|
||||
FF_VTX = (1<<5),
|
||||
FF_MEM = (1<<6),
|
||||
|
||||
FF_SET_TEXTURE_OFFSETS = (1<<7),
|
||||
FF_USE_TEXTURE_OFFSETS = (1<<8),
|
||||
};
|
||||
|
||||
/* flags for CF instructions */
|
||||
@@ -523,7 +526,7 @@ static const struct fetch_op_info fetch_op_table[] = {
|
||||
{"GET_GRADIENTS_H_FINE", { -1, -1, 0x000107, 0x000107 }, FF_GETGRAD },
|
||||
{"GET_GRADIENTS_V_FINE", { -1, -1, 0x000108, 0x000108 }, FF_GETGRAD },
|
||||
{"GET_LERP", { 0x000009, 0x000009, -1, -1 }, 0 },
|
||||
{"SET_TEXTURE_OFFSETS", { -1, -1, 0x000009, 0x000009 }, 0 },
|
||||
{"SET_TEXTURE_OFFSETS", { -1, -1, 0x000009, 0x000009 }, FF_SET_TEXTURE_OFFSETS },
|
||||
{"KEEP_GRADIENTS", { -1, 0x00000A, 0x00000A, 0x00000A }, 0 },
|
||||
{"SET_GRADIENTS_H", { 0x00000B, 0x00000B, 0x00000B, 0x00000B }, FF_SETGRAD },
|
||||
{"SET_GRADIENTS_V", { 0x00000C, 0x00000C, 0x00000C, 0x00000C }, FF_SETGRAD },
|
||||
@@ -550,7 +553,7 @@ static const struct fetch_op_info fetch_op_table[] = {
|
||||
{"GATHER4", { -1, -1, 0x000015, 0x000015 }, FF_TEX },
|
||||
{"SAMPLE_G_LB", { 0x000016, 0x000016, 0x000016, 0x000016 }, FF_TEX | FF_USEGRAD},
|
||||
{"SAMPLE_G_LZ", { 0x000017, 0x000017, -1, -1 }, FF_TEX | FF_USEGRAD},
|
||||
{"GATHER4_O", { -1, -1, 0x000017, 0x000017 }, FF_TEX },
|
||||
{"GATHER4_O", { -1, -1, 0x000017, 0x000017 }, FF_TEX | FF_USE_TEXTURE_OFFSETS},
|
||||
{"SAMPLE_C", { 0x000018, 0x000018, 0x000018, 0x000018 }, FF_TEX },
|
||||
{"SAMPLE_C_L", { 0x000019, 0x000019, 0x000019, 0x000019 }, FF_TEX },
|
||||
{"SAMPLE_C_LB", { 0x00001A, 0x00001A, 0x00001A, 0x00001A }, FF_TEX },
|
||||
@@ -560,7 +563,7 @@ static const struct fetch_op_info fetch_op_table[] = {
|
||||
{"GATHER4_C", { -1, -1, 0x00001D, 0x00001D }, FF_TEX },
|
||||
{"SAMPLE_C_G_LB", { 0x00001E, 0x00001E, 0x00001E, 0x00001E }, FF_TEX | FF_USEGRAD},
|
||||
{"SAMPLE_C_G_LZ", { 0x00001F, 0x00001F, -1, -1 }, FF_TEX | FF_USEGRAD},
|
||||
{"GATHER4_C_O", { -1, -1, 0x00001F, 0x00001F }, FF_TEX }
|
||||
{"GATHER4_C_O", { -1, -1, 0x00001F, 0x00001F }, FF_TEX | FF_USE_TEXTURE_OFFSETS}
|
||||
};
|
||||
|
||||
static const struct cf_op_info cf_op_table[] = {
|
||||
|
||||
@@ -394,6 +394,64 @@ void bc_finalizer::finalize_alu_src(alu_group_node* g, alu_node* a) {
|
||||
}
|
||||
}
|
||||
|
||||
void bc_finalizer::copy_fetch_src(fetch_node &dst, fetch_node &src, unsigned arg_start)
|
||||
{
|
||||
int reg = -1;
|
||||
|
||||
for (unsigned chan = 0; chan < 4; ++chan) {
|
||||
|
||||
dst.bc.dst_sel[chan] = SEL_MASK;
|
||||
|
||||
unsigned sel = SEL_MASK;
|
||||
|
||||
value *v = src.src[arg_start + chan];
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
} else if (v->is_any_gpr()) {
|
||||
unsigned vreg = v->gpr.sel();
|
||||
unsigned vchan = v->gpr.chan();
|
||||
|
||||
if (reg == -1)
|
||||
reg = vreg;
|
||||
else if ((unsigned)reg != vreg) {
|
||||
sblog << "invalid fetch source operand " << chan << " ";
|
||||
dump::dump_op(&src);
|
||||
sblog << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
sel = vchan;
|
||||
|
||||
} else {
|
||||
sblog << "invalid fetch source operand " << chan << " ";
|
||||
dump::dump_op(&src);
|
||||
sblog << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
dst.bc.src_sel[chan] = sel;
|
||||
}
|
||||
|
||||
if (reg >= 0)
|
||||
update_ngpr(reg);
|
||||
|
||||
dst.bc.src_gpr = reg >= 0 ? reg : 0;
|
||||
}
|
||||
|
||||
void bc_finalizer::emit_set_grad(fetch_node* f) {
|
||||
|
||||
assert(f->src.size() == 12);
|
||||
@@ -405,70 +463,27 @@ void bc_finalizer::emit_set_grad(fetch_node* f) {
|
||||
fetch_node *n = sh.create_fetch();
|
||||
n->bc.set_op(ops[op]);
|
||||
|
||||
// FIXME extract this loop into a separate method and reuse it
|
||||
|
||||
int reg = -1;
|
||||
|
||||
arg_start += 4;
|
||||
|
||||
for (unsigned chan = 0; chan < 4; ++chan) {
|
||||
|
||||
n->bc.dst_sel[chan] = SEL_MASK;
|
||||
|
||||
unsigned sel = SEL_MASK;
|
||||
|
||||
value *v = f->src[arg_start + chan];
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
} else if (v->is_any_gpr()) {
|
||||
unsigned vreg = v->gpr.sel();
|
||||
unsigned vchan = v->gpr.chan();
|
||||
|
||||
if (reg == -1)
|
||||
reg = vreg;
|
||||
else if ((unsigned)reg != vreg) {
|
||||
sblog << "invalid fetch source operand " << chan << " ";
|
||||
dump::dump_op(f);
|
||||
sblog << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
sel = vchan;
|
||||
|
||||
} else {
|
||||
sblog << "invalid fetch source operand " << chan << " ";
|
||||
dump::dump_op(f);
|
||||
sblog << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
n->bc.src_sel[chan] = sel;
|
||||
}
|
||||
|
||||
if (reg >= 0)
|
||||
update_ngpr(reg);
|
||||
|
||||
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) {
|
||||
|
||||
@@ -520,7 +520,7 @@ int bc_parser::decode_fetch_clause(cf_node* cf) {
|
||||
|
||||
int bc_parser::prepare_fetch_clause(cf_node *cf) {
|
||||
|
||||
vvec grad_v, grad_h;
|
||||
vvec grad_v, grad_h, texture_offsets;
|
||||
|
||||
for (node_iterator I = cf->begin(), E = cf->end(); I != E; ++I) {
|
||||
|
||||
@@ -538,7 +538,7 @@ int bc_parser::prepare_fetch_clause(cf_node *cf) {
|
||||
sh->uses_gradients = true;
|
||||
}
|
||||
|
||||
if (flags & FF_SETGRAD) {
|
||||
if (flags & (FF_SETGRAD | FF_SET_TEXTURE_OFFSETS)) {
|
||||
|
||||
vvec *grad = NULL;
|
||||
|
||||
@@ -549,6 +549,9 @@ int bc_parser::prepare_fetch_clause(cf_node *cf) {
|
||||
case FETCH_OP_SET_GRADIENTS_H:
|
||||
grad = &grad_h;
|
||||
break;
|
||||
case FETCH_OP_SET_TEXTURE_OFFSETS:
|
||||
grad = &texture_offsets;
|
||||
break;
|
||||
default:
|
||||
assert(!"unexpected SET_GRAD instruction");
|
||||
return -1;
|
||||
@@ -568,11 +571,15 @@ int bc_parser::prepare_fetch_clause(cf_node *cf) {
|
||||
(*grad)[s] = sh->get_const_value(1.0f);
|
||||
}
|
||||
} else {
|
||||
|
||||
// Fold source values for instructions with hidden target values in to the instructions
|
||||
// using them. The set instructions are later re-emitted by bc_finalizer
|
||||
if (flags & FF_USEGRAD) {
|
||||
n->src.resize(12);
|
||||
std::copy(grad_v.begin(), grad_v.end(), n->src.begin() + 4);
|
||||
std::copy(grad_h.begin(), grad_h.end(), n->src.begin() + 8);
|
||||
} else if (flags & FF_USE_TEXTURE_OFFSETS) {
|
||||
n->src.resize(8);
|
||||
std::copy(texture_offsets.begin(), texture_offsets.end(), n->src.begin() + 4);
|
||||
} else {
|
||||
n->src.resize(4);
|
||||
}
|
||||
|
||||
@@ -713,6 +713,9 @@ public:
|
||||
|
||||
void cf_peephole();
|
||||
|
||||
private:
|
||||
void copy_fetch_src(fetch_node &dst, fetch_node &src, unsigned arg_start);
|
||||
void emit_set_texture_offsets(fetch_node &f);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user