diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2016-11-22 12:44:18 +0100 |
---|---|---|
committer | Russell King <rmk@armlinux.org.uk> | 2016-11-22 16:46:53 +0000 |
commit | 53e70fcf904a2d5c4714383dedf4844cb634eca6 (patch) | |
tree | 6899ac207fdf292f9839099eaa148b55ff96cf8c | |
parent | b12b32ce835ce3bf90cc76b53158c9f00a6e3192 (diff) |
etnaviv: apply non-alpha workaround to temporary copy in acquire_src
The blit into the temporary pixmap needs the same workaround for
non-alpha formats as all other blits.
Found via rendercheck, the failing test reports on GC600:
InReverse composite test error of 255.0000 at (6, 3) --
R G B A
got: 0.000 0.000 0.000 0.000
expected: 1.000 1.000 1.000 1.000
src color: 1.00 1.00 1.00 1.00
msk color: 1.00 1.00 1.00 1.00
dst color: 1.00 1.00 1.00 1.00
src: 10x10 x8r8g8b8, mask: 10x10 a8r8g8b8, dst: a8r8g8b8
and GC320:
InReverse composite test error of 255.0000 at (6, 7) --
R G B A
got: 0.000 0.000 0.000 0.000
expected: 1.000 1.000 1.000 1.000
src color: 1.00 1.00 1.00 1.00
msk color: 1.00 1.00 1.00 1.00
dst color: 1.00 1.00 1.00 1.00
src: 10x10 b8g8r8x8, mask: 10x10 a8r8g8b8, dst: a8r8g8b8
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
[edited description to include details of the failure, dropped now
unnecessary format reset. --rmk]
Signed-off-by: Russell King <rmk@armlinux.org.uk>
-rw-r--r-- | etnaviv/etnaviv_render.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/etnaviv/etnaviv_render.c b/etnaviv/etnaviv_render.c index a131d1c..0fb3ac9 100644 --- a/etnaviv/etnaviv_render.c +++ b/etnaviv/etnaviv_render.c @@ -338,6 +338,35 @@ static Bool etnaviv_composite_to_pixmap(CARD8 op, PicturePtr pSrc, } /* + * There is a bug in the GPU hardware with destinations lacking alpha and + * swizzles BGRA/RGBA. Rather than the GPU treating bits 7:0 as alpha, it + * continues to treat bits 31:24 as alpha. This results in it replacing + * the B or R bits on input to the blend operation with 1.0. However, it + * continues to accept the non-existent source alpha from bits 31:24. + * + * Work around this by switching to the equivalent alpha format, and using + * global alpha to replace the alpha channel. The alpha channel subsitution + * is performed at this function's callsite. + */ +static Bool etnaviv_workaround_nonalpha(struct etnaviv_pixmap *vpix) +{ + switch (vpix->pict_format.format) { + case DE_FORMAT_X4R4G4B4: + vpix->pict_format.format = DE_FORMAT_A4R4G4B4; + return TRUE; + case DE_FORMAT_X1R5G5B5: + vpix->pict_format.format = DE_FORMAT_A1R5G5B5; + return TRUE; + case DE_FORMAT_X8R8G8B8: + vpix->pict_format.format = DE_FORMAT_A8R8G8B8; + return TRUE; + case DE_FORMAT_R5G6B5: + return TRUE; + } + return FALSE; +} + +/* * Acquire the source. If we're filling a solid surface, force it to have * alpha; it may be used in combination with a mask. Otherwise, we ask * for the plain source format, with or without alpha, and convert later @@ -350,6 +379,7 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen, { struct etnaviv *etnaviv = etnaviv_get_screen_priv(pScreen); struct etnaviv_pixmap *vSrc, *vTemp; + struct etnaviv_blend_op copy_op; DrawablePtr drawable; uint32_t colour; xPoint src_offset; @@ -413,7 +443,14 @@ copy_to_vtemp: if (!vTemp) return NULL; - if (!etnaviv_blend(etnaviv, clip, NULL, vTemp, vSrc, clip, 1, + copy_op = etnaviv_composite_op[PictOpSrc]; + + if (etnaviv_workaround_nonalpha(vSrc)) { + copy_op.alpha_mode |= VIVS_DE_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_GLOBAL; + copy_op.src_alpha = 255; + } + + if (!etnaviv_blend(etnaviv, clip, ©_op, vTemp, vSrc, clip, 1, *src_topleft, ZERO_OFFSET)) return NULL; @@ -423,35 +460,6 @@ copy_to_vtemp: } /* - * There is a bug in the GPU hardware with destinations lacking alpha and - * swizzles BGRA/RGBA. Rather than the GPU treating bits 7:0 as alpha, it - * continues to treat bits 31:24 as alpha. This results in it replacing - * the B or R bits on input to the blend operation with 1.0. However, it - * continues to accept the non-existent source alpha from bits 31:24. - * - * Work around this by switching to the equivalent alpha format, and using - * global alpha to replace the alpha channel. The alpha channel subsitution - * is performed at this function's callsite. - */ -static Bool etnaviv_workaround_nonalpha(struct etnaviv_pixmap *vpix) -{ - switch (vpix->pict_format.format) { - case DE_FORMAT_X4R4G4B4: - vpix->pict_format.format = DE_FORMAT_A4R4G4B4; - return TRUE; - case DE_FORMAT_X1R5G5B5: - vpix->pict_format.format = DE_FORMAT_A1R5G5B5; - return TRUE; - case DE_FORMAT_X8R8G8B8: - vpix->pict_format.format = DE_FORMAT_A8R8G8B8; - return TRUE; - case DE_FORMAT_R5G6B5: - return TRUE; - } - return FALSE; -} - -/* * Compute the regions (in destination pixmap coordinates) which need to * be composited. Each picture's pCompositeClip includes the drawable * position, so each position must be adjusted for its position on the |