From 52824811b9c0a9bb78a40fcb43af00b315f612d0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Oct 2014 15:03:04 +0100 Subject: [PATCH] vc4: Allow dead code elimination of unused varyings. total instructions in shared programs: 39022 -> 37341 (-4.31%) instructions in affected programs: 26979 -> 25298 (-6.23%) total uniforms in shared programs: 11242 -> 10523 (-6.40%) uniforms in affected programs: 5836 -> 5117 (-12.32%) --- src/gallium/drivers/vc4/vc4_opt_cse.c | 2 +- src/gallium/drivers/vc4/vc4_opt_dead_code.c | 2 +- src/gallium/drivers/vc4/vc4_program.c | 15 +++++++++++++++ src/gallium/drivers/vc4/vc4_qir.c | 15 +++++++++++++-- src/gallium/drivers/vc4/vc4_qir.h | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/vc4/vc4_opt_cse.c b/src/gallium/drivers/vc4/vc4_opt_cse.c index d3ef91083c6..bebfb6526de 100644 --- a/src/gallium/drivers/vc4/vc4_opt_cse.c +++ b/src/gallium/drivers/vc4/vc4_opt_cse.c @@ -132,7 +132,7 @@ qir_opt_cse(struct vc4_compile *c) foreach_s(node, t, &c->instructions) { struct qinst *inst = (struct qinst *)node; - if (qir_has_side_effects(inst)) { + if (qir_has_side_effects(c, inst)) { if (inst->op == QOP_TLB_DISCARD_SETUP) last_sf = NULL; continue; diff --git a/src/gallium/drivers/vc4/vc4_opt_dead_code.c b/src/gallium/drivers/vc4/vc4_opt_dead_code.c index f08818adc95..d958dcb1075 100644 --- a/src/gallium/drivers/vc4/vc4_opt_dead_code.c +++ b/src/gallium/drivers/vc4/vc4_opt_dead_code.c @@ -63,7 +63,7 @@ qir_opt_dead_code(struct vc4_compile *c) if (inst->dst.file == QFILE_TEMP && !used[inst->dst.index] && - (!qir_has_side_effects(inst) || + (!qir_has_side_effects(c, inst) || inst->op == QOP_TEX_RESULT)) { if (inst->op == QOP_TEX_RESULT) { dce_tex = true; diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 01941f88428..0674e4fd01a 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -2018,6 +2018,18 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage, shader->program_id = vc4->next_compiled_program_id++; if (stage == QSTAGE_FRAG) { + bool input_live[c->num_input_semantics]; + struct simple_node *node; + + memset(input_live, 0, sizeof(input_live)); + foreach(node, &c->instructions) { + struct qinst *inst = (struct qinst *)node; + for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { + if (inst->src[i].file == QFILE_VARY) + input_live[inst->src[i].index] = true; + } + } + shader->input_semantics = ralloc_array(shader, struct vc4_varying_semantic, c->num_input_semantics); @@ -2025,6 +2037,9 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage, for (int i = 0; i < c->num_input_semantics; i++) { struct vc4_varying_semantic *sem = &c->input_semantics[i]; + if (!input_live[i]) + continue; + /* Skip non-VS-output inputs. */ if (sem->semantic == (uint8_t)~0) continue; diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index 9c7c15e4924..a7a4d96f758 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -122,12 +122,23 @@ qir_get_op_nsrc(enum qop qop) abort(); } +/** + * Returns whether the instruction has any side effects that must be + * preserved. + */ bool -qir_has_side_effects(struct qinst *inst) +qir_has_side_effects(struct vc4_compile *c, struct qinst *inst) { + /* We can dead-code eliminate varyings, because we only tell the VS + * about the live ones at the end. But we have to preserve the + * point/line coordinates reads, because they're generated by + * fixed-function hardware. + */ for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { - if (inst->src[i].file == QFILE_VARY) + if (inst->src[i].file == QFILE_VARY && + c->input_semantics[inst->src[i].index].semantic == 0xff) { return true; + } } return qir_op_info[inst->op].has_side_effects; diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index c2f83a7e923..077a55ad6fc 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -309,7 +309,7 @@ void qir_emit(struct vc4_compile *c, struct qinst *inst); struct qreg qir_get_temp(struct vc4_compile *c); int qir_get_op_nsrc(enum qop qop); bool qir_reg_equals(struct qreg a, struct qreg b); -bool qir_has_side_effects(struct qinst *inst); +bool qir_has_side_effects(struct vc4_compile *c, struct qinst *inst); bool qir_depends_on_flags(struct qinst *inst); bool qir_writes_r4(struct qinst *inst); bool qir_reads_r4(struct qinst *inst); -- 2.30.2