boolean uses_kill;
boolean fs_write_all;
boolean two_side;
+ boolean needs_scratch_space;
/* Number of color outputs in the TGSI shader,
* sometimes it could be higher than nr_cbufs (bug?).
* Also with writes_all property on eg+ it will be set to max CB number */
value *d = n->dst.empty() ? NULL : n->dst[0];
if (d && d->is_special_reg()) {
- assert((n->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access());
+ assert((n->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access() || d->is_scratch());
d = NULL;
}
n->src.push_back(get_cf_index_value(n->bc.resource_index_mode == V_SQ_CF_INDEX_1));
}
}
+
+ if (n->bc.op == FETCH_OP_READ_SCRATCH) {
+ n->src.push_back(sh->get_special_value(SV_SCRATCH));
+ n->dst.push_back(sh->get_special_value(SV_SCRATCH));
+ }
}
return 0;
c->flags |= NF_DONT_KILL;
}
}
+ else if (c->bc.op == CF_OP_MEM_SCRATCH) {
+ c->src.push_back(sh->get_special_value(SV_SCRATCH));
+ c->dst.push_back(sh->get_special_value(SV_SCRATCH));
+ }
if (!burst_count--)
break;
c->src.push_back(sh->get_special_value(SV_GEOMETRY_EMIT));
c->dst.push_back(sh->get_special_value(SV_GEOMETRY_EMIT));
}
+ } else if (c->bc.op == CF_OP_WAIT_ACK) {
+ c->src.push_back(sh->get_special_value(SV_SCRATCH));
+ c->dst.push_back(sh->get_special_value(SV_SCRATCH));
}
}
// if conversion breaks the dependency tracking between CF_EMIT ops when it removes
// the phi nodes for SV_GEOMETRY_EMIT. Just disable it for GS
- if (sh->target != TARGET_GS && sh->target != TARGET_HS)
+ if ((sh->target != TARGET_GS && sh->target != TARGET_HS) || pshader->needs_scratch_space)
SB_RUN_PASS(if_conversion, 1);
// if_conversion breaks info about uses, but next pass (peephole)
SV_LDS_RW,
SV_LDS_OQA,
SV_LDS_OQB,
+ SV_SCRATCH
};
class node;
v = v->gvn_source;
return v;
}
+ bool is_scratch() {
+ return is_special_reg() && select == sel_chan(SV_SCRATCH, 0);
+ }
bool is_float_0_or_1() {
value *v = gvalue();
assert(!o->is_dead());
- if (o->is_undef() || o->is_geometry_emit())
+ if (o->is_undef() || o->is_geometry_emit() || o->is_scratch())
continue;
if (allow_swz && o->is_float_0_or_1())
value *d = a->dst.empty() ? NULL : a->dst[0];
if (d && d->is_special_reg()) {
- assert((a->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access());
+ assert((a->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access() || d->is_scratch());
d = NULL;
}
case SV_LDS_RW: o << "LDS_RW"; break;
case SV_LDS_OQA: o << "LDS_OQA"; break;
case SV_LDS_OQB: o << "LDS_OQB"; break;
+ case SV_SCRATCH: o << "SCRATCH"; break;
default: o << "???specialreg"; break;
}
break;