diff options
author | George Fufutos <fufutos610@hotmail.com> | 2006-04-27 18:50:42 +0300 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2006-04-27 21:25:21 +0200 |
commit | 3543804ce78d93510ec3f066a5824f81a8d7860c (patch) | |
tree | 81156229e5093ede3a707213050bb30f2e67664a | |
parent | 1d68ebca639b50a4f50d649567dbe62d5c9754d7 (diff) |
[PATCH] Fix EXA for pixmaps with depth other than the native framebuffer depth.
This case comes up with the "smart" migration scheme and requires to set the
DP_PIX_WIDTH register to the depth of the pixmap.
-rw-r--r-- | src/atimach64accel.c | 3 | ||||
-rw-r--r-- | src/atimach64exa.c | 204 |
2 files changed, 148 insertions, 59 deletions
diff --git a/src/atimach64accel.c b/src/atimach64accel.c index dead1a1..fdb8ee3 100644 --- a/src/atimach64accel.c +++ b/src/atimach64accel.c @@ -220,6 +220,7 @@ ATIMach64Sync UncacheRegister(DP_BKGD_CLR); UncacheRegister(DP_FRGD_CLR); UncacheRegister(DP_WRITE_MASK); + UncacheRegister(DP_PIX_WIDTH); UncacheRegister(DP_MIX); UncacheRegister(CLR_CMP_CNTL); } @@ -265,6 +266,7 @@ ATIMach64Sync CacheRegister(DP_BKGD_CLR); CacheRegister(DP_FRGD_CLR); CacheRegister(DP_WRITE_MASK); + CacheRegister(DP_PIX_WIDTH); CacheRegister(DP_MIX); CacheRegister(CLR_CMP_CNTL); } @@ -326,6 +328,7 @@ ATIMach64Sync TestRegisterCaching(DP_BKGD_CLR); TestRegisterCaching(DP_FRGD_CLR); TestRegisterCaching(DP_WRITE_MASK); + TestRegisterCaching(DP_PIX_WIDTH); TestRegisterCaching(DP_MIX); TestRegisterCaching(CLR_CMP_CLR); diff --git a/src/atimach64exa.c b/src/atimach64exa.c index cab8c4e..bea30e8 100644 --- a/src/atimach64exa.c +++ b/src/atimach64exa.c @@ -82,17 +82,93 @@ ATIMach64ValidateClip int sc_bottom ); +#define PATI_FROM_SCREEN(_pScreen) \ + ScrnInfoPtr pScreenInfo = xf86Screens[_pScreen->myNum]; \ + ATIPtr pATI = ATIPTR(pScreenInfo); + +#if 0 +#define MACH64_TRACE(x) \ +do { \ + ErrorF("Mach64(%s): ", __FUNCTION__); \ + ErrorF x; \ +} while(0) +#else +#define MACH64_TRACE(x) do { } while(0) +#endif + +#if 0 +#define MACH64_FALLBACK(x) \ +do { \ + ErrorF("Fallback(%s): ", __FUNCTION__); \ + ErrorF x; \ + return FALSE; \ +} while (0) +#else +#define MACH64_FALLBACK(x) return FALSE +#endif + static void -ATIMach64WaitMarker(ScreenPtr pScreenInfo, int Marker) +Mach64WaitMarker(ScreenPtr pScreenInfo, int Marker) { ATIMach64Sync(xf86Screens[pScreenInfo->myNum]); } -static void -ATIGetOffsetPitch(int bpp, CARD32 *pitch_offset, int offset, int pitch) +static Bool +Mach64GetDatatypeBpp(PixmapPtr pPix, CARD32 *pix_width) { - if (bpp == 24) - bpp = 8; + int bpp = pPix->drawable.bitsPerPixel; + + switch (bpp) { + case 8: + *pix_width = + SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + case 16: + *pix_width = + SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + case 24: + *pix_width = + SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + case 32: + *pix_width = + SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + default: + MACH64_FALLBACK(("Unsupported bpp: %d\n", bpp)); + } + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + + *pix_width |= DP_BYTE_PIX_ORDER; + +#endif /* X_BYTE_ORDER */ + + return TRUE; +} + +static Bool +Mach64GetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset, + unsigned int offset, unsigned int pitch) +{ +#if 0 + PATI_FROM_SCREEN(pPix->drawable.pScreen); + + if (pitch % pATI->pExa->pixmapPitchAlign != 0) + MACH64_FALLBACK(("Bad pitch 0x%08x\n", pitch)); + + if (offset % pATI->pExa->pixmapOffsetAlign != 0) + MACH64_FALLBACK(("Bad offset 0x%08x\n", offset)); +#endif /* pixels / 8 = ((bytes * 8) / bpp) / 8 = bytes / bpp */ pitch = pitch / bpp; @@ -100,29 +176,29 @@ ATIGetOffsetPitch(int bpp, CARD32 *pitch_offset, int offset, int pitch) /* bytes / 8 */ offset = offset >> 3; - *pitch_offset = ((pitch << 22) | /* USR1_DST_PITCH */ - (offset << 0) | /* USR1_DST_OFFSET */ - 0); + *pitch_offset = ((pitch << 22) | (offset << 0)); + + return TRUE; } static Bool -ATIGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset) +Mach64GetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset) { CARD32 pitch, offset; int bpp; bpp = pPix->drawable.bitsPerPixel; + if (bpp == 24) + bpp = 8; pitch = exaGetPixmapPitch(pPix); offset = exaGetPixmapOffset(pPix); - ATIGetOffsetPitch(bpp, pitch_offset, offset, pitch); - - return TRUE; + return Mach64GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); } static Bool -ATIMach64PrepareCopy +Mach64PrepareCopy ( PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, @@ -132,18 +208,23 @@ ATIMach64PrepareCopy Pixel planemask ) { - ScrnInfoPtr pScreenInfo = xf86Screens[pSrcPixmap->drawable.pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - CARD32 src_pitch_offset, dst_pitch_offset; + PATI_FROM_SCREEN(pDstPixmap->drawable.pScreen); + CARD32 src_pitch_offset, dst_pitch_offset, dp_pix_width; ATIDRISync(pScreenInfo); - ATIGetPixmapOffsetPitch(pSrcPixmap,&src_pitch_offset); - ATIGetPixmapOffsetPitch(pDstPixmap,&dst_pitch_offset); - ATIMach64WaitForFIFO(pATI, 5); + if (!Mach64GetDatatypeBpp(pDstPixmap, &dp_pix_width)) + return FALSE; + if (!Mach64GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) + return FALSE; + if (!Mach64GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) + return FALSE; + + ATIMach64WaitForFIFO(pATI, 7); outf(DP_WRITE_MASK, planemask); - outf(SRC_OFF_PITCH,src_pitch_offset); - outf(DST_OFF_PITCH,dst_pitch_offset); + outf(DP_PIX_WIDTH, dp_pix_width); + outf(SRC_OFF_PITCH, src_pitch_offset); + outf(DST_OFF_PITCH, dst_pitch_offset); outf(DP_SRC, DP_MONO_SRC_ALLONES | SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); @@ -167,7 +248,7 @@ ATIMach64PrepareCopy } static void -ATIMach64Copy +Mach64Copy ( PixmapPtr pDstPixmap, int srcX, @@ -178,8 +259,7 @@ ATIMach64Copy int h ) { - ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); + PATI_FROM_SCREEN(pDstPixmap->drawable.pScreen); srcX *= pATI->XModifier; dstY *= pATI->XModifier; @@ -212,11 +292,10 @@ ATIMach64Copy outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); } -static void -ATIMach64DoneCopy(PixmapPtr pDstPixmap) { } +static void Mach64DoneCopy(PixmapPtr pDstPixmap) { } static Bool -ATIMach64PrepareSolid +Mach64PrepareSolid ( PixmapPtr pPixmap, int alu, @@ -224,17 +303,21 @@ ATIMach64PrepareSolid Pixel fg ) { - ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - - CARD32 dst_pitch_offset; + PATI_FROM_SCREEN(pPixmap->drawable.pScreen); + CARD32 dst_pitch_offset, dp_pix_width; ATIDRISync(pScreenInfo); - - ATIGetPixmapOffsetPitch(pPixmap,&dst_pitch_offset); - ATIMach64WaitForFIFO(pATI, 6); + + if (!Mach64GetDatatypeBpp(pPixmap, &dp_pix_width)) + return FALSE; + if (!Mach64GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) + return FALSE; + + ATIMach64WaitForFIFO(pATI, 7); outf(DP_WRITE_MASK, planemask); - outf(DST_OFF_PITCH,dst_pitch_offset); + outf(DP_PIX_WIDTH, dp_pix_width); + outf(DST_OFF_PITCH, dst_pitch_offset); + outf(DP_SRC, DP_MONO_SRC_ALLONES | SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); outf(DP_FRGD_CLR, fg); @@ -244,11 +327,12 @@ ATIMach64PrepareSolid if (pATI->XModifier == 1) outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); + return TRUE; } static void -ATIMach64Solid +Mach64Solid ( PixmapPtr pPixmap, int x1, @@ -257,12 +341,12 @@ ATIMach64Solid int y2 ) { + PATI_FROM_SCREEN(pPixmap->drawable.pScreen); + int x = x1; int y = y1; int w = x2-x1; int h = y2-y1; - ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); ATIDRISync(pScreenInfo); @@ -283,12 +367,10 @@ ATIMach64Solid outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); } -static void -ATIMach64DoneSolid(PixmapPtr pPixmap) { } +static void Mach64DoneSolid(PixmapPtr pPixmap) { } /* Compute log base 2 of val. */ -static __inline__ int -ATILog2(int val) +static __inline__ int Mach64Log2(int val) { int bits; @@ -310,10 +392,9 @@ ATILog2(int val) * "c" is the hw cursor which occupies 1KB */ static void -ATIMach64SetupMemEXA(ScreenPtr pScreen) +Mach64SetupMemEXA(ScreenPtr pScreen) { - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); + PATI_FROM_SCREEN(pScreen); int cpp = (pScreenInfo->bitsPerPixel + 7) / 8; /* front and back buffer */ @@ -386,7 +467,7 @@ ATIMach64SetupMemEXA(ScreenPtr pScreen) if (textureSize > 0) { - int l = ATILog2(textureSize / MACH64_NR_TEX_REGIONS); + int l = Mach64Log2(textureSize / MACH64_NR_TEX_REGIONS); if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY; pATIDRIServer->logTextureGranularity = l; @@ -476,8 +557,8 @@ ATIMach64SetupMemEXA(ScreenPtr pScreen) /* FIXME: set to 64 if that helps for hostdata blits or textures */ /* FIXME: must be multiple of 8 pixels; 32 is ok for 16bpp, 32bpp */ - pExa->pixmapOffsetAlign = 64; - pExa->pixmapPitchAlign = 64; + pExa->pixmapOffsetAlign = 32; + pExa->pixmapPitchAlign = 32; pExa->flags = EXA_OFFSCREEN_PIXMAPS; @@ -487,8 +568,7 @@ ATIMach64SetupMemEXA(ScreenPtr pScreen) Bool ATIMach64ExaInit(ScreenPtr pScreen) { - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); + PATI_FROM_SCREEN(pScreen); ExaDriverPtr pExa; /* FIXME: which chips support EXA ? */ @@ -509,18 +589,24 @@ Bool ATIMach64ExaInit(ScreenPtr pScreen) pExa->exa_major = 2; pExa->exa_minor = 0; - ATIMach64SetupMemEXA(pScreen); + Mach64SetupMemEXA(pScreen); - pExa->WaitMarker = ATIMach64WaitMarker; + pExa->WaitMarker = Mach64WaitMarker; - pExa->PrepareSolid = ATIMach64PrepareSolid; - pExa->Solid = ATIMach64Solid; - pExa->DoneSolid = ATIMach64DoneSolid; + pExa->PrepareSolid = Mach64PrepareSolid; + pExa->Solid = Mach64Solid; + pExa->DoneSolid = Mach64DoneSolid; - pExa->PrepareCopy = ATIMach64PrepareCopy; - pExa->Copy = ATIMach64Copy; - pExa->DoneCopy = ATIMach64DoneCopy; + pExa->PrepareCopy = Mach64PrepareCopy; + pExa->Copy = Mach64Copy; + pExa->DoneCopy = Mach64DoneCopy; - return exaDriverInit(pScreen, pATI->pExa); + if (!exaDriverInit(pScreen, pATI->pExa)) { + xfree(pATI->pExa); + pATI->pExa = NULL; + return FALSE; + } + + return TRUE; } #endif |