From e51e20c35ef89409494161010f86750366faef4c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Aug 2014 13:12:19 -0700 Subject: [PATCH] vc4: Add support for fragment discards. Fixes piglit glsl-fs-discard-01 and -03, and allows a lot of mesa demos to start running. glsl-fs-discard-02 has a problem where the first tile is not getting stored on the first render. --- src/gallium/drivers/vc4/vc4_program.c | 24 ++++++++++++++++++++++++ src/gallium/drivers/vc4/vc4_qir.c | 1 + src/gallium/drivers/vc4/vc4_qir.h | 2 ++ src/gallium/drivers/vc4/vc4_qpu_emit.c | 16 ++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 08ac5e8b826..d404047e4bb 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -47,6 +47,7 @@ struct tgsi_to_qir { struct qreg *uniforms; struct qreg *consts; struct qreg line_x, point_x, point_y; + struct qreg discard; uint32_t num_consts; @@ -605,6 +606,19 @@ emit_vertex_input(struct tgsi_to_qir *trans, int attr) } } +static void +tgsi_to_qir_kill_if(struct tgsi_to_qir *trans, struct qreg *src, int i) +{ + struct qcompile *c = trans->c; + + if (trans->discard.file == QFILE_NULL) + trans->discard = qir_uniform_f(trans, 0.0); + trans->discard = qir_CMP(c, + src[0 * 4 + i], + qir_uniform_f(trans, 1.0), + trans->discard); +} + static void emit_fragcoord_input(struct tgsi_to_qir *trans, int attr) { @@ -734,6 +748,13 @@ emit_tgsi_instruction(struct tgsi_to_qir *trans, tgsi_to_qir_tex(trans, tgsi_inst, op_trans[tgsi_op].op, src_regs); return; + case TGSI_OPCODE_KILL: + trans->discard = qir_uniform_f(trans, 1.0); + return; + case TGSI_OPCODE_KILL_IF: + for (int i = 0; i < 4; i++) + tgsi_to_qir_kill_if(trans, src_regs, i); + return; default: break; } @@ -984,6 +1005,9 @@ emit_frag_end(struct tgsi_to_qir *trans) format_swiz[i]); } + if (trans->discard.file != QFILE_NULL) + qir_TLB_DISCARD_SETUP(c, trans->discard); + if (trans->fs_key->depth_enabled) { qir_emit(c, qir_inst(QOP_TLB_PASSTHROUGH_Z_WRITE, c->undef, c->undef, c->undef)); diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index aa1f40b1162..0b0d2c11cf1 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -59,6 +59,7 @@ static const struct qir_op_info qir_op_info[] = { [QOP_PACK_SCALED] = { "pack_scaled", 1, 2 }, [QOP_VPM_WRITE] = { "vpm_write", 0, 1, true }, [QOP_VPM_READ] = { "vpm_read", 0, 1, true }, + [QOP_TLB_DISCARD_SETUP] = { "discard", 0, 1, true }, [QOP_TLB_PASSTHROUGH_Z_WRITE] = { "tlb_passthrough_z", 0, 0, true }, [QOP_TLB_COLOR_WRITE] = { "tlb_color", 0, 1, true }, [QOP_TLB_COLOR_READ] = { "tlb_color_read", 0, 0, true }, diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index 9277d4abc54..77b5f1af903 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -72,6 +72,7 @@ enum qop { QOP_PACK_COLORS, QOP_VPM_WRITE, QOP_VPM_READ, + QOP_TLB_DISCARD_SETUP, QOP_TLB_PASSTHROUGH_Z_WRITE, QOP_TLB_COLOR_WRITE, QOP_TLB_COLOR_READ, @@ -280,6 +281,7 @@ QIR_ALU0(FRAG_X) QIR_ALU0(FRAG_Y) QIR_ALU0(FRAG_Z) QIR_ALU0(FRAG_RCP_W) +QIR_NODST_1(TLB_DISCARD_SETUP) static inline struct qreg qir_CMP(struct qcompile *c, struct qreg cmp, struct qreg a, struct qreg b) diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c index d777af64d43..415d2b0dfd5 100644 --- a/src/gallium/drivers/vc4/vc4_qpu_emit.c +++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c @@ -213,6 +213,7 @@ vc4_generate_code(struct qcompile *c) int *reg_allocated = calloc(c->num_temps, sizeof(*reg_allocated)); int *reg_uses_remaining = calloc(c->num_temps, sizeof(*reg_uses_remaining)); + bool discard = false; for (int i = 0; i < ARRAY_SIZE(reg_in_use); i++) reg_in_use[i] = false; @@ -508,10 +509,21 @@ vc4_generate_code(struct qcompile *c) qpu_m_NOP())); break; + case QOP_TLB_DISCARD_SETUP: + discard = true; + queue(c, qpu_inst(qpu_a_MOV(src[0], src[0]), + qpu_m_NOP())); + *last_inst(c) |= QPU_SF; + break; + case QOP_TLB_PASSTHROUGH_Z_WRITE: queue(c, qpu_inst(qpu_a_MOV(qpu_ra(QPU_W_TLB_Z), qpu_rb(QPU_R_FRAG_PAYLOAD_ZW)), qpu_m_NOP())); + if (discard) { + *last_inst(c) = qpu_set_cond_add(*last_inst(c), + QPU_COND_ZS); + } break; case QOP_TLB_COLOR_READ: @@ -525,6 +537,10 @@ vc4_generate_code(struct qcompile *c) queue(c, qpu_inst(qpu_a_MOV(qpu_tlbc(), src[0]), qpu_m_NOP())); + if (discard) { + *last_inst(c) = qpu_set_cond_add(*last_inst(c), + QPU_COND_ZS); + } break; case QOP_VARY_ADD_C: -- 2.30.2