diff --git a/configure.ac b/configure.ac index e904f68..511bbf8 100644 --- a/configure.ac +++ b/configure.ac @@ -69,7 +69,7 @@ XORG_DRIVER_CHECK_EXT(XF86MISC, xf86miscproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Obtain compiler/linker options for the driver dependencies -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.18 xproto fontsproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3 xproto fontsproto $REQUIRED_MODULES]) PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]), HAVE_XEXTPROTO_71="no") @@ -156,6 +156,24 @@ AC_CHECK_DECL(XSERVER_LIBPCIACCESS, [#include "xorg-server.h"]) CPPFLAGS="$SAVE_CPPFLAGS" +AC_ARG_ENABLE(xaa, + AS_HELP_STRING([--enable-xaa], + [Enable legacy X Acceleration Architecture (XAA) [default=auto]]), + [XAA="$enableval"], + [XAA=auto]) +if test "x$XAA" != xno; then + save_CFLAGS=$CFLAGS + save_CPPFLAGS=$CPPFLAGS + CFLAGS=$XORG_CFLAGS + CPPFLAGS="$XORG_CFLAGS" + AC_CHECK_HEADERS([xaa.h], XAA=yes, XAA=no) + CFLAGS=$save_CFLAGS + CPPFLAGS=$save_CPPFLAGS +fi +AC_MSG_CHECKING([whether to include XAA support]) +AM_CONDITIONAL(XAA, test "x$XAA" = xyes) +AC_MSG_RESULT([$XAA]) + AM_CONDITIONAL(USE_EXA, test "x$USE_EXA" = xyes) if test "x$XSERVER_LIBPCIACCESS" = xyes; then diff --git a/man/r128.man b/man/r128.man index b48d54b..4289fcc 100644 --- a/man/r128.man +++ b/man/r128.man @@ -1,8 +1,8 @@ .\" shorthand for double quote that works everywhere. .ds q \N'34' -.TH R128 __drivermansuffix__ __vendorversion__ +.TH R128 __drivermansuffix__ 2024-05-14 __vendorversion__ .SH NAME -r128 \- ATI Rage 128 video driver +r128 - ATI Rage 128 video driver for Xorg .SH SYNOPSIS .nf .B "Section \*qDevice\*q" @@ -13,26 +13,26 @@ r128 \- ATI Rage 128 video driver .fi .SH DESCRIPTION .B r128 -is an __xservername__ driver for ATI Rage 128 based video cards. It contains -full support for 8, 15, 16 and 24 bit pixel depths, hardware +is an Xorg driver for ATI Rage 128 based video cards. +It contains full support for 8, 15, 16 and 24 bit pixel depths, hardware acceleration of drawing primitives, hardware cursor, video modes up to 1800x1440 @ 70Hz, doublescan modes (e.g., 320x200 and 320x240), gamma correction at all pixel depths, a fully programming dot clock and robust -text mode restoration for VT switching. Dualhead is supported on M3/M4 -mobile chips. +text mode restoration for VT switching. +Dualhead is supported on M3/M4 mobile chips. .SH SUPPORTED HARDWARE The .B r128 driver supports all ATI Rage 128 based video cards including the Rage -Fury AGP 32MB, the XPERT 128 AGP 16MB and the XPERT 99 AGP 8MB. +Fury AGP 32MB, the XPERT 128 AGP 16MB, and the XPERT 99 AGP 8MB. .SH CONFIGURATION DETAILS -Please refer to __xconfigfile__(__filemansuffix__) for general configuration -details. This section only covers configuration details specific to this -driver. +Please refer to +.BR xorg.conf (__filemansuffix__) +for general configuration details. +This section only covers configuration details specific to this driver. .PP -The driver auto-detects all device information necessary to initialize -the card. However, if you have problems with auto-detection, you can -specify: +The driver auto-detects all device information necessary to initialize the card. +However, if you have problems with auto-detection, you can specify: .PP .RS 4 VideoRam - in kilobytes @@ -49,39 +49,44 @@ In addition, the following driver are supported: .TP .BI "Option \*qSWcursor\*q \*q" boolean \*q -Selects software cursor. The default is +Selects software cursor. +The default is .B off. .TP .BI "Option \*qNoAccel\*q \*q" boolean \*q -Enables or disables all hardware acceleration. The default is to +Enables or disables all hardware acceleration. +The default is to .B enable hardware acceleration. .TP .BI "Option \*qEnablePageFlip\*q \*q" boolean \*q -Enable page flipping for 3D acceleration. This will increase performance -but not work correctly in some rare cases, hence the default is +Enable page flipping for 3D acceleration. +This will increase performance but not work correctly in some rare cases, +hence the default is .B off. .TP .BI "Option \*qRenderAccel\*q \*q" boolean \*q -Enables or disables hardware Render acceleration. It is only supported when -using EXA acceleration and DRI. The default is to +Enables or disables hardware Render acceleration. +It is only supported when using EXA acceleration and DRI. +The default is to .B enable Render acceleration. .TP .BI "Option \*qAccelMethod\*q \*q" "string" \*q -Chooses between available acceleration architectures. The only valid option is -.BR EXA . -XAA was the traditional acceleration architecture, but support for it has -been removed from the Xorg server and this driver. -EXA is a newer acceleration architecture with better performance for +Chooses between available acceleration architectures. Valid options are +.B XAA +and +.B EXA. +XAA is the traditional acceleration architecture and support for it is very +stable. EXA is a newer acceleration architecture with better performance for the Render and Composite extensions. The default is -.BR EXA . +.B XAA. .TP .BI "Option \*qVideoKey\*q \*q" integer \*q This overrides the default pixel value for the YUV video overlay key. The default value is .B undefined. - +.sp .PP The following .B Options @@ -96,55 +101,65 @@ The default depends on the device. .BI "Option \*qPanelWidth\*q \*q" integer \*q .TP .BI "Option \*qPanelHeight\*q \*q" integer \*q -Override the flat panel dimensions in pixels. They are used to program the flat panel -registers and normally determined using the video card BIOS. If the wrong dimensions -are used, the system may hang. +Override the flat panel dimensions in pixels. +They are used to program the flat panel registers +and normally determined using the video card BIOS. +If the wrong dimensions are used, the system may hang. .TP .BI "Option \*qUseFBDev\*q \*q" boolean \*q Enable or disable use of an OS-specific framebuffer device interface -(which is not supported on all OSs). See fbdevhw(__drivermansuffix__) +(which is not supported on all OSs). +See +.BR fbdevhw (__drivermansuffix__) for further information. -Default: -.BI on -for PowerPC, -.BI off +Default: +.B on +for PowerPC, +.B off for other architectures. .TP .BI "Option \*qDMAForXv\*q \*q" boolean \*q -Try or don't try to use DMA for Xv image transfers. This will reduce CPU -usage when playing big videos like DVDs, but may cause instabilities. +Try or don't try to use DMA for Xv image transfers. +This will reduce CPU usage when playing big videos like DVDs, +but may cause instabilities. Default: off. - +.sp .PP The following additional .B Options are supported: .TP .BI "Option \*qShowCache\*q \*q" boolean \*q -Enable or disable viewing offscreen cache memory. A -development debug option. Default: off. +Enable or disable viewing offscreen cache memory. +A development debug option. +Default: off. .TP .BI "Option \*qVGAAccess\*q \*q" boolean \*q -Tell the driver if it can do legacy VGA IOs to the card. This is -necessary for properly resuming consoles when in VGA text mode, but -shouldn't be if the console is using radeonfb or some other graphic -mode driver. Some platforms like PowerPC have issues with those, and they aren't -necessary unless you have a real text mode in console. The default is +Tell the driver if it can do legacy VGA IOs to the card. +This is necessary for properly resuming consoles when in VGA text mode, +but shouldn't be if the console is using radeonfb or some other graphic +mode driver. +Some platforms like PowerPC have issues with those, +and they aren't necessary unless you have a real text mode in console. +The default is .B off on PowerPC and SPARC and .B on on other architectures. - +.sp .PP -.B Dualhead Note: +.B Dualhead Note: The video BIOS on some laptops interacts strangely with dualhead. This can result in flickering and problems changing modes on crtc2. If you experience these problems try toggling your laptop's video -output switch (e.g., fn-f7, etc.) prior to starting X or switch to -another VT and back. - +output switch (e.g., fn-f7, etc.) prior to starting X, +or switch to another VT and back. +.sp .SH "SEE ALSO" -__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) +.BR Xorg (__appmansuffix__), +.BR xorg.conf (__filemansuffix__), +.BR Xserver (__appmansuffix__), +.BR X (__miscmansuffix__) .SH AUTHORS .nf Rickard E. (Rik) Faith \fIfaith@precisioninsight.com\fP diff --git a/src/atipcirename.h b/src/atipcirename.h index 525476d..3e7f686 100644 --- a/src/atipcirename.h +++ b/src/atipcirename.h @@ -37,6 +37,8 @@ enum region_type { #include #include "xf86Module.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 12 + #if (defined(__alpha__) || defined(__ia64__)) && defined (linux) #define PCI_DOM_MASK 0x01fful #else @@ -58,6 +60,7 @@ pciTag(int busnum, int devnum, int funcnum) return tag; } +#endif /* GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 12 */ #ifndef XSERVER_LIBPCIACCESS diff --git a/src/compat-api.h b/src/compat-api.h index 35e22b4..89976e4 100644 --- a/src/compat-api.h +++ b/src/compat-api.h @@ -28,12 +28,77 @@ #ifndef COMPAT_API_H #define COMPAT_API_H +#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR +#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum] +#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p +#endif + +#ifndef XF86_HAS_SCRN_CONV +#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum] +#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex] +#endif + +#ifndef XF86_SCRN_INTERFACE + +#define SCRN_ARG_TYPE int +#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = xf86Screens[(arg1)] + +#define SCREEN_ARG_TYPE int +#define SCREEN_PTR(arg1) ScreenPtr pScreen = screenInfo.screens[(arg1)] + +#define SCREEN_INIT_ARGS_DECL int i, ScreenPtr pScreen, int argc, char **argv + +#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer pTimeout, pointer pReadmask +#define BLOCKHANDLER_ARGS arg, blockData, pTimeout, pReadmask + +#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr pScreen +#define CLOSE_SCREEN_ARGS scrnIndex, pScreen + +#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags +#define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0 + +#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags +#define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0 + +#define FREE_SCREEN_ARGS_DECL int arg, int flags + +#define VT_FUNC_ARGS_DECL int arg, int flags +#define VT_FUNC_ARGS pScrn->scrnIndex, 0 + +#define XF86_SCRN_ARG(x) ((x)->scrnIndex) +#else +#define SCRN_ARG_TYPE ScrnInfoPtr +#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = (arg1) + +#define SCREEN_ARG_TYPE ScreenPtr +#define SCREEN_PTR(arg1) ScreenPtr pScreen = (arg1) + +#define SCREEN_INIT_ARGS_DECL ScreenPtr pScreen, int argc, char **argv + #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(23, 0) -#define BLOCKHANDLER_ARGS_DECL ScreenPtr pScreen, pointer pTimeout -#define BLOCKHANDLER_ARGS pScreen, pTimeout +#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout +#define BLOCKHANDLER_ARGS arg, pTimeout #else -#define BLOCKHANDLER_ARGS_DECL ScreenPtr pScreen, pointer pTimeout, pointer pReadmask -#define BLOCKHANDLER_ARGS pScreen, pTimeout, pReadmask +#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout, pointer pReadmask +#define BLOCKHANDLER_ARGS arg, pTimeout, pReadmask +#endif + +#define CLOSE_SCREEN_ARGS_DECL ScreenPtr pScreen +#define CLOSE_SCREEN_ARGS pScreen + +#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y +#define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y + +#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode +#define SWITCH_MODE_ARGS(arg, m) arg, m + +#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg + +#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg +#define VT_FUNC_ARGS pScrn + +#define XF86_SCRN_ARG(x) (x) + #endif #endif diff --git a/src/r128.h b/src/r128.h index 5340857..fa4d5ba 100644 --- a/src/r128.h +++ b/src/r128.h @@ -48,7 +48,10 @@ #include "exa.h" #endif - /* Offscreen & Cursor Support */ + /* XAA and Cursor Support */ +#ifdef HAVE_XAA_H +#include "xaa.h" +#endif #include "xf86fbman.h" #include "xf86Cursor.h" @@ -329,11 +332,15 @@ typedef struct { R128SaveRec SavedReg; /* Original (text) mode */ R128SaveRec ModeReg; /* Current mode */ - Bool (*CloseScreen)(ScreenPtr pScreen); + Bool (*CloseScreen)(CLOSE_SCREEN_ARGS_DECL); void (*BlockHandler)(BLOCKHANDLER_ARGS_DECL); Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ +#ifdef HAVE_XAA_H + XAAInfoRecPtr accel; +#endif + Bool noAccel; Bool accelOn; Bool useEXA; @@ -517,6 +524,7 @@ extern void R128EngineFlush(ScrnInfoPtr pScrn); extern unsigned R128INPLL(ScrnInfoPtr pScrn, int addr); extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn); +extern Bool R128XAAAccelInit(ScreenPtr pScreen); extern void R128EngineInit(ScrnInfoPtr pScrn); extern Bool R128CursorInit(ScreenPtr pScreen); diff --git a/src/r128_accel.c b/src/r128_accel.c index 61bec20..581be9c 100644 --- a/src/r128_accel.c +++ b/src/r128_accel.c @@ -101,6 +101,9 @@ /* X and server generic header files */ #include "xf86.h" +#ifdef HAVE_XAA_H +#include "r128_rop.h" +#endif /* Flush all dirty data in the Pixel Cache to memory. */ void R128EngineFlush(ScrnInfoPtr pScrn) @@ -300,6 +303,704 @@ int R128CCEStop(ScrnInfoPtr pScrn) #endif +#ifdef HAVE_XAA_H +/* Setup for XAA SolidFill. */ +static void R128SetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void R128SubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h); +} + +/* Setup for XAA solid lines. */ +static void R128SetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_WRITE_MASK, planemask); +} + + +/* Subsequent XAA solid Bresenham line. + + Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program + + [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for + Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] + + x11perf -line500 + 1024x768@76Hz 1024x768@76Hz + 8bpp 32bpp + not used: 39700.0/sec 34100.0/sec + used: 47600.0/sec 36800.0/sec +*/ +static void R128SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + R128WaitForFifo(pScrn, 6); + OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_BRES_ERR, err); + OUTREG(R128_DST_BRES_INC, minor); + OUTREG(R128_DST_BRES_DEC, -major); + OUTREG(R128_DST_BRES_LNTH, len); +} + +/* Subsequent XAA solid horizontal and vertical lines + + 1024x768@76Hz 8bpp + Without With + x11perf -hseg500 87600.0/sec 798000.0/sec + x11perf -vseg500 38100.0/sec 38000.0/sec +*/ +static void R128SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir ) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 1); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); + + if (dir == DEGREES_0) { + R128SubsequentSolidFillRect(pScrn, x, y, len, 1); + } else { + R128SubsequentSolidFillRect(pScrn, x, y, 1, len); + } +} + +/* Setup for XAA dashed lines. + + Tests: xtest CH05/stdshs, XFree86/drwln + + NOTE: Since we can only accelerate lines with power-of-2 patterns of + length <= 32, these x11perf numbers are not representative of the + speed-up on appropriately-sized patterns. + + 1024x768@76Hz 8bpp + Without With + x11perf -dseg100 218000.0/sec 222000.0/sec + x11perf -dline100 215000.0/sec 221000.0/sec + x11perf -ddline100 178000.0/sec 180000.0/sec +*/ +static void R128SetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + uint32_t pat = *(uint32_t *)(pointer)pattern; + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN +# define PAT_SHIFT(pat,n) pat << n +#else +# define PAT_SHIFT(pat,n) pat >> n +#endif + + switch (length) { + case 2: pat |= PAT_SHIFT(pat,2); /* fall through */ + case 4: pat |= PAT_SHIFT(pat,4); /* fall through */ + case 8: pat |= PAT_SHIFT(pat,8); /* fall through */ + case 16: pat |= PAT_SHIFT(pat,16); + } + + R128WaitForFifo(pScrn, 5); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_32x1_MONO_FG_LA + : R128_GMC_BRUSH_32x1_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_BRUSH_BKGD_CLR, bg); + OUTREG(R128_BRUSH_DATA0, pat); +} + +/* Subsequent XAA dashed line. */ +static void R128SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant, + int phase) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + R128WaitForFifo(pScrn, 7); + OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_BRUSH_Y_X, (phase << 16) | phase); + OUTREG(R128_DST_BRES_ERR, err); + OUTREG(R128_DST_BRES_INC, minor); + OUTREG(R128_DST_BRES_DEC, -major); + OUTREG(R128_DST_BRES_LNTH, len); +} + +#if R128_TRAPEZOIDS + /* This doesn't work. Except in the + lower-left quadrant, all of the pixel + errors appear to be because eL and eR + are not correct. Drawing from right to + left doesn't help. Be aware that the + non-_SUB registers set the sub-pixel + values to 0.5 (0x08), which isn't what + XAA wants. */ +/* Subsequent XAA SolidFillTrap. XAA always passes data that assumes we + fill from top to bottom, so dyL and dyR are always non-negative. */ +static void R128SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + int Lymajor = 0; + int Rymajor = 0; + int origdxL = dxL; + int origdxR = dxR; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Trap %d %d; " + "L %d %d %d %d; " + "R %d %d %d %d\n", + y, h, + left, dxL, dyL, eL, + right, dxR, dyR, eR)); + + if (dxL < 0) dxL = -dxL; else flags |= (1 << 0) /* | (1 << 8) */; + if (dxR < 0) dxR = -dxR; else flags |= (1 << 6); + + R128WaitForFifo(pScrn, 11); + +#if 1 + OUTREG(R128_DP_CNTL, flags | (1 << 1) | (1 << 7)); + OUTREG(R128_DST_Y_SUB, ((y) << 4) | 0x0 ); + OUTREG(R128_DST_X_SUB, ((left) << 4)|0x0); + OUTREG(R128_TRAIL_BRES_ERR, eR-dxR); + OUTREG(R128_TRAIL_BRES_INC, dxR); + OUTREG(R128_TRAIL_BRES_DEC, -dyR); + OUTREG(R128_TRAIL_X_SUB, ((right) << 4) | 0x0); + OUTREG(R128_LEAD_BRES_ERR, eL-dxL); + OUTREG(R128_LEAD_BRES_INC, dxL); + OUTREG(R128_LEAD_BRES_DEC, -dyL); + OUTREG(R128_LEAD_BRES_LNTH_SUB, ((h) << 4) | 0x00); +#else + OUTREG(R128_DP_CNTL, flags | (1 << 1) ); + OUTREG(R128_DST_Y_SUB, (y << 4)); + OUTREG(R128_DST_X_SUB, (right << 4)); + OUTREG(R128_TRAIL_BRES_ERR, eL); + OUTREG(R128_TRAIL_BRES_INC, dxL); + OUTREG(R128_TRAIL_BRES_DEC, -dyL); + OUTREG(R128_TRAIL_X_SUB, (left << 4) | 0); + OUTREG(R128_LEAD_BRES_ERR, eR); + OUTREG(R128_LEAD_BRES_INC, dxR); + OUTREG(R128_LEAD_BRES_DEC, -dyR); + OUTREG(R128_LEAD_BRES_LNTH_SUB, h << 4); +#endif +} +#endif + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void R128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + info->xdir = xdir; + info->ydir = ydir; + R128WaitForFifo(pScrn, 3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) + | (ydir >= 0 + ? R128_DST_Y_TOP_TO_BOTTOM + : 0))); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void R128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (ya << 16) | xa); + OUTREG(R128_DST_Y_X, (yb << 16) | xb); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +/* Setup for XAA mono 8x8 pattern color expansion. Patterns with + transparency use `bg == -1'. This routine is only used if the XAA + pixmap cache is turned on. + + Tests: xtest XFree86/fllrctngl (no other test will test this routine with + both transparency and non-transparency) + + 1024x768@76Hz 8bpp + Without With + x11perf -srect100 38600.0/sec 85700.0/sec + x11perf -osrect100 38600.0/sec 85700.0/sec +*/ +static void R128SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 6); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_8X8_MONO_FG_LA + : R128_GMC_BRUSH_8X8_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_BRUSH_BKGD_CLR, bg); + OUTREG(R128_BRUSH_DATA0, patternx); + OUTREG(R128_BRUSH_DATA1, patterny); +} + +/* Subsequent XAA 8x8 pattern color expansion. Because they are used in + the setup function, `patternx' and `patterny' are not used here. */ +static void R128SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_BRUSH_Y_X, (patterny << 8) | patternx); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +#if 0 +/* Setup for XAA color 8x8 pattern fill. + + Tests: xtest XFree86/fllrctngl (with Mono8x8PatternFill off) +*/ +static void R128SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int rop, unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Color8x8 %d %d %d\n", + trans_color, patx, paty)); + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_8x8_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA 8x8 pattern color expansion. */ +static void R128SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Color8x8 %d,%d %d,%d %d %d\n", + patx, paty, x, y, w, h)); + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (paty << 16) | patx); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} +#endif + +/* Setup for XAA indirect CPU-to-screen color expansion (indirect). + Because of how the scratch buffer is initialized, this is really a + mainstore-to-screen color expansion. Transparency is supported when `bg + == -1'. + + x11perf -ftext (pure indirect): + 1024x768@76Hz 1024x768@76Hz + 8bpp 32bpp + not used: 685000.0/sec 794000.0/sec + used: 1070000.0/sec 1080000.0/sec + + We could improve this indirect routine by about 10% if the hardware + could accept DWORD padded scanlines, or if XAA could provide bit-packed + data. We might also be able to move to a direct routine if there were + more HOST_DATA registers. + + Implementing the hybrid indirect/direct scheme improved performance in a + few areas: + + 1024x768@76 8bpp + Indirect Hybrid + x11perf -oddsrect10 50100.0/sec 71700.0/sec + x11perf -oddsrect100 4240.0/sec 6660.0/sec + x11perf -bigsrect10 50300.0/sec 71100.0/sec + x11perf -bigsrect100 4190.0/sec 6800.0/sec + x11perf -polytext 584000.0/sec 714000.0/sec + x11perf -polytext16 154000.0/sec 172000.0/sec + x11perf -seg1 1780000.0/sec 1880000.0/sec + x11perf -copyplane10 42900.0/sec 58300.0/sec + x11perf -copyplane100 4400.0/sec 6710.0/sec + x11perf -putimagexy10 5090.0/sec 6670.0/sec + x11perf -putimagexy100 424.0/sec 575.0/sec + + 1024x768@76 -depth 24 -fbbpp 32 + Indirect Hybrid + x11perf -oddsrect100 4240.0/sec 6670.0/sec + x11perf -bigsrect100 4190.0/sec 6800.0/sec + x11perf -polytext 585000.0/sec 719000.0/sec + x11perf -seg1 2960000.0/sec 2990000.0/sec + x11perf -copyplane100 4400.0/sec 6700.0/sec + x11perf -putimagexy100 138.0/sec 191.0/sec + +*/ +static void R128SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 4); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); +#else /* X_BYTE_ORDER == X_BIG_ENDIAN */ + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_HOST_DATA)); +#endif + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_SRC_FRGD_CLR, fg); + OUTREG(R128_DP_SRC_BKGD_CLR, bg); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void R128SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int x1clip = x+skipleft; + int x2clip = x+w; + + info->scanline_h = h; + info->scanline_words = (w + 31) >> 5; + +#if 0 + /* Seems as though the Rage128's doesn't like blitting directly + * as we must be overwriting something too quickly, therefore we + * render to the buffer first and then blit */ + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(R128_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else +#endif + { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + if (pScrn->bitsPerPixel == 24) { + x1clip *= 3; + x2clip *= 3; + } + + R128WaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(R128_SC_TOP_LEFT, (y << 16) | (x1clip & 0xffff)); + OUTREG(R128_SC_BOTTOM_RIGHT, ((y+h-1) << 16) | ((x2clip-1) & 0xffff)); + OUTREG(R128_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | ((w + 31) & ~31)); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is called + once for each scanline. */ +static void R128SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + uint32_t *p = (pointer)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile uint32_t *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + write_mem_barrier(); + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + R128WaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} + +/* Setup for XAA indirect image write. + + 1024x768@76Hz 8bpp + Without With + x11perf -putimage10 37500.0/sec 39300.0/sec + x11perf -putimage100 2150.0/sec 1170.0/sec + x11perf -putimage500 108.0/sec 49.8/sec + */ +static void R128SetupForScanlineImageWrite(ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int trans_color, + int bpp, + int depth) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + info->scanline_bpp = bpp; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_1X8_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(R128_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA indirect image write. This is only called once for each + rectangle. */ +static void R128SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int x1clip = x+skipleft; + int x2clip = x+w; + + int shift = 0; /* 32bpp */ + + if (pScrn->bitsPerPixel == 8) shift = 3; + else if (pScrn->bitsPerPixel == 16) shift = 1; + + info->scanline_h = h; + info->scanline_words = (w * info->scanline_bpp + 31) >> 5; + +#if 0 + /* Seeing as the CPUToScreen doesn't like this, I've done this + * here too, as it uses pretty much the same path. */ + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(R128_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else +#endif + { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + if (pScrn->bitsPerPixel == 24) { + x1clip *= 3; + x2clip *= 3; + } + + R128WaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(R128_SC_TOP_LEFT, (y << 16) | (x1clip & 0xffff)); + OUTREG(R128_SC_BOTTOM_RIGHT, ((y+h-1) << 16) | ((x2clip-1) & 0xffff)); + OUTREG(R128_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | ((w + shift) & ~shift)); +} + +/* Subsequent XAA indirect image write. This is called once for each + scanline. */ +static void R128SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + uint32_t *p = (pointer)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile uint32_t *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + write_mem_barrier(); + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + R128WaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} +#endif /* Initialize the acceleration hardware. */ void R128EngineInit(ScrnInfoPtr pScrn) @@ -398,6 +1099,452 @@ void R128EngineInit(ScrnInfoPtr pScrn) #ifdef R128DRI +#ifdef HAVE_XAA_H + +/* Setup for XAA SolidFill. */ +static void R128CCESetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 8 ); + + OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern) ); + + OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, color ); + OUT_RING_REG( R128_DP_WRITE_MASK, planemask ); + OUT_RING_REG( R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT | + R128_DST_Y_TOP_TO_BOTTOM)); + ADVANCE_RING(); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void R128CCESubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 4 ); + + OUT_RING_REG( R128_DST_Y_X, (y << 16) | x ); + OUT_RING_REG( R128_DST_WIDTH_HEIGHT, (w << 16) | h ); + + ADVANCE_RING(); +} + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void R128CCESetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + info->xdir = xdir; + info->ydir = ydir; + + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | R128_GMC_BRUSH_NONE + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY) ); + + OUT_RING_REG( R128_DP_WRITE_MASK, planemask ); + OUT_RING_REG( R128_DP_CNTL, + ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) | + (ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0)) ); + + ADVANCE_RING(); + + if (trans_color != -1) { + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_CLR_CMP_CLR_SRC, trans_color ); + OUT_RING_REG( R128_CLR_CMP_MASK, R128_CLR_CMP_MSK ); + OUT_RING_REG( R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR | + R128_CLR_CMP_SRC_SOURCE) ); + + ADVANCE_RING(); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void R128CCESubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_SRC_Y_X, (ya << 16) | xa ); + OUT_RING_REG( R128_DST_Y_X, (yb << 16) | xb ); + OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (h << 16) | w ); + + ADVANCE_RING(); +} + + +/* + * XAA scanline color expansion + * + * We use HOSTDATA_BLT CCE packets, dividing the image in chunks that fit into + * the indirect buffer if necessary. + */ +static void R128CCESetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 2 ); + OUT_RING_REG(R128_DP_WRITE_MASK, planemask); + ADVANCE_RING(); + + info->scanline_rop = rop; + info->scanline_fg = fg; + info->scanline_bg = bg; +} + +/* Helper function to write out a HOSTDATA_BLT packet into the indirect buffer + and set the XAA scratch buffer address appropriately */ +static void R128CCEScanlineCPUToScreenColorExpandFillPacket(ScrnInfoPtr pScrn, + int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + int chunk_words = info->scanline_hpass * info->scanline_words; + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( chunk_words+9 ); + + OUT_RING( CCE_PACKET3( R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, chunk_words+9-2 ) ); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + OUT_RING( (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (info->scanline_bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[info->scanline_rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); +#else /* X_BYTE_ORDER == X_BIG_ENDIAN */ + OUT_RING( (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (info->scanline_bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[info->scanline_rop].rop + | R128_DP_SRC_SOURCE_HOST_DATA)); +#endif + OUT_RING( (info->scanline_y << 16) | (info->scanline_x1clip & 0xffff) ); + OUT_RING( ((info->scanline_y+info->scanline_hpass-1) << 16) | ((info->scanline_x2clip-1) & 0xffff) ); + OUT_RING( info->scanline_fg ); + OUT_RING( info->scanline_bg ); + OUT_RING( (info->scanline_y << 16) | (info->scanline_x & 0xffff)); + + /* Have to pad the width here and use clipping engine */ + OUT_RING( (info->scanline_hpass << 16) | ((info->scanline_w + 31) & ~31)); + + OUT_RING( chunk_words ); + + info->scratch_buffer[bufno] = (unsigned char *) &__head[__count]; + __count += chunk_words; + + ADVANCE_RING(); + + info->scanline_y += info->scanline_hpass; + info->scanline_h -= info->scanline_hpass; + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s: hpass=%d, words=%d => chunk_words=%d, y=%d, h=%d\n", + __FUNCTION__, info->scanline_hpass, info->scanline_words, + chunk_words, info->scanline_y, info->scanline_h ); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void R128CCESubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + +#define BUFSIZE ( R128_BUFFER_SIZE/4-9 ) + + info->scanline_x = x; + info->scanline_y = y; + info->scanline_w = w; + info->scanline_h = h; + + info->scanline_x1clip = x+skipleft; + info->scanline_x2clip = x+w; + + info->scanline_words = (w + 31) >> 5; + info->scanline_hpass = min(h,(BUFSIZE/info->scanline_words)); + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s: x=%d, y=%d, w=%d, h=%d, skipleft=%d => x1clip=%d, x2clip=%d, hpass=%d, words=%d\n", + __FUNCTION__, x, y, w, h, skipleft, info->scanline_x1clip, info->scanline_x2clip, + info->scanline_hpass, info->scanline_words ); + + R128CCEScanlineCPUToScreenColorExpandFillPacket(pScrn, 0); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is called + once for each scanline. */ +static void R128CCESubsequentColorExpandScanline(ScrnInfoPtr pScrn, + int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s enter: scanline_hpass=%d, scanline_h=%d\n", + __FUNCTION__, info->scanline_hpass, info->scanline_h ); + + if (--info->scanline_hpass) { + info->scratch_buffer[bufno] += 4 * info->scanline_words; + } + else if(info->scanline_h) { + info->scanline_hpass = min(info->scanline_h,(BUFSIZE/info->scanline_words)); + R128CCEScanlineCPUToScreenColorExpandFillPacket(pScrn, bufno); + } + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s exit: scanline_hpass=%d, scanline_h=%d\n", + __FUNCTION__, info->scanline_hpass, info->scanline_h ); +} + +/* Solid lines */ +static void R128CCESetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 6 ); + + OUT_RING_REG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUT_RING_REG(R128_DP_BRUSH_FRGD_CLR, color); + OUT_RING_REG(R128_DP_WRITE_MASK, planemask); + + ADVANCE_RING(); +} + +static void R128CCESubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant) +{ + R128InfoPtr info = R128PTR(pScrn); + int flags = 0; + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + BEGIN_RING( 12 ); + + OUT_RING_REG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUT_RING_REG(R128_DST_Y_X, (y << 16) | x); + OUT_RING_REG(R128_DST_BRES_ERR, err); + OUT_RING_REG(R128_DST_BRES_INC, minor); + OUT_RING_REG(R128_DST_BRES_DEC, -major); + OUT_RING_REG(R128_DST_BRES_LNTH, len); + + ADVANCE_RING(); +} + +static void R128CCESubsequentSolidHorVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir ) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 2 ); + + OUT_RING_REG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); + + ADVANCE_RING(); + + if (dir == DEGREES_0) { + R128CCESubsequentSolidFillRect(pScrn, x, y, len, 1); + } else { + R128CCESubsequentSolidFillRect(pScrn, x, y, 1, len); + } +} + +/* Dashed lines */ +static void R128CCESetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + R128InfoPtr info = R128PTR(pScrn); + uint32_t pat = *(uint32_t *)(pointer)pattern; + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN +# define PAT_SHIFT(pat,n) pat << n +#else +# define PAT_SHIFT(pat,n) pat >> n +#endif + + switch (length) { + case 2: pat |= PAT_SHIFT(pat,2); /* fall through */ + case 4: pat |= PAT_SHIFT(pat,4); /* fall through */ + case 8: pat |= PAT_SHIFT(pat,8); /* fall through */ + case 16: pat |= PAT_SHIFT(pat,16); + } + + BEGIN_RING( 10 ); + + OUT_RING_REG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_32x1_MONO_FG_LA + : R128_GMC_BRUSH_32x1_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUT_RING_REG(R128_DP_WRITE_MASK, planemask); + OUT_RING_REG(R128_DP_BRUSH_FRGD_CLR, fg); + OUT_RING_REG(R128_DP_BRUSH_BKGD_CLR, bg); + OUT_RING_REG(R128_BRUSH_DATA0, pat); + + ADVANCE_RING(); +} + +static void R128CCESubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant, + int phase) +{ + R128InfoPtr info = R128PTR(pScrn); + int flags = 0; + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + BEGIN_RING( 14 ); + + OUT_RING_REG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUT_RING_REG(R128_DST_Y_X, (y << 16) | x); + OUT_RING_REG(R128_BRUSH_Y_X, (phase << 16) | phase); + OUT_RING_REG(R128_DST_BRES_ERR, err); + OUT_RING_REG(R128_DST_BRES_INC, minor); + OUT_RING_REG(R128_DST_BRES_DEC, -major); + OUT_RING_REG(R128_DST_BRES_LNTH, len); + + ADVANCE_RING(); +} + +/* Mono 8x8 pattern color expansion */ +static void R128CCESetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 12 ); + + OUT_RING_REG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_8X8_MONO_FG_LA + : R128_GMC_BRUSH_8X8_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUT_RING_REG(R128_DP_WRITE_MASK, planemask); + OUT_RING_REG(R128_DP_BRUSH_FRGD_CLR, fg); + OUT_RING_REG(R128_DP_BRUSH_BKGD_CLR, bg); + OUT_RING_REG(R128_BRUSH_DATA0, patternx); + OUT_RING_REG(R128_BRUSH_DATA1, patterny); + + ADVANCE_RING(); +} + +static void R128CCESubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 6 ); + + OUT_RING_REG(R128_BRUSH_Y_X, (patterny << 8) | patternx); + OUT_RING_REG(R128_DST_Y_X, (y << 16) | x); + OUT_RING_REG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); + + ADVANCE_RING(); +} +#endif + /* Get an indirect buffer for the CCE 2D acceleration commands. */ drmBufPtr R128CCEGetBuffer( ScrnInfoPtr pScrn ) @@ -515,6 +1662,202 @@ void R128CCEReleaseIndirect( ScrnInfoPtr pScrn ) &indirect, sizeof(drmR128Indirect)); } +#ifdef HAVE_XAA_H +/* This callback is required for multihead cards using XAA */ +static +void R128RestoreCCEAccelState(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); +/* unsigned char *R128MMIO = info->MMIO; needed for OUTREG below */ + /*xf86DrvMsg(pScrn->scrnIndex, X_INFO, "===>RestoreCP\n");*/ + + R128WaitForFifo(pScrn, 1); +/* is this needed on r128 + OUTREG( R128_DEFAULT_OFFSET, info->frontPitchOffset); +*/ + R128WaitForIdle(pScrn); + + /* FIXME: May need to restore other things, + like BKGD_CLK FG_CLK...*/ + +} + +static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + R128InfoPtr info = R128PTR(pScrn); + + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); + + /* Sync */ + a->Sync = R128CCEWaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = R128CCESetupForSolidFill; + a->SubsequentSolidFillRect = R128CCESubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + /* Transparency uses the wrong colors for + 24 bpp mode -- the transparent part is + correct, but the opaque color is wrong. + This can be seen with netscape's I-bar + cursor when editing in the URL location + box. */ + a->ScreenToScreenCopyFlags = ((pScrn->bitsPerPixel == 24) + ? NO_TRANSPARENCY + : 0); + a->SetupForScreenToScreenCopy = R128CCESetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = R128CCESubsequentScreenToScreenCopy; + + /* Indirect CPU-To-Screen Color Expand */ + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_buffer[0] = NULL; + a->SetupForScanlineCPUToScreenColorExpandFill + = R128CCESetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = R128CCESubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = R128CCESubsequentColorExpandScanline; + + /* Bresenham Solid Lines */ + a->SetupForSolidLine = R128CCESetupForSolidLine; + a->SubsequentSolidBresenhamLine = R128CCESubsequentSolidBresenhamLine; + a->SubsequentSolidHorVertLine = R128CCESubsequentSolidHorVertLine; + + /* Bresenham Dashed Lines*/ + a->SetupForDashedLine = R128CCESetupForDashedLine; + a->SubsequentDashedBresenhamLine = R128CCESubsequentDashedBresenhamLine; + a->DashPatternMaxLength = 32; + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + | LINE_PATTERN_POWER_OF_2_ONLY); + + /* Mono 8x8 Pattern Fill (Color Expand) */ + a->SetupForMono8x8PatternFill = R128CCESetupForMono8x8PatternFill; + a->SubsequentMono8x8PatternFillRect = R128CCESubsequentMono8x8PatternFillRect; + a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST); + + if (xf86IsEntityShared(info->pEnt->index)) + a->RestoreAccelState = R128RestoreCCEAccelState; + +} +#endif +#endif + +#ifdef HAVE_XAA_H +/* This callback is required for multihead cards using XAA */ +static +void R128RestoreAccelState(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DEFAULT_OFFSET, pScrn->fbOffset); + OUTREG(R128_DEFAULT_PITCH, info->pitch); + + /* FIXME: May need to restore other things, + like BKGD_CLK FG_CLK...*/ + + R128WaitForIdle(pScrn); + +} + +static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + R128InfoPtr info = R128PTR(pScrn); + + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); + + /* Sync */ + a->Sync = R128WaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = R128SetupForSolidFill; + a->SubsequentSolidFillRect = R128SubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + /* Transparency uses the wrong colors for + 24 bpp mode -- the transparent part is + correct, but the opaque color is wrong. + This can be seen with netscape's I-bar + cursor when editing in the URL location + box. */ + a->ScreenToScreenCopyFlags = ((pScrn->bitsPerPixel == 24) + ? NO_TRANSPARENCY + : 0); + a->SetupForScreenToScreenCopy = R128SetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = R128SubsequentScreenToScreenCopy; + + /* Mono 8x8 Pattern Fill (Color Expand) */ + a->SetupForMono8x8PatternFill = R128SetupForMono8x8PatternFill; + a->SubsequentMono8x8PatternFillRect = R128SubsequentMono8x8PatternFillRect; + a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST); + + /* Indirect CPU-To-Screen Color Expand */ + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_save = malloc(((pScrn->virtualX+31)/32*4) + + (pScrn->virtualX + * info->CurrentLayout.pixel_bytes)); + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineCPUToScreenColorExpandFill + = R128SetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = R128SubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = R128SubsequentColorExpandScanline; + + /* Bresenham Solid Lines */ + a->SetupForSolidLine = R128SetupForSolidLine; + a->SubsequentSolidBresenhamLine = R128SubsequentSolidBresenhamLine; + a->SubsequentSolidHorVertLine = R128SubsequentSolidHorVertLine; + + /* Bresenham Dashed Lines*/ + a->SetupForDashedLine = R128SetupForDashedLine; + a->SubsequentDashedBresenhamLine = R128SubsequentDashedBresenhamLine; + a->DashPatternMaxLength = 32; + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + | LINE_PATTERN_POWER_OF_2_ONLY); + + /* ImageWrite */ + a->NumScanlineImageWriteBuffers = 1; + a->ScanlineImageWriteBuffers = info->scratch_buffer; + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineImageWrite = R128SetupForScanlineImageWrite; + a->SubsequentScanlineImageWriteRect= R128SubsequentScanlineImageWriteRect; + a->SubsequentImageWriteScanline = R128SubsequentImageWriteScanline; + a->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD + /* Performance tests show that we shouldn't use GXcopy for + * uploads as a memcpy is faster */ + | NO_GXCOPY + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X + | SCANLINE_PAD_DWORD; + + if (xf86IsEntityShared(info->pEnt->index)) { + /* If there are more than one devices sharing this entity, we + * have to assign this call back, otherwise the XAA will be + * disabled. + */ + if (xf86GetNumEntityInstances(info->pEnt->index) > 1) + a->RestoreAccelState = R128RestoreAccelState; + } + +} #endif void R128CopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap) @@ -553,3 +1896,27 @@ void R128CopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap) if (src != dst) memcpy(dst, src, size); } + +/* Initialize XAA for supported acceleration and also initialize the + graphics hardware for acceleration. */ +#ifdef HAVE_XAA_H +Bool +R128XAAAccelInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + R128InfoPtr info = R128PTR(pScrn); + XAAInfoRecPtr a; + + if (!(a = info->accel = XAACreateInfoRec())) return FALSE; + +#ifdef R128DRI + if (info->directRenderingEnabled) + R128CCEAccelInit(pScrn, a); + else +#endif + R128MMIOAccelInit(pScrn, a); + + R128EngineInit(pScrn); + return XAAInit(pScreen, a); +} +#endif diff --git a/src/r128_crtc.c b/src/r128_crtc.c index d3d192c..1ce4979 100644 --- a/src/r128_crtc.c +++ b/src/r128_crtc.c @@ -965,6 +965,9 @@ static Bool r128_crtc_lock(xf86CrtcPtr crtc) ScreenPtr pScreen = xf86ScrnToScreen(pScrn); R128InfoPtr info = R128PTR(pScrn); +#ifdef HAVE_XAA_H + if (info->accel) info->accel->Sync(pScrn); +#endif #ifdef USE_EXA if (info->ExaDriver) exaWaitSync(pScreen); #endif @@ -978,6 +981,9 @@ static void r128_crtc_unlock(xf86CrtcPtr crtc) ScreenPtr pScreen = xf86ScrnToScreen(pScrn); R128InfoPtr info = R128PTR(pScrn); +#ifdef HAVE_XAA_H + if (info->accel) info->accel->Sync(pScrn); +#endif #ifdef USE_EXA if (info->ExaDriver) exaWaitSync(pScreen); #endif @@ -1046,6 +1052,10 @@ static void r128_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, #ifdef USE_EXA if (info->ExaDriver) exaOffscreenFree(pScreen, (ExaOffscreenArea *) r128_crtc->rotate_mem); +#endif +#ifdef HAVE_XAA_H + if (info->accel) + xf86FreeOffscreenLinear((FBLinearPtr) r128_crtc->rotate_mem); #endif r128_crtc->rotate_mem = NULL; } diff --git a/src/r128_dri.c b/src/r128_dri.c index 560ef33..5db1b50 100644 --- a/src/r128_dri.c +++ b/src/r128_dri.c @@ -99,6 +99,9 @@ static void R128EnterServer(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); R128InfoPtr info = R128PTR(pScrn); +#ifdef HAVE_XAA_H + if (info->accel) info->accel->NeedToSync = TRUE; +#endif #ifdef USE_EXA if (info->ExaDriver) exaMarkSync(pScreen); /* EXA and DRI are fighting over control of the texture hardware. @@ -160,6 +163,11 @@ static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) ScreenPtr pScreen = pWin->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); R128InfoPtr info = R128PTR(pScrn); +#ifdef HAVE_XAA_H + BoxPtr pbox, pboxSave; + int nbox, nboxSave; + int depth; +#endif /* FIXME: Use accel when CCE 2D code is written * EA: What is this code kept for? Radeon doesn't have it and @@ -168,6 +176,51 @@ static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) */ if (info->directRenderingEnabled) return; +#ifdef HAVE_XAA_H + /* FIXME: This should be based on the __GLXvisualConfig info */ + switch (pScrn->bitsPerPixel) { + case 8: depth = 0x000000ff; break; + case 16: depth = 0x0000ffff; break; + case 24: depth = 0x00ffffff; break; + case 32: depth = 0xffffffff; break; + default: depth = 0x00000000; break; + } + + /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */ + /* FIXME: Only initialize the back and depth buffers for contexts + that request them */ + + pboxSave = pbox = REGION_RECTS(prgn); + nboxSave = nbox = REGION_NUM_RECTS(prgn); + + (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, (uint32_t)(-1)); + for (; nbox; nbox--, pbox++) { + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->fbX, + pbox->y1 + info->fbY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->backX, + pbox->y1 + info->backY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + + pbox = pboxSave; + nbox = nboxSave; + + /* FIXME: this needs to consider depth tiling. */ + (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, (uint32_t)(-1)); + for (; nbox; nbox--, pbox++) + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->depthX, + pbox->y1 + info->depthY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + + info->accel->NeedToSync = TRUE; +#endif } /* Copy the back and depth buffers when the X server moves a window. */ @@ -1139,6 +1192,13 @@ static void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0) return; +#ifdef HAVE_XAA_H + if (!info->useEXA) { + (*info->accel->SetupForScreenToScreenCopy)(pScrn, + 1, 1, GXcopy, + (uint32_t)(-1), -1); + } +#endif #ifdef USE_EXA if (info->useEXA) { uint32_t src_pitch_offset, dst_pitch_offset, datatype; @@ -1157,6 +1217,15 @@ static void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1); if (xa <= xb && ya <= yb) { +#ifdef HAVE_XAA_H + if (!info->useEXA) { + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya, + xa + info->backX, + ya + info->backY, + xb - xa + 1, + yb - ya + 1); + } +#endif #ifdef USE_EXA if (info->useEXA) { (*info->ExaDriver->Copy)(pPix, xa, ya, xa, ya, xb - xa + 1, yb - ya + 1); @@ -1175,6 +1244,21 @@ static void R128EnablePageFlip(ScreenPtr pScreen) if (info->allowPageFlip) { /* Duplicate the frontbuffer to the backbuffer */ +#ifdef HAVE_XAA_H + if (!info->useEXA) { + (*info->accel->SetupForScreenToScreenCopy)(pScrn, + 1, 1, GXcopy, + (uint32_t)(-1), -1); + + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, + 0, + 0, + info->backX, + info->backY, + pScrn->virtualX, + pScrn->virtualY); + } +#endif #ifdef USE_EXA if (info->useEXA) { uint32_t src_pitch_offset, dst_pitch_offset, datatype; diff --git a/src/r128_driver.c b/src/r128_driver.c index fc42bfa..dba2cb5 100644 --- a/src/r128_driver.c +++ b/src/r128_driver.c @@ -92,6 +92,10 @@ #include "xf86.h" #include "xf86_OSproc.h" #include "xf86RandR12.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 +#include "xf86RAC.h" +#include "xf86Resources.h" +#endif #include "xf86cmap.h" #include "xf86xv.h" #include "vbe.h" @@ -111,7 +115,7 @@ #include #endif -static Bool R128CloseScreen(ScreenPtr pScreen); +static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL); static Bool R128SaveScreen(ScreenPtr pScreen, int mode); static void R128Save(ScrnInfoPtr pScrn); static void R128Restore(ScrnInfoPtr pScrn); @@ -1438,6 +1442,12 @@ R128PreInitAccel(ScrnInfoPtr pScrn) if ((!info->useEXA) || ((info->useEXA) && (!info->accelOn))) { +#ifdef HAVE_XAA_H + if (xf86LoadSubModule(pScrn, "xaa")) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Loading XAA module.\n"); + } +#endif } } } @@ -1548,7 +1558,9 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags) info->useEXA = FALSE; #ifdef USE_EXA +#ifndef HAVE_XAA_H info->useEXA = TRUE; +#endif #endif info->swCursor = FALSE; @@ -1691,6 +1703,7 @@ static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors, static void R128BlockHandler(BLOCKHANDLER_ARGS_DECL) { + SCREEN_PTR(arg); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); R128InfoPtr info = R128PTR(pScrn); @@ -1709,7 +1722,7 @@ R128BlockHandler(BLOCKHANDLER_ARGS_DECL) } /* Called at the start of each server generation. */ -Bool R128ScreenInit(ScreenPtr pScreen, int argc, char **argv) +Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); R128InfoPtr info = R128PTR(pScrn); @@ -1929,8 +1942,14 @@ Bool R128ScreenInit(ScreenPtr pScreen, int argc, char **argv) } if (!info->noAccel) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Acceleration disabled.\n"); + if (R128XAAAccelInit(pScreen)) { + info->accelOn = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "XAA acceleration enabled.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Acceleration disabled.\n"); + } } } } @@ -2083,7 +2102,7 @@ Bool R128ScreenInit(ScreenPtr pScreen, int argc, char **argv) } R128SaveScreen(pScreen, SCREEN_SAVER_ON); - //pScrn->AdjustFrame(pScrn, pScrn->frameX0, pScrn->frameY0); + //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); /* DGA setup */ #ifdef XFreeXDGA @@ -2714,8 +2733,9 @@ static Bool R128SaveScreen(ScreenPtr pScreen, int mode) * The workaround is to switch the mode, then switch to another VT, then * switch back. --AGD */ -Bool R128SwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +Bool R128SwitchMode(SWITCH_MODE_ARGS_DECL) { + SCRN_INFO_PTR(arg); R128InfoPtr info = R128PTR(pScrn); Bool ret; @@ -2794,9 +2814,10 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags) } /* Used to disallow modes that are not supported by the hardware. */ -ModeStatus R128ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, +ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) { + SCRN_INFO_PTR(arg); R128EntPtr pR128Ent = R128EntPriv(pScrn); xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]); @@ -2805,8 +2826,9 @@ ModeStatus R128ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, /* Adjust viewport into virtual desktop such that (0,0) in viewport space is (x,y) in virtual space. */ -void R128AdjustFrame(ScrnInfoPtr pScrn, int x, int y) +void R128AdjustFrame(ADJUST_FRAME_ARGS_DECL) { + SCRN_INFO_PTR(arg); R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; int Base; @@ -2833,8 +2855,9 @@ void R128AdjustFrame(ScrnInfoPtr pScrn, int x, int y) /* Called when VT switching back to the X server. Reinitialize the video mode. */ -Bool R128EnterVT(ScrnInfoPtr pScrn) +Bool R128EnterVT(VT_FUNC_ARGS_DECL) { + SCRN_INFO_PTR(arg); R128InfoPtr info = R128PTR(pScrn); DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2842,7 +2865,7 @@ Bool R128EnterVT(ScrnInfoPtr pScrn) pScrn->vtSema = TRUE; if (info->FBDev) { - if (!fbdevHWEnterVT(pScrn)) return FALSE; + if (!fbdevHWEnterVT(VT_FUNC_ARGS)) return FALSE; } else { if (!xf86SetDesiredModes(pScrn)) return FALSE; } @@ -2865,15 +2888,16 @@ Bool R128EnterVT(ScrnInfoPtr pScrn) #endif info->PaletteSavedOnVT = FALSE; - //pScrn->AdjustFrame(pScrn, pScrn->frameX0, pScrn->frameY0); + //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); return TRUE; } /* Called when VT switching away from the X server. Restore the original text mode. */ -void R128LeaveVT(ScrnInfoPtr pScrn) +void R128LeaveVT(VT_FUNC_ARGS_DECL) { + SCRN_INFO_PTR(arg); R128InfoPtr info = R128PTR(pScrn); R128SavePtr save = &info->ModeReg; @@ -2892,7 +2916,7 @@ void R128LeaveVT(ScrnInfoPtr pScrn) R128SavePalette(pScrn, save); info->PaletteSavedOnVT = TRUE; if (info->FBDev) - fbdevHWLeaveVT(pScrn); + fbdevHWLeaveVT(VT_FUNC_ARGS); else R128Restore(pScrn); } @@ -2901,7 +2925,7 @@ void R128LeaveVT(ScrnInfoPtr pScrn) /* Called at the end of each server generation. Restore the original text mode, unmap video memory, and unwrap and call the saved CloseScreen function. */ -static Bool R128CloseScreen(ScreenPtr pScreen) +static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); R128InfoPtr info = R128PTR(pScrn); @@ -2923,10 +2947,16 @@ static Bool R128CloseScreen(ScreenPtr pScreen) } #ifdef USE_EXA - if (info->useEXA) { - exaDriverFini(pScreen); - free(info->ExaDriver); - } + if (info->useEXA) { + exaDriverFini(pScreen); + free(info->ExaDriver); + } else +#endif +#ifdef HAVE_XAA_H + { + if (info->accel) XAADestroyInfoRec(info->accel); + info->accel = NULL; + } #endif if (info->scratch_save) free(info->scratch_save); @@ -2942,11 +2972,12 @@ static Bool R128CloseScreen(ScreenPtr pScreen) pScreen->BlockHandler = info->BlockHandler; pScreen->CloseScreen = info->CloseScreen; - return (*pScreen->CloseScreen)(pScreen); + return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); } -void R128FreeScreen(ScrnInfoPtr pScrn) +void R128FreeScreen(FREE_SCREEN_ARGS_DECL) { + SCRN_INFO_PTR(arg); R128InfoPtr info = R128PTR(pScrn); DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, diff --git a/src/r128_output.c b/src/r128_output.c index 6543971..ff95fbf 100644 --- a/src/r128_output.c +++ b/src/r128_output.c @@ -333,7 +333,7 @@ static R128MonitorType R128DisplayDDCConnected(xf86OutputPtr output) /* XXX: Radeon does something here to appease old monitors. */ OUTREG(pR128I2CBus->ddc_reg, INREG(pR128I2CBus->ddc_reg) | mask1); OUTREG(pR128I2CBus->ddc_reg, INREG(pR128I2CBus->ddc_reg) & ~mask2); - *MonInfo = xf86DoEDID_DDC2(pScrn, r128_output->pI2CBus); + *MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), r128_output->pI2CBus); } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n"); return MT_NONE; @@ -555,7 +555,10 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn) output = R128OutputCreate(pScrn, "DVI-%d", --num_dvi); } - if (!output) return FALSE; + if (!output) { + free(r128_output); + return FALSE; + } output->interlaceAllowed = TRUE; output->doubleScanAllowed = TRUE; output->driver_private = r128_output; diff --git a/src/r128_probe.c b/src/r128_probe.c index e1a5a9f..6cb3c3a 100644 --- a/src/r128_probe.c +++ b/src/r128_probe.c @@ -44,6 +44,10 @@ #include "xf86.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 +#include "xf86Resources.h" +#endif + #include "r128_probe.h" #ifndef XSERVER_LIBPCIACCESS diff --git a/src/r128_probe.h b/src/r128_probe.h index f66bfb8..4026989 100644 --- a/src/r128_probe.h +++ b/src/r128_probe.h @@ -169,13 +169,13 @@ extern SymTabRec R128Chipsets[]; /* r128_driver.c */ extern Bool R128PreInit(ScrnInfoPtr, int); -extern Bool R128ScreenInit(ScreenPtr pScreen, int argc, char **argv); -extern Bool R128SwitchMode(ScrnInfoPtr pScrnInfo, DisplayModePtr mode); -extern void R128AdjustFrame(ScrnInfoPtr arg, int x, int y); -extern Bool R128EnterVT(ScrnInfoPtr pScrn); -extern void R128LeaveVT(ScrnInfoPtr pScrn); -extern void R128FreeScreen(ScrnInfoPtr pScrn); -extern ModeStatus R128ValidMode(ScrnInfoPtr, DisplayModePtr, Bool, int); +extern Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL); +extern Bool R128SwitchMode(SWITCH_MODE_ARGS_DECL); +extern void R128AdjustFrame(ADJUST_FRAME_ARGS_DECL); +extern Bool R128EnterVT(VT_FUNC_ARGS_DECL); +extern void R128LeaveVT(VT_FUNC_ARGS_DECL); +extern void R128FreeScreen(FREE_SCREEN_ARGS_DECL); +extern ModeStatus R128ValidMode(SCRN_ARG_TYPE, DisplayModePtr, Bool, int); extern const OptionInfoRec * R128OptionsWeak(void); diff --git a/src/r128_video.c b/src/r128_video.c index fc057f4..d819e88 100644 --- a/src/r128_video.c +++ b/src/r128_video.c @@ -585,6 +585,12 @@ R128AllocateMemory( Bool do_linear = !need_accel; uint32_t offset = 0; +#ifdef HAVE_XAA_H + if (!info->accel && need_accel) + do_linear = FALSE; + else + do_linear = TRUE; +#endif #ifdef USE_EXA if (info->ExaDriver) { ExaOffscreenArea *area = *mem_struct;