}
if (config != ~0) {
- tmu->src[vir_get_implicit_uniform_src(tmu)] =
- vir_uniform_ui(c, config);
+ tmu->uniform = vir_get_uniform_index(c, QUNIFORM_CONSTANT,
+ config);
}
if (vir_in_nonuniform_control_flow(c))
} else
tlb_specifier |= TLB_DEPTH_TYPE_PER_PIXEL;
- inst->src[vir_get_implicit_uniform_src(inst)] =
- vir_uniform_ui(c, tlb_specifier | 0xffffff00);
+ inst->uniform = vir_get_uniform_index(c, QUNIFORM_CONSTANT,
+ tlb_specifier |
+ 0xffffff00);
c->writes_z = true;
} else if (c->s->info.fs.uses_discard ||
!c->s->info.fs.early_fragment_tests ||
tlb_specifier |= TLB_DEPTH_TYPE_INVARIANT;
}
- inst->src[vir_get_implicit_uniform_src(inst)] =
- vir_uniform_ui(c, tlb_specifier | 0xffffff00);
+ inst->uniform = vir_get_uniform_index(c,
+ QUNIFORM_CONSTANT,
+ tlb_specifier |
+ 0xffffff00);
c->writes_z = true;
}
TLB_VEC_SIZE_MINUS_1_SHIFT);
inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
- inst->src[vir_get_implicit_uniform_src(inst)] =
- vir_uniform_ui(c, conf);
+ inst->uniform = vir_get_uniform_index(c,
+ QUNIFORM_CONSTANT,
+ conf);
for (int i = 1; i < num_components; i++) {
inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0),
if (c->fs_key->f32_color_rb & (1 << rt)) {
inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), r);
- inst->src[vir_get_implicit_uniform_src(inst)] =
- vir_uniform_ui(c, conf);
+ inst->uniform = vir_get_uniform_index(c,
+ QUNIFORM_CONSTANT,
+ conf);
if (num_components >= 2)
vir_MOV_dest(c, vir_reg(QFILE_TLB, 0), g);
inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g);
if (conf != ~0) {
inst->dst.file = QFILE_TLBU;
- inst->src[vir_get_implicit_uniform_src(inst)] =
- vir_uniform_ui(c, conf);
+ inst->uniform = vir_get_uniform_index(c,
+ QUNIFORM_CONSTANT,
+ conf);
}
if (num_components >= 3)
vir_BARRIERID_dest(c,
vir_reg(QFILE_MAGIC,
V3D_QPU_WADDR_SYNCU));
- sync->src[vir_get_implicit_uniform_src(sync)] =
- vir_uniform_ui(c,
- 0xffffff00 |
- V3D_TSY_WAIT_INC_CHECK);
+ sync->uniform =
+ vir_get_uniform_index(c, QUNIFORM_CONSTANT,
+ 0xffffff00 |
+ V3D_TSY_WAIT_INC_CHECK);
}
}
/* inst->sig.ldunif or sideband uniform read */
- if (qinst->uniform != ~0)
+ if (vir_has_uniform(qinst))
add_write_dep(state, &state->last_unif, n);
if (v3d_qpu_reads_flags(inst))
unit));
}
- struct qreg texture_u[] = {
- vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0_0 + unit, p0_packed),
- vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, p1_packed),
+ int texture_u[] = {
+ vir_get_uniform_index(c, QUNIFORM_TEXTURE_CONFIG_P0_0 + unit, p0_packed),
+ vir_get_uniform_index(c, QUNIFORM_TEXTURE_CONFIG_P1, p1_packed),
};
- uint32_t next_texture_u = 0;
for (int i = 0; i < next_coord; i++) {
struct qreg dst;
struct qinst *tmu = vir_MOV_dest(c, dst, coords[i]);
- if (i < 2) {
- tmu->has_implicit_uniform = true;
- tmu->src[vir_get_implicit_uniform_src(tmu)] =
- texture_u[next_texture_u++];
- }
+ if (i < 2)
+ tmu->uniform = texture_u[i];
}
vir_emit_thrsw(c);
{
struct qinst *inst = vir_NOP(c);
inst->qpu.sig.wrtmuc = true;
- inst->has_implicit_uniform = true;
- inst->src[0] = vir_uniform(c, contents, data);
+ inst->uniform = vir_get_uniform_index(c, contents, data);
}
static const struct V3D41_TMU_CONFIG_PARAMETER_1 p1_unpacked_default = {
/* Pre-register-allocation references to src/dst registers */
struct qreg dst;
struct qreg src[3];
- bool has_implicit_uniform;
bool is_last_thrsw;
- /* After vir_to_qpu.c: If instr reads a uniform, which uniform from
- * the uncompiled stream it is.
+ /* If the instruction reads a uniform (other than through src[i].file
+ * == QFILE_UNIF), that uniform's index in c->uniform_contents. ~0
+ * otherwise.
*/
int uniform;
};
bool uses_center_w;
};
+static inline bool
+vir_has_uniform(struct qinst *inst)
+{
+ return inst->uniform != ~0;
+}
+
/* Special nir_load_input intrinsic index for loading the current TLB
* destination color.
*/
struct qreg src0, struct qreg src1);
struct qinst *vir_mul_inst(enum v3d_qpu_mul_op op, struct qreg dst,
struct qreg src0, struct qreg src1);
-struct qinst *vir_branch_inst(enum v3d_qpu_branch_cond cond, struct qreg src0);
+struct qinst *vir_branch_inst(struct v3d_compile *c,
+ enum v3d_qpu_branch_cond cond);
void vir_remove_instruction(struct v3d_compile *c, struct qinst *qinst);
+uint32_t vir_get_uniform_index(struct v3d_compile *c,
+ enum quniform_contents contents,
+ uint32_t data);
struct qreg vir_uniform(struct v3d_compile *c,
enum quniform_contents contents,
uint32_t data);
struct qreg vir_get_temp(struct v3d_compile *c);
void vir_emit_last_thrsw(struct v3d_compile *c);
void vir_calculate_live_intervals(struct v3d_compile *c);
-bool vir_has_implicit_uniform(struct qinst *inst);
-int vir_get_implicit_uniform_src(struct qinst *inst);
-int vir_get_non_sideband_nsrc(struct qinst *inst);
int vir_get_nsrc(struct qinst *inst);
bool vir_has_side_effects(struct v3d_compile *c, struct qinst *inst);
bool vir_get_add_op(struct qinst *inst, enum v3d_qpu_add_op *op);
vir_BRANCH(struct v3d_compile *c, enum v3d_qpu_branch_cond cond)
{
/* The actual uniform_data value will be set at scheduling time */
- return vir_emit_nondef(c, vir_branch_inst(cond, vir_uniform_ui(c, 0)));
+ return vir_emit_nondef(c, vir_branch_inst(c, cond));
}
#define vir_for_each_block(block, c) \
#include "v3d_compiler.h"
int
-vir_get_non_sideband_nsrc(struct qinst *inst)
+vir_get_nsrc(struct qinst *inst)
{
switch (inst->qpu.type) {
case V3D_QPU_INSTR_TYPE_BRANCH:
return 0;
}
-int
-vir_get_nsrc(struct qinst *inst)
-{
- int nsrc = vir_get_non_sideband_nsrc(inst);
-
- if (vir_has_implicit_uniform(inst))
- nsrc++;
-
- return nsrc;
-}
-
-bool
-vir_has_implicit_uniform(struct qinst *inst)
-{
- switch (inst->qpu.type) {
- case V3D_QPU_INSTR_TYPE_BRANCH:
- return true;
- case V3D_QPU_INSTR_TYPE_ALU:
- switch (inst->dst.file) {
- case QFILE_TLBU:
- return true;
- case QFILE_MAGIC:
- switch (inst->dst.index) {
- case V3D_QPU_WADDR_TLBU:
- case V3D_QPU_WADDR_TMUAU:
- case V3D_QPU_WADDR_SYNCU:
- return true;
- default:
- break;
- }
- break;
- default:
- return inst->has_implicit_uniform;
- }
- }
- return false;
-}
-
-/* The sideband uniform for textures gets stored after the normal ALU
- * arguments.
- */
-int
-vir_get_implicit_uniform_src(struct qinst *inst)
-{
- if (!vir_has_implicit_uniform(inst))
- return -1;
- return vir_get_nsrc(inst) - 1;
-}
-
/**
* Returns whether the instruction has any side effects that must be
* preserved.
}
struct qinst *
-vir_branch_inst(enum v3d_qpu_branch_cond cond, struct qreg src)
+vir_branch_inst(struct v3d_compile *c, enum v3d_qpu_branch_cond cond)
{
struct qinst *inst = calloc(1, sizeof(*inst));
inst->qpu.branch.bdu = V3D_QPU_BRANCH_DEST_REL;
inst->dst = vir_nop_reg();
- inst->src[0] = src;
- inst->uniform = ~0;
+ inst->uniform = vir_get_uniform_index(c, QUNIFORM_CONSTANT, 0);
return inst;
}
ralloc_free(c);
}
-struct qreg
-vir_uniform(struct v3d_compile *c,
- enum quniform_contents contents,
- uint32_t data)
+uint32_t
+vir_get_uniform_index(struct v3d_compile *c,
+ enum quniform_contents contents,
+ uint32_t data)
{
for (int i = 0; i < c->num_uniforms; i++) {
if (c->uniform_contents[i] == contents &&
c->uniform_data[i] == data) {
- return vir_reg(QFILE_UNIF, i);
+ return i;
}
}
c->uniform_contents[uniform] = contents;
c->uniform_data[uniform] = data;
+ return uniform;
+}
+
+struct qreg
+vir_uniform(struct v3d_compile *c,
+ enum quniform_contents contents,
+ uint32_t data)
+{
+ uint32_t uniform = vir_get_uniform_index(c, contents, data);
+
return vir_reg(QFILE_UNIF, uniform);
}
vir_dump_alu(struct v3d_compile *c, struct qinst *inst)
{
struct v3d_qpu_instr *instr = &inst->qpu;
- int nsrc = vir_get_non_sideband_nsrc(inst);
- int sideband_nsrc = vir_get_nsrc(inst);
+ int nsrc = vir_get_nsrc(inst);
enum v3d_qpu_input_unpack unpack[2];
if (inst->qpu.alu.add.op != V3D_QPU_A_NOP) {
unpack[1] = instr->alu.mul.b_unpack;
}
- for (int i = 0; i < sideband_nsrc; i++) {
+ for (int i = 0; i < nsrc; i++) {
fprintf(stderr, ", ");
vir_print_reg(c, inst, inst->src[i]);
- if (i < nsrc)
- fprintf(stderr, "%s", v3d_qpu_unpack_name(unpack[i]));
+ fprintf(stderr, "%s", v3d_qpu_unpack_name(unpack[i]));
}
vir_dump_sig(c, inst);
break;
}
}
-
- if (vir_has_implicit_uniform(inst)) {
- fprintf(stderr, " ");
- vir_print_reg(c, inst, inst->src[vir_get_implicit_uniform_src(inst)]);
- }
-
break;
}
+
+ if (vir_has_uniform(inst)) {
+ fprintf(stderr, " (");
+ vir_dump_uniform(c->uniform_contents[inst->uniform],
+ c->uniform_data[inst->uniform]);
+ fprintf(stderr, ")");
+ }
}
void
{
if (inst->src[i].file != QFILE_UNIF)
return false;
- return i != vir_get_implicit_uniform_src(inst);
+ return true;
}
/* Returns the number of different uniform values referenced by the
static uint32_t
vir_get_instruction_uniform_count(struct qinst *inst)
{
- uint32_t count = 0;
+ uint32_t count = vir_has_uniform(inst);
for (int i = 0; i < vir_get_nsrc(inst); i++) {
if (inst->src[i].file != QFILE_UNIF)
continue;
for (int i = 0; i < nsrc; i++) {
- if (is_lowerable_uniform(inst, i))
- add_uniform(ht, inst->src[i]);
+ add_uniform(ht, inst->src[i]);
}
}
continue;
}
- if (vir_has_implicit_uniform(inst) &&
- i == vir_get_implicit_uniform_src(inst)) {
- /* No turning the implicit uniform read into
- * an immediate.
- */
- continue;
- }
-
/* Check if the uniform is suitable as a small
* immediate.
*/
struct qinst *temp;
- if (vir_has_implicit_uniform(qinst)) {
- int src = vir_get_implicit_uniform_src(qinst);
- assert(qinst->src[src].file == QFILE_UNIF);
- qinst->uniform = qinst->src[src].index;
+ if (vir_has_uniform(qinst))
c->num_uniforms++;
- }
- int nsrc = vir_get_non_sideband_nsrc(qinst);
+ int nsrc = vir_get_nsrc(qinst);
struct qpu_reg src[ARRAY_SIZE(qinst->src)];
bool emitted_ldunif = false;
for (int i = 0; i < nsrc; i++) {