summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2014-08-03 12:46:47 +0100
committerRussell King <rmk@arm.linux.org.uk>2014-08-03 12:49:36 +0100
commitc8439dcebaf0b8bcdd2cf2a2750d6ae84af5d1fd (patch)
tree66a8d048a9ba4f9b99a4e21552d4ef6640fae19d
parent00dff49e13c46517e005611a18f9a846528640d5 (diff)
downloadxf86-video-armada-c8439dcebaf0b8bcdd2cf2a2750d6ae84af5d1fd.tar.gz
vivante: fix overlapping operations
Where the 2D engine has multiple pixel pipes, it is possible for two GPU operations to overlap and operate concurrently. If this occurs with an overlapping blit copy, one copying to the scanout buffer, and another copying from the scanout buffer, it results in corrupted pixel data read from the scanout buffer. This happens when software cursor mode is enabled with a GC320, as is the case with iMX6Q SoCs. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--src/vivante_accel.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/vivante_accel.c b/src/vivante_accel.c
index f30f8cf..82a7a58 100644
--- a/src/vivante_accel.c
+++ b/src/vivante_accel.c
@@ -339,6 +339,14 @@ gal_prepare_gpu(struct vivante *vivante, struct vivante_pixmap *vPix,
return TRUE;
}
+static void vivante_flush(struct vivante *vivante)
+{
+ gceSTATUS err = gco2D_Flush(vivante->e2d);
+
+ if (err != gcvSTATUS_OK)
+ vivante_error(vivante, "Flush", err);
+}
+
void vivante_commit(struct vivante *vivante, Bool stall)
{
gceSTATUS err;
@@ -348,9 +356,7 @@ void vivante_commit(struct vivante *vivante, Bool stall)
vivante_batch_commit(vivante);
#endif
- err = gco2D_Flush(vivante->e2d);
- if (err != gcvSTATUS_OK)
- vivante_error(vivante, "Flush", err);
+ vivante_flush(vivante);
err = gcoHAL_Commit(vivante->hal, stall ? gcvTRUE : gcvFALSE);
if (err != gcvSTATUS_OK)
@@ -503,6 +509,7 @@ static Bool vivante_fill(struct vivante *vivante, struct vivante_pixmap *vPix,
vivante_error(vivante, "Blit", err);
vivante_batch_add(vivante, vPix);
+ vivante_flush(vivante);
return TRUE;
}
@@ -762,6 +769,7 @@ void vivante_accel_CopyNtoN(DrawablePtr pSrc, DrawablePtr pDst,
vivante_batch_add(vivante, vSrc);
vivante_batch_add(vivante, vDst);
+ vivante_flush(vivante);
return;
@@ -981,6 +989,7 @@ Bool vivante_accel_PolyFillRectTiled(DrawablePtr pDrawable, GCPtr pGC, int n,
}
vivante_batch_add(vivante, vTile);
vivante_batch_add(vivante, vPix);
+ vivante_flush(vivante);
ret = err == 0 ? TRUE : FALSE;
} else {
ret = TRUE;
@@ -1184,6 +1193,7 @@ static Bool vivante_blend(struct vivante *vivante, gcsRECT_PTR clip,
vivante_batch_add(vivante, vDst);
vivante_batch_add(vivante, vSrc);
+ vivante_flush(vivante);
return TRUE;
}
@@ -1241,6 +1251,7 @@ static struct vivante_pixmap *vivante_acquire_src(struct vivante *vivante,
colour |= 0xff000000;
if (!vivante_fill_single(vivante, vTemp, clip, colour))
return NULL;
+ vivante_flush(vivante);
return vTemp;
}
@@ -1533,6 +1544,7 @@ fprintf(stderr, "%s: i: op 0x%02x src=%p,%d,%d mask=%p,%d,%d dst=%p,%d,%d %ux%u\
vTemp->pict_format = vivante_pict_format(pSrc->format, TRUE);
if (!vivante_fill_single(vivante, vTemp, &clipTemp, 0))
goto failed;
+ vivante_flush(vivante);
vSrc = vTemp;
xSrc = 0;
ySrc = 0;