diff options
author | George Fufutos <fufutos610@hotmail.com> | 2006-05-06 00:15:51 +0300 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2006-05-07 20:21:03 +0200 |
commit | 6671b68b1add34f44e0246a4afeaef26146f2f48 (patch) | |
tree | b94f8673c4571ae162c48ac7996b40e139c1ad47 /src | |
parent | 701c58f3de6cac99236e0da89bd7574bd13fc224 (diff) |
[PATCH] Fix corruption when scaling 1-pixel wide pixmaps [1/1] (bug 807, Ivor Hewitt
ivor@ivor.org, Marc Aurele La France).
The problem shows itself when scaling a 1 pixel wide pixmap onto the screen,
the first CPU read of the framebuffer will return stale data.
Always invalidate the read-back (or read buffer) cache in ATIMach64Sync().
This bug always manifests itself in RENDER with EXA:
RENDER commonly uses 1x1 repeating pictures in composite operations. In some
cases it is possible to reduce the composite operation with 1x1 repeating
pictures to a solid operation. This solid operation gets accelerated and when
the pixmap is read back from the framebuffer corruption appears.
With this patch, mach64 EXA passes rendercheck.
Diffstat (limited to 'src')
-rw-r--r-- | src/atimach64accel.c | 105 |
1 files changed, 104 insertions, 1 deletions
diff --git a/src/atimach64accel.c b/src/atimach64accel.c index fdb8ee3..dc51249 100644 --- a/src/atimach64accel.c +++ b/src/atimach64accel.c @@ -353,7 +353,110 @@ ATIMach64Sync * caching of framebuffer data I haven't found any way of disabling, or * otherwise circumventing. Thanks to Mark Vojkovich for the suggestion. */ - pATI = *(volatile ATIPtr *)pATI->pMemory; + if (pATI->Chip >= ATI_CHIP_264VTB) + { + /* + * Flush the read-back cache (by turning on INVALIDATE_RB_CACHE), + * otherwise the host might get stale data when reading through the + * aperture. + */ + outr(MEM_BUF_CNTL, pATI->NewHW.mem_buf_cntl); + } + + if (!pATI->OptionMMIOCache || !pATI->OptionTestMMIOCache) + return; + + /* + * For debugging purposes, attempt to verify that each cached register + * should actually be cached. + */ + TestRegisterCaching(SRC_CNTL); + + TestRegisterCaching(HOST_CNTL); + + TestRegisterCaching(PAT_REG0); + TestRegisterCaching(PAT_REG1); + TestRegisterCaching(PAT_CNTL); + + if (RegisterIsCached(SC_LEFT_RIGHT) && /* Special case */ + (CacheSlot(SC_LEFT_RIGHT) != + (SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0)))) + { + UncacheRegister(SC_LEFT_RIGHT); + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, + "SC_LEFT_RIGHT write cache disabled!\n"); + } + + if (RegisterIsCached(SC_TOP_BOTTOM) && /* Special case */ + (CacheSlot(SC_TOP_BOTTOM) != + (SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0)))) + { + UncacheRegister(SC_TOP_BOTTOM); + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, + "SC_TOP_BOTTOM write cache disabled!\n"); + } + + TestRegisterCaching(DP_BKGD_CLR); + TestRegisterCaching(DP_FRGD_CLR); + TestRegisterCaching(DP_WRITE_MASK); + TestRegisterCaching(DP_MIX); + + TestRegisterCaching(CLR_CMP_CLR); + TestRegisterCaching(CLR_CMP_MSK); + TestRegisterCaching(CLR_CMP_CNTL); + + if (!pATI->Block1Base) + return; + + TestRegisterCaching(OVERLAY_Y_X_START); + TestRegisterCaching(OVERLAY_Y_X_END); + + TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR); + TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK); + + TestRegisterCaching(OVERLAY_KEY_CNTL); + + TestRegisterCaching(OVERLAY_SCALE_INC); + TestRegisterCaching(OVERLAY_SCALE_CNTL); + + TestRegisterCaching(SCALER_HEIGHT_WIDTH); + + TestRegisterCaching(SCALER_TEST); + + TestRegisterCaching(VIDEO_FORMAT); + + if (pATI->Chip < ATI_CHIP_264VTB) + { + TestRegisterCaching(BUF0_OFFSET); + TestRegisterCaching(BUF0_PITCH); + TestRegisterCaching(BUF1_OFFSET); + TestRegisterCaching(BUF1_PITCH); + + return; + } + + TestRegisterCaching(SCALER_BUF0_OFFSET); + TestRegisterCaching(SCALER_BUF1_OFFSET); + TestRegisterCaching(SCALER_BUF_PITCH); + + TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ); + TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT); + + if (pATI->Chip < ATI_CHIP_264GTPRO) + return; + + TestRegisterCaching(SCALER_COLOUR_CNTL); + + TestRegisterCaching(SCALER_H_COEFF0); + TestRegisterCaching(SCALER_H_COEFF1); + TestRegisterCaching(SCALER_H_COEFF2); + TestRegisterCaching(SCALER_H_COEFF3); + TestRegisterCaching(SCALER_H_COEFF4); + + TestRegisterCaching(SCALER_BUF0_OFFSET_U); + TestRegisterCaching(SCALER_BUF0_OFFSET_V); + TestRegisterCaching(SCALER_BUF1_OFFSET_U); + TestRegisterCaching(SCALER_BUF1_OFFSET_V); } #ifdef USE_XAA |