}
c->num_texture_samples++;
- qir_emit(c, qir_inst(QOP_TEX_RESULT, c->undef, c->undef, c->undef));
+ struct qreg r4 = qir_TEX_RESULT(c);
struct qreg unpacked[4];
for (int i = 0; i < 4; i++)
- unpacked[i] = qir_R4_UNPACK(c, i);
+ unpacked[i] = qir_R4_UNPACK(c, r4, i);
enum pipe_format format = c->key->tex_format[unit];
const uint8_t *swiz = vc4_get_format_swizzle(format);
struct qreg dst_color[4] = { c->undef, c->undef, c->undef, c->undef };
if (c->fs_key->blend.blend_enable ||
c->fs_key->blend.colormask != 0xf) {
- qir_emit(c, qir_inst(QOP_TLB_COLOR_READ, c->undef,
- c->undef, c->undef));
+ struct qreg r4 = qir_TLB_COLOR_READ(c);
for (int i = 0; i < 4; i++)
- tlb_read_color[i] = qir_R4_UNPACK(c, i);
+ tlb_read_color[i] = qir_R4_UNPACK(c, r4, i);
for (int i = 0; i < 4; i++)
dst_color[i] = get_swizzled_channel(c,
tlb_read_color,
[QOP_TLB_DISCARD_SETUP] = { "discard", 0, 1, true },
[QOP_TLB_PASSTHROUGH_Z_WRITE] = { "tlb_passthrough_z", 0, 0, true },
[QOP_TLB_COLOR_WRITE] = { "tlb_color", 0, 1, true },
- [QOP_TLB_COLOR_READ] = { "tlb_color_read", 0, 0, true },
+ [QOP_TLB_COLOR_READ] = { "tlb_color_read", 1, 0, true },
[QOP_VARY_ADD_C] = { "vary_add_c", 1, 1 },
[QOP_FRAG_X] = { "frag_x", 1, 0 },
[QOP_TEX_T] = { "tex_t", 0, 2 },
[QOP_TEX_R] = { "tex_r", 0, 2 },
[QOP_TEX_B] = { "tex_b", 0, 2 },
- [QOP_TEX_RESULT] = { "tex_result", 0, 0 },
- [QOP_R4_UNPACK_A] = { "r4_unpack_a", 1, 0 },
- [QOP_R4_UNPACK_B] = { "r4_unpack_b", 1, 0 },
- [QOP_R4_UNPACK_C] = { "r4_unpack_c", 1, 0 },
- [QOP_R4_UNPACK_D] = { "r4_unpack_d", 1, 0 },
+ [QOP_TEX_RESULT] = { "tex_result", 1, 0, true },
+ [QOP_R4_UNPACK_A] = { "r4_unpack_a", 1, 1 },
+ [QOP_R4_UNPACK_B] = { "r4_unpack_b", 1, 1 },
+ [QOP_R4_UNPACK_C] = { "r4_unpack_c", 1, 1 },
+ [QOP_R4_UNPACK_D] = { "r4_unpack_d", 1, 1 },
};
static const char *
QIR_ALU0(FRAG_Y)
QIR_ALU0(FRAG_Z)
QIR_ALU0(FRAG_RCP_W)
+QIR_ALU0(TEX_RESULT)
+QIR_ALU0(TLB_COLOR_READ)
QIR_NODST_1(TLB_DISCARD_SETUP)
static inline struct qreg
-qir_R4_UNPACK(struct vc4_compile *c, int i)
+qir_R4_UNPACK(struct vc4_compile *c, struct qreg r4, int i)
{
struct qreg t = qir_get_temp(c);
- qir_emit(c, qir_inst(QOP_R4_UNPACK_A + i, t, c->undef, c->undef));
+ qir_emit(c, qir_inst(QOP_R4_UNPACK_A + i, t, r4, c->undef));
return t;
}
void
vc4_generate_code(struct vc4_compile *c)
{
- struct qpu_reg allocate_to_qpu_reg[3 + 32 + 32];
+ struct qpu_reg allocate_to_qpu_reg[4 + 32 + 32];
bool reg_in_use[ARRAY_SIZE(allocate_to_qpu_reg)];
int *reg_allocated = calloc(c->num_temps, sizeof(*reg_allocated));
int *reg_uses_remaining =
reg_in_use[i] = false;
for (int i = 0; i < c->num_temps; i++)
reg_allocated[i] = -1;
- for (int i = 0; i < 3; i++)
- allocate_to_qpu_reg[i] = qpu_rn(i);
+
+ uint32_t next_reg = 0;
+ for (int i = 0; i < 4; i++)
+ allocate_to_qpu_reg[next_reg++] = qpu_rn(i == 3 ? 4 : i);
for (int i = 0; i < 32; i++)
- allocate_to_qpu_reg[i + 3] = qpu_ra(i);
+ allocate_to_qpu_reg[next_reg++] = qpu_ra(i);
for (int i = 0; i < 32; i++)
- allocate_to_qpu_reg[i + 3 + 32] = qpu_rb(i);
+ allocate_to_qpu_reg[next_reg++] = qpu_rb(i);
+ assert(next_reg == ARRAY_SIZE(allocate_to_qpu_reg));
make_empty_list(&c->qpu_inst_list);
for (alloc = 0;
alloc < ARRAY_SIZE(reg_in_use);
alloc++) {
- /* The pack flags require an A-file register. */
- if (qinst->op == QOP_PACK_SCALED &&
- allocate_to_qpu_reg[alloc].mux != QPU_MUX_A) {
- continue;
+ struct qpu_reg reg = allocate_to_qpu_reg[alloc];
+
+ switch (qinst->op) {
+ case QOP_PACK_SCALED:
+ /* The pack flags require an
+ * A-file register.
+ */
+ if (reg.mux != QPU_MUX_A)
+ continue;
+ break;
+ case QOP_TEX_RESULT:
+ case QOP_TLB_COLOR_READ:
+ /* Only R4-generating
+ * instructions get to store
+ * values in R4 for now, until
+ * we figure out how to do
+ * interference.
+ */
+ if (reg.mux != QPU_MUX_R4)
+ continue;
+ break;
+ default:
+ if (reg.mux == QPU_MUX_R4)
+ continue;
+ break;
}
if (!reg_in_use[alloc])
case QOP_R4_UNPACK_B:
case QOP_R4_UNPACK_C:
case QOP_R4_UNPACK_D:
- queue(c, qpu_a_MOV(dst, qpu_r4()));
+ assert(src[0].mux == QPU_MUX_R4);
+ queue(c, qpu_a_MOV(dst, src[0]));
*last_inst(c) |= QPU_PM;
*last_inst(c) |= QPU_SET_FIELD(QPU_UNPACK_R4_8A +
(qinst->op -