From 572f6ab489db2d2311d89ab5910764ebb83cb49d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 3 Jul 2018 16:24:35 -0700 Subject: [PATCH] v3d: Add proper support for GL_EXT_draw_buffers2's blending enables. 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 | 9 ++++++++- src/gallium/drivers/v3d/v3d_program.c | 8 ++++---- src/gallium/drivers/v3d/v3dx_emit.c | 26 ++++++++++++++++--------- src/gallium/drivers/v3d/v3dx_state.c | 28 ++++++++++++++++----------- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index 7c920dbc3db..dea9f9f3d2c 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -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__); \ diff --git a/src/gallium/drivers/v3d/v3d_program.c b/src/gallium/drivers/v3d/v3d_program.c index c67104df234..b5742b3bb1e 100644 --- a/src/gallium/drivers/v3d/v3d_program.c +++ b/src/gallium/drivers/v3d/v3d_program.c @@ -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 || diff --git a/src/gallium/drivers/v3d/v3dx_emit.c b/src/gallium/drivers/v3d/v3dx_emit.c index 03e47d66156..78edf02d79a 100644 --- a/src/gallium/drivers/v3d/v3dx_emit.c +++ b/src/gallium/drivers/v3d/v3dx_emit.c @@ -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++) { diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index c0f43d800ea..ff1c4b52125 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -36,16 +36,6 @@ #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 -- 2.30.2