From c8439dcebaf0b8bcdd2cf2a2750d6ae84af5d1fd Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Aug 2014 12:46:47 +0100 Subject: 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 --- src/vivante_accel.c | 18 +++++++++++++++--- 1 file 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; -- cgit