summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Fufutos <fufutos610@hotmail.com>2006-04-27 18:50:42 +0300
committerLuc Verhaegen <libv@skynet.be>2006-04-27 21:25:21 +0200
commit3543804ce78d93510ec3f066a5824f81a8d7860c (patch)
tree81156229e5093ede3a707213050bb30f2e67664a
parent1d68ebca639b50a4f50d649567dbe62d5c9754d7 (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.c3
-rw-r--r--src/atimach64exa.c204
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