summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_program.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2015-08-03 19:08:37 -0700
committerEric Anholt <eric@anholt.net>2015-08-04 17:33:34 -0700
commit45248d3640f5a0356085e26c44548bf3af5dec0f (patch)
treebdf8fa860a38df8916777c0280c43e3d51c363c1 /src/gallium/drivers/vc4/vc4_program.c
parenta70f63ab20d8bf922a307a92020237b1dec36314 (diff)
vc4: Don't bother de-SSAing values that aren't part of phi webs.
We can just support them the same way we do load_const's SSA values.
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index d6c60739e93..307667e23c8 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -110,18 +110,32 @@ indirect_uniform_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
}
static struct qreg *
-ntq_get_dest(struct vc4_compile *c, nir_dest dest)
+ntq_init_ssa_def(struct vc4_compile *c, nir_ssa_def *def)
{
- assert(!dest.is_ssa);
- nir_register *reg = dest.reg.reg;
- struct hash_entry *entry = _mesa_hash_table_search(c->def_ht, reg);
- assert(reg->num_array_elems == 0);
- assert(dest.reg.base_offset == 0);
-
- struct qreg *qregs = entry->data;
+ struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
+ def->num_components);
+ _mesa_hash_table_insert(c->def_ht, def, qregs);
return qregs;
}
+static struct qreg *
+ntq_get_dest(struct vc4_compile *c, nir_dest *dest)
+{
+ if (dest->is_ssa) {
+ struct qreg *qregs = ntq_init_ssa_def(c, &dest->ssa);
+ for (int i = 0; i < dest->ssa.num_components; i++)
+ qregs[i] = c->undef;
+ return qregs;
+ } else {
+ nir_register *reg = dest->reg.reg;
+ assert(dest->reg.base_offset == 0);
+ assert(reg->num_array_elems == 0);
+ struct hash_entry *entry =
+ _mesa_hash_table_search(c->def_ht, reg);
+ return entry->data;
+ }
+}
+
static struct qreg
ntq_get_src(struct vc4_compile *c, nir_src src, int i)
{
@@ -433,7 +447,7 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
texture_output[i]);
}
- struct qreg *dest = ntq_get_dest(c, instr->dest);
+ struct qreg *dest = ntq_get_dest(c, &instr->dest);
for (int i = 0; i < 4; i++) {
dest[i] = get_swizzled_channel(c, texture_output,
c->key->tex[unit].swizzle[i]);
@@ -800,7 +814,7 @@ ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
srcs[i] = ntq_get_src(c, instr->src[i].src,
instr->src[i].swizzle[0]);
- struct qreg *dest = ntq_get_dest(c, instr->dest.dest);
+ struct qreg *dest = ntq_get_dest(c, &instr->dest.dest);
for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
dest[i] = srcs[i];
return;
@@ -814,7 +828,7 @@ ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
/* Pick the channel to store the output in. */
assert(!instr->dest.saturate);
- struct qreg *dest = ntq_get_dest(c, instr->dest.dest);
+ struct qreg *dest = ntq_get_dest(c, &instr->dest.dest);
assert(util_is_power_of_two(instr->dest.write_mask));
dest += ffs(instr->dest.write_mask) - 1;
@@ -1761,8 +1775,7 @@ ntq_setup_registers(struct vc4_compile *c, struct exec_list *list)
static void
ntq_emit_load_const(struct vc4_compile *c, nir_load_const_instr *instr)
{
- struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
- instr->def.num_components);
+ struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
for (int i = 0; i < instr->def.num_components; i++)
qregs[i] = qir_uniform_ui(c, instr->value.u[i]);
@@ -1770,13 +1783,25 @@ ntq_emit_load_const(struct vc4_compile *c, nir_load_const_instr *instr)
}
static void
+ntq_emit_ssa_undef(struct vc4_compile *c, nir_ssa_undef_instr *instr)
+{
+ struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
+
+ /* QIR needs there to be *some* value, so pick 0 (same as for
+ * ntq_setup_registers().
+ */
+ for (int i = 0; i < instr->def.num_components; i++)
+ qregs[i] = qir_uniform_ui(c, 0);
+}
+
+static void
ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
{
const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
struct qreg *dest = NULL;
if (info->has_dest) {
- dest = ntq_get_dest(c, instr->dest);
+ dest = ntq_get_dest(c, &instr->dest);
}
switch (instr->intrinsic) {
@@ -1844,6 +1869,10 @@ ntq_emit_instr(struct vc4_compile *c, nir_instr *instr)
ntq_emit_load_const(c, nir_instr_as_load_const(instr));
break;
+ case nir_instr_type_ssa_undef:
+ ntq_emit_ssa_undef(c, nir_instr_as_ssa_undef(instr));
+ break;
+
case nir_instr_type_tex:
ntq_emit_tex(c, nir_instr_as_tex(instr));
break;
@@ -2008,7 +2037,7 @@ vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage,
nir_remove_dead_variables(c->s);
- nir_convert_from_ssa(c->s, false);
+ nir_convert_from_ssa(c->s, true);
if (vc4_debug & VC4_DEBUG_SHADERDB) {
fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d NIR instructions\n",