v3d: Add proper support for GL_EXT_draw_buffers2's blending enables.
authorEric Anholt <eric@anholt.net>
Tue, 3 Jul 2018 23:24:35 +0000 (16:24 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 5 Jul 2018 19:39:36 +0000 (12:39 -0700)
I had flagged it as enabled on V3D 4.x, but not actually implemented the
per-RT enables.  Fixes piglit fbo_drawbuffers2-blend.

src/gallium/drivers/v3d/v3d_context.h
src/gallium/drivers/v3d/v3d_program.c
src/gallium/drivers/v3d/v3dx_emit.c
src/gallium/drivers/v3d/v3dx_state.c

index 7c920dbc3db380683d37bc3064c82efda172b65d..dea9f9f3d2cfcd9337ef38cd93de470af5ca2087 100644 (file)
@@ -375,7 +375,7 @@ struct v3d_context {
 
         /** @{ Current pipeline state objects */
         struct pipe_scissor_state scissor;
-        struct pipe_blend_state *blend;
+        struct v3d_blend_state *blend;
         struct v3d_rasterizer_state *rasterizer;
         struct v3d_depth_stencil_alpha_state *zsa;
 
@@ -454,6 +454,13 @@ struct v3d_depth_stencil_alpha_state {
         uint8_t stencil_back[6];
 };
 
+struct v3d_blend_state {
+        struct pipe_blend_state base;
+
+        /* Per-RT mask of whether blending is enabled. */
+        uint8_t blend_enables;
+};
+
 #define perf_debug(...) do {                            \
         if (unlikely(V3D_DEBUG & V3D_DEBUG_PERF))       \
                 fprintf(stderr, __VA_ARGS__);           \
index c67104df234804d7fb96141f46aaf06b6817f18f..b5742b3bb1e9ca395972a8ba052fa7333fbaa7d0 100644 (file)
@@ -414,8 +414,8 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
         key->is_lines = (prim_mode >= PIPE_PRIM_LINES &&
                          prim_mode <= PIPE_PRIM_LINE_STRIP);
         key->clamp_color = v3d->rasterizer->base.clamp_fragment_color;
-        if (v3d->blend->logicop_enable) {
-                key->logicop_func = v3d->blend->logicop_func;
+        if (v3d->blend->base.logicop_enable) {
+                key->logicop_func = v3d->blend->base.logicop_func;
         } else {
                 key->logicop_func = PIPE_LOGICOP_COPY;
         }
@@ -423,8 +423,8 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
                 key->msaa = v3d->rasterizer->base.multisample;
                 key->sample_coverage = (v3d->rasterizer->base.multisample &&
                                         v3d->sample_mask != (1 << VC5_MAX_SAMPLES) - 1);
-                key->sample_alpha_to_coverage = v3d->blend->alpha_to_coverage;
-                key->sample_alpha_to_one = v3d->blend->alpha_to_one;
+                key->sample_alpha_to_coverage = v3d->blend->base.alpha_to_coverage;
+                key->sample_alpha_to_one = v3d->blend->base.alpha_to_one;
         }
 
         key->depth_enabled = (v3d->zsa->base.depth.enabled ||
index 03e47d6615627ac38c18c89361bcf08fbded8bf1..78edf02d79a138e09c0a7c1fda5bb14a6b1dca03 100644 (file)
@@ -400,7 +400,7 @@ v3dX(emit_state)(struct pipe_context *pctx)
                         config.direct3d_provoking_vertex =
                                 v3d->rasterizer->base.flatshade_first;
 
-                        config.blend_enable = v3d->blend->rt[0].blend_enable;
+                        config.blend_enable = v3d->blend->blend_enables;
 
                         /* Note: EZ state may update based on the compiled FS,
                          * along with ZSA
@@ -481,19 +481,27 @@ v3dX(emit_state)(struct pipe_context *pctx)
                 }
         }
 
-        if (v3d->dirty & VC5_DIRTY_BLEND && v3d->blend->rt[0].blend_enable) {
-                struct pipe_blend_state *blend = v3d->blend;
+        if (v3d->dirty & VC5_DIRTY_BLEND) {
+                struct v3d_blend_state *blend = v3d->blend;
 
-                if (blend->independent_blend_enable) {
-                        for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++)
-                                emit_rt_blend(v3d, job, blend, i);
-                } else {
-                        emit_rt_blend(v3d, job, blend, 0);
+                if (blend->blend_enables) {
+#if V3D_VERSION >= 40
+                        cl_emit(&job->bcl, BLEND_ENABLES, enables) {
+                                enables.mask = blend->blend_enables;
+                        }
+#endif
+
+                        if (blend->base.independent_blend_enable) {
+                                for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++)
+                                        emit_rt_blend(v3d, job, &blend->base, i);
+                        } else {
+                                emit_rt_blend(v3d, job, &blend->base, 0);
+                        }
                 }
         }
 
         if (v3d->dirty & VC5_DIRTY_BLEND) {
-                struct pipe_blend_state *blend = v3d->blend;
+                struct pipe_blend_state *blend = &v3d->blend->base;
 
                 cl_emit(&job->bcl, COLOUR_WRITE_MASKS, mask) {
                         for (int i = 0; i < 4; i++) {
index c0f43d800eabec46bedfa6da497f2a5df441d1c0..ff1c4b52125e2b67ef91d50980f299babfdf39b7 100644 (file)
 #include "broadcom/common/v3d_macros.h"
 #include "broadcom/cle/v3dx_pack.h"
 
-static void *
-v3d_generic_cso_state_create(const void *src, uint32_t size)
-{
-        void *dst = calloc(1, size);
-        if (!dst)
-                return NULL;
-        memcpy(dst, src, size);
-        return dst;
-}
-
 static void
 v3d_generic_cso_state_delete(struct pipe_context *pctx, void *hwcso)
 {
@@ -128,7 +118,23 @@ static void *
 v3d_create_blend_state(struct pipe_context *pctx,
                        const struct pipe_blend_state *cso)
 {
-        return v3d_generic_cso_state_create(cso, sizeof(*cso));
+        struct v3d_blend_state *so;
+
+        so = CALLOC_STRUCT(v3d_blend_state);
+        if (!so)
+                return NULL;
+
+        so->base = *cso;
+
+        for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
+                so->blend_enables |= cso->rt[i].blend_enable << i;
+
+                /* V3D 4.x is when we got independent blend enables. */
+                assert(V3D_VERSION >= 40 ||
+                       cso->rt[i].blend_enable == cso->rt[0].blend_enable);
+        }
+
+        return so;
 }
 
 static uint32_t