From 92ab7214593061fa57d5cdd829dc98de6434ef7c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 23 Dec 2003 22:29:38 +0000 Subject: - 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. --- hw/kdrive/ati/Makefile.am | 1 + hw/kdrive/ati/ati_draw.c | 64 ++++++++++++++- hw/kdrive/ati/ati_drawtmp.h | 5 +- hw/kdrive/ati/ati_reg.h | 131 +++++++++++++++++++++++++----- hw/kdrive/ati/r128_blendtmp.h | 119 +++++++++++++++++++++++++++ hw/kdrive/src/kaa.c | 184 ++++++++++++++++++++++++++++++++++++------ hw/kdrive/src/kdrive.h | 13 +++ 7 files changed, 469 insertions(+), 48 deletions(-) create mode 100644 hw/kdrive/ati/r128_blendtmp.h 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 (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return; + + + kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0, + REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), + 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 (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; - - kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0, - REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), - 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(®ion); + pbox = REGION_RECTS(®ion); + + 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) -- cgit v1.2.3