}
}
+static void
+emit_fragcoord_input(struct tgsi_to_qir *trans, int attr)
+{
+ struct qcompile *c = trans->c;
+
+ trans->inputs[attr * 4 + 0] = qir_FRAG_X(c);
+ trans->inputs[attr * 4 + 1] = qir_FRAG_Y(c);
+ trans->inputs[attr * 4 + 2] =
+ qir_FMUL(c,
+ qir_FRAG_Z(c),
+ qir_uniform_f(trans, 1.0 / 0xffffff));
+ trans->inputs[attr * 4 + 3] = qir_FRAG_RCP_W(c);
+}
+
static void
emit_fragment_input(struct tgsi_to_qir *trans, int attr)
{
i <= decl->Range.Last;
i++) {
if (c->stage == QSTAGE_FRAG) {
- emit_fragment_input(trans, i);
+ if (decl->Semantic.Name ==
+ TGSI_SEMANTIC_POSITION) {
+ emit_fragcoord_input(trans, i);
+ } else {
+ emit_fragment_input(trans, i);
+ }
} else {
emit_vertex_input(trans, i);
}
[QOP_TLB_COLOR_WRITE] = { "tlb_color", 0, 1, true },
[QOP_VARY_ADD_C] = { "vary_add_c", 1, 1 },
+ [QOP_FRAG_X] = { "frag_x", 1, 0 },
+ [QOP_FRAG_Y] = { "frag_y", 1, 0 },
+ [QOP_FRAG_Z] = { "frag_z", 1, 0 },
+ [QOP_FRAG_RCP_W] = { "frag_rcp_w", 1, 0 },
+
[QOP_TEX_S] = { "tex_s", 0, 2 },
[QOP_TEX_T] = { "tex_t", 0, 2 },
[QOP_TEX_R] = { "tex_r", 0, 2 },
QOP_TLB_COLOR_WRITE,
QOP_VARY_ADD_C,
+ QOP_FRAG_X,
+ QOP_FRAG_Y,
+ QOP_FRAG_Z,
+ QOP_FRAG_RCP_W,
+
/** Texture x coordinate parameter write */
QOP_TEX_S,
/** Texture y coordinate parameter write */
bool qir_opt_copy_propagation(struct qcompile *c);
bool qir_opt_dead_code(struct qcompile *c);
+#define QIR_ALU0(name) \
+static inline struct qreg \
+qir_##name(struct qcompile *c) \
+{ \
+ struct qreg t = qir_get_temp(c); \
+ qir_emit(c, qir_inst(QOP_##name, t, c->undef, c->undef)); \
+ return t; \
+}
+
#define QIR_ALU1(name) \
static inline struct qreg \
qir_##name(struct qcompile *c, struct qreg a) \
QIR_NODST_2(TEX_T)
QIR_NODST_2(TEX_R)
QIR_NODST_2(TEX_B)
+QIR_ALU0(FRAG_X)
+QIR_ALU0(FRAG_Y)
+QIR_ALU0(FRAG_Z)
+QIR_ALU0(FRAG_RCP_W)
static inline struct qreg
qir_CMP(struct qcompile *c, struct qreg cmp, struct qreg a, struct qreg b)
if (qinst->src[i].file == QFILE_TEMP)
reg_uses_remaining[qinst->src[i].index]++;
}
- if (qinst->op == QOP_TLB_PASSTHROUGH_Z_WRITE)
+ if (qinst->op == QOP_TLB_PASSTHROUGH_Z_WRITE ||
+ qinst->op == QOP_FRAG_Z)
reg_in_use[3 + 32 + QPU_R_FRAG_PAYLOAD_ZW] = true;
}
break;
+ case QOP_FRAG_X:
+ queue(c, qpu_inst(qpu_a_ITOF(dst,
+ qpu_ra(QPU_R_XY_PIXEL_COORD)),
+ qpu_m_NOP()));
+ break;
+
+ case QOP_FRAG_Y:
+ queue(c, qpu_inst(qpu_a_ITOF(dst,
+ qpu_rb(QPU_R_XY_PIXEL_COORD)),
+ qpu_m_NOP()));
+ break;
+
+ case QOP_FRAG_Z:
+ queue(c, qpu_inst(qpu_a_ITOF(dst,
+ qpu_rb(QPU_R_FRAG_PAYLOAD_ZW)),
+ qpu_m_NOP()));
+ break;
+
+ case QOP_FRAG_RCP_W:
+ queue(c, qpu_inst(qpu_a_MOV(qpu_rb(QPU_W_SFU_RECIP),
+ qpu_ra(QPU_R_FRAG_PAYLOAD_ZW)),
+ qpu_m_NOP()));
+
+ queue(c, qpu_inst(qpu_a_MOV(dst, qpu_r4()),
+ qpu_m_NOP()));
+ break;
+
case QOP_TLB_PASSTHROUGH_Z_WRITE:
queue(c, qpu_inst(qpu_a_MOV(qpu_ra(QPU_W_TLB_Z),
qpu_rb(QPU_R_FRAG_PAYLOAD_ZW)),
case PIPE_CAP_MAX_VIEWPORTS:
return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+
/* Unsupported features. */
case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
case PIPE_CAP_ANISOTROPIC_FILTER:
case PIPE_CAP_TEXTURE_SWIZZLE:
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_SEAMLESS_CUBE_MAP:
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
case PIPE_CAP_TGSI_INSTANCEID: