From 8644b59b5d98cf58deaecc583f68edd8be23bfca Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sun, 4 Jun 2017 21:06:32 +0200 Subject: etnaviv: mask correct channel for RB swapped rendertargets Now that we support RB swapped targets by using a shader variant, we must derive the color mask from both the blend state and the bound framebuffer. Fixes piglit: fbo-colormask-formats Fixes: 7f62ffb68ad ("etnaviv: add support for rb swap") Cc: mesa-stable@lists.freedesktop.org Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner --- src/gallium/drivers/etnaviv/etnaviv_blend.c | 48 +++++++++++++++++++++-------- src/gallium/drivers/etnaviv/etnaviv_blend.h | 7 +++++ src/gallium/drivers/etnaviv/etnaviv_state.c | 4 +++ 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_blend.c b/src/gallium/drivers/etnaviv/etnaviv_blend.c index ebef75daa7a..8ea09a37ae7 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blend.c +++ b/src/gallium/drivers/etnaviv/etnaviv_blend.c @@ -48,7 +48,7 @@ etna_blend_state_create(struct pipe_context *pctx, * - NOT source factor is ONE and destination factor ZERO for both rgb and * alpha (which would mean that blending is effectively disabled) */ - bool enable = rt0->blend_enable && + co->enable = rt0->blend_enable && !(rt0->rgb_src_factor == PIPE_BLENDFACTOR_ONE && rt0->rgb_dst_factor == PIPE_BLENDFACTOR_ZERO && rt0->alpha_src_factor == PIPE_BLENDFACTOR_ONE && @@ -59,17 +59,11 @@ etna_blend_state_create(struct pipe_context *pctx, * - NOT source factor is equal to destination factor for both rgb abd * alpha (which would effectively that mean alpha is not separate) */ - bool separate_alpha = enable && + bool separate_alpha = co->enable && !(rt0->rgb_src_factor == rt0->alpha_src_factor && rt0->rgb_dst_factor == rt0->alpha_dst_factor); - /* If the complete render target is written, set full_overwrite: - * - The color mask is 1111 - * - No blending is used - */ - bool full_overwrite = (rt0->colormask == 15) && !enable; - - if (enable) { + if (co->enable) { co->PE_ALPHA_CONFIG = VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR | COND(separate_alpha, VIVS_PE_ALPHA_CONFIG_BLEND_SEPARATE_ALPHA) | @@ -83,10 +77,6 @@ etna_blend_state_create(struct pipe_context *pctx, co->PE_ALPHA_CONFIG = 0; } - co->PE_COLOR_FORMAT = - VIVS_PE_COLOR_FORMAT_COMPONENTS(rt0->colormask) | - COND(full_overwrite, VIVS_PE_COLOR_FORMAT_OVERWRITE); - co->PE_LOGIC_OP = VIVS_PE_LOGIC_OP_OP(so->logicop_enable ? so->logicop_func : LOGIC_OP_COPY) | 0x000E4000 /* ??? */; @@ -107,3 +97,35 @@ etna_blend_state_create(struct pipe_context *pctx, return co; } + +bool +etna_update_blend(struct etna_context *ctx) +{ + struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s; + struct pipe_blend_state *pblend = ctx->blend; + struct etna_blend_state *blend = etna_blend_state(pblend); + const struct pipe_rt_blend_state *rt0 = &pblend->rt[0]; + uint32_t colormask; + + if (pfb->cbufs[0] && + translate_rs_format_rb_swap(pfb->cbufs[0]->texture->format)) { + colormask = rt0->colormask & (PIPE_MASK_A | PIPE_MASK_G); + if (rt0->colormask & PIPE_MASK_R) + colormask |= PIPE_MASK_B; + if (rt0->colormask & PIPE_MASK_B) + colormask |= PIPE_MASK_R; + } else { + colormask = rt0->colormask; + } + + /* If the complete render target is written, set full_overwrite: + * - The color mask is 1111 + * - No blending is used + */ + bool full_overwrite = (rt0->colormask == 0xf) && !blend->enable; + blend->PE_COLOR_FORMAT = + VIVS_PE_COLOR_FORMAT_COMPONENTS(colormask) | + COND(full_overwrite, VIVS_PE_COLOR_FORMAT_OVERWRITE); + + return true; +} diff --git a/src/gallium/drivers/etnaviv/etnaviv_blend.h b/src/gallium/drivers/etnaviv/etnaviv_blend.h index 54e7bab0f8a..e26864d409f 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blend.h +++ b/src/gallium/drivers/etnaviv/etnaviv_blend.h @@ -30,9 +30,13 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +struct etna_context; + struct etna_blend_state { struct pipe_blend_state base; + bool enable; + uint32_t PE_ALPHA_CONFIG; uint32_t PE_COLOR_FORMAT; uint32_t PE_LOGIC_OP; @@ -49,4 +53,7 @@ void * etna_blend_state_create(struct pipe_context *pctx, const struct pipe_blend_state *so); +bool +etna_update_blend(struct etna_context *ctx); + #endif diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index cd9f974112d..fb7bb0f4c50 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -29,6 +29,7 @@ #include "hw/common.xml.h" +#include "etnaviv_blend.h" #include "etnaviv_clear_blit.h" #include "etnaviv_context.h" #include "etnaviv_format.h" @@ -596,6 +597,9 @@ static const struct etna_state_updater etna_state_updates[] = { }, { etna_shader_link, ETNA_DIRTY_SHADER, + }, + { + etna_update_blend, ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER } }; -- cgit v1.2.3