summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc5/vc5_context.h8
-rw-r--r--src/gallium/drivers/vc5/vc5_emit.c9
-rw-r--r--src/gallium/drivers/vc5/vc5_program.c9
-rw-r--r--src/gallium/drivers/vc5/vc5_state.c15
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;
}