summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2003-12-23 22:29:38 +0000
committerEric Anholt <anholt@freebsd.org>2003-12-23 22:29:38 +0000
commit92ab7214593061fa57d5cdd829dc98de6434ef7c (patch)
tree29de965d3e5b4de57f8235f3fb74bd6635a27c18
parentf5ccdc1618e58853ecc522f5b2c52c91787cb9e2 (diff)
- Implement acceleration of Composite on R128 when there is no mask, no
transformation, no repeat, and only certain ops are used. - Add debugging output for software fallbacks for Composite. - Allow pixmaps in offscreen that don't match root depth. - Clean up some mess in ati_reg.h. Many thanks to andersca for a lot of this code.
-rw-r--r--hw/kdrive/ati/Makefile.am1
-rw-r--r--hw/kdrive/ati/ati_draw.c64
-rw-r--r--hw/kdrive/ati/ati_drawtmp.h5
-rw-r--r--hw/kdrive/ati/ati_reg.h131
-rw-r--r--hw/kdrive/ati/r128_blendtmp.h119
-rw-r--r--hw/kdrive/src/kaa.c184
-rw-r--r--hw/kdrive/src/kdrive.h13
7 files changed, 469 insertions, 48 deletions
diff --git a/hw/kdrive/ati/Makefile.am b/hw/kdrive/ati/Makefile.am
index b7cb8896a..69c88f019 100644
--- a/hw/kdrive/ati/Makefile.am
+++ b/hw/kdrive/ati/Makefile.am
@@ -44,6 +44,7 @@ libati_a_SOURCES = \
ati.c \
ati.h \
ati_reg.h \
+ r128_blendtmp.h \
$(DRI_SOURCES)
Xati_SOURCES = \
diff --git a/hw/kdrive/ati/ati_draw.c b/hw/kdrive/ati/ati_draw.c
index c4835b958..6e8575ef7 100644
--- a/hw/kdrive/ati/ati_draw.c
+++ b/hw/kdrive/ati/ati_draw.c
@@ -73,9 +73,41 @@ CARD8 ATIBltRop[16] = {
/* GXset */ 0xff, /* 1 */
};
+static CARD32 R128BlendOp[] = {
+ /* Clear */
+ R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_ZERO,
+ /* Src */
+ R128_ALPHA_BLEND_SRC_ONE | R128_ALPHA_BLEND_DST_ZERO,
+ /* Dst */
+ R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_ONE,
+ /* Over */
+ R128_ALPHA_BLEND_SRC_ONE | R128_ALPHA_BLEND_DST_INVSRCALPHA,
+ /* OverReverse */
+ R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_ONE,
+ /* In */
+ R128_ALPHA_BLEND_SRC_DSTALPHA | R128_ALPHA_BLEND_DST_ZERO,
+ /* InReverse */
+ R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_SRCALPHA,
+ /* Out */
+ R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_ZERO,
+ /* OutReverse */
+ R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_INVSRCALPHA,
+ /* Atop */
+ R128_ALPHA_BLEND_SRC_DSTALPHA | R128_ALPHA_BLEND_DST_INVSRCALPHA,
+ /* AtopReverse */
+ R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_SRCALPHA,
+ /* Xor */
+ R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_INVSRCALPHA,
+ /* Add */
+ R128_ALPHA_BLEND_SRC_ONE | R128_ALPHA_BLEND_DST_ONE,
+};
+
int copydx, copydy;
int fifo_size;
ATIScreenInfo *accel_atis;
+int src_pitch;
+int src_offset;
+int src_bpp;
static void
ATIWaitAvailMMIO(int n)
@@ -313,14 +345,34 @@ drmBufPtr ATIDMAGetBuffer()
buf->used = 0;
return buf;
}
+#endif /* USE_DRI */
+
+static Bool
+R128GetDatatype(CARD32 format, CARD32 *type)
+{
+ switch (format) {
+ case PICT_a8r8g8b8:
+ *type = R128_DATATYPE_ARGB_8888;
+ return TRUE;
+ case PICT_r5g6b5:
+ *type = R128_DATATYPE_RGB_565;
+ return TRUE;
+ }
+
+ ErrorF ("Unsupported format: %x\n", format);
+ return FALSE;
+}
+
+#ifdef USE_DRI
#define USE_DMA
#include "ati_drawtmp.h"
-
+#include "r128_blendtmp.h"
#endif /* USE_DRI */
#undef USE_DMA
#include "ati_drawtmp.h"
+#include "r128_blendtmp.h"
static void
ATIDoneSolid(void)
@@ -385,6 +437,11 @@ ATIDrawInit(ScreenPtr pScreen)
atis->kaa.Solid = ATISolidDMA;
atis->kaa.PrepareCopy = ATIPrepareCopyDMA;
atis->kaa.Copy = ATICopyDMA;
+ if (!atic->is_radeon && !atis->is_24bpp) {
+ atis->kaa.PrepareBlend = R128PrepareBlendDMA;
+ atis->kaa.Blend = R128BlendDMA;
+ atis->kaa.DoneBlend = R128DoneBlendDMA;
+ }
} else {
#else
{
@@ -393,6 +450,11 @@ ATIDrawInit(ScreenPtr pScreen)
atis->kaa.Solid = ATISolidMMIO;
atis->kaa.PrepareCopy = ATIPrepareCopyMMIO;
atis->kaa.Copy = ATICopyMMIO;
+ if (!atic->is_radeon && !atis->is_24bpp) {
+ atis->kaa.PrepareBlend = R128PrepareBlendMMIO;
+ atis->kaa.Blend = R128BlendMMIO;
+ atis->kaa.DoneBlend = R128DoneBlendMMIO;
+ }
}
atis->kaa.DoneSolid = ATIDoneSolid;
atis->kaa.DoneCopy = ATIDoneCopy;
diff --git a/hw/kdrive/ati/ati_drawtmp.h b/hw/kdrive/ati/ati_drawtmp.h
index 890800d2a..6573aef68 100644
--- a/hw/kdrive/ati/ati_drawtmp.h
+++ b/hw/kdrive/ati/ati_drawtmp.h
@@ -25,7 +25,8 @@
#ifdef USE_DMA
#define TAG(x) x##DMA
-#define LOCALS RING_LOCALS
+#define LOCALS (void)atic; \
+ RING_LOCALS
#define BEGIN(x) BEGIN_RING(x * 2)
#define OUT_REG(reg, val) OUT_RING_REG(reg, val)
#define END() ADVANCE_RING()
@@ -43,7 +44,7 @@ TAG(ATISetup)(PixmapPtr pDst, PixmapPtr pSrc)
KdScreenPriv(pDst->drawable.pScreen);
ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
- int dst_offset, dst_pitch, src_offset = 0, src_pitch = 0;
+ int dst_offset, dst_pitch;
int bpp = pScreenPriv->screen->fb[0].bitsPerPixel;
LOCALS;
diff --git a/hw/kdrive/ati/ati_reg.h b/hw/kdrive/ati/ati_reg.h
index 776c5ed33..4b0341c3b 100644
--- a/hw/kdrive/ati/ati_reg.h
+++ b/hw/kdrive/ati/ati_reg.h
@@ -48,20 +48,23 @@
#define RADEON_REG_DST_Y_X 0x1438
#define RADEON_REG_DST_HEIGHT_WIDTH 0x143c
#define RADEON_REG_DP_GUI_MASTER_CNTL 0x146c
-#define RADEON_REG_DP_BRUSH_FRGD_CLR 0x147c
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4)
# define RADEON_GMC_BRUSH_NONE (15 << 4)
# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12)
# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24)
+# define RADEON_GMC_3D_FCN_EN (1 << 27)
# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28)
# define RADEON_GMC_AUX_CLIP_DIS (1 << 29)
+#define RADEON_REG_DP_BRUSH_FRGD_CLR 0x147c
+#define RADEON_REG_DST_WIDTH_HEIGHT 0x1598
+#define RADEON_REG_CLR_CMP_CNTL 0x15c0
+#define RADEON_REG_AUX_SC_CNTL 0x1660
#define RADEON_REG_DP_CNTL 0x16c0
# define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0)
# define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1)
-#define RADEON_REG_DST_WIDTH_HEIGHT 0x1598
-#define RADEON_REG_AUX_SC_CNTL 0x1660
+#define RADEON_REG_DP_MIX 0x16c8
#define RADEON_REG_DP_WRITE_MASK 0x16cc
#define RADEON_REG_DEFAULT_OFFSET 0x16e0
#define RADEON_REG_DEFAULT_PITCH 0x16e4
@@ -76,28 +79,112 @@
# define RADEON_RB2D_DC_FLUSH_ALL 0xf
# define RADEON_RB2D_DC_BUSY (1 << 31)
-#define RADEON_CP_PACKET0 0x00000000
-#define RADEON_CP_PACKET1 0x40000000
-#define RADEON_CP_PACKET2 0x80000000
+#define RADEON_CP_PACKET0 0x00000000
+#define RADEON_CP_PACKET1 0x40000000
+#define RADEON_CP_PACKET2 0x80000000
#define R128_REG_PC_NGUI_CTLSTAT 0x0184
# define R128_PC_BUSY (1 << 31)
+#define R128_REG_PCI_GART_PAGE 0x017c
+#define R128_REG_PC_NGUI_CTLSTAT 0x0184
+#define R128_REG_BM_CHUNK_0_VAL 0x0a18
+# define R128_BM_PTR_FORCE_TO_PCI (1 << 21)
+# define R128_BM_PM4_RD_FORCE_TO_PCI (1 << 22)
+# define R128_BM_GLOBAL_FORCE_TO_PCI (1 << 23)
#define R128_REG_GUI_STAT 0x1740
# define R128_GUI_ACTIVE (1 << 31)
-#define R128_REG_PCI_GART_PAGE 0x017c
-#define R128_REG_PC_NGUI_CTLSTAT 0x0184
-#define R128_REG_BM_CHUNK_0_VAL 0x0a18
-# define R128_BM_PTR_FORCE_TO_PCI (1 << 21)
-# define R128_BM_PM4_RD_FORCE_TO_PCI (1 << 22)
-# define R128_BM_GLOBAL_FORCE_TO_PCI (1 << 23)
+#define R128_REG_TEX_CNTL 0x1800
+
+#define R128_REG_SCALE_SRC_HEIGHT_WIDTH 0x1994
+#define R128_REG_SCALE_OFFSET_0 0x1998
+#define R128_REG_SCALE_PITCH 0x199c
+#define R128_REG_SCALE_X_INC 0x19a0
+#define R128_REG_SCALE_Y_INC 0x19a4
+#define R128_REG_SCALE_HACC 0x19a8
+#define R128_REG_SCALE_VACC 0x19ac
+#define R128_REG_SCALE_DST_X_Y 0x19b0
+#define R128_REG_SCALE_DST_HEIGHT_WIDTH 0x19b4
+#define R128_REG_SCALE_3D_CNTL 0x1a00
+# define R128_SCALE_DITHER_ERR_DIFF (0 << 1)
+# define R128_SCALE_DITHER_TABLE (1 << 1)
+# define R128_TEX_CACHE_SIZE_FULL (0 << 2)
+# define R128_TEX_CACHE_SIZE_HALF (1 << 2)
+# define R128_DITHER_INIT_CURR (0 << 3)
+# define R128_DITHER_INIT_RESET (1 << 3)
+# define R128_ROUND_24BIT (1 << 4)
+# define R128_TEX_CACHE_DISABLE (1 << 5)
+# define R128_SCALE_3D_NOOP (0 << 6)
+# define R128_SCALE_3D_SCALE (1 << 6)
+# define R128_SCALE_3D_TEXMAP_SHADE (2 << 6)
+# define R128_SCALE_PIX_BLEND (0 << 8)
+# define R128_SCALE_PIX_REPLICATE (1 << 8)
+# define R128_TEX_CACHE_SPLIT (1 << 9)
+# define R128_APPLE_YUV_MODE (1 << 10)
+# define R128_TEX_CACHE_PALLETE_MODE (1 << 11)
+# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12)
+# define R128_ALPHA_COMB_ADD_NCLAMP (1 << 12)
+# define R128_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12)
+# define R128_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12)
+# define R128_FOG_TABLE (1 << 14)
+# define R128_SIGNED_DST_CLAMP (1 << 15)
+# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16)
+# define R128_ALPHA_BLEND_SRC_ONE (1 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16)
+# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16)
+# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16)
+# define R128_ALPHA_BLEND_SRC_DSTALPHA (6 << 16)
+# define R128_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16)
+# define R128_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16)
+# define R128_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16)
+# define R128_ALPHA_BLEND_SRC_SAT (10 << 16)
+# define R128_ALPHA_BLEND_SRC_BLEND (11 << 16)
+# define R128_ALPHA_BLEND_SRC_INVBLEND (12 << 16)
+# define R128_ALPHA_BLEND_DST_ZERO (0 << 20)
+# define R128_ALPHA_BLEND_DST_ONE (1 << 20)
+# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20)
+# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20)
+# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20)
+# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20)
+# define R128_ALPHA_BLEND_DST_DSTALPHA (6 << 20)
+# define R128_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20)
+# define R128_ALPHA_BLEND_DST_DSTCOLOR (8 << 20)
+# define R128_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20)
+# define R128_ALPHA_TEST_NEVER (0 << 24)
+# define R128_ALPHA_TEST_LESS (1 << 24)
+# define R128_ALPHA_TEST_LESSEQUAL (2 << 24)
+# define R128_ALPHA_TEST_EQUAL (3 << 24)
+# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24)
+# define R128_ALPHA_TEST_GREATER (5 << 24)
+# define R128_ALPHA_TEST_NEQUAL (6 << 24)
+# define R128_ALPHA_TEST_ALWAYS (7 << 24)
+# define R128_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28)
+# define R128_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28)
+# define R128_COMPOSITE_SHADOW (1 << 29)
+# define R128_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30)
+# define R128_TEX_CACHE_LINE_SIZE_8QW (0 << 31)
+# define R128_TEX_CACHE_LINE_SIZE_4QW (1 << 31)
+#define R128_REG_SCALE_3D_DATATYPE 0x1a20
+
+#define R128_DATATYPE_C8 2
+#define R128_DATATYPE_ARGB_1555 3
+#define R128_DATATYPE_RGB_565 4
+#define R128_DATATYPE_ARGB_8888 6
+#define R128_DATATYPE_RGB_332 7
+#define R128_DATATYPE_Y8 8
+#define R128_DATATYPE_RGB_8 9
+#define R128_DATATYPE_VYUY_422 11
+#define R128_DATATYPE_YVYU_422 12
+#define R128_DATATYPE_AYUV_444 14
+#define R128_DATATYPE_ARGB_4444 15
-# define R128_PM4_NONPM4 (0 << 28)
-# define R128_PM4_192PIO (1 << 28)
-# define R128_PM4_192BM (2 << 28)
-# define R128_PM4_128PIO_64INDBM (3 << 28)
-# define R128_PM4_128BM_64INDBM (4 << 28)
-# define R128_PM4_64PIO_128INDBM (5 << 28)
-# define R128_PM4_64BM_128INDBM (6 << 28)
-# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
-# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
-# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
+#define R128_PM4_NONPM4 (0 << 28)
+#define R128_PM4_192PIO (1 << 28)
+#define R128_PM4_192BM (2 << 28)
+#define R128_PM4_128PIO_64INDBM (3 << 28)
+#define R128_PM4_128BM_64INDBM (4 << 28)
+#define R128_PM4_64PIO_128INDBM (5 << 28)
+#define R128_PM4_64BM_128INDBM (6 << 28)
+#define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
+#define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
+#define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
diff --git a/hw/kdrive/ati/r128_blendtmp.h b/hw/kdrive/ati/r128_blendtmp.h
new file mode 100644
index 000000000..af2fc5cdd
--- /dev/null
+++ b/hw/kdrive/ati/r128_blendtmp.h
@@ -0,0 +1,119 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2003 Eric Anholt, Anders Carlsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Eric Anholt not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Eric Anholt makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $Header$ */
+
+#ifdef USE_DMA
+#define TAG(x) x##DMA
+#define LOCALS (void)atic; \
+ RING_LOCALS
+#define BEGIN(x) BEGIN_RING(x * 2)
+#define OUT_REG(reg, val) OUT_RING_REG(reg, val)
+#define END() ADVANCE_RING()
+#else
+#define TAG(x) x##MMIO
+#define LOCALS char *mmio = atic->reg_base
+#define BEGIN(x) ATIWaitAvailMMIO(x)
+#define OUT_REG(reg, val) MMIO_OUT32(mmio, (reg), (val))
+#define END()
+#endif
+
+static Bool
+TAG(R128PrepareBlend)(int op, PicturePtr pSrcPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ ATIScreenInfo(pScreenPriv);
+ ATICardInfo(pScreenPriv);
+ CARD32 dstDatatype, srcDatatype;
+ LOCALS;
+
+ accel_atis = atis;
+
+ if (!TAG(ATISetup)(pDst, pSrc))
+ return FALSE;
+
+ src_bpp = pSrc->drawable.bitsPerPixel;
+
+ if (op >= sizeof(R128BlendOp)/sizeof(R128BlendOp[0]))
+ return FALSE;
+ if (pSrcPicture->repeat || pSrcPicture->transform != NULL)
+ return FALSE;
+
+ if (!R128GetDatatype(pDstPicture->format, &dstDatatype) ||
+ !R128GetDatatype(pSrcPicture->format, &srcDatatype))
+ return FALSE;
+
+ BEGIN(9);
+ OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL,
+ (dstDatatype << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_AUX_CLIP_DIS |
+ (ATIBltRop[3] << 16) |
+ RADEON_GMC_3D_FCN_EN);
+ OUT_REG(R128_REG_SCALE_3D_CNTL,
+ R128_SCALE_3D_SCALE |
+ R128BlendOp[op] |
+ R128_TEX_MAP_ALPHA_IN_TEXTURE);
+ OUT_REG(R128_REG_SCALE_3D_DATATYPE, srcDatatype);
+ OUT_REG(R128_REG_SCALE_PITCH, src_pitch / src_bpp);
+ /* 4.16 fixed point scaling factor? */
+ OUT_REG(R128_REG_SCALE_X_INC, 65536);
+ OUT_REG(R128_REG_SCALE_Y_INC, 65536);
+ OUT_REG(R128_REG_SCALE_HACC, 0x00000000);
+ OUT_REG(R128_REG_SCALE_VACC, 0x00000000);
+ OUT_REG(RADEON_REG_DP_CNTL,
+ RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM );
+ END();
+
+ return TRUE;
+}
+
+static void
+TAG(R128Blend)(int srcX, int srcY, int dstX, int dstY, int width, int height)
+{
+ ATIScreenInfo *atis = accel_atis;
+ ATICardInfo *atic = atis->atic;
+ LOCALS;
+
+ BEGIN(4);
+ OUT_REG(R128_REG_SCALE_OFFSET_0, src_offset + srcY * src_pitch + srcX *
+ (src_bpp >> 3));
+ OUT_REG(R128_REG_SCALE_SRC_HEIGHT_WIDTH, (height << 16) | width);
+ OUT_REG(R128_REG_SCALE_DST_X_Y, (dstX << 16) | dstY);
+ OUT_REG(R128_REG_SCALE_DST_HEIGHT_WIDTH, (height << 16) | width);
+ END();
+}
+
+static void
+TAG(R128DoneBlend)(void)
+{
+}
+
+#undef TAG
+#undef LOCALS
+#undef BEGIN
+#undef OUT_REG
+#undef END
diff --git a/hw/kdrive/src/kaa.c b/hw/kdrive/src/kaa.c
index c9a72a95d..1a39c25e9 100644
--- a/hw/kdrive/src/kaa.c
+++ b/hw/kdrive/src/kaa.c
@@ -153,7 +153,6 @@ kaaMoveInPixmap (PixmapPtr pPixmap)
unsigned char *dst, *src;
int i;
- return;
KdCheckSync (pPixmap->drawable.pScreen);
DBG_MIGRATE (("-> 0x%08x (0x%x) (%dx%d)\n",
@@ -271,6 +270,7 @@ kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
break;
}
}
+
pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp);
if (!pPixmap)
return NULL;
@@ -278,8 +278,7 @@ kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
pKaaPixmap->score = 0;
pKaaPixmap->area = NULL;
- if (depth == pScreen->rootDepth &&
- (pPixmap->devKind * h) >= MIN_OFFPIX_SIZE)
+ if ((pPixmap->devKind * h) >= MIN_OFFPIX_SIZE)
kaaPixmapAllocArea (pPixmap);
return pPixmap;
}
@@ -939,6 +938,76 @@ kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
#ifdef RENDER
#include "mipict.h"
+#define KAA_DEBUG_FALLBACKS 0
+
+#if KAA_DEBUG_FALLBACKS
+static void
+kaaPrintCompositeFallback(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst)
+{
+ char sop[20], ssfmt[20], smfmt[20], sdfmt[20];
+ char sloc, mloc, dloc;
+ int temp;
+
+ switch(op)
+ {
+ case PictOpSrc:
+ sprintf(sop, "Src");
+ break;
+ case PictOpOver:
+ sprintf(sop, "Over");
+ break;
+ default:
+ sprintf(sop, "0x%x", (int)op);
+ break;
+ }
+ switch(pSrc->format)
+ {
+ case PICT_a8r8g8b8:
+ sprintf(ssfmt, "ARGB8888");
+ break;
+ default:
+ sprintf(ssfmt, "0x%x", (int)pSrc->format);
+ break;
+ }
+ sprintf(smfmt, "(none)");
+ if (pMask) {
+ switch(pMask->format)
+ {
+ case PICT_a8:
+ sprintf(smfmt, "A8");
+ break;
+ default:
+ sprintf(smfmt, "0x%x", (int)pMask->format);
+ break;
+ }
+ }
+ switch(pDst->format)
+ {
+ case PICT_r5g6b5:
+ sprintf(sdfmt, "RGB565");
+ break;
+ default:
+ sprintf(sdfmt, "0x%x", (int)pDst->format);
+ break;
+ }
+ strcpy (smfmt, ("None"));
+ pMask = 0x0;
+
+ sloc = kaaGetOffscreenPixmap(pSrc->pDrawable, &temp, &temp) ? 's' : 'm';
+ mloc = (pMask && kaaGetOffscreenPixmap(pMask->pDrawable, &temp, &temp)) ?
+ 's' : 'm';
+ dloc = kaaGetOffscreenPixmap(pDst->pDrawable, &temp, &temp) ? 's' : 'm';
+
+ ErrorF("Composite fallback: op %s, src 0x%x (%c), mask 0x%x (%c), "
+ "dst 0x%x (%c)\n"
+ " srcfmt %s, maskfmt %s, dstfmt %s\n",
+ sop, pSrc, sloc, pMask, mloc, pDst, dloc, ssfmt, smfmt, sdfmt);
+}
+#endif
+
static void
kaaComposite(CARD8 op,
PicturePtr pSrc,
@@ -953,42 +1022,111 @@ kaaComposite(CARD8 op,
CARD16 width,
CARD16 height)
{
- if (op == PictOpSrc && !pMask)
+ KdScreenPriv (pDst->pDrawable->pScreen);
+ KaaScreenPriv (pDst->pDrawable->pScreen);
+
+ if (!pMask)
{
- /*
- * Check for two special cases -- solid fill and copy area
- */
- if (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
- pSrc->repeat)
+ if (op == PictOpSrc)
{
- ;
+ /*
+ * Check for two special cases -- solid fill and copy area
+ */
+ if (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+ pSrc->repeat)
+ {
+ ;
+ }
+ else if (!pSrc->repeat && pSrc->format == pDst->format)
+ {
+ RegionRec region;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return;
+
+
+ kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
+ REGION_RECTS(&region), REGION_NUM_RECTS(&region),
+ xSrc - xDst, ySrc - yDst,
+ FALSE, FALSE, 0, 0);
+ return;
+ }
}
- else if (!pSrc->repeat && pSrc->format == pDst->format)
+
+ if (pScreenPriv->enabled && pKaaScr->info->PrepareBlend)
{
- RegionRec region;
-
+ RegionRec region;
+ BoxPtr pbox;
+ int nbox;
+ int src_off_x, src_off_y;
+ int dst_off_x, dst_off_y;
+ PixmapPtr pSrcPix, pDstPix;
+
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
+
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
- if (pMask)
- {
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
- }
+
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
return;
-
- kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
- REGION_RECTS(&region), REGION_NUM_RECTS(&region),
- xSrc - xDst, ySrc - yDst,
- FALSE, FALSE, 0, 0);
+
+ /* Migrate pixmaps to same place as destination */
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
+
+ pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x,
+ &src_off_y);
+ pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x,
+ &dst_off_y);
+ if (!pSrcPix || !pDstPix ||
+ !(*pKaaScr->info->PrepareBlend) (op, pSrc, pDst, pSrcPix,
+ pDstPix))
+ {
+ goto software;
+ }
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ xSrc -= xDst;
+ ySrc -= yDst;
+
+ while (nbox--)
+ {
+ (*pKaaScr->info->Blend) (pbox->x1 + xSrc + src_off_x,
+ pbox->y1 + ySrc + src_off_y,
+ pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ (*pKaaScr->info->DoneBlend) ();
+ KdMarkSync(pDst->pDrawable->pScreen);
+
return;
}
}
+
+software:
+#if KAA_DEBUG_FALLBACKS
+ kaaPrintCompositeFallback (op, pSrc, pMask, pDst);
+#endif
+
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index df2ead9f4..9bde73d21 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -332,6 +332,19 @@ typedef struct _KaaScreenInfo {
int offscreenByteAlign;
int offscreenPitch;
int flags;
+
+ Bool (*PrepareBlend) (int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PixmapPtr pSrc,
+ PixmapPtr pDst);
+ void (*Blend) (int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int width,
+ int height);
+ void (*DoneBlend) (void);
} KaaScreenInfoRec, *KaaScreenInfoPtr;
#define KAA_OFFSCREEN_PIXMAPS (1 << 0)