summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2015-11-20 17:18:03 -0800
committerEric Anholt <[email protected]>2015-12-04 09:23:55 -0800
commit74c4b3b80cc4246fd1eb503d97edb3d293eef5de (patch)
tree8a2abe8d61c1bc772c249c2f78db25fb2bee8895 /src
parent3a508a0d94d020d9cd95f8882e9393d83ffac377 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c7
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.c2
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h3
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu_emit.c8
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu_schedule.c4
5 files changed, 24 insertions, 0 deletions
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;