summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2016-11-22 12:44:18 +0100
committerRussell King <rmk@armlinux.org.uk>2016-11-22 16:46:53 +0000
commit53e70fcf904a2d5c4714383dedf4844cb634eca6 (patch)
tree6899ac207fdf292f9839099eaa148b55ff96cf8c
parentb12b32ce835ce3bf90cc76b53158c9f00a6e3192 (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.c68
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, &copy_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