summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_cse.c2
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_dead_code.c2
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c15
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.c15
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h2
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);