diff options
author | Russell King <rmk@arm.linux.org.uk> | 2014-08-03 12:46:47 +0100 |
---|---|---|
committer | Russell King <rmk@arm.linux.org.uk> | 2014-08-03 12:49:36 +0100 |
commit | c8439dcebaf0b8bcdd2cf2a2750d6ae84af5d1fd (patch) | |
tree | 66a8d048a9ba4f9b99a4e21552d4ef6640fae19d /src | |
parent | 00dff49e13c46517e005611a18f9a846528640d5 (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/vivante_accel.c | 18 |
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; |