freedreno/a6xx: disable LRZ when color channels are masked
[mesa.git] / src / gallium / drivers / freedreno / a6xx / fd6_blend.c
index 279f9ea551252f94c5fa7e616618d68263d68722..fe63be97fd5c83fd8d8dfff144716979c8d247f5 100644 (file)
@@ -78,7 +78,7 @@ __fd6_setup_blend_variant(struct fd6_blend_stateobj *blend, unsigned sample_mask
                        ((A6XX_MAX_RENDER_TARGETS * 4) + 6) * 4);
        so->stateobj = ring;
 
-       for (unsigned i = 0; i < A6XX_MAX_RENDER_TARGETS; i++) {
+       for (unsigned i = 0; i <= cso->max_rt; i++) {
                const struct pipe_rt_blend_state *rt;
 
                if (cso->independent_blend_enable)
@@ -132,6 +132,7 @@ __fd6_setup_blend_variant(struct fd6_blend_stateobj *blend, unsigned sample_mask
        OUT_REG(ring, A6XX_RB_BLEND_CNTL(
                        .enable_blend      = mrt_blend,
                        .alpha_to_coverage = cso->alpha_to_coverage,
+                       .alpha_to_one = cso->alpha_to_one,
                        .independent_blend = cso->independent_blend_enable,
                        .sample_mask       = sample_mask
                ));
@@ -148,11 +149,6 @@ fd6_blend_state_create(struct pipe_context *pctx,
                const struct pipe_blend_state *cso)
 {
        struct fd6_blend_stateobj *so;
-       bool reads_dest = false;
-
-       if (cso->logicop_enable) {
-               reads_dest = util_logicop_reads_dest(cso->logicop_func);
-       }
 
        so = rzalloc_size(NULL, sizeof(*so));
        if (!so)
@@ -160,21 +156,34 @@ fd6_blend_state_create(struct pipe_context *pctx,
 
        so->base = *cso;
        so->ctx = fd_context(pctx);
-       so->lrz_write = true;  /* unless blend enabled for any MRT */
 
-       unsigned nr = cso->independent_blend_enable ? A6XX_MAX_RENDER_TARGETS : 1;
-       for (unsigned i = 0; i < nr; i++) {
+       if (cso->logicop_enable) {
+               so->reads_dest |= util_logicop_reads_dest(cso->logicop_func);
+       }
+
+       unsigned nr = cso->independent_blend_enable ? cso->max_rt : 0;
+       for (unsigned i = 0; i <= nr; i++) {
                const struct pipe_rt_blend_state *rt = &cso->rt[i];
 
-               if (rt->blend_enable) {
-                       so->lrz_write = false;
+               so->reads_dest |= rt->blend_enable;
+
+               /* From the PoV of LRZ, having masked color channels is
+                * the same as having blend enabled, in that the draw will
+                * care about the fragments from an earlier draw.
+                *
+                * NOTE we actually don't care about masked color channels
+                * that don't actually exist in the render target, but we
+                * don't know the render target format here to determine
+                * that.  It is probably not worth worrying about, but if
+                * we find a game/benchmark that goes out of it's way to
+                * mask off non-existent channels, we should fixup the
+                * pipe_blend_state to give us more info.
+                */
+               if (rt->blend_enable || (rt->colormask != 0xf)) {
+                       so->reads_dest = true;
                }
        }
 
-       if (reads_dest) {
-               so->lrz_write = false;
-       }
-
        util_dynarray_init(&so->variants, so);
 
        return so;