From 74c4b3b80cc4246fd1eb503d97edb3d293eef5de Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 20 Nov 2015 17:18:03 -0800 Subject: [PATCH] vc4: Add support for storing sample mask. From the API perspective, writing 1 bits can't turn on pixels that were off, so we AND it with the sample mask from the payload. --- src/gallium/drivers/vc4/vc4_program.c | 7 +++++++ src/gallium/drivers/vc4/vc4_qir.c | 2 ++ src/gallium/drivers/vc4/vc4_qir.h | 3 +++ src/gallium/drivers/vc4/vc4_qpu_emit.c | 8 ++++++++ src/gallium/drivers/vc4/vc4_qpu_schedule.c | 4 ++++ 5 files changed, 24 insertions(+) diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 9c6e8647256..081adfd185c 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -1109,6 +1109,10 @@ emit_frag_end(struct vc4_compile *c) } } + if (c->output_sample_mask_index != -1) { + qir_MS_MASK(c, c->outputs[c->output_sample_mask_index]); + } + if (c->fs_key->depth_enabled) { struct qreg z; if (c->output_position_index != -1) { @@ -1359,6 +1363,9 @@ ntq_setup_outputs(struct vc4_compile *c) case FRAG_RESULT_DEPTH: c->output_position_index = loc; break; + case FRAG_RESULT_SAMPLE_MASK: + c->output_sample_mask_index = loc; + break; } } else { switch (var->data.location) { diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index f2855e159fc..4c6667a9d9f 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -87,6 +87,7 @@ static const struct qir_op_info qir_op_info[] = { [QOP_TLB_Z_WRITE] = { "tlb_z", 0, 1, true }, [QOP_TLB_COLOR_WRITE] = { "tlb_color", 0, 1, true }, [QOP_TLB_COLOR_READ] = { "tlb_color_read", 1, 0 }, + [QOP_MS_MASK] = { "ms_mask", 0, 1, true }, [QOP_VARY_ADD_C] = { "vary_add_c", 1, 1 }, [QOP_FRAG_X] = { "frag_x", 1, 0 }, @@ -399,6 +400,7 @@ qir_compile_init(void) c->output_position_index = -1; c->output_color_index = -1; c->output_point_size_index = -1; + c->output_sample_mask_index = -1; c->def_ht = _mesa_hash_table_create(c, _mesa_hash_pointer, _mesa_key_pointer_equal); diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index ad243ec1113..97a23df10c6 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -122,6 +122,7 @@ enum qop { QOP_TLB_Z_WRITE, QOP_TLB_COLOR_WRITE, QOP_TLB_COLOR_READ, + QOP_MS_MASK, QOP_VARY_ADD_C, QOP_FRAG_X, @@ -397,6 +398,7 @@ struct vc4_compile { uint32_t output_position_index; uint32_t output_color_index; uint32_t output_point_size_index; + uint32_t output_sample_mask_index; struct qreg undef; enum qstage stage; @@ -620,6 +622,7 @@ QIR_NODST_1(TLB_COLOR_WRITE) QIR_NODST_1(TLB_Z_WRITE) QIR_NODST_1(TLB_DISCARD_SETUP) QIR_NODST_1(TLB_STENCIL_SETUP) +QIR_NODST_1(MS_MASK) static inline struct qreg qir_UNPACK_8_F(struct vc4_compile *c, struct qreg src, int i) diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c index e0d3633da42..a3d1627156f 100644 --- a/src/gallium/drivers/vc4/vc4_qpu_emit.c +++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c @@ -387,6 +387,14 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c) qpu_rb(QPU_R_MS_REV_FLAGS))); break; + case QOP_MS_MASK: + src[1] = qpu_ra(QPU_R_MS_REV_FLAGS); + fixup_raddr_conflict(c, dst, &src[0], &src[1], + qinst, &unpack); + queue(c, qpu_a_AND(qpu_ra(QPU_W_MS_FLAGS), + src[0], src[1]) | unpack); + break; + case QOP_FRAG_Z: case QOP_FRAG_W: /* QOP_FRAG_Z/W don't emit instructions, just allocate diff --git a/src/gallium/drivers/vc4/vc4_qpu_schedule.c b/src/gallium/drivers/vc4/vc4_qpu_schedule.c index 19cbf7bb98c..94303d942ec 100644 --- a/src/gallium/drivers/vc4/vc4_qpu_schedule.c +++ b/src/gallium/drivers/vc4/vc4_qpu_schedule.c @@ -295,6 +295,10 @@ process_waddr_deps(struct schedule_state *state, struct schedule_node *n, add_write_dep(state, &state->last_tlb, n); break; + case QPU_W_MS_FLAGS: + add_write_dep(state, &state->last_tlb, n); + break; + case QPU_W_NOP: break; -- 2.30.2