xenocara/driver/xf86-video-geode/src/gx_accel.c
2008-06-14 22:15:30 +00:00

2067 lines
63 KiB
C

/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Neither the name of the Advanced Micro Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
* */
/*
* File Contents: This file is consists of main Xfree acceleration supported
* routines like solid fill used here.
*
* Project: Geode Xfree Frame buffer device driver.
* */
/* #undef OPT_ACCEL */
/* Xfree86 header files */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "vgaHW.h"
#include "xf86.h"
#include "xaalocal.h"
#include "xf86fbman.h"
#include "miline.h"
#include "xaarop.h"
#include "servermd.h"
#include "picture.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Pci.h"
#include "xf86PciInfo.h"
#include "geode.h"
#include "gfx_defs.h"
#include "gfx_regs.h"
/* Common macros for blend operations are here */
#include "geode_blend.h"
#undef ulong
typedef unsigned long ulong;
#undef uint
typedef unsigned int uint;
#undef ushort
typedef unsigned short ushort;
#undef uchar
typedef unsigned char uchar;
#define CALC_FBOFFSET(x, y) \
(((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift)))
#define FBADDR(x,y) \
((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y))
#define OS_UDELAY 0
#if OS_UDELAY > 0
#define OS_USLEEP(usec) usleep(usec);
#else
#define OS_USLEEP(usec)
#endif
#ifdef OPT_ACCEL
static unsigned int BPP;
static unsigned int BLT_MODE, VEC_MODE;
static unsigned int ACCEL_STRIDE;
#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
#define GU2_WAIT_BUSY while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
#endif
#define HOOK(fn) localRecPtr->fn = GX##fn
#define DLOG(l, fmt, args...) ErrorF(fmt, ##args)
/* static storage declarations */
typedef struct sGBltBox
{
ulong x, y;
ulong w, h;
ulong color;
int bpp, transparent;
} GBltBox;
#if GX_SCANLINE_SUPPORT
static GBltBox giwr;
#endif
#if GX_CPU2SCREXP_SUPPORT
static GBltBox gc2s;
#endif
#if GX_CLREXP_8X8_PAT_SUPPORT
static ulong *gc8x8p;
#endif
#if GX_DASH_LINE_SUPPORT
typedef struct sGDashLine
{
ulong pat[2];
int len;
int fg;
int bg;
} GDashLine;
static GDashLine gdln;
#endif
static unsigned int gu2_xshift, gu2_yshift;
static unsigned int gu2_pitch;
static XAAInfoRecPtr localRecPtr;
/* pat 0xF0 */
/* src 0xCC */
/* dst 0xAA */
/* (src FUNC dst) */
static const int SDfn[16] = {
0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
};
/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
static const int SDfn_PM[16] = {
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
};
/* (pat FUNC dst) */
static const int PDfn[16] = {
0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
};
/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
static const int PDfn_SM[16] = {
0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
};
#ifdef OPT_ACCEL
static inline CARD32
amd_gx_BppToRasterMode(int bpp)
{
switch (bpp) {
case 16:
return MGP_RM_BPPFMT_565;
case 32:
return MGP_RM_BPPFMT_8888;
case 8:
return MGP_RM_BPPFMT_332;
default:
return 0;
}
}
#endif /* OPT_ACCEL */
/*----------------------------------------------------------------------------
* GXAccelSync.
*
* Description :This function is called to synchronize with the graphics
* engine and it waits the graphic engine is idle. This is
* required before allowing direct access to the framebuffer.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
*
* Returns :none
*---------------------------------------------------------------------------*/
void
GXAccelSync(ScrnInfoPtr pScrni)
{
//ErrorF("GXAccelSync()\n");
#ifndef OPT_ACCEL
gfx_wait_until_idle();
#else
GU2_WAIT_BUSY;
#endif
}
#if GX_FILL_RECT_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForSolidFill.
*
* Description :The SetupFor and Subsequent SolidFill(Rect) provide
* filling rectangular areas of the screen with a
* foreground color.
*
* Parameters.
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* color int foreground fill color
* rop int unmapped raster op
* planemask uint -1 (fill) or pattern data
*
* Returns :none
*--------------------------------------------------------------------------*/
static void
GXSetupForSolidFill(ScrnInfoPtr pScrni,
int color, int rop, unsigned int planemask)
{
//ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask);
rop &= 0x0F;
#ifndef OPT_ACCEL
gfx_set_solid_pattern(planemask);
gfx_set_solid_source(color);
gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
#else
{
unsigned int ROP =
BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
BLT_MODE |= MGP_BM_DST_REQ;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, planemask);
WRITE_GP32(MGP_SRC_COLOR_FG, color);
WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
}
#endif
}
/*----------------------------------------------------------------------------
* GXSubsequentSolidFillRect.
*
* Description :see GXSetupForSolidFill.
*
* Parameters.
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x int destination x offset
* y int destination y offset
* w int fill area width (pixels)
* h int fill area height (pixels)
*
* Returns :none
*
* Sample application uses:
* - Window backgrounds.
* - pull down highlighting.
* - x11perf: rectangle tests (-rect500).
* - x11perf: fill trapezoid tests (-trap100).
* - x11perf: horizontal line segments (-hseg500).
*----------------------------------------------------------------------------*/
static void
GXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
{
//ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h);
#ifndef OPT_ACCEL
gfx_pattern_fill(x, y, w, h);
#else
{
unsigned int offset = CALC_FBOFFSET(x, y);
unsigned int size = (w << 16) | h;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
}
#endif
}
#endif /* if GX_FILL_RECT_SUPPORT */
#if GX_CLREXP_8X8_PAT_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForColor8x8PatternFill
*
* Description :8x8 color pattern data is 64 pixels of full color data
* stored linearly in offscreen video memory. These patterns
* are useful as a substitute for 8x8 mono patterns when tiling,
* doing opaque stipples, or regular stipples.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* patx int x offset to pattern data
* paty int y offset to pattern data
* rop int unmapped raster operation
* planemask uint -1 (copy) or pattern data
* trans_color int -1 (copy) or transparent color (not enabled)
* trans color only supported on source channel
* or in monochrome pattern channel
*
* Returns :none.
*
*---------------------------------------------------------------------------*/
static void
GXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
uint planemask, int trans_color)
{
GeodeRec *pGeode = GEODEPTR(pScrni);
//ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n",
// patx, paty, rop, planemask, trans_color);
rop &= 0x0F;
gc8x8p = (unsigned long *)FBADDR(patx, paty);
/* gfx_set_solid_pattern is needed to clear src/pat transparency */
gfx_set_solid_pattern(0);
gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
(gfx_set_solid_source(planemask), PDfn_SM[rop]));
gfx2_set_source_stride(pGeode->Pitch);
gfx2_set_destination_stride(pGeode->Pitch);
if (trans_color == -1)
gfx2_set_source_transparency(0, 0);
else
gfx2_set_source_transparency(trans_color, ~0);
}
/*----------------------------------------------------------------------------
* GXSubsequentColor8x8PatternFillRect
*
* Description :see GXSetupForColor8x8PatternFill.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* patx int pattern phase x offset
* paty int pattern phase y offset
* x int destination x offset
* y int destination y offset
* w int fill area width (pixels)
* h int fill area height (pixels)
*
* Returns :none
*
* Sample application uses:
* - Patterned desktops
* - x11perf: stippled rectangle tests (-srect500).
* - x11perf: opaque stippled rectangle tests (-osrect500).
*--------------------------------------------------------------------------*/
static void
GXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
int x, int y, int w, int h)
{
//ErrorF(
// "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
// patx, paty, x, y, w, h);
gfx2_set_pattern_origin(patx, paty);
gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p);
}
/* GX_CLREXP_8X8_PAT_SUPPORT */
#endif
#if GX_MONO_8X8_PAT_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForMono8x8PatternFill
*
* Description :8x8 mono pattern data is 64 bits of color expansion data
* with ones indicating the foreground color and zeros
* indicating the background color. These patterns are
* useful when tiling, doing opaque stipples, or regular
* stipples.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* patx int x offset to pattern data
* paty int y offset to pattern data
* fg int foreground color
* bg int -1 (transparent) or background color
* rop int unmapped raster operation
* planemask uint -1 (copy) or pattern data
*
* Returns :none.
*
* Comments :none.
*
*--------------------------------------------------------------------------*/
static void
GXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
int fg, int bg, int rop, uint planemask)
{
//ErrorF(
//"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
//patx, paty, fg, bg, rop, planemask);
rop &= 0x0F;
#ifndef OPT_ACCEL
gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0);
gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
(gfx_set_solid_source(planemask), PDfn_SM[rop]));
#else
{
unsigned int ROP = BPP |
(bg ==
-1 ? MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS : MGP_RM_PAT_MONO) |
(planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
BLT_MODE |= MGP_BM_DST_REQ;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
WRITE_GP32(MGP_PAT_COLOR_0, bg);
WRITE_GP32(MGP_PAT_COLOR_1, fg);
WRITE_GP32(MGP_PAT_DATA_0, patx);
WRITE_GP32(MGP_PAT_DATA_1, paty);
WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
}
#endif
}
/*----------------------------------------------------------------------------
* GXSubsequentMono8x8PatternFillRect
*
* Description :see GXSetupForMono8x8PatternFill
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* patx int pattern phase x offset
* paty int pattern phase y offset
* x int destination x offset
* y int destination y offset
* w int fill area width (pixels)
* h int fill area height (pixels)
* Returns :none
*
* Sample application uses:
* - Patterned desktops
* - x11perf: stippled rectangle tests (-srect500).
* - x11perf: opaque stippled rectangle tests (-osrect500).
*--------------------------------------------------------------------------*/
static void
GXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
int x, int y, int w, int h)
{
DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n",
__func__, patx, paty, x, y, w, h));
#ifndef OPT_ACCEL
gfx_pattern_fill(x, y, w, h);
#else
{
unsigned int offset =
CALC_FBOFFSET(x, y) | ((x & 7) << 26) | ((y & 7) << 29);
unsigned int size = (w << 16) | h;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
}
#endif
}
#endif /* GX_MONO_8X8_PAT_SUPPORT */
#if GX_SCR2SCRCPY_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForScreenToScreenCopy
*
* Description :SetupFor and Subsequent ScreenToScreenCopy functions
* provide an interface for copying rectangular areas from
* video memory to video memory.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* xdir int x copy direction (up/dn)
* ydir int y copy direction (up/dn)
* rop int unmapped raster operation
* planemask uint -1 (copy) or pattern data
* trans_color int -1 (copy) or transparent color
*
* Returns :none
*---------------------------------------------------------------------------*/
static void
GXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
uint planemask, int trans_color)
{
DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n",
__func__, xdir, ydir, rop, planemask, trans_color));
rop &= 0x0F;
#ifndef OPT_ACCEL
{
GeodeRec *pGeode = GEODEPTR(pScrni);
gfx_set_solid_pattern(planemask);
/* transparency is a parameter to set_rop, but set...pattern clears
* transparency */
if (trans_color == -1)
gfx2_set_source_transparency(0, 0);
else
gfx2_set_source_transparency(trans_color, ~0);
gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
gfx2_set_source_stride(pGeode->Pitch);
gfx2_set_destination_stride(pGeode->Pitch);
}
#else
{
unsigned int ROP =
BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
if (trans_color != -1)
ROP |= MGP_RM_SRC_TRANS;
BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, planemask);
WRITE_GP32(MGP_SRC_COLOR_FG, trans_color);
WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
}
#endif
}
/*----------------------------------------------------------------------------
* GXSubsquentScreenToScreenCopy
*
* Description :see GXSetupForScreenToScreenCopy.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x1 int source x offset
* y1 int source y offset
* x2 int destination x offset
* y2 int destination y offset
* w int copy area width (pixels)
* h int copy area height (pixels)
*
* Returns :none
*
* Sample application uses (non-transparent):
* - Moving windows.
* - x11perf: scroll tests (-scroll500).
* - x11perf: copy from window to window (-copywinwin500).
*---------------------------------------------------------------------------*/
static void
GXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
int x1, int y1, int x2, int y2, int w, int h)
{
DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n",
__func__, x1, y1, x2, y2, w, h));
#ifndef OPT_ACCEL
{
int flags = 0;
if (x2 > x1)
flags |= 1;
if (y2 > y1)
flags |= 2;
gfx2_screen_to_screen_blt(CALC_FBOFFSET(x1, y1), CALC_FBOFFSET(x2,
y2), w, h, flags);
}
#else
{
GeodeRec *pGeode = GEODEPTR(pScrni);
unsigned int src = CALC_FBOFFSET(x1, y1);
unsigned int dst = CALC_FBOFFSET(x2, y2);
unsigned int size = (w << 16) | h;
unsigned int blt_mode = BLT_MODE;
if (x2 > x1) {
int n = (w << gu2_xshift) - 1;
src += n;
dst += n;
blt_mode |= MGP_BM_NEG_XDIR;
}
if (y2 > y1) {
int n = (h - 1) * pGeode->Pitch;
src += n;
dst += n;
blt_mode |= MGP_BM_NEG_YDIR;
}
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, src);
WRITE_GP32(MGP_DST_OFFSET, dst);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP16(MGP_BLT_MODE, blt_mode);
}
#endif
}
#endif /* if GX_SCR2SCRCPY_SUPPORT */
#if GX_SCANLINE_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForScanlineImageWrite
*
* Description :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
* transfer full color pixel data from system memory to video
* memory. This is useful for dealing with alignment issues and
* performing raster ops on the data.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* rop int unmapped raster operation
* planemask uint -1 (copy) or pattern data
* bpp int bits per pixel (unused)
* depth int color depth (unused)
*
* Returns :none
*
* x11perf -putimage10
* x11perf -putimage100
* x11perf -putimage500
*----------------------------------------------------------------------------
*/
static void
GXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
int trans_color, int bpp, int depth)
{
GeodeRec *pGeode = GEODEPTR(pScrni);
DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n",
__func__, rop, planemask, trans_color, bpp, depth));
rop &= 0x0F;
/* transparency is a parameter to set_rop, but set...pattern clears
* transparency */
gfx_set_solid_pattern(planemask);
if (trans_color == -1)
gfx2_set_source_transparency(0, 0);
else
gfx2_set_source_transparency(trans_color, ~0);
gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
gfx2_set_source_stride(pGeode->Pitch);
gfx2_set_destination_stride(pGeode->Pitch);
}
/*----------------------------------------------------------------------------
* GXSubsequentScanlineImageWriteRect
*
* Description : see GXSetupForScanlineImageWrite.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x int destination x offset
* y int destination y offset
* w int copy area width (pixels)
* h int copy area height (pixels)
* skipleft int x margin (pixels) to skip (not enabled)
*
* Returns :none
*---------------------------------------------------------------------------*/
static void
GXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
int x, int y, int w, int h, int skipleft)
{
DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n",
__func__, x, y, w, h, skipleft));
giwr.x = x;
giwr.y = y;
giwr.w = w;
giwr.h = h;
#if !GX_USE_OFFSCRN_MEM
#if !GX_ONE_LINE_AT_A_TIME
GXAccelSync(pScrni);
#endif
#endif
}
/*----------------------------------------------------------------------------
* GXSubsquentImageWriteScanline
*
* Description : see GXSetupForScanlineImageWrite.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* bufno int scanline number in write group
*
* Returns :none
*
* Sample application uses (non-transparent):
* - Moving windows.
* - x11perf: scroll tests (-scroll500).
* - x11perf: copy from window to window (-copywinwin500).
*
*---------------------------------------------------------------------------*/
static void
GXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
{
GeodeRec *pGeode = GEODEPTR(pScrni);
#if !GX_USE_OFFSCRN_MEM
unsigned long offset;
#endif
#if GX_ONE_LINE_AT_A_TIME
DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
#if !GX_USE_OFFSCRN_MEM
offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase;
gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
1, 0);
#else /* if !GX_USE_OFFSCRN_MEM */
gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
giwr.w, 1, pGeode->AccelImageWriteBuffers[bufno], pGeode->Pitch);
#endif /* if !GX_USE_OFFSCRN_MEM */
++giwr.y;
#else /* if GX_ONE_LINE_AT_A_TIME */
int blt_height;
DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h)
blt_height = giwr.h;
if (++bufno < blt_height)
return;
#if !GX_USE_OFFSCRN_MEM
offset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
blt_height, 0);
GXAccelSync(pScrni);
#else /* if !GX_USE_OFFSCRN_MEM */
gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
giwr.w, blt_height, pGeode->AccelImageWriteBuffers[0], pGeode->Pitch);
#endif /* if !GX_USE_OFFSCRN_MEM */
giwr.h -= blt_height;
giwr.y += blt_height;
#endif /* if GX_ONE_LINE_AT_A_TIME */
}
#endif /* GX_SCANLINE_SUPPORT */
#if GX_CPU2SCREXP_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForScanlineCPUToScreenColorExpandFill
*
* Description :SetupFor/Subsequent CPUToScreenColorExpandFill and
* ColorExpandScanline routines provide an interface for
* doing expansion blits from source patterns stored in
* system memory.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* fg int foreground color
* bg int -1 (transparent) or background color
* rop int unmapped raster operation
* planemask uint -1 (copy) or pattern data
*
* Returns :none.
*---------------------------------------------------------------------------*/
static void
GXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
int fg, int bg, int rop, uint planemask)
{
GeodeRec *pGeode = GEODEPTR(pScrni);
ulong srcpitch;
DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
__func__, fg, bg, rop, planemask));
rop &= 0x0F;
srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
#ifndef OPT_ACCEL
gfx_set_solid_pattern(planemask);
gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
gfx2_set_source_stride(srcpitch);
gfx2_set_destination_stride(pGeode->Pitch);
#else
{
unsigned int stride = (srcpitch << 16) | pGeode->Pitch;
unsigned int ROP =
BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
if (bg == -1)
ROP |= MGP_RM_SRC_TRANS;
BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, planemask);
WRITE_GP32(MGP_SRC_COLOR_BG, bg);
WRITE_GP32(MGP_SRC_COLOR_FG, fg);
WRITE_GP32(MGP_STRIDE, stride);
}
#endif
}
/*----------------------------------------------------------------------------
* GXSubsequentScanlineCPUToScreenColorExpandFill
*
Description :see GXSetupForScanlineCPUToScreenColorExpandFill
*
* Parameters:
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x int destination x offset
* y int destination y offset
* w int fill area width (pixels)
* h int fill area height (pixels)
*
* Returns :none
*
*---------------------------------------------------------------------------*/
static void
GXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
int x, int y, int w, int h, int skipleft)
{
DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n",
__func__, x, y, w, h, skipleft));
gc2s.x = x;
gc2s.y = y;
gc2s.w = w;
gc2s.h = h;
#ifdef OPT_ACCEL
{
#if GX_ONE_LINE_AT_A_TIME
unsigned int size = (gc2s.w << 16) | 1;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_WID_HEIGHT, size);
#else
GeodeRec *pGeode = GEODEPTR(pScrni);
unsigned int src =
pGeode->AccelColorExpandBuffers[0] - pGeode->FBBase;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, src);
#endif
}
#endif
}
/*----------------------------------------------------------------------------
* GXSubsequentColorExpandScanline
*
* Description :see GXSetupForScanlineCPUToScreenColorExpandFill
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* bufno int scanline number in write group
*
* Returns :none
*----------------------------------------------------------------------------
*/
static void
GXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
{
GeodeRec *pGeode = GEODEPTR(pScrni);
DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
#ifndef OPT_ACCEL
{
#if GX_ONE_LINE_AT_A_TIME
ulong offset =
pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
gfx2_mono_expand_blt(offset, 0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
gc2s.w, 1, 0);
++gc2s.y;
#else /* if GX_ONE_LINE_AT_A_TIME */
ulong srcpitch;
int blt_height;
if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
blt_height = gc2s.h;
if (++bufno < blt_height)
return;
/* convert from bits to dwords */
srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
gc2s.w, blt_height, pGeode->AccelColorExpandBuffers[0], srcpitch);
gc2s.h -= blt_height;
gc2s.y += blt_height;
#endif /* if GX_ONE_LINE_AT_A_TIME */
}
#else /* ifndef OPT_ACCEL */
{
#if GX_ONE_LINE_AT_A_TIME
unsigned int src =
pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
unsigned int dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
++gc2s.y;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, src);
WRITE_GP32(MGP_DST_OFFSET, dst);
WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
#else /* if GX_ONE_LINE_AT_A_TIME */
unsigned int dst, size;
int blt_height;
GU2_WAIT_BUSY;
if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
blt_height = gc2s.h;
if (++bufno < blt_height)
return;
dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
size = (gc2s.w << 16) | blt_height;
gc2s.h -= blt_height;
gc2s.y += blt_height;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, dst);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
#endif /* if GX_ONE_LINE_AT_A_TIME */
}
#endif /* ifndef OPT_ACCEL */
}
#endif /* GX_CPU2SCREXP_SUPPORT */
#if GX_SCR2SCREXP_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForScreenToScreenColorExpandFill
*
* Description :SetupFor/Subsequent ScreenToScreenColorExpandFill and
* ColorExpandScanline routines provide an interface for
* doing expansion blits from source patterns stored in
* video memory.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* fg int foreground color
* bg int -1 (transparent) or background color
* rop int unmapped raster operation
* planemask uint -1 (copy) or pattern data
*
* Returns :none.
*---------------------------------------------------------------------------*/
static void
GXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
int rop, uint planemask)
{
DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
__func__, fg, bg, rop, planemask));
rop &= 0x0F;
#ifndef OPT_ACCEL
{
GeodeRec *pGeode = GEODEPTR(pScrni);
gfx_set_solid_pattern(planemask);
gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
gfx2_set_source_stride(pGeode->Pitch);
gfx2_set_destination_stride(pGeode->Pitch);
}
#else
{
unsigned int ROP =
BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
if (bg == -1)
ROP |= MGP_RM_SRC_TRANS;
BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, planemask);
WRITE_GP32(MGP_SRC_COLOR_BG, bg);
WRITE_GP32(MGP_SRC_COLOR_FG, fg);
WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
}
#endif
}
/*----------------------------------------------------------------------------
* GXSubsequentScreenToScreenColorExpandFill
*
* Description :see GXSetupForScreenToScreenColorExpandFill
*
* Parameters:
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x int destination x offset
* y int destination y offset
* w int fill area width (pixels)
* h int fill area height (pixels)
* offset int initial x offset
*
* Returns :none
*
*---------------------------------------------------------------------------*/
static void
GXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
int x, int y, int w, int h, int srcx, int srcy, int offset)
{
DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n",
__func__, x, y, w, h, srcx, srcy, offset));
#ifndef OPT_ACCEL
gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0,
CALC_FBOFFSET(x, y), w, h, 0);
#else
{
unsigned int src = (CALC_FBOFFSET(srcx,
srcy) + (offset >> 3)) | ((offset & 7) << 26);
unsigned int dst = CALC_FBOFFSET(x, y);
unsigned int size = (w << 16) | h;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, src);
WRITE_GP32(MGP_DST_OFFSET, dst);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
}
#endif
}
#endif /* GX_SCR2SCREXP_SUPPORT */
#define VM_MAJOR_DEC 0
#define VM_MINOR_DEC 0
static unsigned short vmode[] = {
VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
/* !XDECREASING !YDECREASING !YMAJOR */
VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
/* !XDECREASING !YDECREASING YMAJOR */
VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
/* !XDECREASING YDECREASING !YMAJOR */
VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
/* !XDECREASING YDECREASING YMAJOR */
VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
/* XDECREASING !YDECREASING !YMAJOR */
VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
/* XDECREASING !YDECREASING YMAJOR */
VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
/* XDECREASING YDECREASING !YMAJOR */
VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
/* XDECREASING YDECREASING YMAJOR */
};
#if GX_BRES_LINE_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForSolidLine
*
* Description :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
* BresenhamLine provides an interface for drawing thin
* solid lines.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* color int foreground fill color
* rop int unmapped raster op
* planemask uint -1 (fill) or pattern data (not enabled)
*
* Returns :none
*---------------------------------------------------------------------------*/
static void
GXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
{
DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n",
__func__, color, rop, planemask));
rop &= 0x0F;
#ifndef OPT_ACCEL
gfx_set_solid_pattern(color);
gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
(gfx_set_solid_source(planemask), PDfn_SM[rop]));
#else
{
unsigned int ROP =
BPP | (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
VEC_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? ((BLT_MODE |=
MGP_BM_DST_REQ), MGP_VM_DST_REQ) : 0;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, color);
WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
}
#endif
}
/*---------------------------------------------------------------------------
* GXSubsequentSolidBresenhamLine
*
* Description :see GXSetupForSolidLine
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x1 int destination x offset
* y1 int destination y offset
* absmaj int Bresenman absolute major
* absmin int Bresenman absolute minor
* err int Bresenman initial error term
* len int length of the vector (pixels)
* octant int specifies sign and magnitude relationships
* used to determine axis of magor rendering
* and direction of vector progress.
*
* Returns :none
*
* - Window outlines on window move.
* - x11perf: line segments (-line500).
* - x11perf: line segments (-seg500).
*---------------------------------------------------------------------------*/
static void
GXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
int absmaj, int absmin, int err, int len, int octant)
{
long axial, diagn;
DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n",
__func__, x1, y1, absmaj, absmin, err, len, octant));
if (len <= 0)
return;
axial = absmin;
err += axial;
diagn = absmin - absmaj;
#ifndef OPT_ACCEL
gfx_bresenham_line(x1, y1, len, err, axial, diagn, vmode[octant]);
#else
{
unsigned int offset = CALC_FBOFFSET(x1, y1);
unsigned int vec_err = (axial << 16) | (unsigned short)diagn;
unsigned int vec_len = (len << 16) | (unsigned short)err;
unsigned int vec_mode = VEC_MODE | vmode[octant];
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_VEC_ERR, vec_err);
WRITE_GP32(MGP_VEC_LEN, vec_len);
WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
}
#endif
}
/*---------------------------------------------------------------------------
* GXSubsequentSolidTwoPointLine
*
* Description :see GXSetupForSolidLine
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x0 int destination x start offset
* y0 int destination y start offset
* x1 int destination x end offset
* y1 int destination y end offset
* flags int OMIT_LAST, dont draw last pixel (not used)
*
* Returns :none
*---------------------------------------------------------------------------*/
static void
GXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
int x1, int y1, int flags)
{
long dx, dy, dmaj, dmin, octant, bias;
long axial, diagn, err, len;
DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n",
__func__, x0, y0, x1, y1, flags));
if ((dx = x1 - x0) < 0)
dx = -dx;
if ((dy = y1 - y0) < 0)
dy = -dy;
if (dy >= dx) {
dmaj = dy;
dmin = dx;
octant = YMAJOR;
} else {
dmaj = dx;
dmin = dy;
octant = 0;
}
len = dmaj;
if ((flags & OMIT_LAST) == 0)
++len;
if (len <= 0)
return;
if (x1 < x0)
octant |= XDECREASING;
if (y1 < y0)
octant |= YDECREASING;
axial = dmin << 1;
bias = miGetZeroLineBias(pScrni->pScreen);
err = axial - dmaj - ((bias >> octant) & 1);
diagn = (dmin - dmaj) << 1;
#ifndef OPT_ACCEL
gfx_bresenham_line(x0, y0, len, err, axial, diagn, vmode[octant]);
#else
{
unsigned int offset = CALC_FBOFFSET(x0, y0);
unsigned int vec_err = (axial << 16) | (unsigned short)diagn;
unsigned int vec_len = (len << 16) | (unsigned short)err;
unsigned int vec_mode = VEC_MODE | vmode[octant];
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_VEC_ERR, vec_err);
WRITE_GP32(MGP_VEC_LEN, vec_len);
WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
}
#endif
}
/*---------------------------------------------------------------------------
* GXSubsequentSolidHorVertLine
*
* Description :see GXSetupForSolidLine
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x int destination x offset
* y int destination y offset
* len int length of the vector (pixels)
* dir int DEGREES_270 or DEGREES_0 line direction
*
* Sample application uses:
* - Window outlines on window move.
* - x11perf: line segments (-hseg500).
* - x11perf: line segments (-vseg500).
*---------------------------------------------------------------------------
*/
static void
GXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni,
int x, int y, int len, int dir)
{
DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", __func__, x, y, len, dir));
#ifndef OPT_ACCEL
if (dir == DEGREES_0)
gfx_pattern_fill(x, y, len, 1);
else
gfx_pattern_fill(x, y, 1, len);
#else
{
unsigned int offset = CALC_FBOFFSET(x, y);
unsigned int size =
dir == DEGREES_0 ? (len << 16) | 1 : (1 << 16) | len;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
}
#endif
}
#endif /* GX_BRES_LINE_SUPPORT */
#if GX_DASH_LINE_SUPPORT
/*----------------------------------------------------------------------------
* GXSetupForDashedLine
*
* Description :SetupForDashedLine and Subsequent TwoPointLine
* BresenhamLine provides an interface for drawing thin
* dashed lines.
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* fg int foreground fill color
* bg int -1 (transp) or background fill color
* rop int unmapped raster op
* planemask uint -1 (fill) or pattern data (not enabled)
* length int pattern length (bits)
* pattern uchar* dash pattern mask
*
* Returns :none
*---------------------------------------------------------------------------*/
static void
GXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
unsigned int planemask, int length, unsigned char *pattern)
{
int i, l, n, m;
CARD32 pat = *pattern;
CARD32 pat8x8[2];
if (length <= 0)
return;
i = l = m = 0;
while (i < 2) {
m |= pat >> l;
l += length;
if ((n = l - 32) >= 0) {
pat8x8[i++] = m;
m = pat << (length - n);
l = n;
}
}
gdln.pat[0] = pat8x8[0];
gdln.pat[1] = pat8x8[1];
gdln.len = length;
gdln.fg = fg;
gdln.bg = bg;
rop &= 0x0F;
gfx_set_solid_pattern(0);
gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
(gfx_set_solid_source(planemask), PDfn_SM[rop]));
}
/*---------------------------------------------------------------------------
* GXSubsequentDashedBresenhamLine
*
* Description: This function is used to render a vector using the
* specified bresenham parameters.
*
* Parameters:
* pScrni: Screen handler pointer having screen information.
* x1: Specifies the starting x position
* y1: Specifies starting y possition
* absmaj: Specfies the Bresenman absolute major.
* absmin: Specfies the Bresenman absolute minor.
* err: Specifies the bresenham err term.
* len: Specifies the length of the vector interms of pixels.
* octant: not used in this function,may be added for standard
* interface.
*
* Returns: none
*
* Comments: none
*
* Sample application uses:
* - Window outlines on window move.
* - x11perf: line segments (-line500).
* - x11perf: line segments (-seg500).
*----------------------------------------------------------------------------
*/
static void
GXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni,
int x1, int y1, int absmaj, int absmin,
int err, int len, int octant, int phase)
{
int i, n;
int axial, diagn;
int trans = (gdln.bg == -1);
unsigned long pat8x8[2];
//ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin,
//err, len, octant);
i = phase >= 32 ? (phase -= 32, 1) : 0;
n = 32 - phase;
pat8x8[0] =
((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
pat8x8[1] =
((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
axial = absmin;
err += axial;
diagn = absmin - absmaj;
gfx_set_mono_pattern(gdln.bg, gdln.fg, pat8x8[0], pat8x8[1], trans);
gfx2_set_pattern_origin(x1, y1);
gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn,
vmode[octant]);
}
/*---------------------------------------------------------------------------
* GXSubsequentDashedTwoPointLine
*
* Description :see GXSetupForDashedLine
*
* Arg Type Comment
* pScrni ScrnInfoPtr pointer to Screeen info
* x0 int destination x start offset
* y0 int destination y start offset
* x1 int destination x end offset
* y1 int destination y end offset
* flags int OMIT_LAST, dont draw last pixel (not used)
* phase int initial pattern offset at x1,y1
*
* Returns :none
*---------------------------------------------------------------------------*/
static void
GXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
int x1, int y1, int flags, int phase)
{
int i, n;
long dx, dy, dmaj, dmin, octant, bias;
long axial, diagn, err, len, pat8x8[2];
//ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n",
// x0, y0, x1, y1, flags, phase);
i = phase >= 32 ? (phase -= 32, 1) : 0;
n = 32 - phase;
pat8x8[0] =
((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
pat8x8[1] =
((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
if ((dx = x1 - x0) < 0)
dx = -dx;
if ((dy = y1 - y0) < 0)
dy = -dy;
if (dy >= dx) {
dmaj = dy;
dmin = dx;
octant = YMAJOR;
} else {
dmaj = dx;
dmin = dy;
octant = 0;
}
len = dmaj;
if ((flags & OMIT_LAST) == 0)
++len;
if (len <= 0)
return;
if (x1 < x0)
octant |= XDECREASING;
if (y1 < y0)
octant |= YDECREASING;
axial = dmin << 1;
bias = miGetZeroLineBias(pScrni->pScreen);
err = axial - dmaj - ((bias >> octant) & 1);
diagn = (dmin - dmaj) << 1;
gfx2_set_pattern_origin(x0, y0);
gfx2_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn,
vmode[octant]);
}
#endif /* GX_DASH_LINE_SUPPORT */
#if GX_WRITE_PIXMAP_SUPPORT
static void
GXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h,
unsigned char *src, int srcwidth, int rop, unsigned int planemask,
int trans, int bpp, int depth)
{
GeodeRec *pGeode = GEODEPTR(pScrni);
//ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
// x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
if (bpp == pScrni->bitsPerPixel) {
rop &= 0x0F;
if (rop == GXcopy && trans == -1) {
gfx_wait_until_idle();
geode_memory_to_screen_blt((unsigned long)src,
(unsigned long)FBADDR(x, y), srcwidth, pGeode->Pitch, w,
h, bpp);
} else {
gfx_set_solid_pattern(planemask);
gfx_set_raster_operation(planemask ==
~0U ? SDfn[rop] : SDfn_PM[rop]);
if (trans != -1)
gfx_color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src,
srcwidth, trans);
else
gfx_color_bitmap_to_screen_blt(0, 0, x, y, w, h, src,
srcwidth);
SET_SYNC_FLAG(pGeode->AccelInfoRec);
}
} else
pGeode->WritePixmap(pScrni, x, y, w, h, src, srcwidth, rop, planemask,
trans, bpp, depth);
}
#endif /* if GX_WRITE_PIXMAP_SUPPORT */
#if XF86EXA
static void
amd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker)
{
GU2_WAIT_BUSY;
}
static void
amd_gx_exa_Done(PixmapPtr p)
{
}
static Bool
amd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
char *src, int src_pitch)
{
char *dst = pDst->devPrivate.ptr;
int dst_pitch = exaGetPixmapPitch(pDst);
int bpp = pDst->drawable.bitsPerPixel;
dst += y * dst_pitch + x * (bpp >> 3);
GU2_WAIT_BUSY;
geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst,
src_pitch, dst_pitch, w, h, bpp);
return TRUE;
}
static Bool
amd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
char *dst, int dst_pitch)
{
char *src = pSrc->devPrivate.ptr;
int src_pitch = exaGetPixmapPitch(pSrc);
int bpp = pSrc->drawable.bitsPerPixel;
src += (y * src_pitch) + (x * (bpp >> 3));
GU2_WAIT_BUSY;
geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst,
src_pitch, dst_pitch, w, h, bpp);
return TRUE;
}
/* Solid */
static Bool
amd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg)
{
int dstPitch = exaGetPixmapPitch(pxMap);
unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel)
| (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
// FIXME: this should go away -- workaround for the blockparty icon corruption
//if (pxMap->drawable.bitsPerPixel == 32)
// return FALSE;
BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
BLT_MODE |= MGP_BM_DST_REQ;
//ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE);
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, planemask);
WRITE_GP32(MGP_SRC_COLOR_FG, fg);
WRITE_GP32(MGP_STRIDE, dstPitch);
return TRUE;
}
static void
amd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
{
int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8;
int pitch = exaGetPixmapPitch(pxMap);
unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1;
unsigned int size = ((x2 - x1) << 16) | (y2 - y1);
//ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp);
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
}
/* Copy */
static Bool
amd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
int alu, Pixel planemask)
{
GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
int dstPitch = exaGetPixmapPitch(pxDst);
unsigned int ROP;
/* Punt if the color formats aren't the same */
if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel)
return FALSE;
//ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n",
// dx, dy, alu, planemask);
pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc);
pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc);
pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
pGeode->cpyDx = dx;
pGeode->cpyDy = dy;
ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) |
(planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, ROP);
WRITE_GP32(MGP_PAT_COLOR_0, planemask);
WRITE_GP32(MGP_SRC_COLOR_FG, ~0);
WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch);
return TRUE;
}
static void
amd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY,
int w, int h)
{
GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
int dstPitch = exaGetPixmapPitch(pxDst);
unsigned int srcOffset =
pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) +
(pGeode->cpySrcBpp * srcX);
unsigned int dstOffset =
exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX);
unsigned int size = (w << 16) | h;
unsigned int blt_mode = BLT_MODE;
//ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY,
// dstX, dstY, w, h);
if (pGeode->cpyDx < 0) {
srcOffset += w * pGeode->cpySrcBpp - 1;
dstOffset += w * dstBpp - 1;
blt_mode |= MGP_BM_NEG_XDIR;
}
if (pGeode->cpyDy < 0) {
srcOffset += (h - 1) * pGeode->cpySrcPitch;
dstOffset += (h - 1) * dstPitch;
blt_mode |= MGP_BM_NEG_YDIR;
}
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, srcOffset);
WRITE_GP32(MGP_DST_OFFSET, dstOffset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP16(MGP_BLT_MODE, blt_mode);
}
/* A=SRC, B=DST */
#define SRC_DST 0
/* B=SRC, A=DST */
#define DST_SRC MGP_RM_DEST_FROM_CHAN_A
/* A*alpha + B*0 */
#define Aa_B0 MGP_RM_ALPHA_TIMES_A
/* A*0 + B*(1-alpha) */
#define A0_B1a MGP_RM_BETA_TIMES_B
/* A*1 + B*(1-alpha) */
#define A1_B1a MGP_RM_A_PLUS_BETA_B
/* A*alpha + B*(1-alpha) */
#define Aa_B1a MGP_RM_ALPHA_A_PLUS_BETA_B
/* alpha from A */
#define a_A MGP_RM_SELECT_ALPHA_A
/* alpha from B */
#define a_B MGP_RM_SELECT_ALPHA_B
/* alpha from const */
#define a_C MGP_RM_SELECT_ALPHA_R
/* alpha = 1 */
#define a_1 MGP_RM_SELECT_ALPHA_1
#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB)
#define gxPictOpMAX PictOpAdd /* highest accelerated op */
unsigned int amd_gx_exa_alpha_ops[] =
/* A B OP AS const = 0 */
{
(SRC_DST | Aa_B0 | a_C), 0, /* clear (src*0) */
(SRC_DST | Aa_B0 | a_1), 0, /* src (src*1) */
(DST_SRC | Aa_B0 | a_1), 0, /* dst (dst*1) */
(SRC_DST | A1_B1a | a_A), 0, /* src-over (src*1 + dst(1-A)) */
(DST_SRC | A1_B1a | a_A), 0, /* dst-over (dst*1 + src(1-B)) */
(SRC_DST | Aa_B0 | a_B), 0, /* src-in (src*B) */
(DST_SRC | Aa_B0 | a_B), 0, /* dst-in (dst*A) */
(DST_SRC | A0_B1a | a_A), 0, /* src-out (src*(1-B)) */
(SRC_DST | A0_B1a | a_A), 0, /* dst-out (dst*(1-A)) */
/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */
(DST_SRC | Aa_B0 | a_B), /* srcatop (src*B) */
(SRC_DST | A0_B1a | a_A), /* + (dst(1-A)) */
(SRC_DST | Aa_B0 | a_B), /* dstatop (dst*A) */
(DST_SRC | A0_B1a | a_A), /* + (src(1-B) */
(SRC_DST | A0_B1a | a_A), /* xor (src*(1-B) */
(SRC_DST | A0_B1a | a_A), /* + (dst(1-A) */
(SRC_DST | A1_B1a | a_C), 0, /* add (src*1 + dst*1) */
};
typedef struct
{
int exa_fmt;
int bpp;
int gx_fmt;
int alpha_bits;
} amd_gx_exa_fmt_t;
amd_gx_exa_fmt_t amd_gx_exa_fmts[] = {
{PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8},
{PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0},
{PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4},
{PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1},
{PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0},
{PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0},
};
static amd_gx_exa_fmt_t *
amd_gx_exa_check_format(PicturePtr p)
{
int i;
int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0;
amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0];
for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0;
++fp) {
if (fp->bpp < bpp)
return NULL;
if (fp->bpp != bpp)
continue;
if (fp->exa_fmt == p->format)
break;
}
return i < 0 ? NULL : fp;
}
/* Composite */
static Bool
amd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
PicturePtr pDst)
{
GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst);
if (op > gxPictOpMAX)
return FALSE;
if (pMsk)
return FALSE;
if (usesPasses(op) && pGeode->exaBfrSz == 0)
return FALSE;
if (pSrc->filter != PictFilterNearest &&
pSrc->filter != PictFilterFast &&
pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest)
return FALSE;
if (pSrc->repeat)
return FALSE;
if (pSrc->transform)
return FALSE;
return TRUE;
}
static Bool
amd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, PixmapPtr pxDst)
{
int srcPitch;
GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
amd_gx_exa_fmt_t *sfp, *dfp;
//ErrorF("amd_gx_exa_PrepareComposite()\n");
if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL)
return FALSE;
if (sfp->alpha_bits == 0 && usesSrcAlpha(op))
return FALSE;
if ((dfp = amd_gx_exa_check_format(pDst)) == NULL)
return FALSE;
if (dfp->alpha_bits == 0 && usesDstAlpha(op))
return FALSE;
if (sfp->gx_fmt != dfp->gx_fmt)
return FALSE;
srcPitch = exaGetPixmapPitch(pxSrc);
if (usesPasses(op) && srcPitch > pGeode->exaBfrSz)
return FALSE;
pGeode->cmpSrcPitch = srcPitch;
pGeode->cmpOp = op;
pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc);
pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
pGeode->cmpSrcFmt = sfp->gx_fmt;
pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ?
MGP_RM_ALPHA_TO_RGB : MGP_RM_ALPHA_TO_ARGB);
return TRUE;
}
static void
amd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
int maskY, int dstX, int dstY, int width, int height)
{
int op, current_line, max_lines, lines, pass, scratchPitch;
unsigned int srcOffset, srcOfs=0, srcPitch, srcPch=0, srcBpp;
unsigned int dstOffset, dstOfs=0, dstPitch, dstPch=0, dstBpp;
unsigned int sizes, strides, blt_mode = 0, rop = 0;
GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
//ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n",
// srcX, srcY, dstX, dstY, width, height);
op = pGeode->cmpOp;
if (usesPasses(op)) {
int cacheLineSz = 32;
int cachelines =
(width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz;
scratchPitch = cachelines * cacheLineSz;
if (scratchPitch > pGeode->cmpSrcPitch)
scratchPitch = pGeode->cmpSrcPitch;
max_lines = pGeode->exaBfrSz / scratchPitch;
} else {
scratchPitch = 0;
max_lines = height;
}
dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
dstPitch = exaGetPixmapPitch(pxDst);
dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX;
srcBpp = pGeode->cmpSrcBpp;
srcPitch = pGeode->cmpSrcPitch;
srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX;
current_line = pass = 0;
while (current_line < height) {
if (usesPasses(op)) {
lines = height - current_line;
if (lines > max_lines)
lines = max_lines;
switch (pass) {
case 0: /* copy src to scratch */
srcPch = srcPitch;
srcOfs = srcOffset + current_line * srcPch;
dstPch = scratchPitch;
dstOfs = pGeode->exaBfrOffset;
rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2];
blt_mode = usesChanB0(PictOpSrc) ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
++pass;
break;
case 1: /* pass1 */
srcPch = dstPitch;
srcOfs = dstOffset + current_line * srcPch;
dstPch = scratchPitch;
dstOfs = pGeode->exaBfrOffset;
rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
rop |= amd_gx_exa_alpha_ops[op * 2];
blt_mode = usesChanB1(op) ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
++pass;
break;
case 2: /* pass2 */
srcPch = srcPitch;
srcOfs = srcOffset + current_line * srcPch;
dstPch = dstPitch;
dstOfs = dstOffset + current_line * dstPch;
rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
rop |= amd_gx_exa_alpha_ops[op * 2 + 1];
blt_mode = usesChanB2(op) ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
++pass;
break;
case 3: /* add */
srcPch = scratchPitch;
srcOfs = pGeode->exaBfrOffset;
dstPch = dstPitch;
dstOfs = dstOffset + current_line * dstPch;
rop = pGeode->cmpDstFmt;
rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2];
blt_mode = usesChanB0(PictOpAdd) ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
current_line += lines;
pass = 0;
break;
}
strides = (srcPch << 16) | dstPch;
} else { /* not multi pass */
srcOfs = srcOffset;
dstOfs = dstOffset;
current_line = lines = height;
strides = (srcPitch << 16) | dstPitch;
rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2];
blt_mode = usesChanB0(op) ?
MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
}
sizes = (width << 16) | lines;
if (srcOfs < dstOfs) {
srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1;
dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1;
blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR;
}
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, rop);
WRITE_GP32(MGP_SRC_OFFSET, srcOfs);
WRITE_GP32(MGP_DST_OFFSET, dstOfs);
WRITE_GP32(MGP_WID_HEIGHT, sizes);
WRITE_GP32(MGP_STRIDE, strides);
WRITE_GP16(MGP_BLT_MODE, blt_mode);
}
}
#endif /* #if XF86EXA */
/*----------------------------------------------------------------------------
* GXAccelInit.
*
* Description: This function sets up the supported acceleration routines and
* appropriate flags.
*
* Parameters:
* pScrn: Screeen pointer structure.
*
* Returns: TRUE on success and FALSE on Failure
*
* Comments: This function is called in GXScreenInit in
* geode_driver.c to set * the acceleration.
*----------------------------------------------------------------------------
*/
Bool
GXAccelInit(ScreenPtr pScrn)
{
ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
GeodeRec *pGeode = GEODEPTR(pScrni);
#if XF86EXA
ExaDriverPtr pExa = pGeode->pExa;
#endif
gu2_xshift = pScrni->bitsPerPixel >> 4;
/* XXX - fixme - this will change - we'll need to update it */
gu2_pitch = pGeode->Pitch;
switch (pGeode->Pitch) {
case 1024:
gu2_yshift = 10;
break;
case 2048:
gu2_yshift = 11;
break;
case 4096:
gu2_yshift = 12;
break;
default:
gu2_yshift = 13;
break;
}
#ifdef OPT_ACCEL
ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch;
BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel);
#endif
#if XF86EXA
if (pExa && pGeode->useEXA) {
pExa->exa_major = EXA_VERSION_MAJOR;
pExa->exa_minor = EXA_VERSION_MINOR;
/* Sync */
pExa->WaitMarker = amd_gx_exa_WaitMarker;
/* UploadToScreen */
pExa->UploadToScreen = amd_gx_exa_UploadToScreen;
pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen;
/* Solid fill */
pExa->PrepareSolid = amd_gx_exa_PrepareSolid;
pExa->Solid = amd_gx_exa_Solid;
pExa->DoneSolid = amd_gx_exa_Done;
/* Copy */
pExa->PrepareCopy = amd_gx_exa_PrepareCopy;
pExa->Copy = amd_gx_exa_Copy;
pExa->DoneCopy = amd_gx_exa_Done;
/* Composite */
pExa->CheckComposite = amd_gx_exa_CheckComposite;
pExa->PrepareComposite = amd_gx_exa_PrepareComposite;
pExa->Composite = amd_gx_exa_Composite;
pExa->DoneComposite = amd_gx_exa_Done;
return exaDriverInit(pScrn, pGeode->pExa);
}
#endif
/* Getting the pointer for acceleration Inforecord */
pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
if (!pGeode->AccelInfoRec)
return FALSE;
/* SET ACCELERATION FLAGS */
localRecPtr->Flags =
PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
/* HOOK SYNCRONIZARION ROUTINE */
localRecPtr->Sync = GXAccelSync;
#if GX_FILL_RECT_SUPPORT
/* HOOK FILLED RECTANGLES */
HOOK(SetupForSolidFill);
HOOK(SubsequentSolidFillRect);
localRecPtr->SolidFillFlags = 0;
#endif
#if GX_MONO_8X8_PAT_SUPPORT
/* Color expansion */
HOOK(SetupForMono8x8PatternFill);
HOOK(SubsequentMono8x8PatternFillRect);
/* BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST |
HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
#endif
#if GX_CLREXP_8X8_PAT_SUPPORT
/* Color expansion */
HOOK(SetupForColor8x8PatternFill);
HOOK(SubsequentColor8x8PatternFillRect);
/* BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
localRecPtr->Color8x8PatternFillFlags =
BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
#endif
#if GX_SCR2SCRCPY_SUPPORT
/* HOOK SCREEN TO SCREEN COPIES
* Set flag to only allow copy if transparency is enabled.
*/
HOOK(SetupForScreenToScreenCopy);
HOOK(SubsequentScreenToScreenCopy);
localRecPtr->ScreenToScreenCopyFlags =
BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
#endif
#if GX_BRES_LINE_SUPPORT
/* HOOK BRESENHAM SOLID LINES */
localRecPtr->SolidLineFlags = NO_PLANEMASK;
HOOK(SetupForSolidLine);
HOOK(SubsequentSolidBresenhamLine);
HOOK(SubsequentSolidHorVertLine);
HOOK(SubsequentSolidTwoPointLine);
localRecPtr->SolidBresenhamLineErrorTermBits = 15;
#endif
#if GX_DASH_LINE_SUPPORT
/* HOOK BRESENHAM DASHED LINES */
HOOK(SetupForDashedLine);
HOOK(SubsequentDashedBresenhamLine);
HOOK(SubsequentDashedTwoPointLine);
localRecPtr->DashedBresenhamLineErrorTermBits = 15;
localRecPtr->DashPatternMaxLength = 64;
localRecPtr->DashedLineFlags = NO_PLANEMASK | /* TRANSPARENCY_ONLY | */
LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED;
#endif
#if GX_SCR2SCREXP_SUPPORT
/* Color expansion */
HOOK(SetupForScreenToScreenColorExpandFill);
HOOK(SubsequentScreenToScreenColorExpandFill);
localRecPtr->ScreenToScreenColorExpandFillFlags =
BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY;
#endif
if (pGeode->AccelImageWriteBuffers) {
#if GX_SCANLINE_SUPPORT
localRecPtr->ScanlineImageWriteBuffers =
pGeode->AccelImageWriteBuffers;
localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
HOOK(SetupForScanlineImageWrite);
HOOK(SubsequentScanlineImageWriteRect);
HOOK(SubsequentImageWriteScanline);
localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY |
BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
#endif
} else {
localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
}
if (pGeode->AccelColorExpandBuffers) {
#if GX_CPU2SCREXP_SUPPORT
/* Color expansion */
localRecPtr->ScanlineColorExpandBuffers =
pGeode->AccelColorExpandBuffers;
localRecPtr->NumScanlineColorExpandBuffers =
pGeode->NoOfColorExpandLines;
HOOK(SetupForScanlineCPUToScreenColorExpandFill);
HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
HOOK(SubsequentColorExpandScanline);
localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
#endif
}
#if GX_WRITE_PIXMAP_SUPPORT
pGeode->WritePixmap = localRecPtr->WritePixmap;
HOOK(WritePixmap);
#endif
return (XAAInit(pScrn, localRecPtr));
}
/* END OF FILE */