uint32_t val)
{
if (reg.file == QFILE_UNIF &&
+ !reg.pack &&
c->uniform_contents[reg.index] == QUNIFORM_CONSTANT &&
c->uniform_data[reg.index] == val) {
return true;
struct qreg src = qir_follow_movs(c, inst->src[i]);
if (src.file != QFILE_UNIF ||
+ src.pack ||
c->uniform_contents[src.index] !=
QUNIFORM_CONSTANT) {
continue;
continue;
}
- if (qir_src_needs_a_file(inst))
- continue;
-
uint32_t imm = c->uniform_data[src.index];
uint32_t small_imm = qpu_encode_small_immediate(imm);
if (small_imm == ~0)
static const struct qir_op_info qir_op_info[] = {
[QOP_MOV] = { "mov", 1, 1 },
+ [QOP_FMOV] = { "fmov", 1, 1 },
[QOP_FADD] = { "fadd", 1, 2 },
[QOP_FSUB] = { "fsub", 1, 2 },
[QOP_FMUL] = { "fmul", 1, 2 },
[QOP_TEX_B] = { "tex_b", 0, 2 },
[QOP_TEX_DIRECT] = { "tex_direct", 0, 2 },
[QOP_TEX_RESULT] = { "tex_result", 1, 0, true },
- [QOP_UNPACK_8A_F] = { "unpack_8a_f", 1, 1 },
- [QOP_UNPACK_8B_F] = { "unpack_8b_f", 1, 1 },
- [QOP_UNPACK_8C_F] = { "unpack_8c_f", 1, 1 },
- [QOP_UNPACK_8D_F] = { "unpack_8d_f", 1, 1 },
- [QOP_UNPACK_16A_F] = { "unpack_16a_f", 1, 1 },
- [QOP_UNPACK_16B_F] = { "unpack_16b_f", 1, 1 },
- [QOP_UNPACK_8A_I] = { "unpack_8a_i", 1, 1 },
- [QOP_UNPACK_8B_I] = { "unpack_8b_i", 1, 1 },
- [QOP_UNPACK_8C_I] = { "unpack_8c_i", 1, 1 },
- [QOP_UNPACK_8D_I] = { "unpack_8d_i", 1, 1 },
- [QOP_UNPACK_16A_I] = { "unpack_16a_i", 1, 1 },
- [QOP_UNPACK_16B_I] = { "unpack_16b_i", 1, 1 },
};
static const char *
qir_is_float_input(struct qinst *inst)
{
switch (inst->op) {
+ case QOP_FMOV:
case QOP_FMUL:
case QOP_FADD:
case QOP_FSUB:
case QOP_FMINABS:
case QOP_FMAXABS:
case QOP_FTOI:
- case QOP_UNPACK_8A_F:
- case QOP_UNPACK_8B_F:
- case QOP_UNPACK_8C_F:
- case QOP_UNPACK_8D_F:
- case QOP_UNPACK_16A_F:
- case QOP_UNPACK_16B_F:
return true;
default:
return false;
bool
qir_is_raw_mov(struct qinst *inst)
{
- return (inst->op == QOP_MOV &&
+ return ((inst->op == QOP_MOV ||
+ inst->op == QOP_FMOV) &&
!inst->dst.pack &&
!inst->src[0].pack);
}
}
}
-bool
-qir_src_needs_a_file(struct qinst *inst)
-{
- switch (inst->op) {
- case QOP_UNPACK_8A_F:
- case QOP_UNPACK_8B_F:
- case QOP_UNPACK_8C_F:
- case QOP_UNPACK_8D_F:
- case QOP_UNPACK_16A_F:
- case QOP_UNPACK_16B_F:
- case QOP_UNPACK_8A_I:
- case QOP_UNPACK_8B_I:
- case QOP_UNPACK_8C_I:
- case QOP_UNPACK_8D_I:
- case QOP_UNPACK_16A_I:
- case QOP_UNPACK_16B_I:
- return true;
- default:
- return false;
- }
-}
-
bool
qir_writes_r4(struct qinst *inst)
{
#include "util/u_math.h"
#include "vc4_screen.h"
+#include "vc4_qpu_defines.h"
#include "pipe/p_state.h"
struct nir_builder;
enum qop {
QOP_UNDEF,
QOP_MOV,
+ QOP_FMOV,
QOP_FADD,
QOP_FSUB,
QOP_FMUL,
QOP_FRAG_W,
QOP_FRAG_REV_FLAG,
- QOP_UNPACK_8A_F,
- QOP_UNPACK_8B_F,
- QOP_UNPACK_8C_F,
- QOP_UNPACK_8D_F,
- QOP_UNPACK_16A_F,
- QOP_UNPACK_16B_F,
-
- QOP_UNPACK_8A_I,
- QOP_UNPACK_8B_I,
- QOP_UNPACK_8C_I,
- QOP_UNPACK_8D_I,
- QOP_UNPACK_16A_I,
- QOP_UNPACK_16B_I,
-
/** Texture x coordinate parameter write */
QOP_TEX_S,
/** Texture y coordinate parameter write */
bool qir_is_float_input(struct qinst *inst);
bool qir_depends_on_flags(struct qinst *inst);
bool qir_writes_r4(struct qinst *inst);
-bool qir_src_needs_a_file(struct qinst *inst);
struct qreg qir_follow_movs(struct vc4_compile *c, struct qreg reg);
void qir_dump(struct vc4_compile *c);
}
QIR_ALU1(MOV)
+QIR_ALU1(FMOV)
QIR_ALU2(FADD)
QIR_ALU2(FSUB)
QIR_ALU2(FMUL)
static inline struct qreg
qir_UNPACK_8_F(struct vc4_compile *c, struct qreg src, int i)
{
- struct qreg t = qir_get_temp(c);
- qir_emit(c, qir_inst(QOP_UNPACK_8A_F + i, t, src, c->undef));
+ struct qreg t = qir_FMOV(c, src);
+ c->defs[t.index]->src[0].pack = QPU_UNPACK_8A + i;
return t;
}
static inline struct qreg
qir_UNPACK_8_I(struct vc4_compile *c, struct qreg src, int i)
{
- struct qreg t = qir_get_temp(c);
- qir_emit(c, qir_inst(QOP_UNPACK_8A_I + i, t, src, c->undef));
+ struct qreg t = qir_MOV(c, src);
+ c->defs[t.index]->src[0].pack = QPU_UNPACK_8A + i;
return t;
}
static inline struct qreg
qir_UNPACK_16_F(struct vc4_compile *c, struct qreg src, int i)
{
- struct qreg t = qir_get_temp(c);
- qir_emit(c, qir_inst(QOP_UNPACK_16A_F + i, t, src, c->undef));
+ struct qreg t = qir_FMOV(c, src);
+ c->defs[t.index]->src[0].pack = QPU_UNPACK_16A + i;
return t;
}
static inline struct qreg
qir_UNPACK_16_I(struct vc4_compile *c, struct qreg src, int i)
{
- struct qreg t = qir_get_temp(c);
- qir_emit(c, qir_inst(QOP_UNPACK_16A_I + i, t, src, c->undef));
+ struct qreg t = qir_MOV(c, src);
+ c->defs[t.index]->src[0].pack = QPU_UNPACK_16A + i;
return t;
}
uint32_t vpm_read_fifo_count = 0;
uint32_t vpm_read_offset = 0;
int last_vpm_read_index = -1;
- /* Map from the QIR ops enum order to QPU unpack bits. */
- static const uint32_t unpack_map[] = {
- QPU_UNPACK_8A,
- QPU_UNPACK_8B,
- QPU_UNPACK_8C,
- QPU_UNPACK_8D,
- QPU_UNPACK_16A,
- QPU_UNPACK_16B,
- };
list_inithead(&c->qpu_inst_list);
* out the same as a MOV.
*/
[QOP_MOV] = { QPU_A_OR },
+ [QOP_FMOV] = { QPU_A_FMAX },
};
+ uint64_t unpack = 0;
struct qpu_reg src[4];
for (int i = 0; i < qir_get_op_nsrc(qinst->op); i++) {
int index = qinst->src[i].index;
break;
case QFILE_TEMP:
src[i] = temp_registers[index];
+ if (qinst->src[i].pack) {
+ assert(!unpack ||
+ unpack == qinst->src[i].pack);
+ unpack = QPU_SET_FIELD(qinst->src[i].pack,
+ QPU_UNPACK);
+ if (src[i].mux == QPU_MUX_R4)
+ unpack |= QPU_PM;
+ }
break;
case QFILE_UNIF:
src[i] = qpu_unif();
queue(c, qpu_a_MOV(dst, qpu_r4()));
break;
- case QOP_UNPACK_8A_F:
- case QOP_UNPACK_8B_F:
- case QOP_UNPACK_8C_F:
- case QOP_UNPACK_8D_F:
- case QOP_UNPACK_16A_F:
- case QOP_UNPACK_16B_F:
- if (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_8A +
- (qinst->op -
- QOP_UNPACK_8A_F),
- QPU_UNPACK);
- } else {
- assert(src[0].mux == QPU_MUX_A);
-
- queue(c, qpu_a_FMAX(dst, src[0], src[0]));
- *last_inst(c) |=
- QPU_SET_FIELD(unpack_map[qinst->op -
- QOP_UNPACK_8A_F],
- QPU_UNPACK);
- }
- break;
-
- case QOP_UNPACK_8A_I:
- case QOP_UNPACK_8B_I:
- case QOP_UNPACK_8C_I:
- case QOP_UNPACK_8D_I:
- case QOP_UNPACK_16A_I:
- case QOP_UNPACK_16B_I:
- assert(src[0].mux == QPU_MUX_A);
-
- queue(c, qpu_a_MOV(dst, src[0]));
- *last_inst(c) |= QPU_SET_FIELD(unpack_map[qinst->op -
- QOP_UNPACK_8A_I],
- QPU_UNPACK);
- break;
-
default:
assert(qinst->op < ARRAY_SIZE(translate));
assert(translate[qinst->op].op != 0); /* NOPs */
class_bits[inst->dst.index] &= CLASS_BIT_A;
}
- if (qir_src_needs_a_file(inst)) {
- if (qir_is_float_input(inst)) {
- /* Special case: these can be done as R4
- * unpacks, as well.
- */
- class_bits[inst->src[0].index] &= (CLASS_BIT_A |
- CLASS_BIT_R4);
- } else {
- class_bits[inst->src[0].index] &= CLASS_BIT_A;
+ /* Apply restrictions for src unpacks. The integer unpacks
+ * can only be done from regfile A, while float unpacks can be
+ * either A or R4.
+ */
+ for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
+ if (inst->src[i].file == QFILE_TEMP &&
+ inst->src[i].pack) {
+ if (qir_is_float_input(inst)) {
+ class_bits[inst->src[i].index] &=
+ CLASS_BIT_A | CLASS_BIT_R4;
+ } else {
+ class_bits[inst->src[i].index] &=
+ CLASS_BIT_A;
+ }
}
}
+
ip++;
}