OPC_META_FO = _OPC(-1, 2),
OPC_META_FI = _OPC(-1, 3),
+ /* placeholder for texture fetches that run before FS invocation
+ * starts:
+ */
+ OPC_META_TEX_PREFETCH = _OPC(-1, 4),
+
} opc_t;
#define opc_cat(opc) ((int)((opc) >> NOPC_BITS))
struct {
int off; /* component/offset */
} fo;
+ struct {
+ unsigned samp, tex;
+ unsigned input_offset;
+ } prefetch;
struct {
/* for sysvals, identifies the sysval type. Mostly so we can
* identify the special cases where a sysval should not be DCE'd
INSTR0(BAR)
INSTR0(FENCE)
+/* meta instructions: */
+INSTR0(META_TEX_PREFETCH);
+
/* ************************************************************************* */
/* split this out or find some helper to use.. like main/bitset.h.. */
compile_assert(ctx, i < so->inputs_count);
used_components[i] |= 1 << j;
+ } else if (instr->opc == OPC_META_TEX_PREFETCH) {
+ for (int n = 0; n < 2; n++) {
+ unsigned inloc = instr->prefetch.input_offset + n;
+ unsigned i = inloc / 4;
+ unsigned j = inloc % 4;
+
+ compile_assert(ctx, i < so->inputs_count);
+
+ used_components[i] |= 1 << j;
+ }
}
}
}
n->flags &= ~(IR3_INSTR_SS | IR3_INSTR_SY);
- if (is_meta(n))
+ /* _meta::tex_prefetch instructions removed later in
+ * collect_tex_prefetches()
+ */
+ if (is_meta(n) && (n->opc != OPC_META_TEX_PREFETCH))
continue;
if (is_input(n)) {
if (is_sfu(n))
regmask_set(&state->needs_ss, n->regs[0]);
- if (is_tex(n)) {
+ if (is_tex(n) || (n->opc == OPC_META_TEX_PREFETCH)) {
regmask_set(&state->needs_sy, n->regs[0]);
ctx->need_pixlod = true;
} else if (n->opc == OPC_RESINFO) {
case OPC_META_INPUT: printf("_meta:in"); break;
case OPC_META_FO: printf("_meta:fo"); break;
case OPC_META_FI: printf("_meta:fi"); break;
+ case OPC_META_TEX_PREFETCH: printf("_meta:tex_prefetch"); break;
/* shouldn't hit here.. just for debugging: */
default: printf("_meta:%d", instr->opc); break;
if (instr->opc == OPC_META_FO) {
printf(", off=%d", instr->fo.off);
+ } else if (instr->opc == OPC_META_TEX_PREFETCH) {
+ printf(", tex=%d, samp=%d, input_offset=%d", instr->prefetch.tex,
+ instr->prefetch.samp, instr->prefetch.input_offset);
}
if (is_flow(instr) && instr->cat0.target) {
* occupied), and move remaining to depth sorted list:
*/
list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node) {
- if (instr->opc == OPC_META_INPUT) {
+ if ((instr->opc == OPC_META_INPUT) ||
+ (instr->opc == OPC_META_TEX_PREFETCH)) {
schedule(ctx, instr);
} else {
ir3_insert_by_depth(instr, &ctx->depth_list);