From 61bb0df60e08d0b5707879c49beed899d46eaf9a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Oct 2017 14:41:35 -0700 Subject: [PATCH] broadcom/vc5: Do BGRA vs RGBA swapping for the BLEND_CONSTANT_COLOR. Fixes many of the fbo-blending-formats tests. --- src/gallium/drivers/vc5/vc5_context.h | 8 ++++++++ src/gallium/drivers/vc5/vc5_emit.c | 9 ++++++--- src/gallium/drivers/vc5/vc5_program.c | 9 +-------- src/gallium/drivers/vc5/vc5_state.c | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h index a1017bd1a6a..99d170b7dc0 100644 --- a/src/gallium/drivers/vc5/vc5_context.h +++ b/src/gallium/drivers/vc5/vc5_context.h @@ -337,6 +337,14 @@ struct vc5_context { struct pipe_stencil_ref stencil_ref; unsigned sample_mask; struct pipe_framebuffer_state framebuffer; + + /* Per render target, whether we should swap the R and B fields in the + * shader's color output and in blending. If render targets disagree + * on the R/B swap and use the constant color, then we would need to + * fall back to in-shader blending. + */ + uint8_t swap_color_rb; + struct pipe_poly_stipple stipple; struct pipe_clip_state clip; struct pipe_viewport_state viewport; diff --git a/src/gallium/drivers/vc5/vc5_emit.c b/src/gallium/drivers/vc5/vc5_emit.c index 9b5d293079c..1368d34729a 100644 --- a/src/gallium/drivers/vc5/vc5_emit.c +++ b/src/gallium/drivers/vc5/vc5_emit.c @@ -360,10 +360,13 @@ vc5_emit_state(struct pipe_context *pctx) if (vc5->dirty & VC5_DIRTY_BLEND_COLOR) { cl_emit(&job->bcl, BLEND_CONSTANT_COLOUR, colour) { - /* XXX: format-dependent swizzling */ - colour.red_f16 = vc5->blend_color.hf[2]; + colour.red_f16 = (vc5->swap_color_rb ? + vc5->blend_color.hf[2] : + vc5->blend_color.hf[0]); colour.green_f16 = vc5->blend_color.hf[1]; - colour.blue_f16 = vc5->blend_color.hf[0]; + colour.blue_f16 = (vc5->swap_color_rb ? + vc5->blend_color.hf[0] : + vc5->blend_color.hf[2]); colour.alpha_f16 = vc5->blend_color.hf[3]; } } diff --git a/src/gallium/drivers/vc5/vc5_program.c b/src/gallium/drivers/vc5/vc5_program.c index 7463709aa5c..cf2d1b830b8 100644 --- a/src/gallium/drivers/vc5/vc5_program.c +++ b/src/gallium/drivers/vc5/vc5_program.c @@ -365,20 +365,13 @@ vc5_update_compiled_fs(struct vc5_context *vc5, uint8_t prim_mode) * there are means that the buffer count needs to be in the key. */ key->nr_cbufs = vc5->framebuffer.nr_cbufs; + key->swap_color_rb = vc5->swap_color_rb; for (int i = 0; i < key->nr_cbufs; i++) { struct pipe_surface *cbuf = vc5->framebuffer.cbufs[i]; const struct util_format_description *desc = util_format_description(cbuf->format); - /* For BGRA8 formats (DRI window system default format), we - * need to swap R and B, since the HW's format is RGBA8. - */ - if (desc->swizzle[0] == PIPE_SWIZZLE_Z && - cbuf->format != PIPE_FORMAT_B5G6R5_UNORM) { - key->swap_color_rb |= 1 << i; - } - if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT && desc->channel[0].size == 32) { key->f32_color_rb |= 1 << i; diff --git a/src/gallium/drivers/vc5/vc5_state.c b/src/gallium/drivers/vc5/vc5_state.c index fc0e2874273..a7717b30dfb 100644 --- a/src/gallium/drivers/vc5/vc5_state.c +++ b/src/gallium/drivers/vc5/vc5_state.c @@ -388,6 +388,21 @@ vc5_set_framebuffer_state(struct pipe_context *pctx, cso->width = framebuffer->width; cso->height = framebuffer->height; + vc5->swap_color_rb = 0; + for (int i = 0; i < vc5->framebuffer.nr_cbufs; i++) { + struct pipe_surface *cbuf = vc5->framebuffer.cbufs[i]; + const struct util_format_description *desc = + util_format_description(cbuf->format); + + /* For BGRA8 formats (DRI window system default format), we + * need to swap R and B, since the HW's format is RGBA8. + */ + if (desc->swizzle[0] == PIPE_SWIZZLE_Z && + cbuf->format != PIPE_FORMAT_B5G6R5_UNORM) { + vc5->swap_color_rb |= 1 << i; + } + } + vc5->dirty |= VC5_DIRTY_FRAMEBUFFER; } -- 2.30.2