diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/Imakefile xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/Imakefile --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/Imakefile 2005-08-30 13:44:21.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/Imakefile 2005-08-30 14:09:16.000000000 +1000 @@ -24,6 +24,14 @@ #define IHaveModules #include + +XAA_DEFINES = -DUSE_XAA + +EXA_DIR = -I$(XF86SRC)/exa +EXA_DEFINES = -DUSE_EXA +RADEON_EXA_SOURCE = radeon_exa.c +RADEON_EXA_OBJS = radeon_exa.o + #ifdef ATIDriverCCOptions CCOPTIONS = ATIDriverCCOptions #endif @@ -186,7 +194,7 @@ #endif DEFINES = $(CPIODEFINES) $(DGADEFINES) $(NONPCIDEFINES) $(DRIDEFINES) \ - $(TVOUTDEFINES) $(VGAHWDEFINES) + $(TVOUTDEFINES) $(VGAHWDEFINES) $(EXA_DEFINES) $(XAA_DEFINES) SRCS1 = ati.c atiadapter.c atibus.c atichip.c atiident.c atioption.c \ atiprobe.c atividmem.c $(CPIOSRCS1) $(MODSRCS1) \ @@ -201,7 +209,7 @@ r128_video.c $(DRISRCS3) $(MODSRCS3) SRCS4 = radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c radeon_driver.c \ radeon_video.c radeon_bios.c radeon_mm_i2c.c radeon_vip.c \ - $(DRISRCS4) $(MODSRCS4) + $(RADEON_EXA_SOURCE) $(DRISRCS4) $(MODSRCS4) SRCS_THEATRE_DETECT = theatre.c $(MODSRC_THEATRE_DETECT) SRCS_THEATRE = theatre.c $(MODSRC_THEATRE) SRCS_THEATRE200 = theatre200.c $(MODSRC_THEATRE200) @@ -219,7 +227,7 @@ r128_video.o $(DRIOBJS3) $(MODOBJS3) OBJS4 = radeon_accel.o radeon_mergedfb.o radeon_cursor.o radeon_dga.o radeon_driver.o \ radeon_video.o radeon_bios.o radeon_mm_i2c.o radeon_vip.o \ - $(DRIOBJS4) $(MODOBJS4) + $(RADEON_EXA_OBJS) $(DRIOBJS4) $(MODOBJS4) OBJS_THEATRE_DETECT = theatre_detect.o $(MODOBJ_THEATRE_DETECT) OBJS_THEATRE = theatre.o $(MODOBJ_THEATRE) OBJS_THEATRE200 = theatre200.o $(MODOBJ_THEATRE200) @@ -234,7 +242,7 @@ -I$(XF86SRC)/vbe -I$(XF86SRC)/int10 \ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ -I$(XF86SRC)/rac -I$(XF86SRC)/ramdac \ - -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa $(EXA_DIR) \ -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \ diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon.h --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h 2005-08-17 11:55:36.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon.h 2005-08-31 10:27:53.000000000 +1000 @@ -43,8 +43,15 @@ /* PCI support */ #include "xf86Pci.h" - /* XAA and Cursor Support */ +#ifdef USE_EXA +#include "exa.h" +#endif +#ifdef USE_XAA #include "xaa.h" +#include "xf86fbman.h" +#endif + + /* Exa and Cursor Support */ #include "vbe.h" #include "xf86Cursor.h" @@ -122,6 +129,7 @@ #define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) #define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate) + typedef struct { /* Common registers */ CARD32 ovr_clr; @@ -382,11 +390,21 @@ Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ +#ifdef USE_EXA + ExaDriverRec exa; +#endif +#ifdef USE_XAA XAAInfoRecPtr accel; +#endif Bool accelOn; xf86CursorInfoPtr cursor; - unsigned long cursor_start; +#ifdef USE_EXA + ExaOffscreenArea *cursorArea; +#endif + unsigned long cursor_offset; +#ifdef USE_XAA unsigned long cursor_end; +#endif Bool allowColorTiling; Bool tilingEnabled; /* mirror of sarea->tiling_enabled */ #ifdef ARGB_CURSOR @@ -395,11 +413,13 @@ int cursor_fg; int cursor_bg; +#ifdef USE_XAA /* * XAAForceTransBlit is used to change the behavior of the XAA * SetupForScreenToScreenCopy function, to make it DGA-friendly. */ Bool XAAForceTransBlit; +#endif int fifo_slots; /* Free slots in the FIFO (64 max) */ int pix24bpp; /* Depth of pixmap for 24bpp fb */ @@ -416,6 +436,12 @@ int xdir; int ydir; +#ifdef USE_EXA + int scratch_offset; + int scratch_next; + ExaOffscreenArea *scratch_area; +#endif +#ifdef USE_XAA /* ScanlineScreenToScreenColorExpand support */ unsigned char *scratch_buffer[1]; unsigned char *scratch_save; @@ -432,7 +458,7 @@ int scanline_hpass; int scanline_x1clip; int scanline_x2clip; - +#endif /* Saved values for DashedTwoPointLine */ int dashLen; CARD32 dashPattern; @@ -539,6 +565,7 @@ int textureSize; int log2TexGran; +#ifdef USE_XAA CARD32 frontPitchOffset; CARD32 backPitchOffset; CARD32 depthPitchOffset; @@ -548,6 +575,7 @@ FBAreaPtr backArea; int depthTexLines; FBAreaPtr depthTexArea; +#endif /* Saved scissor values */ CARD32 sc_left; @@ -577,7 +605,9 @@ /* XVideo */ XF86VideoAdaptorPtr adaptor; void (*VideoTimerCallback)(ScrnInfoPtr, Time); +#ifdef USE_XAA FBLinearPtr videoLinear; +#endif int videoKey; int RageTheatreCrystal; int RageTheatreTunerPort; @@ -600,19 +630,31 @@ CARD8 input[5]; } MM_TABLE; CARD16 video_decoder_type; - /* Render */ + + /* Render */ Bool RenderAccel; - Bool RenderInited3D; +#ifdef USE_XAA FBLinearPtr RenderTex; void (*RenderCallback)(ScrnInfoPtr); Time RenderTimeout; +#endif - /* general */ + /* general */ Bool showCache; OptionInfoPtr Options; + + Bool useEXA; #ifdef XFree86LOADER +#ifdef USE_EXA + XF86ModReqInfo exaReq; +#endif +#ifdef USE_XAA XF86ModReqInfo xaaReq; #endif +#endif + + /* X itself has the 3D context */ + Bool XInited3D; /* merged fb stuff, also covers clone modes */ Bool MergedFB; @@ -689,11 +731,22 @@ extern void RADEONChangeSurfaces(ScrnInfoPtr pScrn); extern Bool RADEONAccelInit(ScreenPtr pScreen); +#ifdef USE_EXA +extern Bool RADEONSetupMemEXA (ScreenPtr pScreen); +extern Bool RADEONDrawInitMMIO(ScreenPtr pScreen); +#ifdef XF86DRI +extern Bool RADEONDrawInitCP(ScreenPtr pScreen); +#endif +#endif +#ifdef USE_XAA extern void RADEONAccelInitMMIO(ScreenPtr pScreen, XAAInfoRecPtr a); +#endif extern void RADEONEngineInit(ScrnInfoPtr pScrn); extern Bool RADEONCursorInit(ScreenPtr pScreen); extern Bool RADEONDGAInit(ScreenPtr pScreen); +extern void RADEONInit3DEngine(ScrnInfoPtr pScrn); + extern int RADEONMinBits(int val); extern void RADEONInitVideo(ScreenPtr pScreen); @@ -704,7 +757,9 @@ extern void RADEONPllErrataAfterData(RADEONInfoPtr info); #ifdef XF86DRI +#ifdef USE_XAA extern void RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a); +#endif extern Bool RADEONDRIScreenInit(ScreenPtr pScreen); extern void RADEONDRICloseScreen(ScreenPtr pScreen); extern void RADEONDRIResume(ScreenPtr pScreen); @@ -719,10 +774,14 @@ unsigned int w, CARD32 dstPitch, CARD32 *bufPitch, CARD8 **dst, unsigned int *h, unsigned int *hpass); -extern void RADEONHostDataBlitCopyPass(CARD8 *dst, CARD8 *src, +extern void RADEONHostDataBlitCopyPass(ScrnInfoPtr pScrn, + unsigned int bpp, + CARD8 *dst, CARD8 *src, unsigned int hpass, unsigned int dstPitch, unsigned int srcPitch); +extern void RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size, + int swap); extern Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10); extern Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn); @@ -903,19 +962,43 @@ #define RADEON_FLUSH_CACHE() \ do { \ BEGIN_RING(2); \ - OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB2D_DC_FLUSH); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH); \ ADVANCE_RING(); \ } while (0) #define RADEON_PURGE_CACHE() \ do { \ BEGIN_RING(2); \ - OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB2D_DC_FLUSH_ALL); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \ ADVANCE_RING(); \ } while (0) #endif /* XF86DRI */ +static __inline__ void RADEON_MARK_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn) +{ +#ifdef USE_EXA + if (info->useEXA) + exaMarkSync(pScrn->pScreen); +#endif +#ifdef USE_XAA + if (!info->useEXA) + SET_SYNC_FLAG(info->accel); +#endif +} + +static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn) +{ +#ifdef USE_EXA + if (info->useEXA) + exaWaitSync(pScrn->pScreen); +#endif +#ifdef USE_XAA + if (!info->useEXA && info->accel) + info->accel->Sync(pScrn); +#endif +} + #endif /* _RADEON_H_ */ diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c 2005-08-17 11:55:36.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c 2005-08-31 10:30:53.000000000 +1000 @@ -93,6 +93,7 @@ /* X and server generic header files */ #include "xf86.h" + static struct { int rop; int pattern; @@ -153,11 +154,11 @@ unsigned char *RADEONMMIO = info->MMIO; int i; - OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT, - RADEON_RB2D_DC_FLUSH_ALL, - ~RADEON_RB2D_DC_FLUSH_ALL); + OUTREGP(RADEON_RB3D_DSTCACHE_CTLSTAT, + RADEON_RB3D_DC_FLUSH_ALL, + ~RADEON_RB3D_DC_FLUSH_ALL); for (i = 0; i < RADEON_TIMEOUT; i++) { - if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY)) + if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY)) break; } } @@ -249,8 +250,8 @@ RADEON_SOFT_RESET_E2)); INREG(RADEON_RBBM_SOFT_RESET); OUTREG(RADEON_RBBM_SOFT_RESET, 0); - tmp = INREG(RADEON_RB2D_DSTCACHE_MODE); - OUTREG(RADEON_RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */ + tmp = INREG(RADEON_RB3D_DSTCACHE_MODE); + OUTREG(RADEON_RB3D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */ } else { OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | RADEON_SOFT_RESET_CP | @@ -295,7 +296,7 @@ RADEONWaitForFifo(pScrn, 1); - /* NOTE: The following RB2D_DSTCACHE_MODE setting will cause the + /* NOTE: The following RB3D_DSTCACHE_MODE setting will cause the * R300 to hang. ATI does not see a reason to change it from the * default BIOS settings (even on non-R300 cards). This setting * might be removed in future versions of the Radeon driver. @@ -303,7 +304,7 @@ /* Turn of all automatic flushing - we'll do it all */ if (!IS_R300_VARIANT) - OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0); + OUTREG(RADEON_RB3D_DSTCACHE_MODE, 0); pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6; @@ -342,9 +343,7 @@ RADEONWaitForIdleMMIO(pScrn); -#ifdef RENDER - info->RenderInited3D = FALSE; -#endif + info->XInited3D = FALSE; } /* Initialize the acceleration hardware */ @@ -353,6 +352,12 @@ RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + ErrorF("Initializing engine !\n"); + + ErrorF("EngineInit (%d/%d)\n", + info->CurrentLayout.pixel_code, + info->CurrentLayout.bitsPerPixel); + RADEONTRACE(("EngineInit (%d/%d)\n", info->CurrentLayout.pixel_code, info->CurrentLayout.bitsPerPixel)); @@ -376,6 +381,7 @@ info->pitch = ((info->CurrentLayout.displayWidth / 8) * (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1)); + ErrorF("Pitch for acceleration = %d\n", info->pitch); RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch)); info->dp_gui_master_cntl = @@ -399,13 +405,15 @@ RADEONEngineRestore(pScrn); } + #define ACCEL_MMIO #define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO #define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) #define OUT_ACCEL_REG(reg, val) OUTREG(reg, val) #define FINISH_ACCEL() -#ifdef RENDER +#include "radeon_commonfuncs.c" +#if defined(RENDER) && defined(USE_XAA) #include "radeon_render.c" #endif #include "radeon_accelfuncs.c" @@ -426,7 +434,9 @@ #define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val) #define FINISH_ACCEL() ADVANCE_RING() -#ifdef RENDER + +#include "radeon_commonfuncs.c" +#if defined(RENDER) && defined(USE_XAA) #include "radeon_render.c" #endif #include "radeon_accelfuncs.c" @@ -656,14 +666,22 @@ } #if X_BYTE_ORDER == X_BIG_ENDIAN - BEGIN_RING(2); - if (bpp == 2) - OUT_RING_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_16BIT); - else if (bpp == 1) - OUT_RING_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT); - else - OUT_RING_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE); - ADVANCE_RING(); + /* Swap doesn't work on R300 and later, it's handled during the + * copy to ind. buffer pass + */ + if (info->ChipFamily < CHIP_FAMILY_R300) { + BEGIN_RING(2); + if (bpp == 2) + OUT_RING_REG(RADEON_RBBM_GUICNTL, + RADEON_HOST_DATA_SWAP_HDW); + else if (bpp == 1) + OUT_RING_REG(RADEON_RBBM_GUICNTL, + RADEON_HOST_DATA_SWAP_32BIT); + else + OUT_RING_REG(RADEON_RBBM_GUICNTL, + RADEON_HOST_DATA_SWAP_NONE); + ADVANCE_RING(); + } #endif /*RADEON_PURGE_CACHE(); @@ -704,11 +722,61 @@ return ret; } +void RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size, int swap) +{ + switch(swap) { + case RADEON_HOST_DATA_SWAP_HDW: + { + unsigned int *d = (unsigned int *)dst; + unsigned int *s = (unsigned int *)src; + unsigned int nwords = size >> 2; + + for (; nwords > 0; --nwords, ++d, ++s) + *d = ((*s & 0xffff) << 16) | ((*s >> 16) & 0xffff); + return; + } + case RADEON_HOST_DATA_SWAP_32BIT: + { + unsigned int *d = (unsigned int *)dst; + unsigned int *s = (unsigned int *)src; + unsigned int nwords = size >> 2; + + for (; nwords > 0; --nwords, ++d, ++s) +#ifdef __powerpc__ + asm volatile("stwbrx %0,0,%1" : : "r" (*s), "r" (d)); +#else + *d = ((*s >> 24) & 0xff) | ((*s >> 8) & 0xff00) + | ((*s & 0xff00) << 8) | ((*s & 0xff) << 24); +#endif + return; + } + case RADEON_HOST_DATA_SWAP_16BIT: + { + unsigned short *d = (unsigned short *)dst; + unsigned short *s = (unsigned short *)src; + unsigned int nwords = size >> 1; + + for (; nwords > 0; --nwords, ++d, ++s) +#ifdef __powerpc__ + asm volatile("stwbrx %0,0,%1" : : "r" (*s), "r" (d)); +#else + *d = ((*s >> 24) & 0xff) | ((*s >> 8) & 0xff00) + | ((*s & 0xff00) << 8) | ((*s & 0xff) << 24); +#endif + return; + } + } + if (src != dst) + memmove(dst, src, size); +} + /* Copies a single pass worth of data for a hostdata blit set up by * RADEONHostDataBlit(). */ void RADEONHostDataBlitCopyPass( + ScrnInfoPtr pScrn, + unsigned int bpp, CARD8 *dst, CARD8 *src, unsigned int hpass, @@ -716,11 +784,27 @@ unsigned int srcPitch ){ + RADEONInfoPtr info = RADEONPTR( pScrn ); + /* RADEONHostDataBlitCopy can return NULL ! */ if( (dst==NULL) || (src==NULL)) return; if ( dstPitch == srcPitch ) { +#if X_BYTE_ORDER == X_BIG_ENDIAN + if (info->ChipFamily >= CHIP_FAMILY_R300) { + switch(bpp) { + case 1: + RADEONCopySwap(dst, src, hpass * dstPitch, + RADEON_HOST_DATA_SWAP_32BIT); + return; + case 2: + RADEONCopySwap(dst, src, hpass * dstPitch, + RADEON_HOST_DATA_SWAP_HDW); + return; + } + } +#endif memcpy( dst, src, hpass * dstPitch ); } else @@ -728,7 +812,22 @@ unsigned int minPitch = min( dstPitch, srcPitch ); while ( hpass-- ) { +#if X_BYTE_ORDER == X_BIG_ENDIAN + if (info->ChipFamily >= CHIP_FAMILY_R300) { + switch(bpp) { + case 1: + RADEONCopySwap(dst, src, minPitch, + RADEON_HOST_DATA_SWAP_32BIT); + goto next; + case 2: + RADEONCopySwap(dst, src, minPitch, + RADEON_HOST_DATA_SWAP_HDW); + goto next; + } + } +#endif memcpy( dst, src, minPitch ); + next: src += srcPitch; dst += dstPitch; } @@ -737,33 +836,69 @@ #endif -/* Initialize XAA for supported acceleration and also initialize the - * graphics hardware for acceleration - */ Bool RADEONAccelInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); - XAAInfoRecPtr a; - if (!(a = info->accel = XAACreateInfoRec())) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAACreateInfoRec Error\n"); - return FALSE; +#ifdef USE_EXA + if (info->useEXA) { +# ifdef XF86DRI + if (info->directRenderingEnabled) { + if (!RADEONDrawInitCP(pScreen)) + return FALSE; + } else +# endif /* XF86DRI */ + { + if (!RADEONDrawInitMMIO(pScreen)) + return FALSE; + } } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + XAAInfoRecPtr a; + + if (!(a = info->accel = XAACreateInfoRec())) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAACreateInfoRec Error\n"); + return FALSE; + } #ifdef XF86DRI - if (info->directRenderingEnabled) - RADEONAccelInitCP(pScreen, a); - else -#endif - RADEONAccelInitMMIO(pScreen, a); + if (info->directRenderingEnabled) + RADEONAccelInitCP(pScreen, a); + else +#endif /* XF86DRI */ + RADEONAccelInitMMIO(pScreen, a); + + RADEONEngineInit(pScrn); + + if (!XAAInit(pScreen, a)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAAInit Error\n"); + return FALSE; + } + } +#endif /* USE_XAA */ + return TRUE; +} - RADEONEngineInit(pScrn); +void RADEONInit3DEngine(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR (pScrn); - if (!XAAInit(pScreen, a)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAAInit Error\n"); - return FALSE; - } + ErrorF("Initing 3D engine !\n"); - return TRUE; +#ifdef XF86DRI + if (info->directRenderingEnabled) { + RADEONSAREAPrivPtr pSAREAPriv; + + pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen); + RADEONInit3DEngineCP(pScrn); + } else +#endif + RADEONInit3DEngineMMIO(pScrn); + + info->XInited3D = TRUE; } + diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c 2005-08-17 11:55:36.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c 2005-08-31 09:25:30.000000000 +1000 @@ -95,82 +95,7 @@ #endif #endif -/* MMIO: - * - * Wait for the graphics engine to be completely idle: the FIFO has - * drained, the Pixel Cache is flushed, and the engine is idle. This is - * a standard "sync" function that will make the hardware "quiescent". - * - * CP: - * - * Wait until the CP is completely idle: the FIFO has drained and the CP - * is idle. - */ -void -FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - int i = 0; - -#ifdef ACCEL_CP - /* Make sure the CP is idle first */ - if (info->CPStarted) { - int ret; - FLUSH_RING(); - - for (;;) { - do { - ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); - if (ret && ret != -EBUSY) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "%s: CP idle %d\n", __FUNCTION__, ret); - } - } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT)); - - if (ret == 0) return; - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Idle timed out, resetting engine...\n"); - RADEONEngineReset(pScrn); - RADEONEngineRestore(pScrn); - - /* Always restart the engine when doing CP 2D acceleration */ - RADEONCP_RESET(pScrn, info); - RADEONCP_START(pScrn, info); - } - } -#endif - - RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS))); - - /* Wait for the engine to go idle */ - RADEONWaitForFifoFunction(pScrn, 64); - - for (;;) { - for (i = 0; i < RADEON_TIMEOUT; i++) { - if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { - RADEONEngineFlush(pScrn); - return; - } - } - RADEONTRACE(("Idle timed out: %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS))); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Idle timed out, resetting engine...\n"); - RADEONEngineReset(pScrn); - RADEONEngineRestore(pScrn); -#ifdef XF86DRI - if (info->directRenderingEnabled) { - RADEONCP_RESET(pScrn, info); - RADEONCP_START(pScrn, info); - } -#endif - } -} +#ifdef USE_XAA /* This callback is required for multiheader cards using XAA */ static void @@ -775,6 +700,8 @@ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); + info->scanline_bpp = 0; + /* Save for later clipping */ info->dp_gui_master_cntl_clip = (info->dp_gui_master_cntl | RADEON_GMC_DST_CLIPPING @@ -812,9 +739,12 @@ #if X_BYTE_ORDER == X_LITTLE_ENDIAN BEGIN_ACCEL(1); #else - BEGIN_ACCEL(2); + if (info->ChipFamily < CHIP_FAMILY_R300) { + BEGIN_ACCEL(2); - OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT); + OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT); + } else + BEGIN_ACCEL(1); #endif OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); @@ -939,6 +869,21 @@ #else /* ACCEL_CP */ +#if X_BYTE_ORDER == X_BIG_ENDIAN + if (info->ChipFamily >= CHIP_FAMILY_R300) { + if (info->scanline_bpp == 16) + RADEONCopySwap(info->scratch_buffer[bufno], + info->scratch_buffer[bufno], + info->scanline_words << 2, + RADEON_HOST_DATA_SWAP_HDW); + else if (info->scanline_bpp < 15) + RADEONCopySwap(info->scratch_buffer[bufno], + info->scratch_buffer[bufno], + info->scanline_words << 2, + RADEON_HOST_DATA_SWAP_32BIT); + } +#endif + if (--info->scanline_hpass) { info->scratch_buffer[bufno] += 4 * info->scanline_words; } else if (info->scanline_h) { @@ -994,12 +939,15 @@ #if X_BYTE_ORDER == X_LITTLE_ENDIAN BEGIN_ACCEL(1); #else - BEGIN_ACCEL(2); + if (info->ChipFamily < CHIP_FAMILY_R300) { + BEGIN_ACCEL(2); - if (bpp == 16) - OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW); - else - OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE); + if (bpp == 16) + OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW); + else + OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE); + } else + BEGIN_ACCEL(1); #endif #endif OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); @@ -1225,7 +1173,8 @@ = FUNC_NAME(RADEONSetupForScanlineCPUToScreenColorExpandFill); a->SubsequentScanlineCPUToScreenColorExpandFill = FUNC_NAME(RADEONSubsequentScanlineCPUToScreenColorExpandFill); - a->SubsequentColorExpandScanline = FUNC_NAME(RADEONSubsequentScanline); + a->SubsequentColorExpandScanline + = FUNC_NAME(RADEONSubsequentScanline); /* Solid Lines */ a->SetupForSolidLine @@ -1394,4 +1343,6 @@ #endif /* RENDER */ } +#endif /* USE_XAA */ + #undef FUNC_NAME diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_commonfuncs.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_commonfuncs.c --- /dev/null 2005-08-22 11:32:55.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_commonfuncs.c 2005-08-31 10:50:58.000000000 +1000 @@ -0,0 +1,231 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#if defined(ACCEL_MMIO) && defined(ACCEL_CP) +#error Cannot define both MMIO and CP acceleration! +#endif + +#if !defined(UNIXCPP) || defined(ANSICPP) +#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix +#else +#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix +#endif + +#ifdef ACCEL_MMIO +#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO) +#else +#ifdef ACCEL_CP +#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP) +#else +#error No accel type defined! +#endif +#endif + +static void FUNC_NAME(RadeonInit3DEngine)(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ACCEL_PREAMBLE(); + + if (info->ChipFamily >= CHIP_FAMILY_R300) { + /* Unimplemented */ + } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || + (info->ChipFamily == CHIP_FAMILY_RV280) || + (info->ChipFamily == CHIP_FAMILY_RS300) || + (info->ChipFamily == CHIP_FAMILY_R200)) { + + BEGIN_ACCEL(7); + if (info->ChipFamily == CHIP_FAMILY_RS300) { + OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS); + } else { + OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0); + } + OUT_ACCEL_REG(R200_PP_CNTL_X, 0); + OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0); + OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0); + OUT_ACCEL_REG(R200_RE_CNTL, 0x0); + /* XXX: correct? Want it to be like RADEON_VTX_ST?_NONPARAMETRIC */ + OUT_ACCEL_REG(R200_SE_VTE_CNTL, R200_VTX_ST_DENORMALIZED); + OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE | + R200_VAP_VF_MAX_VTX_NUM); + FINISH_ACCEL(); + } else { + BEGIN_ACCEL(2); + if ((info->ChipFamily == CHIP_FAMILY_RADEON) || + (info->ChipFamily == CHIP_FAMILY_RV200)) + OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0); + else + OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS); + OUT_ACCEL_REG(RADEON_SE_COORD_FMT, + RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_ST0_NONPARAMETRIC | + RADEON_VTX_ST1_NONPARAMETRIC | + RADEON_TEX1_W_ROUTING_USE_W0); + FINISH_ACCEL(); + } + + BEGIN_ACCEL(3); + OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); + OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff); + OUT_ACCEL_REG(RADEON_SE_CNTL, RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX); + FINISH_ACCEL(); +} + + +#if defined(ACCEL_MMIO) && defined(ACCEL_CP) +#error Cannot define both MMIO and CP acceleration! +#endif + +#if !defined(UNIXCPP) || defined(ANSICPP) +#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix +#else +#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix +#endif + +#ifdef ACCEL_MMIO +#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO) +#else +#ifdef ACCEL_CP +#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP) +#else +#error No accel type defined! +#endif +#endif + +static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ACCEL_PREAMBLE(); + + if (info->ChipFamily >= CHIP_FAMILY_R300) { + /* Unimplemented */ + } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || + (info->ChipFamily == CHIP_FAMILY_RV280) || + (info->ChipFamily == CHIP_FAMILY_RS300) || + (info->ChipFamily == CHIP_FAMILY_R200)) { + + BEGIN_ACCEL(7); + if (info->ChipFamily == CHIP_FAMILY_RS300) { + OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS); + } else { + OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0); + } + OUT_ACCEL_REG(R200_PP_CNTL_X, 0); + OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0); + OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0); + OUT_ACCEL_REG(R200_RE_CNTL, 0x0); + /* XXX: correct? Want it to be like RADEON_VTX_ST?_NONPARAMETRIC */ + OUT_ACCEL_REG(R200_SE_VTE_CNTL, R200_VTX_ST_DENORMALIZED); + OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE | + R200_VAP_VF_MAX_VTX_NUM); + FINISH_ACCEL(); + } else { + BEGIN_ACCEL(2); + if ((info->ChipFamily == CHIP_FAMILY_RADEON) || + (info->ChipFamily == CHIP_FAMILY_RV200)) + OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0); + else + OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS); + OUT_ACCEL_REG(RADEON_SE_COORD_FMT, + RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_ST0_NONPARAMETRIC | + RADEON_VTX_ST1_NONPARAMETRIC | + RADEON_TEX1_W_ROUTING_USE_W0); + FINISH_ACCEL(); + } + + BEGIN_ACCEL(3); + OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); + OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff); + OUT_ACCEL_REG(RADEON_SE_CNTL, RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX); + FINISH_ACCEL(); +} + + +/* MMIO: + * + * Wait for the graphics engine to be completely idle: the FIFO has + * drained, the Pixel Cache is flushed, and the engine is idle. This is + * a standard "sync" function that will make the hardware "quiescent". + * + * CP: + * + * Wait until the CP is completely idle: the FIFO has drained and the CP + * is idle. + */ +void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i = 0; + +#ifdef ACCEL_CP + /* Make sure the CP is idle first */ + if (info->CPStarted) { + int ret; + + FLUSH_RING(); + + for (;;) { + do { + ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); + if (ret && ret != -EBUSY) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "%s: CP idle %d\n", __FUNCTION__, ret); + } + } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT)); + + if (ret == 0) return; + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); + + /* Always restart the engine when doing CP 2D acceleration */ + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + } + } +#endif + + RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + + /* Wait for the engine to go idle */ + RADEONWaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { + RADEONEngineFlush(pScrn); + return; + } + } + RADEONTRACE(("Idle timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); +#ifdef XF86DRI + if (info->directRenderingEnabled) { + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + } +#endif + } +} diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c 2005-08-17 11:55:36.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c 2005-08-29 07:51:46.000000000 +1000 @@ -68,9 +68,7 @@ #define CURSOR_WIDTH 64 #define CURSOR_HEIGHT 64 -#define COMMON_CURSOR_SWAPPING_START() \ - if (info->accel && info->accel->Sync) \ - info->accel->Sync(pScrn); +#define COMMON_CURSOR_SWAPPING_START() RADEON_SYNC(info, pScrn) /* * The cursor bits are always 32bpp. On MSBFirst buses, @@ -108,7 +106,7 @@ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { RADEONInfoPtr info = RADEONPTR(pScrn); - CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_start); + CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_offset); int pixel, i; CURSOR_SWAPPING_DECL_MMIO @@ -173,7 +171,7 @@ OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); - OUTREG(RADEON_CUR_OFFSET, info->cursor_start + yorigin * stride); + OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride); } else { OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK | (xorigin << 16) @@ -182,7 +180,7 @@ | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); OUTREG(RADEON_CUR2_OFFSET, - info->cursor_start + pScrn->fbOffset + yorigin * stride); + info->cursor_offset + pScrn->fbOffset + yorigin * stride); } } @@ -195,7 +193,7 @@ RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; CARD8 *s = (CARD8 *)(pointer)image; - CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_start); + CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset); CARD32 save1 = 0; CARD32 save2 = 0; CARD8 chunk; @@ -279,7 +277,7 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); - return info->cursor_start ? TRUE : FALSE; + return info->cursor_offset ? TRUE : FALSE; } #ifdef ARGB_CURSOR @@ -290,7 +288,7 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); - if (info->cursor_start && + if (info->cursor_offset && pCurs->bits->height <= CURSOR_HEIGHT && pCurs->bits->width <= CURSOR_WIDTH) return TRUE; return FALSE; @@ -300,7 +298,7 @@ { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_start); + CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset); int x, y, w, h; CARD32 save1 = 0; CARD32 save2 = 0; @@ -361,6 +359,18 @@ #endif +#ifdef USE_EXA +static void +ATICursorSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + info->cursorArea = NULL; + info->cursor_offset = 0; +} +#endif + /* Initialize hardware cursor support. */ Bool RADEONCursorInit(ScreenPtr pScreen) @@ -368,7 +378,6 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); xf86CursorInfoPtr cursor; - FBAreaPtr fbarea; int width; int width_bytes; int height; @@ -405,29 +414,49 @@ width = pScrn->displayWidth; width_bytes = width * (pScrn->bitsPerPixel / 8); height = (size_bytes + width_bytes - 1) / width_bytes; - fbarea = xf86AllocateOffscreenArea(pScreen, - width, - height, - 256, - NULL, - NULL, - NULL); - - if (!fbarea) { - info->cursor_start = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + +#ifdef USE_EXA + if (info->useEXA) { + info->cursorArea = exaOffscreenAlloc(pScreen, size_bytes, + 128, TRUE, ATICursorSave, info); + + if (!info->cursorArea) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to insufficient offscreen memory\n"); + info->cursor_offset = 0; + } else { + info->cursor_offset = info->cursorArea->offset; + } + + RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", + info->cursor_offset, + info->cursor_offset + info->cursorArea->size)); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + FBAreaPtr fbarea; + + fbarea = xf86AllocateOffscreenArea(pScreen, width, height, + 256, NULL, NULL, NULL); + + if (!fbarea) { + info->cursor_offset = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Hardware cursor disabled" " due to insufficient offscreen memory\n"); - } else { - info->cursor_start = RADEON_ALIGN((fbarea->box.x1 + - fbarea->box.y1 * width) * - info->CurrentLayout.pixel_bytes, - 256); - info->cursor_end = info->cursor_start + size_bytes; + } else { + info->cursor_offset = RADEON_ALIGN((fbarea->box.x1 + + fbarea->box.y1 * width) * + info->CurrentLayout.pixel_bytes, + 256); + info->cursor_end = info->cursor_offset + size_bytes; + } + RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", + info->cursor_offset, info->cursor_end)); } - - RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", - info->cursor_start, info->cursor_end)); +#endif return xf86InitCursor(pScreen, cursor); } diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c 2005-08-17 11:55:36.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c 2005-08-29 07:51:46.000000000 +1000 @@ -61,9 +61,10 @@ static void RADEON_SetViewport(ScrnInfoPtr, int, int, int); static void RADEON_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); static void RADEON_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#ifdef USE_XAA static void RADEON_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, unsigned long); - +#endif static DGAModePtr RADEONSetupDGAMode(ScrnInfoPtr pScrn, DGAModePtr modes, @@ -112,7 +113,17 @@ if (pixmap) currentMode->flags |= DGA_PIXMAP_AVAILABLE; - if (info->accel) { +#ifdef USE_EXA + if (info->useEXA) { + /* XXX: This is probably not correct */ + if (info->exa.accel.PrepareSolid && info->exa.accel.Solid) + currentMode->flags |= DGA_FILL_RECT; + if (info->exa.accel.PrepareCopy && info->exa.accel.Copy) + currentMode->flags |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS; + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA && info->accel) { if (info->accel->SetupForSolidFill && info->accel->SubsequentSolidFillRect) currentMode->flags |= DGA_FILL_RECT; @@ -124,6 +135,8 @@ DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS)) currentMode->flags &= ~DGA_CONCURRENT_ACCESS; } +#endif /* USE_XAA */ + if (pMode->Flags & V_DBLSCAN) currentMode->flags |= DGA_DOUBLESCAN; if (pMode->Flags & V_INTERLACE) @@ -237,7 +250,20 @@ info->DGAFuncs.BlitRect = NULL; info->DGAFuncs.BlitTransRect = NULL; - if (info->accel) { +#ifdef USE_EXA + /*FIXME*/ + /*info->DGAFuncs.Sync = info->exa.accel->Sync;*/ + if (info->useEXA) { + if (info->exa.accel.PrepareSolid && info->exa.accel.Solid) { + info->DGAFuncs.FillRect = RADEON_FillRect; + } + if (info->exa.accel.PrepareCopy && info->exa.accel.Copy) { + info->DGAFuncs.BlitRect = RADEON_BlitRect; + } + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA && info->accel) { info->DGAFuncs.Sync = info->accel->Sync; if (info->accel->SetupForSolidFill && info->accel->SubsequentSolidFillRect) @@ -248,6 +274,7 @@ info->DGAFuncs.BlitTransRect = RADEON_BlitTransRect; } } +#endif /* USE_XAA */ return DGAInit(pScreen, &info->DGAFuncs, modes, num); } @@ -332,17 +359,33 @@ info->DGAViewportStatus = 0; /* FIXME */ } + static void RADEON_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) { RADEONInfoPtr info = RADEONPTR(pScrn); - (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, (CARD32)(~0)); - (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h); +#ifdef USE_EXA + /* XXX */ + if (info->useEXA) { + /* + info->exa.accel.PrepareSolid(pScrn, color, GXcopy, (CARD32)(~0)); + info->exa.accel.Solid(pScrn, x, y, x+w, y+h); + info->exa.accel.DoneSolid(); + */ + RADEON_MARK_SYNC(info, pScrn); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, (CARD32)(~0)); + (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h); + if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel) + RADEON_MARK_SYNC(info, pScrn); + } +#endif /* USE_XAA */ - if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel) - SET_SYNC_FLAG(info->accel); } static void RADEON_BlitRect(ScrnInfoPtr pScrn, @@ -353,15 +396,30 @@ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; int ydir = (srcy < dsty) ? -1 : 1; - (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, - GXcopy, (CARD32)(~0), -1); - (*info->accel->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, - dstx, dsty, w, h); - - if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel) - SET_SYNC_FLAG(info->accel); + #ifdef USE_EXA + /* XXX */ + if (info->useEXA) { + /* + info->exa.accel.PrepareCopy(pScrn, color, GXcopy, (CARD32)(~0)); + info->exa.accel.Copy(pScrn, srcx, srcy, dstx, dsty, w, h); + info->exa.accel.DoneCopy(); + */ + RADEON_MARK_SYNC(info, pScrn); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, + GXcopy, (CARD32)(~0), -1); + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, + dstx, dsty, w, h); + if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel) + RADEON_MARK_SYNC(info, pScrn); + } +#endif /* USE_XAA */ } +#ifdef USE_XAA static void RADEON_BlitTransRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long color) @@ -371,7 +429,6 @@ int ydir = (srcy < dsty) ? -1 : 1; info->XAAForceTransBlit = TRUE; - (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, (CARD32)(~0), color); @@ -381,8 +438,9 @@ dstx, dsty, w, h); if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel) - SET_SYNC_FLAG(info->accel); + RADEON_MARK_SYNC(info, pScrn); } +#endif /* USE_XAA */ static Bool RADEON_OpenFramebuffer(ScrnInfoPtr pScrn, char **name, diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 2005-08-30 13:44:21.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 2005-08-31 09:29:41.000000000 +1000 @@ -347,17 +347,15 @@ { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); -#ifdef RENDER RADEONSAREAPrivPtr pSAREAPriv; -#endif - if (info->accel) info->accel->NeedToSync = TRUE; -#ifdef RENDER + RADEON_MARK_SYNC(info, pScrn); + pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); if (pSAREAPriv->ctxOwner != DRIGetContext(pScrn->pScreen)) - info->RenderInited3D = FALSE; -#endif + info->XInited3D = FALSE; + /* TODO: Fix this more elegantly. * Sometimes (especially with multiple DRI clients), this code @@ -528,6 +526,7 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 indx) { +#ifdef USE_XAA ScreenPtr pScreen = pParent->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); @@ -551,6 +550,10 @@ int dx = pParent->drawable.x - ptOldOrg.x; int dy = pParent->drawable.y - ptOldOrg.y; + /* XXX: Fix in EXA case. */ + if (info->useEXA) + return; + /* If the copy will overlap in Y, reverse the order */ if (dy > 0) { ydir = -1; @@ -683,6 +686,7 @@ DEALLOCATE_LOCAL(pboxNew1); info->accel->NeedToSync = TRUE; +#endif /* USE_XAA */ } static void RADEONDRIInitGARTValues(RADEONInfoPtr info) @@ -1183,7 +1187,10 @@ /* Make sure the CP is on for the X server */ RADEONCP_START(pScrn, info); - info->dst_pitch_offset = info->frontPitchOffset; +#ifdef USE_XAA + if (!info->useEXA) /* XXX? */ + info->dst_pitch_offset = info->frontPitchOffset; +#endif } @@ -1276,7 +1283,7 @@ RADEON_VERSION_MAJOR_TILED : RADEON_VERSION_MAJOR; pDRIInfo->ddxDriverMinorVersion = RADEON_VERSION_MINOR; pDRIInfo->ddxDriverPatchVersion = RADEON_VERSION_PATCH; - pDRIInfo->frameBufferPhysicalAddress = info->LinearAddr; + pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr; pDRIInfo->frameBufferSize = info->FbMapSize; pDRIInfo->frameBufferStride = (pScrn->displayWidth * info->CurrentLayout.pixel_bytes); @@ -1394,7 +1401,7 @@ req_minor = 10; req_patch = 0; } else if (info->ChipFamily >= CHIP_FAMILY_R300) { - req_minor = 17; + req_minor = 12; req_patch = 0; } else if (info->ChipFamily >= CHIP_FAMILY_R200) { req_minor = 5; @@ -1527,6 +1534,8 @@ info->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; /* info->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ + ErrorF("RADEONDRIFinishScreenInit\n"); + /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit * because *DRIKernelInit requires that the hardware lock is held by * the X server, and the first time the hardware lock is grabbed is @@ -1602,7 +1611,7 @@ #endif /* Have shadowfb run only while there is 3d active. */ - if (info->allowPageFlip /* && info->drmMinor >= 3 */) { + if (!info->useEXA && info->allowPageFlip /* && info->drmMinor >= 3 */) { ShadowFBInit( pScreen, RADEONDRIRefreshArea ); } else { info->allowPageFlip = 0; @@ -1795,6 +1804,8 @@ if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0) return; +#ifdef USE_XAA + /* XXX: implement for EXA */ /* pretty much a hack. */ if (info->tilingEnabled) info->dst_pitch_offset |= RADEON_DST_TILE_MACRO; @@ -1815,6 +1826,7 @@ } } info->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO; +#endif /* USE_XAA */ } static void RADEONEnablePageFlip(ScreenPtr pScreen) @@ -1823,6 +1835,8 @@ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); +#ifdef USE_XAA + /* XXX: Fix in EXA case */ if (info->allowPageFlip) { /* pretty much a hack. */ if (info->tilingEnabled) @@ -1843,6 +1857,7 @@ info->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO; pSAREAPriv->pfAllowPageFlip = 1; } +#endif /* USE_XAA */ } static void RADEONDisablePageFlip(ScreenPtr pScreen) @@ -1871,6 +1886,7 @@ { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); +#ifdef USE_XAA FBAreaPtr fbarea; int width, height; @@ -1929,13 +1945,14 @@ "experience screen corruption\n"); xf86FreeOffscreenArea(fbarea); +#endif info->have3DWindows = 1; RADEONChangeSurfaces(pScrn); RADEONEnablePageFlip(pScreen); - if (info->cursor_start) + if (info->cursor_offset != 0) xf86ForceHWCursor (pScreen, TRUE); } @@ -1952,20 +1969,27 @@ /* Shut down shadowing if we've made it back to the front page */ if (pSAREAPriv->pfCurrentPage == 0) { RADEONDisablePageFlip(pScreen); - xf86FreeOffscreenArea(info->backArea); - info->backArea = NULL; +#ifdef USE_XAA + if (!info->useEXA) { + xf86FreeOffscreenArea(info->backArea); + info->backArea = NULL; + } +#endif } else { xf86DrvMsg(pScreen->myNum, X_WARNING, "[dri] RADEONDRITransitionTo2d: " "kernel failed to unflip buffers.\n"); } - xf86FreeOffscreenArea(info->depthTexArea); +#ifdef USE_XAA + if (!info->useEXA) + xf86FreeOffscreenArea(info->depthTexArea); +#endif info->have3DWindows = 0; RADEONChangeSurfaces(pScrn); - if (info->cursor_start) - xf86ForceHWCursor (pScreen, FALSE); + if (info->cursor_offset != 0) + xf86ForceHWCursor (pScreen, FALSE); } diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 2005-08-30 13:44:21.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 2005-08-31 09:14:29.000000000 +1000 @@ -96,15 +96,9 @@ #include "xf86cmap.h" #include "vbe.h" - /* fbdevhw & vgaHW definitions */ -#ifdef WITH_VGAHW -#include "vgaHW.h" -#endif + /* fbdevhw * vgaHW definitions */ #include "fbdevhw.h" - - /* DPMS support. */ -#define DPMS_SERVER -#include +#include "vgaHW.h" #include "radeon_chipset.h" @@ -193,7 +187,8 @@ OPTION_BIOS_HOTKEYS, OPTION_VGA_ACCESS, OPTION_REVERSE_DDC, - OPTION_LVDS_PROBE_PLL + OPTION_LVDS_PROBE_PLL, + OPTION_ACCELMETHOD } RADEONOpts; static const OptionInfoRec RADEONOptions[] = { @@ -255,12 +250,12 @@ { OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE }, { OPTION_REVERSE_DDC, "ReverseDDC", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; _X_EXPORT const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; } -#ifdef WITH_VGAHW static const char *vgahwSymbols[] = { "vgaHWFreeHWRec", "vgaHWGetHWRec", @@ -272,7 +267,6 @@ "vgaHWGetIOBase", NULL }; -#endif static const char *fbdevHWSymbols[] = { "fbdevHWInit", @@ -315,12 +309,25 @@ NULL }; + +#ifdef USE_EXA +static const char *exaSymbols[] = { + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; +#endif /* USE_EXA */ + +#ifdef USE_XAA static const char *xaaSymbols[] = { "XAACreateInfoRec", "XAADestroyInfoRec", "XAAInit", NULL }; +#endif /* USE_XAA */ #if 0 static const char *xf8_32bppSymbols[] = { @@ -429,12 +436,14 @@ * Tell the loader about symbols from other modules that this module might * refer to. */ - xf86LoaderRefSymLists( -#ifdef WITH_VGAHW - vgahwSymbols, -#endif + xf86LoaderRefSymLists(vgahwSymbols, fbSymbols, +#ifdef USE_EXA + exaSymbols, +#endif +#ifdef USE_XAA xaaSymbols, +#endif #if 0 xf8_32bppSymbols, #endif @@ -2266,6 +2275,10 @@ RADEONWaitForIdleMMIO(pScrn); + ErrorF("info->fbLocation: %x\n", info->fbLocation); + ErrorF("mc_fb_location: %x\n", mc_fb_location); + ErrorF("mc_agp_location: %x\n", mc_fb_location); + OUTREG(RADEON_MC_FB_LOCATION, mc_fb_location); OUTREG(RADEON_MC_AGP_LOCATION, mc_agp_location); OUTREG(RADEON_DISPLAY_BASE_ADDR, info->fbLocation); @@ -3695,10 +3708,10 @@ NULL, /* linePitches */ 8 * 64, /* minPitch */ 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : + info->allowColorTiling ? info->MaxSurfaceWidth : 64 * pScrn1->bitsPerPixel, /* pitchInc */ 128, /* minHeight */ - info->MaxLines, /* maxHeight */ + 8 * 1024, /*2048,*/ /* maxHeight */ pScrn1->display->virtualX ? pScrn1->virtualX : 0, pScrn1->display->virtualY ? pScrn1->virtualY : 0, info->FbMapSize, @@ -3758,10 +3771,10 @@ NULL, /* linePitches */ 8 * 64, /* minPitch */ 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : + info->allowColorTiling ? info->MaxSurfaceWidth : 64 * pScrn1->bitsPerPixel, /* pitchInc */ 128, /* minHeight */ - info->MaxLines, /* maxHeight */ + 8 * 1024, /*2048,*/ /* maxHeight */ pScrn1->display->virtualX, pScrn1->display->virtualY, info->FbMapSize, @@ -3960,7 +3973,7 @@ NULL, /* linePitches */ 8 * 64, /* minPitch */ 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : + info->allowColorTiling ? info->MaxSurfaceWidth : 64 * pScrn->bitsPerPixel, /* pitchInc */ 128, /* minHeight */ info->MaxLines, /* maxHeight */ @@ -4029,7 +4042,7 @@ NULL, /* linePitches */ 8 * 64, /* minPitch */ 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : + info->allowColorTiling ? info->MaxSurfaceWidth : 64 * pScrn->bitsPerPixel, /* pitchInc */ 128, /* minHeight */ info->MaxLines, /* maxHeight */ @@ -4199,31 +4212,72 @@ { #ifdef XFree86LOADER RADEONInfoPtr info = RADEONPTR(pScrn); + MessageType from; +#if defined(USE_EXA) && defined(USE_XAA) + char *optstr; +#endif if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { int errmaj = 0, errmin = 0; - info->xaaReq.majorversion = 1; - info->xaaReq.minorversion = 2; + from = X_DEFAULT; +#if defined(USE_EXA) +#if defined(USE_XAA) + optstr = (char *)xf86GetOptValString(info->Options, OPTION_ACCELMETHOD); + if (optstr != NULL) { + if (xf86NameCmp(optstr, "EXA") == 0) { + from = X_CONFIG; + info->useEXA = TRUE; + } else if (xf86NameCmp(optstr, "XAA") == 0) { + from = X_CONFIG; + } + } +#else /* USE_XAA */ + info->useEXA = TRUE; +#endif /* !USE_XAA */ +#endif /* USE_EXA */ + xf86DrvMsg(pScrn->scrnIndex, from, + "Using %s acceleration architecture\n", + info->useEXA ? "EXA" : "XAA"); - if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, - &info->xaaReq, &errmaj, &errmin)) { - info->xaaReq.minorversion = 1; +#ifdef USE_EXA + if (info->useEXA) { + info->exaReq.majorversion = 1; + info->exaReq.minorversion = 0; + + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, + &info->exaReq, &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + return FALSE; + } + xf86LoaderReqSymLists(exaSymbols, NULL); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + info->xaaReq.majorversion = 1; + info->xaaReq.minorversion = 2; if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, - &info->xaaReq, &errmaj, &errmin)) { - info->xaaReq.minorversion = 0; + &info->xaaReq, &errmaj, &errmin)) { + info->xaaReq.minorversion = 1; if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, &info->xaaReq, &errmaj, &errmin)) { - LoaderErrorMsg(NULL, "xaa", errmaj, errmin); - return FALSE; + info->xaaReq.minorversion = 0; + + if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, + &info->xaaReq, &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "xaa", errmaj, errmin); + return FALSE; + } } } + xf86LoaderReqSymLists(xaaSymbols, NULL); } - xf86LoaderReqSymLists(xaaSymbols, NULL); +#endif /* USE_XAA */ } -#endif +#endif /* XFree86Loader */ return TRUE; } @@ -4601,13 +4655,12 @@ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); /* By default, don't do VGA IOs on ppc */ -#if defined(__powerpc__) || !defined(WITH_VGAHW) +#ifdef __powerpc__ info->VGAAccess = FALSE; #else info->VGAAccess = TRUE; #endif -#ifdef WITH_VGAHW xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess); if (info->VGAAccess) { if (!xf86LoadSubModule(pScrn, "vgahw")) @@ -4625,7 +4678,6 @@ " VGA module load skipped\n"); if (info->VGAAccess) vgaHWGetIOBase(VGAHWPTR(pScrn)); -#endif if (!RADEONPreInitWeight(pScrn)) @@ -4847,10 +4899,8 @@ if (pInt10) xf86FreeInt10(pInt10); -#ifdef WITH_VGAHW if (info->VGAAccess) vgaHWFreeHWRec(pScrn); -#endif fail2: if(info->MMIO) RADEONUnmapMMIO(pScrn); @@ -4876,7 +4926,8 @@ if (info->CPStarted) DRILock(pScrn->pScreen, 0); #endif - if (info->accelOn && pScrn->pScreen) info->accel->Sync(pScrn); + if (info->accelOn && pScrn->pScreen) + RADEON_SYNC(info, pScrn); if (info->FBDev) { fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual); @@ -4999,8 +5050,9 @@ RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI - if (info->directRenderingEnabled) + if (info->directRenderingEnabled) { FLUSH_RING(); + } #endif pScreen->BlockHandler = info->BlockHandler; @@ -5010,12 +5062,320 @@ if (info->VideoTimerCallback) (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds); -#ifdef RENDER +#if defined(RENDER) && defined(USE_XAA) if(info->RenderCallback) (*info->RenderCallback)(pScrn); #endif +} + + +#ifdef USE_XAA +#ifdef XF86DRI +Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + int cpp = info->CurrentLayout.pixel_bytes; + int width_bytes = pScrn->displayWidth * cpp; + int bufferSize; + int depthSize; + int l; + int scanlines; + BoxRec MemBox; + FBAreaPtr fbarea; + + info->frontOffset = 0; + info->frontPitch = pScrn->displayWidth; + info->backPitch = pScrn->displayWidth; + + /* make sure we use 16 line alignment for tiling (8 might be enough). + * Might need that for non-XF86DRI too? + */ + if (info->allowColorTiling) { + bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + } + else { + bufferSize = (pScrn->virtualY * width_bytes + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + } + + /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels, + * which is always the case if color tiling is used due to color pitch + * but not necessarily otherwise, and its height a multiple of 16 lines. + */ + info->depthPitch = (pScrn->displayWidth + 31) & ~31; + depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch + * cpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); + + switch (info->CPMode) { + case RADEON_DEFAULT_CP_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n"); + break; + case RADEON_DEFAULT_CP_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB GART aperture\n", info->gartSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex/indirect buffers\n", info->bufSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for GART textures\n", info->gartTexSize); + + /* Try for front, back, depth, and three framebuffers worth of + * pixmap cache. Should be enough for a fullscreen background + * image plus some leftovers. + */ + info->textureSize = info->FbMapSize - 5 * bufferSize - depthSize; + + /* If that gives us less than half the available memory, let's + * be greedy and grab some more. Sorry, I care more about 3D + * performance than playing nicely, and you'll get around a full + * framebuffer's worth of pixmap cache anyway. + */ + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize; + } + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize; + } + + /* If there's still no space for textures, try without pixmap cache, but never use + * the reserved space and the space hw cursor might use + */ + if (info->textureSize < 0) { + info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize + - 2 * width_bytes - 16384; + } + + /* Check to see if there is more room available after the 8192nd + * scanline for textures + */ + /* FIXME: what's this good for? condition is pretty much impossible to meet */ + if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize + > info->textureSize) { + info->textureSize = + info->FbMapSize - 8192*width_bytes - bufferSize - depthSize; + } + + /* If backbuffer is disabled, don't allocate memory for it */ + if (info->noBackBuffer) { + info->textureSize += bufferSize; + } + /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer! + At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned, + otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee + it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor + area otherwise). + This might cause some space at the end of the video memory to be unused, since it + can't be used (?) due to that log_tex_granularity thing??? + Could use different copyscreentoscreen function for the pageflip copies + (which would use different src and dst offsets) to avoid this. */ + if (info->allowColorTiling && !info->noBackBuffer) { + info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize + + width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16); + } + if (info->textureSize > 0) { + l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) + l = RADEON_LOG_TEX_GRANULARITY; + /* Round the texture size up to the nearest whole number of + * texture regions. Again, be greedy about this, don't + * round down. + */ + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + } else { + info->textureSize = 0; + } + + /* Set a minimum usable local texture heap size. This will fit + * two 256x256x32bpp textures. + */ + if (info->textureSize < 512 * 1024) { + info->textureOffset = 0; + info->textureSize = 0; + } + + if (info->allowColorTiling && !info->noBackBuffer) { + info->textureOffset = ((info->FbMapSize - info->textureSize) / + (width_bytes * 16)) * (width_bytes * 16); + } + else { + /* Reserve space for textures */ + info->textureOffset = ((info->FbMapSize - info->textureSize + + RADEON_BUFFER_ALIGN) & + ~(CARD32)RADEON_BUFFER_ALIGN); + } + + /* Reserve space for the shared depth + * buffer. + */ + info->depthOffset = ((info->textureOffset - depthSize + + RADEON_BUFFER_ALIGN) & + ~(CARD32)RADEON_BUFFER_ALIGN); + + /* Reserve space for the shared back buffer */ + if (info->noBackBuffer) { + info->backOffset = info->depthOffset; + } else { + info->backOffset = ((info->depthOffset - bufferSize + + RADEON_BUFFER_ALIGN) & + ~(CARD32)RADEON_BUFFER_ALIGN); + } + + info->backY = info->backOffset / width_bytes; + info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp; + + scanlines = info->FbMapSize / width_bytes; + if (scanlines > 8191) + scanlines = 8191; + + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + MemBox.y2 = scanlines; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to " + "(%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + /* why oh why can't we just request modes which are guaranteed to be 16 lines + aligned... sigh */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + info->allowColorTiling ? + ((pScrn->virtualY + 15) & ~15) + - pScrn->virtualY + 2 : 2, + 0, NULL, NULL, + NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, + &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + + /* Lines in offscreen area needed for depth buffer and + * textures + */ + info->depthTexLines = (scanlines + - info->depthOffset / width_bytes); + info->backLines = (scanlines + - info->backOffset / width_bytes + - info->depthTexLines); + info->backArea = NULL; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to determine largest offscreen area " + "available\n"); + return FALSE; + } + } + + xf86DrvMsg(scrnIndex, X_INFO, + "Will use back buffer at offset 0x%x\n", + info->backOffset); + xf86DrvMsg(scrnIndex, X_INFO, + "Will use depth buffer at offset 0x%x\n", + info->depthOffset); + xf86DrvMsg(scrnIndex, X_INFO, + "Will use %d kb for textures at offset 0x%x\n", + info->textureSize/1024, info->textureOffset); + + info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | + ((info->frontOffset + info->fbLocation) >> 10)); + + info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | + ((info->backOffset + info->fbLocation) >> 10)); + + info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | + ((info->depthOffset + info->fbLocation) >> 10)); } +#endif /* XF86DRI */ + +Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + BoxRec MemBox; + int y2; + + int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes; + + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + y2 = info->FbMapSize / width_bytes; + if (y2 >= 32768) + y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + + /* The acceleration engine uses 14 bit + * signed coordinates, so we can't have any + * drawable caches beyond this region. + */ + if (MemBox.y2 > 8191) + MemBox.y2 = 8191; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to " + "(%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + FBAreaPtr fbarea; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + info->allowColorTiling ? + ((pScrn->virtualY + 15) & ~15) + - pScrn->virtualY + 2 : 2, + 0, NULL, NULL, + NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } +} +#endif /* USE_XAA */ /* Called at the start of each server generation. */ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, @@ -5023,8 +5383,9 @@ { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); - BoxRec MemBox; - int y2; + int hasDRI = 0; +#ifdef USE_XAA +#endif #ifdef RENDER int subPixelOrder = SubPixelUnknown; char* s; @@ -5061,6 +5422,11 @@ } } + if (info->allowColorTiling && info->useEXA) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Color tiling not supported yet with EXA, disabling\n"); + info->allowColorTiling = FALSE; + } if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling not supported with virtual x resolutions larger than %d, disabling\n", @@ -5179,6 +5545,8 @@ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Depth moves disabled by default\n"); } + + hasDRI = info->directRenderingEnabled; #endif RADEONSetFBLocation(pScrn); @@ -5229,294 +5597,27 @@ } #endif /* Memory manager setup */ -#ifdef XF86DRI - if (info->directRenderingEnabled) { - FBAreaPtr fbarea; - int cpp = info->CurrentLayout.pixel_bytes; - int width_bytes = pScrn->displayWidth * cpp; - int bufferSize; - int depthSize; - int l; - int scanlines; - - info->frontOffset = 0; - info->frontPitch = pScrn->displayWidth; - info->backPitch = pScrn->displayWidth; - /* make sure we use 16 line alignment for tiling (8 might be enough). - Might need that for non-XF86DRI too? */ - if (info->allowColorTiling) { - bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes - + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; - } - else { - bufferSize = (pScrn->virtualY * width_bytes - + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; - } - /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels, - * which is always the case if color tiling is used due to color pitch - * but not necessarily otherwise, and its height a multiple of 16 lines. - */ - info->depthPitch = (pScrn->displayWidth + 31) & ~31; - depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch - * cpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); - - switch (info->CPMode) { - case RADEON_DEFAULT_CP_PIO_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n"); - break; - case RADEON_DEFAULT_CP_BM_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n"); - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n"); - break; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB GART aperture\n", info->gartSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for the ring buffer\n", info->ringSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for GART textures\n", info->gartTexSize); - - /* Try for front, back, depth, and three framebuffers worth of - * pixmap cache. Should be enough for a fullscreen background - * image plus some leftovers. - */ - info->textureSize = info->FbMapSize - 5 * bufferSize - depthSize; - - /* If that gives us less than half the available memory, let's - * be greedy and grab some more. Sorry, I care more about 3D - * performance than playing nicely, and you'll get around a full - * framebuffer's worth of pixmap cache anyway. - */ - if (info->textureSize < (int)info->FbMapSize / 2) { - info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize; - } - if (info->textureSize < (int)info->FbMapSize / 2) { - info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize; - } - /* If there's still no space for textures, try without pixmap cache, but never use - the reserved space and the space hw cursor might use */ - if (info->textureSize < 0) { - info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize - - 2 * width_bytes - 16384; - } - - /* Check to see if there is more room available after the 8192nd - scanline for textures */ - /* FIXME: what's this good for? condition is pretty much impossible to meet */ - if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize - > info->textureSize) { - info->textureSize = - info->FbMapSize - 8192*width_bytes - bufferSize - depthSize; - } - - /* If backbuffer is disabled, don't allocate memory for it */ - if (info->noBackBuffer) { - info->textureSize += bufferSize; - } - - /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer! - At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned, - otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee - it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor - area otherwise). - This might cause some space at the end of the video memory to be unused, since it - can't be used (?) due to that log_tex_granularity thing??? - Could use different copyscreentoscreen function for the pageflip copies - (which would use different src and dst offsets) to avoid this. */ - if (info->allowColorTiling && !info->noBackBuffer) { - info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize + - width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16); - } - if (info->textureSize > 0) { - l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; - } else { - info->textureSize = 0; - } - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - if (info->allowColorTiling && !info->noBackBuffer) { - info->textureOffset = ((info->FbMapSize - info->textureSize) / - (width_bytes * 16)) * (width_bytes * 16); - } - else { - /* Reserve space for textures */ - info->textureOffset = ((info->FbMapSize - info->textureSize + - RADEON_BUFFER_ALIGN) & - ~(CARD32)RADEON_BUFFER_ALIGN); - } - - /* Reserve space for the shared depth - * buffer. - */ - info->depthOffset = ((info->textureOffset - depthSize + - RADEON_BUFFER_ALIGN) & - ~(CARD32)RADEON_BUFFER_ALIGN); - - /* Reserve space for the shared back buffer */ - if (info->noBackBuffer) { - info->backOffset = info->depthOffset; - } else { - info->backOffset = ((info->depthOffset - bufferSize + - RADEON_BUFFER_ALIGN) & - ~(CARD32)RADEON_BUFFER_ALIGN); - } - - info->backY = info->backOffset / width_bytes; - info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp; - - scanlines = info->FbMapSize / width_bytes; - if (scanlines > 8191) scanlines = 8191; - - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - MemBox.y2 = scanlines; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to " - "(%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - /* why oh why can't we just request modes which are guaranteed to be 16 lines - aligned... sigh */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->displayWidth, - info->allowColorTiling ? - ((pScrn->virtualY + 15) & ~15) - - pScrn->virtualY + 2 : 2, - 0, NULL, NULL, - NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - - /* Lines in offscreen area needed for depth buffer and - * textures - */ - info->depthTexLines = (scanlines - - info->depthOffset / width_bytes); - info->backLines = (scanlines - - info->backOffset / width_bytes - - info->depthTexLines); - info->backArea = NULL; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Unable to determine largest offscreen area " - "available\n"); - return FALSE; - } - } - - xf86DrvMsg(scrnIndex, X_INFO, - "Will use back buffer at offset 0x%x\n", - info->backOffset); - xf86DrvMsg(scrnIndex, X_INFO, - "Will use depth buffer at offset 0x%x\n", - info->depthOffset); - xf86DrvMsg(scrnIndex, X_INFO, - "Will use %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - - info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | - ((info->frontOffset + info->fbLocation) >> 10)); - - info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | - ((info->backOffset + info->fbLocation) >> 10)); +#ifdef USE_EXA + if (info->useEXA && !RADEONSetupMemEXA(pScreen)) + return FALSE; +#endif - info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | - ((info->depthOffset + info->fbLocation) >> 10)); - } else +#if defined(XF86DRI) && defined(USE_XAA) + if (!info->useEXA && hasDRI && !RADEONSetupMemXAA_DRI(scrnIndex, pScreen)) + return FALSE; #endif - { - int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes; - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - y2 = info->FbMapSize / width_bytes; - if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ - MemBox.y2 = y2; - - /* The acceleration engine uses 14 bit - signed coordinates, so we can't have any - drawable caches beyond this region. */ - if (MemBox.y2 > 8191) MemBox.y2 = 8191; - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to " - "(%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - FBAreaPtr fbarea; +#ifdef USE_XAA + if (!info->useEXA && !hasDRI && !RADEONSetupMemXAA(scrnIndex, pScreen)) + return FALSE; +#endif - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->displayWidth, - info->allowColorTiling ? - ((pScrn->virtualY + 15) & ~15) - - pScrn->virtualY + 2 : 2, - 0, NULL, NULL, - NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, - 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } - } + info->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) + << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10)); - info->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) << 22) | - ((info->fbLocation + pScrn->fbOffset) >> 10)); + ErrorF("info->dst_pitch_offset = %x\n", info->dst_pitch_offset); - /* Acceleration setup */ + /* Acceleration setup */ if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { if (RADEONAccelInit(pScreen)) { xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); @@ -5532,41 +5633,53 @@ info->accelOn = FALSE; } - /* DGA setup */ - RADEONDGAInit(pScreen); + /* DGA setup XXX FIXME EXA */ + if (!info->useEXA) + RADEONDGAInit(pScreen); - /* Backing store setup */ + /* Backing store setup */ miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); - /* Set Silken Mouse */ + /* Set Silken Mouse */ xf86SetSilkenMouse(pScreen); - /* Cursor setup */ + /* Cursor setup */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - /* Hardware cursor setup */ + /* Hardware cursor setup */ if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { if (RADEONCursorInit(pScreen)) { - int width, height; +#ifdef USE_EXA + if (info->useEXA) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using hardware cursor (offset %d)\n", + info->cursor_offset); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + int width, height; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using hardware cursor (scanline %ld)\n", - info->cursor_start / pScrn->displayWidth - / info->CurrentLayout.pixel_bytes); - if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using hardware cursor (scanline %ld)\n", + info->cursor_offset / pScrn->displayWidth + / info->CurrentLayout.pixel_bytes); + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } } +#endif /* USE_XAA */ } else { xf86DrvMsg(scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } } else { - info->cursor_start = 0; + info->cursor_offset = 0; xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } @@ -5616,7 +5729,15 @@ done their thing, complete the DRI setup. */ if (!(info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen))) { - RADEONAccelInitMMIO(pScreen, info->accel); +#ifdef USE_EXA + if (info->useEXA) { + RADEONDrawInitMMIO(pScreen); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) + RADEONAccelInitMMIO(pScreen, info->accel); +#endif /* USE_XAA */ } } if (info->directRenderingEnabled) { @@ -6557,25 +6678,23 @@ } if (!info->IsSecondary) { -#ifdef WITH_VGAHW if (info->VGAAccess) { vgaHWPtr hwp = VGAHWPTR(pScrn); vgaHWUnlock(hwp); -# if defined(__powerpc__) +#if defined(__powerpc__) /* temporary hack to prevent crashing on PowerMacs when trying to * read VGA fonts and colormap, will find a better solution * in the future. TODO: Check if there's actually some VGA stuff * setup in the card at all !! */ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ -# else +#else /* Save mode * & fonts & cmap */ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); -# endif +#endif vgaHWLock(hwp); } -#endif save->dp_datatype = INREG(RADEON_DP_DATATYPE); save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); @@ -6636,19 +6755,18 @@ usleep(100000); #endif -#ifdef WITH_VGAHW if (info->VGAAccess) { vgaHWPtr hwp = VGAHWPTR(pScrn); if (!info->IsSecondary) { vgaHWUnlock(hwp); -# if defined(__powerpc__) +#if defined(__powerpc__) /* Temporary hack to prevent crashing on PowerMacs when trying to * write VGA fonts, will find a better solution in the future */ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); -# else +#else vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); -# endif +#endif vgaHWLock(hwp); } else { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); @@ -6668,7 +6786,6 @@ } } } -#endif RADEONUnblank(pScrn); #if 0 @@ -7974,7 +8091,8 @@ #endif } - if (info->accelOn) info->accel->Sync(pScrn); + if (info->accelOn) + RADEON_SYNC(info, pScrn); if (info->FBDev) { RADEONSaveFBDevRegisters(pScrn, &info->ModeReg); @@ -7997,7 +8115,7 @@ } if (info->accelOn) { - info->accel->Sync(pScrn); + RADEON_SYNC(info, pScrn); RADEONEngineRestore(pScrn); } @@ -8167,7 +8285,8 @@ if (info->CPStarted) DRILock(pScrn->pScreen, 0); #endif - if (info->accelOn) info->accel->Sync(pScrn); + if (info->accelOn) + RADEON_SYNC(info, pScrn); if(info->MergedFB) { RADEONAdjustFrameMerged(scrnIndex, x, y, flags); @@ -8294,10 +8413,12 @@ } #endif - if(info->RenderTex) { +#ifdef USE_XAA + if(!info->useEXA && info->RenderTex) { xf86FreeOffscreenLinear(info->RenderTex); info->RenderTex = NULL; } +#endif /* USE_XAA */ if (pScrn->vtSema) { RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0); @@ -8305,11 +8426,21 @@ } RADEONUnmapMem(pScrn); - if (info->accel) XAADestroyInfoRec(info->accel); - info->accel = NULL; - - if (info->scratch_save) xfree(info->scratch_save); - info->scratch_save = NULL; +#ifdef USE_EXA + if (info->useEXA && info->accelOn) + exaDriverFini(pScreen); +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) { + if (info->accel) + XAADestroyInfoRec(info->accel); + info->accel = NULL; + + if (info->scratch_save) + xfree(info->scratch_save); + info->scratch_save = NULL; + } +#endif /* USE_XAA */ if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); info->cursor = NULL; @@ -8370,10 +8501,8 @@ } } -#ifdef WITH_VGAHW if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(pScrn); -#endif RADEONFreeRec(pScrn); } @@ -8458,7 +8587,8 @@ if (info->CPStarted) DRILock(pScrn->pScreen, 0); #endif - if (info->accelOn) info->accel->Sync(pScrn); + if (info->accelOn) + RADEON_SYNC(info, pScrn); if (info->FBDev) { fbdevHWDPMSSet(pScrn, PowerManagementMode, flags); diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_exa.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_exa.c --- /dev/null 2005-08-22 11:32:55.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_exa.c 2005-08-31 10:47:41.000000000 +1000 @@ -0,0 +1,687 @@ +#include "radeon.h" +#include "radeon_reg.h" +#include "radeon_dri.h" +#include "radeon_macros.h" +#include "radeon_probe.h" +#include "radeon_version.h" +#include "radeon_sarea.h" + +#include "xf86.h" + + +/***********************************************************************/ +#define RINFO_FROM_SCREEN(pScr) ScrnInfoPtr pScrn = xf86Screens[pScr->myNum]; \ + RADEONInfoPtr info = RADEONPTR(pScrn) + +#define RADEON_TRACE_FALL 1 +#define RADEON_TRACE_DRAW 0 + +#if RADEON_TRACE_FALL +#define RADEON_FALLBACK(x) \ +do { \ + ErrorF("%s: ", __FUNCTION__); \ + ErrorF x; \ + return FALSE; \ +} while (0) +#else +#define RADEON_FALLBACK(x) return FALSE +#endif + +#if RADEON_TRACE_DRAW +#define TRACE do { ErrorF("TRACE: %s\n", __FUNCTION__); } while(0) +#else +#define TRACE +#endif + +static struct { + int rop; + int pattern; +} RADEON_ROP[] = { + { RADEON_ROP3_ZERO, RADEON_ROP3_ZERO }, /* GXclear */ + { RADEON_ROP3_DSa, RADEON_ROP3_DPa }, /* Gxand */ + { RADEON_ROP3_SDna, RADEON_ROP3_PDna }, /* GXandReverse */ + { RADEON_ROP3_S, RADEON_ROP3_P }, /* GXcopy */ + { RADEON_ROP3_DSna, RADEON_ROP3_DPna }, /* GXandInverted */ + { RADEON_ROP3_D, RADEON_ROP3_D }, /* GXnoop */ + { RADEON_ROP3_DSx, RADEON_ROP3_DPx }, /* GXxor */ + { RADEON_ROP3_DSo, RADEON_ROP3_DPo }, /* GXor */ + { RADEON_ROP3_DSon, RADEON_ROP3_DPon }, /* GXnor */ + { RADEON_ROP3_DSxn, RADEON_ROP3_PDxn }, /* GXequiv */ + { RADEON_ROP3_Dn, RADEON_ROP3_Dn }, /* GXinvert */ + { RADEON_ROP3_SDno, RADEON_ROP3_PDno }, /* GXorReverse */ + { RADEON_ROP3_Sn, RADEON_ROP3_Pn }, /* GXcopyInverted */ + { RADEON_ROP3_DSno, RADEON_ROP3_DPno }, /* GXorInverted */ + { RADEON_ROP3_DSan, RADEON_ROP3_DPan }, /* GXnand */ + { RADEON_ROP3_ONE, RADEON_ROP3_ONE } /* GXset */ +}; + +/* Compute log base 2 of val. */ +static __inline__ int +RADEONLog2(int val) +{ + int bits; + + for (bits = 0; val != 0; val >>= 1, ++bits) + ; + return bits - 1; +} + +static __inline__ CARD32 F_TO_DW(float val) +{ + union { + float f; + CARD32 l; + } tmp; + tmp.f = val; + return tmp.l; +} + +/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we + * require src and dest datatypes to be equal. + */ +static Bool +RADEONGetDatatypeBpp(int bpp, CARD32 *type) +{ + switch (bpp) { + case 8: + *type = ATI_DATATYPE_CI8; + return TRUE; + case 16: + *type = ATI_DATATYPE_RGB565; + return TRUE; + case 24: + *type = ATI_DATATYPE_CI8; + return TRUE; + case 32: + *type = ATI_DATATYPE_ARGB8888; + return TRUE; + default: + RADEON_FALLBACK(("Unsupported bpp: %d\n", bpp)); + return FALSE; + } +} + +static Bool +RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset, + unsigned int offset, unsigned int pitch) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + + if (pitch % info->exa.card.pixmapPitchAlign != 0) + RADEON_FALLBACK(("Bad pitch 0x%08x\n", pitch)); + + if (offset % info->exa.card.pixmapOffsetAlign != 0) + RADEON_FALLBACK(("Bad offset 0x%08x\n", offset)); + + pitch = pitch >> 6; + *pitch_offset = (pitch << 22) | (offset >> 10); + + /* If it's the front buffer, we've got to note that it's tiled? */ + if (exaGetPixmapOffset(pPix) == 0 && info->tilingEnabled) + *pitch_offset |= RADEON_DST_TILE_MACRO; + return TRUE; +} + +static Bool +RADEONGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + CARD32 pitch, offset; + int bpp; + + bpp = pPix->drawable.bitsPerPixel; + if (bpp == 24) + bpp = 8; + + offset = exaGetPixmapOffset(pPix) + info->fbLocation; + pitch = exaGetPixmapPitch(pPix); + + return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); +} + +#define RADEON_SWITCH_TO_2D() \ + BEGIN_ACCEL(2);\ + OUT_ACCEL_REG(RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH); \ + OUT_ACCEL_REG(RADEON_WAIT_UNTIL,\ + RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);\ + FINISH_ACCEL() + + +#define ENTER_DRAW(x) TRACE +#define LEAVE_DRAW(x) TRACE +/***********************************************************************/ + +#define ACCEL_MMIO +#define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO +#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) +#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val) +#define FINISH_ACCEL() + +#include "radeon_exa_funcs.c" + +#undef ACCEL_MMIO +#undef ACCEL_PREAMBLE +#undef BEGIN_ACCEL +#undef OUT_ACCEL_REG +#undef FINISH_ACCEL + +#ifdef XF86DRI + +#define ACCEL_CP +#define ACCEL_PREAMBLE() \ + RING_LOCALS; \ + RADEONCP_REFRESH(pScrn, info) +#define BEGIN_ACCEL(n) BEGIN_RING(2*(n)) +#define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val) +#define FINISH_ACCEL() ADVANCE_RING() + +#define RADEON_SWITCH_TO_3D() BEGIN_RING(4); \ + OUT_RING_REG(RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH); \ + OUT_RING_REG(RADEON_WAIT_UNTIL, \ + RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);\ + ADVANCE_RING(); + +#define OUT_RING_F(x) OUT_RING(F_TO_DW(x)) + +static Bool is_transform[2]; +static PictTransform *transform[2]; + +struct blendinfo { + Bool dst_alpha; + Bool src_alpha; + CARD32 blend_cntl; +}; + +static struct blendinfo RadeonBlendOp[] = { + /* Clear */ + {0, 0, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ZERO}, + /* Src */ + {0, 0, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO}, + /* Dst */ + {0, 0, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ONE}, + /* Over */ + {0, 1, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA}, + /* OverReverse */ + {1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ONE}, + /* In */ + {1, 0, RADEON_SRC_BLEND_GL_DST_ALPHA | RADEON_DST_BLEND_GL_ZERO}, + /* InReverse */ + {0, 1, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_SRC_ALPHA}, + /* Out */ + {1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ZERO}, + /* OutReverse */ + {0, 1, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA}, + /* Atop */ + {1, 1, RADEON_SRC_BLEND_GL_DST_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA}, + /* AtopReverse */ + {1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_SRC_ALPHA}, + /* Xor */ + {1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA}, + /* Add */ + {0, 0, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ONE}, +}; + +struct formatinfo { + int fmt; + Bool byte_swap; + CARD32 card_fmt; +}; + +/* Note on texture formats: + * TXFORMAT_Y8 expands to (Y,Y,Y,1). TXFORMAT_I8 expands to (I,I,I,I) + */ +static struct formatinfo R200TexFormats[] = { + {PICT_a8r8g8b8, 0, R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP}, + {PICT_x8r8g8b8, 0, R200_TXFORMAT_ARGB8888}, + {PICT_a8r8g8b8, 1, R200_TXFORMAT_RGBA8888 | R200_TXFORMAT_ALPHA_IN_MAP}, + {PICT_x8r8g8b8, 1, R200_TXFORMAT_RGBA8888}, + {PICT_r5g6b5, 0, R200_TXFORMAT_RGB565}, + {PICT_a1r5g5b5, 0, R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP}, + {PICT_x1r5g5b5, 0, R200_TXFORMAT_ARGB1555}, + {PICT_a8, 0, R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP}, +}; + +/* Common Radeon setup code */ + +static Bool RADEONGetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format) +{ + switch (pDstPicture->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + *dst_format = RADEON_COLOR_FORMAT_ARGB8888; + break; + case PICT_r5g6b5: + *dst_format = RADEON_COLOR_FORMAT_RGB565; + break; + case PICT_a1r5g5b5: + case PICT_x1r5g5b5: + *dst_format = RADEON_COLOR_FORMAT_ARGB1555; + break; + case PICT_a8: + *dst_format = RADEON_COLOR_FORMAT_RGB8; + break; + default: + RADEON_FALLBACK(("Unsupported dest format 0x%x\n", + pDstPicture->format)); + } + + return TRUE; +} + +static Bool R200CheckCompositeTexture(PicturePtr pPict, int unit) +{ + int w = pPict->pDrawable->width; + int h = pPict->pDrawable->height; + int i; + + if ((w > 0x7ff) || (h > 0x7ff)) + RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h)); + + for (i = 0; i < sizeof(R200TexFormats) / sizeof(R200TexFormats[0]); i++) + { + if (R200TexFormats[i].fmt == pPict->format) + break; + } + if (i == sizeof(R200TexFormats) / sizeof(R200TexFormats[0])) + RADEON_FALLBACK(("Unsupported picture format 0x%x\n", + pPict->format)); + + if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0)) + RADEON_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h)); + + if (pPict->filter != PictFilterNearest && + pPict->filter != PictFilterBilinear) + RADEON_FALLBACK(("Unsupported filter 0x%x\n", pPict->filter)); + + return TRUE; +} + +static Bool R200TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + CARD32 txfilter, txformat, txoffset, txpitch; + int w = pPict->pDrawable->width; + int h = pPict->pDrawable->height; + int i; + RING_LOCALS; + + txpitch = exaGetPixmapPitch(pPix); + txoffset = exaGetPixmapOffset(pPix) + info->fbLocation; + + for (i = 0; i < sizeof(R200TexFormats) / sizeof(R200TexFormats[0]); i++) + { + if (R200TexFormats[i].fmt == pPict->format) + break; + } + txformat = R200TexFormats[i].card_fmt; + if (R200TexFormats[i].byte_swap) + txoffset |= R200_TXO_ENDIAN_BYTE_SWAP; + + if (pPict->repeat) { + txformat |= RADEONLog2(w) << R200_TXFORMAT_WIDTH_SHIFT; + txformat |= RADEONLog2(h) << R200_TXFORMAT_HEIGHT_SHIFT; + } else + txformat |= R200_TXFORMAT_NON_POWER2; + txformat |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT; + + if ((txoffset & 0x1f) != 0) + RADEON_FALLBACK(("Bad texture offset 0x%x\n", txoffset)); + if ((txpitch & 0x1f) != 0) + RADEON_FALLBACK(("Bad texture pitch 0x%x\n", txpitch)); + + switch (pPict->filter) { + case PictFilterNearest: + txfilter = (R200_MAG_FILTER_NEAREST | + R200_MIN_FILTER_NEAREST); + break; + case PictFilterBilinear: + txfilter = (R200_MAG_FILTER_LINEAR | + R200_MIN_FILTER_LINEAR); + break; + default: + RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); + } + + if (unit == 0) { + BEGIN_RING(6); + OUT_RING(CP_PACKET0(R200_PP_TXFILTER_0 + 0x20 * unit, 4)); + OUT_RING(txfilter);/*R200_PP_TXFILTER_0*/ + OUT_RING(txformat);/*R200_PP_TXFORMAT_0*/ + OUT_RING(0);/*R200_PP_TXFORMAT_X_0*/ + OUT_RING((pPix->drawable.width - 1) | + ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); /*R200_PP_TXSIZE_0*/ + OUT_RING(txpitch - 32);/*R200_PP_TXPITCH_0*/ + ADVANCE_RING(); + } else { + BEGIN_RING(6); + OUT_RING(CP_PACKET0(R200_PP_TXFILTER_1, 4)); + OUT_RING(txfilter);/*R200_PP_TXFILTER_1*/ + OUT_RING(txformat);/*R200_PP_TXFORMAT_1*/ + OUT_RING(0);/*R200_PP_TXFORMAT_X_1*/ + OUT_RING((pPix->drawable.width - 1) | + ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));/*R200_PP_TXSIZE_1*/ + OUT_RING(txpitch - 32);/*R200_PP_TXPITCH_1*/ + ADVANCE_RING(); + } + + BEGIN_RING(2); + OUT_RING_REG(R200_PP_TXOFFSET_0 + 0x18 * unit, txoffset); + ADVANCE_RING(); + + if (pPict->transform != 0) { + is_transform[unit] = TRUE; + transform[unit] = pPict->transform; + } else { + is_transform[unit] = FALSE; + } + + return TRUE; +} + +static Bool R200CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + CARD32 tmp1; + + TRACE; + + ErrorF("Checking COMPOSITE yeah !\n"); + + /* Check for unsupported compositing operations. */ + if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0])) + RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op)); + if (pMaskPicture != NULL && pMaskPicture->componentAlpha && + RadeonBlendOp[op].src_alpha) + RADEON_FALLBACK(("Component alpha not supported with source " + "alpha blending.\n")); + + if (!R200CheckCompositeTexture(pSrcPicture, 0)) + return FALSE; + if (pMaskPicture != NULL && !R200CheckCompositeTexture(pMaskPicture, 1)) + return FALSE; + + if (!RADEONGetDestFormat(pDstPicture, &tmp1)) + return FALSE; + + return TRUE; +} + +static Bool R200PrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + CARD32 dst_format, dst_offset, dst_pitch; + CARD32 pp_cntl, blendcntl, cblend, ablend; + int pixel_shift; + RING_LOCALS; + + TRACE; + ErrorF("Preparing COMPOSITE yeah !\n"); + + if (!info->XInited3D) + RADEONInit3DEngine(pScrn); + + RADEONGetDestFormat(pDstPicture, &dst_format); + pixel_shift = pDst->drawable.bitsPerPixel >> 4; + + dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation; + dst_pitch = exaGetPixmapPitch(pDst); + if ((dst_offset & 0x0f) != 0) + RADEON_FALLBACK(("Bad destination offset 0x%x\n", dst_offset)); + if (((dst_pitch >> pixel_shift) & 0x7) != 0) + RADEON_FALLBACK(("Bad destination pitch 0x%x\n", dst_pitch)); + + if (!R200TextureSetup(pSrcPicture, pSrc, 0)) + return FALSE; + pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; + + if (pMask != NULL) { + if (!R200TextureSetup(pMaskPicture, pMask, 1)) + return FALSE; + pp_cntl |= RADEON_TEX_1_ENABLE; + } else { + is_transform[1] = FALSE; + } + + RADEON_SWITCH_TO_3D(); + + BEGIN_RING(17); + + OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2)); + OUT_RING(pp_cntl);/*RADEON_PP_CNTL*/ + OUT_RING(dst_format | RADEON_ALPHA_BLEND_ENABLE);/*RADEON_RB3D_CNTL*/ + OUT_RING(dst_offset);/*RADEON_RB3D_COLOROFFSET*/ + + OUT_RING_REG(R200_SE_VTX_FMT_0, R200_VTX_XY); + OUT_RING_REG(R200_SE_VTX_FMT_1, + (2 << R200_VTX_TEX0_COMP_CNT_SHIFT) | + (2 << R200_VTX_TEX1_COMP_CNT_SHIFT)); + + OUT_RING_REG(RADEON_RB3D_COLORPITCH, dst_pitch >> pixel_shift); + + /* IN operator: Multiply src by mask components or mask alpha. + * BLEND_CTL_ADD is A * B + C. + * If a picture is a8, we have to explicitly zero its color values. + * If the destination is a8, we have to route the alpha to red, I think. + */ + cblend = R200_TXC_OP_MADD | R200_TXC_ARG_C_ZERO; + ablend = R200_TXA_OP_MADD | R200_TXA_ARG_C_ZERO; + + if (pDstPicture->format == PICT_a8) + cblend |= R200_TXC_ARG_A_R0_ALPHA; + else if (pSrcPicture->format == PICT_a8) + cblend |= R200_TXC_ARG_A_ZERO; + else + cblend |= R200_TXC_ARG_A_R0_COLOR; + ablend |= R200_TXA_ARG_A_R0_ALPHA; + + if (pMask) { + if (pMaskPicture->componentAlpha && + pDstPicture->format != PICT_a8) + cblend |= R200_TXC_ARG_B_R1_COLOR; + else + cblend |= R200_TXC_ARG_B_R1_ALPHA; + ablend |= R200_TXA_ARG_B_R1_ALPHA; + } else { + cblend |= R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B; + ablend |= R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B; + } + + OUT_RING(CP_PACKET0(R200_PP_TXCBLEND_0, 3)); + OUT_RING(cblend);/*R200_PP_TXCBLEND_0*/ + OUT_RING(R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0);/*R200_PP_TXCBLEND2_0*/ + OUT_RING(ablend);/*R200_PP_TXABLEND_0*/ + OUT_RING(R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0);/*R200_PP_TXABLEND2_0*/ + + /* Op operator. */ + blendcntl = RadeonBlendOp[op].blend_cntl; + if (PICT_FORMAT_A(pDstPicture->format) == 0 && + RadeonBlendOp[op].dst_alpha) { + if ((blendcntl & RADEON_SRC_BLEND_MASK) == + RADEON_SRC_BLEND_GL_DST_ALPHA) + blendcntl = (blendcntl & ~RADEON_SRC_BLEND_MASK) | + RADEON_SRC_BLEND_GL_ONE; + else if ((blendcntl & RADEON_SRC_BLEND_MASK) == + RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA) + blendcntl = (blendcntl & ~RADEON_SRC_BLEND_MASK) | + RADEON_SRC_BLEND_GL_ZERO; + } + OUT_RING_REG(RADEON_RB3D_BLENDCNTL, blendcntl); + ADVANCE_RING(); + + return TRUE; +} + +union intfloat { + float f; + CARD32 i; +}; + +struct blend_vertex { + union intfloat x, y; + union intfloat s0, t0; + union intfloat s1, t1; +}; + +#define VTX_DWORD_COUNT 6 + +#define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \ +do { \ + OUT_RING_F(_dstX); \ + OUT_RING_F(_dstY); \ + OUT_RING_F(_srcX); \ + OUT_RING_F(_srcY); \ + OUT_RING_F(_maskX); \ + OUT_RING_F(_maskY); \ +} while (0) + +static void R200Composite(PixmapPtr pDst, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int w, int h) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + int srcXend, srcYend, maskXend, maskYend; + RING_LOCALS; + PictVector v; + + ENTER_DRAW(0); + + ErrorF("RadeonComposite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", + srcX, srcY, maskX, maskY,dstX, dstY, w, h); + + srcXend = srcX + w; + srcYend = srcY + h; + maskXend = maskX + w; + maskYend = maskY + h; + if (is_transform[0]) { + v.vector[0] = IntToxFixed(srcX); + v.vector[1] = IntToxFixed(srcY); + v.vector[2] = xFixed1; + PictureTransformPoint(transform[0], &v); + srcX = xFixedToInt(v.vector[0]); + srcY = xFixedToInt(v.vector[1]); + v.vector[0] = IntToxFixed(srcXend); + v.vector[1] = IntToxFixed(srcYend); + v.vector[2] = xFixed1; + PictureTransformPoint(transform[0], &v); + srcXend = xFixedToInt(v.vector[0]); + srcYend = xFixedToInt(v.vector[1]); + } + if (is_transform[1]) { + v.vector[0] = IntToxFixed(maskX); + v.vector[1] = IntToxFixed(maskY); + v.vector[2] = xFixed1; + PictureTransformPoint(transform[1], &v); + maskX = xFixedToInt(v.vector[0]); + maskY = xFixedToInt(v.vector[1]); + v.vector[0] = IntToxFixed(maskXend); + v.vector[1] = IntToxFixed(maskYend); + v.vector[2] = xFixed1; + PictureTransformPoint(transform[1], &v); + maskXend = xFixedToInt(v.vector[0]); + maskYend = xFixedToInt(v.vector[1]); + } + + BEGIN_RING(4 * VTX_DWORD_COUNT + 2); + OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, + 4 * VTX_DWORD_COUNT)); + OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN | + RADEON_CP_VC_CNTL_PRIM_WALK_RING | + (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); + + + VTX_OUT(dstX, dstY, srcX, srcY, maskX, maskY); + VTX_OUT(dstX, dstY + h, srcX, srcYend, maskX, maskYend); + VTX_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend); + VTX_OUT(dstX + w, dstY, srcXend, srcY, maskXend, maskY); + + LEAVE_DRAW(0); + + ADVANCE_RING(); +} + +static void R200DoneComposite(PixmapPtr pDst) +{ + ENTER_DRAW(0); + LEAVE_DRAW(0); +} + +#include "radeon_exa_funcs.c" + +#endif /* XF86DRI */ + +/* + * Once screen->off_screen_base is set, this function + * allocates the remaining memory appropriately + */ +Bool RADEONSetupMemEXA (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + int l; + int screen_size; + int byteStride = pScrn->displayWidth * pScrn->bitsPerPixel / 8; + + screen_size = byteStride * pScreen->height; + + info->exa.card.memoryBase = info->FB + pScrn->fbOffset; + info->exa.card.memorySize = info->FbMapSize; + info->exa.card.offScreenBase = screen_size; + + ErrorF("INIT exa.card.offScreenBase = screen_size = %d (%f Mb)\n", + screen_size, (float)screen_size / (1024.0 * 1024.0)); + + ErrorF("INIT exa.card.memorySize = screen_size = %d (%f Mb)\n", + info->exa.card.memorySize, + (float)info->exa.card.memorySize / (1024.0 * 1024.0)); + +#if defined(XF86DRI) + /* Reserve a static area for the back buffer the same size as the + * visible screen. XXX: This would be better initialized in ati_dri.c + * when GLX is set up, but the offscreen memory manager's allocations + * don't last through VT switches, while the kernel's understanding of + * offscreen locations does. + */ + info->frontOffset = 0; + info->frontPitch = byteStride; + + if (info->exa.card.offScreenBase + screen_size <= info->exa.card.memorySize) { + info->backOffset = info->exa.card.offScreenBase; + info->backPitch = byteStride; + info->exa.card.offScreenBase += screen_size; + } + + /* Reserve the static depth buffer, which happens to be the same + * bitsPerPixel as the screen. + */ + if (info->exa.card.offScreenBase + screen_size <= info->exa.card.memorySize) { + info->depthOffset = info->exa.card.offScreenBase; + info->depthPitch = byteStride; + info->exa.card.offScreenBase += screen_size; + } + + ErrorF("INIT exa.card.offScreenBase = textures = %d (%f Mb)\n", + info->exa.card.offScreenBase, + (float)info->exa.card.offScreenBase / (1024.0 * 1024.0)); + + /* Reserve approx. half of remaining offscreen memory for local + * textures. Round down to a whole number of texture regions. + */ + info->textureSize = (info->exa.card.memorySize - info->exa.card.offScreenBase) / 2; + l = RADEONLog2(info->textureSize / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) + l = RADEON_LOG_TEX_GRANULARITY; + info->textureSize = (info->textureSize >> l) << l; + if (info->textureSize >= 512 * 1024) { + info->textureOffset = info->exa.card.offScreenBase; + info->exa.card.offScreenBase += info->textureSize; + } else { + /* Minimum texture size is for 2 256x256x32bpp textures */ + info->textureSize = 0; + } + ErrorF("INIT RESULTS: offscreen area = %ld (%f Mb)\n", info->exa.card.offScreenBase, + (float)info->exa.card.offScreenBase/(1024.0*1024.0)); +#endif /* XF86DRI */ +} + diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_exa_funcs.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_exa_funcs.c --- /dev/null 2005-08-22 11:32:55.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_exa_funcs.c 2005-08-31 10:38:30.000000000 +1000 @@ -0,0 +1,376 @@ +#if defined(ACCEL_MMIO) && defined(ACCEL_CP) +#error Cannot define both MMIO and CP acceleration! +#endif + +#if !defined(UNIXCPP) || defined(ANSICPP) +#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix +#else +#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix +#endif + +#ifdef ACCEL_MMIO +#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO) +#else +#ifdef ACCEL_CP +#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP) +#else +#error No accel type defined! +#endif +#endif + +#include "radeon.h" +#include "atidri.h" + +#include "exa.h" + +#include "fbdevhw.h" + +static void +FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker) +{ + TRACE; + + FUNC_NAME(RADEONWaitForIdle)(xf86Screens[pScreen->myNum]); +} + +static Bool +FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + CARD32 datatype, dst_pitch_offset; + ACCEL_PREAMBLE(); + + TRACE; + + if (!RADEONGetDatatypeBpp(pPix->drawable.bitsPerPixel, &datatype)) + RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n")); + if (!RADEONGetPixmapOffsetPitch(pPix, &dst_pitch_offset)) + RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n")); + + BEGIN_ACCEL(5); + OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (datatype << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP[alu].pattern | + RADEON_GMC_CLR_CMP_CNTL_DIS); + OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); + OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); + OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, pm); + OUT_ACCEL_REG(RADEON_DP_CNTL, + (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); + FINISH_ACCEL(); + + return TRUE; +} + + +static void +FUNC_NAME(RADEONSolid)(PixmapPtr pPix, int x1, int y1, int x2, int y2) +{ + + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + ACCEL_PREAMBLE(); + + TRACE; + + BEGIN_ACCEL(2); + OUT_ACCEL_REG(RADEON_DST_Y_X, (y1 << 16) | x1); + OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, ((y2 - y1) << 16) | (x2 - x1)); + FINISH_ACCEL(); +} + +static void +FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPix) +{ + TRACE; +} + +static Bool +FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst, + int xdir, int ydir, + int rop, + Pixel planemask) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + CARD32 datatype, src_pitch_offset, dst_pitch_offset; + ACCEL_PREAMBLE(); + + TRACE; + + info->xdir = xdir; + info->ydir = ydir; + + if (!RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype)) + RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n")); + if (!RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset)) + RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch source failed\n")); + if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset)) + RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n")); + + BEGIN_ACCEL(5); + OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (datatype << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP[rop].rop | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS); + OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); + OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset); + OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); + OUT_ACCEL_REG(RADEON_DP_CNTL, + ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | + (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0))); + FINISH_ACCEL(); + return TRUE; +} + +static void +FUNC_NAME(RADEONCopy)(PixmapPtr pDst, + int srcX, int srcY, + int dstX, int dstY, + int w, int h) +{ + + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + ACCEL_PREAMBLE(); + + TRACE; + + if (info->xdir < 0) { + srcX += w - 1; + dstX += w - 1; + } + if (info->ydir < 0) { + srcY += h - 1; + dstY += h - 1; + } + + BEGIN_ACCEL(3); + + OUT_ACCEL_REG(RADEON_SRC_Y_X, (srcY << 16) | srcX); + OUT_ACCEL_REG(RADEON_DST_Y_X, (dstY << 16) | dstX); + OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); + + FINISH_ACCEL(); +} + +static void +FUNC_NAME(RADEONDoneCopy)(PixmapPtr pDst) +{ + TRACE; +} + +static Bool +FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, char *src, int src_pitch) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + CARD8 *dst = pDst->devPrivate.ptr; + unsigned int dst_pitch = exaGetPixmapPitch(pDst); + unsigned int w = pDst->drawable.width; + unsigned int h = pDst->drawable.height; + unsigned int bpp = pDst->drawable.bitsPerPixel; + unsigned int hpass; + CARD32 buf_pitch; + + TRACE; + +#ifdef ACCEL_CP + if (info->directRenderingEnabled) { + CARD8 *buf; + + bpp = (bpp + 1) / 8; + while (buf = RADEONHostDataBlit(pScrn, + bpp, w, dst_pitch, &buf_pitch, + &dst, &h, &hpass)) { + RADEONHostDataBlitCopyPass(pScrn, bpp, buf, (unsigned char *)src, + hpass, buf_pitch, src_pitch); + src += hpass * src_pitch; + } + + exaMarkSync(pDst->drawable.pScreen); + return TRUE; + } +#endif + + /* Do we need that sync here ? probably not .... */ + exaWaitSync(pDst->drawable.pScreen); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + unsigned char *RADEONMMIO = info->MMIO; + unsigned int swapper = info->ModeReg.surface_cntl & + ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | + RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP); + + switch(bpp) { + case 15: + case 16: + swapper |= RADEON_NONSURF_AP0_SWP_16BPP + | RADEON_NONSURF_AP1_SWP_16BPP; + break; + case 24: + case 32: + swapper |= RADEON_NONSURF_AP0_SWP_32BPP + | RADEON_NONSURF_AP1_SWP_32BPP; + break; + } + OUTREG(RADEON_SURFACE_CNTL, swapper); +#endif + w *= (bpp + 1) / 8; + + while (h--) { + memcpy(dst, src, w); + src += src_pitch; + dst += dst_pitch; + } + +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* restore byte swapping */ + OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl); +#endif + + return TRUE; +} + +static Bool +FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + RINFO_FROM_SCREEN(pSrc->drawable.pScreen); + unsigned char *src = pSrc->devPrivate.ptr; + int src_pitch = exaGetPixmapPitch(pSrc); + int bpp = pSrc->drawable.bitsPerPixel; + int bm = (bpp + 1) / 8; + + TRACE; + + /* + * This is currently done without DMA until I have ironed out the + * various endian issues with R300 among others + */ + exaWaitSync(pSrc->drawable.pScreen); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + unsigned char *RADEONMMIO = info->MMIO; + unsigned int swapper = info->ModeReg.surface_cntl & + ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | + RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP); + + switch(bpp) { + case 15: + case 16: + swapper |= RADEON_NONSURF_AP0_SWP_16BPP + | RADEON_NONSURF_AP1_SWP_16BPP; + break; + case 24: + case 32: + swapper |= RADEON_NONSURF_AP0_SWP_32BPP + | RADEON_NONSURF_AP1_SWP_32BPP; + break; + } + OUTREG(RADEON_SURFACE_CNTL, swapper); +#endif + + src += (x * bm) + (y * src_pitch); + w *= bm; + + while (h--) { + memcpy(dst, src, w); + src += src_pitch; + dst += dst_pitch; + } + +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* restore byte swapping */ + OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl); +#endif + + return TRUE; +} + +Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) +{ + RINFO_FROM_SCREEN(pScreen); + + memset(&info->exa.accel, 0, sizeof(ExaAccelInfoRec)); + + info->exa.accel.PrepareSolid = FUNC_NAME(RADEONPrepareSolid); + info->exa.accel.Solid = FUNC_NAME(RADEONSolid); + info->exa.accel.DoneSolid = FUNC_NAME(RADEONDoneSolid); + + info->exa.accel.PrepareCopy = FUNC_NAME(RADEONPrepareCopy); + info->exa.accel.Copy = FUNC_NAME(RADEONCopy); + info->exa.accel.DoneCopy = FUNC_NAME(RADEONDoneCopy); + + info->exa.accel.WaitMarker = FUNC_NAME(RADEONSync); + info->exa.accel.UploadToScreen = FUNC_NAME(RADEONUploadToScreen); + info->exa.accel.DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen); + + info->exa.card.flags = EXA_OFFSCREEN_PIXMAPS; + info->exa.card.pixmapOffsetAlign = 1024; + info->exa.card.pixmapPitchAlign = 64; + + info->exa.card.maxX = 2047; + info->exa.card.maxY = 2047; + +#ifdef ACCEL_CP + if (info->directRenderingEnabled) { + if (info->ChipFamily >= CHIP_FAMILY_R300) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite acceleration " + "unsupported on R200 type cards and newer.\n"); + } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || + (info->ChipFamily == CHIP_FAMILY_RV280) || + (info->ChipFamily == CHIP_FAMILY_RS300) || + (info->ChipFamily == CHIP_FAMILY_R200)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite acceleration " + "enabled for R200 type cards.\n"); + info->exa.accel.CheckComposite = R200CheckComposite; + info->exa.accel.PrepareComposite = R200PrepareComposite; + info->exa.accel.Composite = R200Composite; + info->exa.accel.DoneComposite = R200DoneComposite; + } else { +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite acceleration " + "enabled for R100 type cards.\n"); + info->exa.accel.CheckComposite = R100CheckComposite; + info->exa.accel.PrepareComposite = R100PrepareComposite; + info->exa.accel.Composite = R100Composite; + info->exa.accel.DoneComposite = R100DoneComposite; +#endif + } + } +#endif + + RADEONEngineInit(pScrn); + + if (!exaDriverInit(pScreen, &info->exa)) { + return FALSE; + } + exaMarkSync(pScreen); + + info->scratch_area = NULL; + +#if 0 + /* Reserve a scratch area. It'll be used for storing glyph data during + * Composite operations, because glyphs aren't in real pixmaps and thus + * can't be migrated. + */ + info->scratch_area = exaOffscreenAlloc(pScreen, 131072, + info->exa.card.pixmapOffsetAlign, + TRUE, + FUNC_NAME(RADEONScratchSave), + info); + if (info->scratch_area != NULL) { + info->scratch_next = info->scratch_area->offset; + info->exa.accel.UploadToScratch = FUNC_NAME(RADEONUploadToScratch); + } +#endif + + return TRUE; +} + +#undef FUNC_NAME diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_mergedfb.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_mergedfb.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_mergedfb.c 2005-08-17 11:55:37.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_mergedfb.c 2005-08-29 07:51:46.000000000 +1000 @@ -1961,7 +1961,14 @@ OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | ((xorigin ? 0 : x1) << 16) | (yorigin ? 0 : y1))); - OUTREG(RADEON_CUR_OFFSET, info->cursor_start + yorigin * stride); +#ifdef USE_EXA + if (info->useEXA) + OUTREG(RADEON_CUR_OFFSET, info->cursorArea->offset + yorigin * stride); +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) + OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride); +#endif /* USE_XAA */ /* cursor2 */ OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK | (xorigin << 16) @@ -1969,9 +1976,14 @@ OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK | ((xorigin ? 0 : x2) << 16) | (yorigin ? 0 : y2))); - OUTREG(RADEON_CUR2_OFFSET, - info->cursor_start + yorigin * stride); - +#ifdef USE_EXA + if (info->useEXA) + OUTREG(RADEON_CUR2_OFFSET, info->cursorArea->offset + yorigin * stride); +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!info->useEXA) + OUTREG(RADEON_CUR2_OFFSET, info->cursor_offset + yorigin * stride); +#endif /* USE_XAA */ } /* radeon Xv helpers */ diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h 2005-08-17 11:55:37.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h 2005-08-29 07:51:47.000000000 +1000 @@ -53,6 +53,22 @@ #ifndef _RADEON_REG_H_ #define _RADEON_REG_H_ +#define ATI_DATATYPE_VQ 0 +#define ATI_DATATYPE_CI4 1 +#define ATI_DATATYPE_CI8 2 +#define ATI_DATATYPE_ARGB1555 3 +#define ATI_DATATYPE_RGB565 4 +#define ATI_DATATYPE_RGB888 5 +#define ATI_DATATYPE_ARGB8888 6 +#define ATI_DATATYPE_RGB332 7 +#define ATI_DATATYPE_Y8 8 +#define ATI_DATATYPE_RGB8 9 +#define ATI_DATATYPE_CI16 10 +#define ATI_DATATYPE_VYUY_422 11 +#define ATI_DATATYPE_YVYU_422 12 +#define ATI_DATATYPE_AYUV_444 14 +#define ATI_DATATYPE_ARGB4444 15 + /* Registers for 2D/Video/Overlay */ #define RADEON_ADAPTER_ID 0x0f2c /* PCI */ #define RADEON_AGP_BASE 0x0170 @@ -1226,6 +1242,28 @@ # define RADEON_RB2D_DC_FLUSH_ALL 0xf # define RADEON_RB2D_DC_BUSY (1 << 31) #define RADEON_RB2D_DSTCACHE_MODE 0x3428 + +#define RADEON_RB3D_DSTCACHE_MODE 0x3258 +# define RADEON_RB3D_DC_CACHE_ENABLE (0) +# define RADEON_RB3D_DC_2D_CACHE_DISABLE (1) +# define RADEON_RB3D_DC_3D_CACHE_DISABLE (2) +# define RADEON_RB3D_DC_CACHE_DISABLE (3) +# define RADEON_RB3D_DC_2D_CACHE_LINESIZE_128 (1 << 2) +# define RADEON_RB3D_DC_3D_CACHE_LINESIZE_128 (2 << 2) +# define RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH (1 << 8) +# define RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH (2 << 8) +# define R200_RB3D_DC_2D_CACHE_AUTOFREE (1 << 10) +# define R200_RB3D_DC_3D_CACHE_AUTOFREE (2 << 10) +# define RADEON_RB3D_DC_FORCE_RMW (1 << 16) +# define RADEON_RB3D_DC_DISABLE_RI_FILL (1 << 24) +# define RADEON_RB3D_DC_DISABLE_RI_READ (1 << 25) + +#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325C +# define RADEON_RB3D_DC_FLUSH (3 << 0) +# define RADEON_RB3D_DC_FREE (3 << 2) +# define RADEON_RB3D_DC_FLUSH_ALL 0xf +# define RADEON_RB3D_DC_BUSY (1 << 31) + #define RADEON_REG_BASE 0x0f18 /* PCI */ #define RADEON_REGPROG_INF 0x0f09 /* PCI */ #define RADEON_REVISION_ID 0x0f08 /* PCI */ @@ -2305,6 +2343,11 @@ # define R200_VC_16BIT_SWAP (1 << 0) # define R200_VC_32BIT_SWAP (2 << 0) #define R200_PP_TXFILTER_0 0x2c00 +#define R200_PP_TXFILTER_1 0x2c20 +#define R200_PP_TXFILTER_2 0x2c40 +#define R200_PP_TXFILTER_3 0x2c60 +#define R200_PP_TXFILTER_4 0x2c80 +#define R200_PP_TXFILTER_5 0x2ca0 # define R200_MAG_FILTER_NEAREST (0 << 0) # define R200_MAG_FILTER_LINEAR (1 << 0) # define R200_MAG_FILTER_MASK (1 << 0) @@ -2355,6 +2398,11 @@ # define R200_BORDER_MODE_OGL (0 << 31) # define R200_BORDER_MODE_D3D (1 << 31) #define R200_PP_TXFORMAT_0 0x2c04 +#define R200_PP_TXFORMAT_1 0x2c24 +#define R200_PP_TXFORMAT_2 0x2c44 +#define R200_PP_TXFORMAT_3 0x2c64 +#define R200_PP_TXFORMAT_4 0x2c84 +#define R200_PP_TXFORMAT_5 0x2ca4 # define R200_TXFORMAT_I8 (0 << 0) # define R200_TXFORMAT_AI88 (1 << 0) # define R200_TXFORMAT_RGB332 (2 << 0) @@ -2394,8 +2442,26 @@ # define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) # define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) #define R200_PP_TXFORMAT_X_0 0x2c08 +#define R200_PP_TXFORMAT_X_1 0x2c28 +#define R200_PP_TXFORMAT_X_2 0x2c48 +#define R200_PP_TXFORMAT_X_3 0x2c68 +#define R200_PP_TXFORMAT_X_4 0x2c88 +#define R200_PP_TXFORMAT_X_5 0x2ca8 + #define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ +#define R200_PP_TXSIZE_1 0x2c2c /* NPOT only */ +#define R200_PP_TXSIZE_2 0x2c4c /* NPOT only */ +#define R200_PP_TXSIZE_3 0x2c6c /* NPOT only */ +#define R200_PP_TXSIZE_4 0x2c8c /* NPOT only */ +#define R200_PP_TXSIZE_5 0x2cac /* NPOT only */ + #define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ +#define R200_PP_TXPITCH_1 0x2c30 /* NPOT only */ +#define R200_PP_TXPITCH_2 0x2c50 /* NPOT only */ +#define R200_PP_TXPITCH_3 0x2c70 /* NPOT only */ +#define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */ +#define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */ + #define R200_PP_TXOFFSET_0 0x2d00 # define R200_TXO_ENDIAN_NO_SWAP (0 << 0) # define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_render.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_render.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_render.c 2005-08-17 11:55:37.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_render.c 2005-08-31 09:29:00.000000000 +1000 @@ -2,6 +2,8 @@ #include "config.h" #endif +#ifdef USE_XAA + #include "dixstruct.h" #include "xaa.h" @@ -228,24 +230,6 @@ return bits - 1; } -static void RadeonInit3DEngine(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR (pScrn); - -#ifdef XF86DRI - if (info->directRenderingEnabled) { - RADEONSAREAPrivPtr pSAREAPriv; - - pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); - pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen); - RadeonInit3DEngineCP(pScrn); - } else -#endif - RadeonInit3DEngineMMIO(pScrn); - - info->RenderInited3D = TRUE; -} - static void RemoveLinear (FBLinearPtr linear) { @@ -357,61 +341,6 @@ #endif #endif - -static void FUNC_NAME(RadeonInit3DEngine)(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - ACCEL_PREAMBLE(); - - if (info->ChipFamily >= CHIP_FAMILY_R300) { - /* Unimplemented */ - } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || - (info->ChipFamily == CHIP_FAMILY_RV280) || - (info->ChipFamily == CHIP_FAMILY_RS300) || - (info->ChipFamily == CHIP_FAMILY_R200)) { - - BEGIN_ACCEL(7); - if (info->ChipFamily == CHIP_FAMILY_RS300) { - OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS); - } else { - OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0); - } - OUT_ACCEL_REG(R200_PP_CNTL_X, 0); - OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0); - OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0); - OUT_ACCEL_REG(R200_RE_CNTL, 0x0); - /* XXX: correct? Want it to be like RADEON_VTX_ST?_NONPARAMETRIC */ - OUT_ACCEL_REG(R200_SE_VTE_CNTL, R200_VTX_ST_DENORMALIZED); - OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE | - R200_VAP_VF_MAX_VTX_NUM); - FINISH_ACCEL(); - } else { - BEGIN_ACCEL(2); - if ((info->ChipFamily == CHIP_FAMILY_RADEON) || - (info->ChipFamily == CHIP_FAMILY_RV200)) - OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0); - else - OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS); - OUT_ACCEL_REG(RADEON_SE_COORD_FMT, - RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | - RADEON_VTX_ST0_NONPARAMETRIC | - RADEON_VTX_ST1_NONPARAMETRIC | - RADEON_TEX1_W_ROUTING_USE_W0); - FINISH_ACCEL(); - } - - BEGIN_ACCEL(3); - OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); - OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff); - OUT_ACCEL_REG(RADEON_SE_CNTL, RADEON_DIFFUSE_SHADE_GOURAUD | - RADEON_BFACE_SOLID | - RADEON_FFACE_SOLID | - RADEON_VTX_PIX_CENTER_OGL | - RADEON_ROUND_MODE_ROUND | - RADEON_ROUND_PREC_4TH_PIX); - FINISH_ACCEL(); -} - static Bool FUNC_NAME(R100SetupTexture)( ScrnInfoPtr pScrn, CARD32 format, @@ -474,9 +403,10 @@ while ( height ) { tmp_dst = RADEONHostDataBlit( pScrn, tex_bytepp, width, - dst_pitch, &buf_pitch, - &dst, &height, &hpass ); - RADEONHostDataBlitCopyPass( tmp_dst, src, hpass, buf_pitch, src_pitch ); + dst_pitch, &buf_pitch, + &dst, &height, &hpass); + RADEONHostDataBlitCopyPass( pScrn, tex_bytepp, tmp_dst, src, + hpass, buf_pitch, src_pitch ); src += hpass * src_pitch; } @@ -542,8 +472,8 @@ if (blend_cntl == 0) return FALSE; - if (!info->RenderInited3D) - RadeonInit3DEngine(pScrn); + if (!info->XInited3D) + RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R100SetupTexture)(pScrn, maskFormat, alphaPtr, alphaPitch, width, height, flags)) @@ -593,8 +523,8 @@ if (blend_cntl == 0) return FALSE; - if (!info->RenderInited3D) - RadeonInit3DEngine(pScrn); + if (!info->XInited3D) + RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R100SetupTexture)(pScrn, srcFormat, texPtr, texPitch, width, height, flags)) @@ -805,9 +735,10 @@ while ( height ) { tmp_dst = RADEONHostDataBlit( pScrn, tex_bytepp, width, - dst_pitch, &buf_pitch, - &dst, &height, &hpass ); - RADEONHostDataBlitCopyPass( tmp_dst, src, hpass, buf_pitch, src_pitch ); + dst_pitch, &buf_pitch, + &dst, &height, &hpass ); + RADEONHostDataBlitCopyPass( pScrn, tex_bytepp, tmp_dst, src, + hpass, buf_pitch, src_pitch ); src += hpass * src_pitch; } @@ -873,8 +804,8 @@ if (blend_cntl == 0) return FALSE; - if (!info->RenderInited3D) - RadeonInit3DEngine(pScrn); + if (!info->XInited3D) + RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R200SetupTexture)(pScrn, maskFormat, alphaPtr, alphaPitch, width, height, flags)) @@ -925,8 +856,8 @@ if (blend_cntl == 0) return FALSE; - if (!info->RenderInited3D) - RadeonInit3DEngine(pScrn); + if (!info->XInited3D) + RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R200SetupTexture)(pScrn, srcFormat, texPtr, texPitch, width, height, flags)) @@ -1074,4 +1005,4 @@ } #undef FUNC_NAME - +#endif /* USE_XAA */ diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c 2005-08-17 11:55:37.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c 2005-08-30 15:59:58.000000000 +1000 @@ -14,6 +14,7 @@ #include "xf86.h" #include "dixstruct.h" #include "xf86PciInfo.h" +#include "xf86fbman.h" #include #include "fourcc.h" @@ -24,6 +25,13 @@ #include "msp3430.h" #include "tda9885.h" +#ifdef USE_EXA +/* FIXME : the video code hasn't been ported so this is a hack to make + * it compile at all without too much ifdefing */ +#include "xaa.h" +#include "xf86fbman.h" +#endif + #define OFF_DELAY 250 /* milliseconds */ #define FREE_DELAY 15000 @@ -114,6 +122,19 @@ (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr) +#ifdef USE_EXA +static void +ATIVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + + if (pPriv->off_screen == area) + pPriv->off_screen = 0; +} +#endif + void RADEONInitVideo(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -1038,7 +1059,8 @@ /* this function is called from ScreenInit. pScreen is used by XAA internally, but not valid until ScreenInit finishs. */ - if (info->accelOn && pScrn->pScreen) info->accel->Sync(pScrn); + if (info->accelOn && pScrn->pScreen) + RADEON_SYNC(info, pScrn); /* this is done here because each time the server is reset these could change.. Otherwise they remain constant */ @@ -1204,20 +1226,20 @@ } else { t->wComp0Connector=RT_COMP1; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %d\n", t->wComp0Connector); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %ld\n", t->wComp0Connector); break; case 3: if(a & 0x4){ t->wSVideo0Connector=RT_YCR_COMP4; } else { t->wSVideo0Connector=RT_YCF_COMP4; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %d\n", t->wSVideo0Connector); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %ld\n", t->wSVideo0Connector); break; default: break; } } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%d, composite=%d, svideo=%d\n", + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%ld, composite=%ld, svideo=%ld\n", t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector); } @@ -1226,7 +1248,7 @@ if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort; if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%d, composite=%d, svideo=%d\n", + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%ld, composite=%ld, svideo=%ld\n", t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector); switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){ @@ -1253,7 +1275,6 @@ XF86VideoAdaptorPtr adapt; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv; - unsigned char *RADEONMMIO = info->MMIO; CARD32 dot_clock; if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn))) @@ -1531,10 +1552,18 @@ if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE); if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); } +#ifdef USE_EXA + if (pPriv->off_screen) { + exaOffscreenFree (pScrn->pScreen, pPriv->off_screen); + pPriv->off_screen = 0; + } +#endif +#ifdef USE_XAA if(info->videoLinear) { xf86FreeOffscreenLinear(info->videoLinear); info->videoLinear = NULL; } +#endif pPriv->videoStatus = 0; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { @@ -1556,7 +1585,7 @@ Bool setAlpha = FALSE; unsigned char *RADEONMMIO = info->MMIO; - info->accel->Sync(pScrn); + RADEON_SYNC(info, pScrn); #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) #define RTFBrightness(a) (((a)*1.0)/2000.0) @@ -1785,7 +1814,7 @@ else if(attribute == xvAdjustment) { pPriv->adjustment=value; - xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %d\n", pPriv->adjustment); + xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %ld\n", pPriv->adjustment); if(pPriv->tda9885!=0){ pPriv->tda9885->top_adjustment=value; RADEON_TDA9885_SetEncoding(pPriv); @@ -1825,7 +1854,7 @@ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; - if (info->accelOn) info->accel->Sync(pScrn); + if (info->accelOn) RADEON_SYNC(info, pScrn); if(attribute == xvAutopaintColorkey) *value = pPriv->autopaint_colorkey; @@ -2008,11 +2037,11 @@ ScrnInfoPtr pScrn, unsigned char *src, unsigned char *dst, - int srcPitch, - int dstPitch, - int h, - int w, - int bpp + unsigned int srcPitch, + unsigned int dstPitch, + unsigned int h, + unsigned int w, + unsigned int bpp ){ RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI @@ -2033,7 +2062,8 @@ while ( buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitch, &bufPitch, &dst, &h, &hpass ) ) { - RADEONHostDataBlitCopyPass( buf, src, hpass, bufPitch, srcPitch ); + RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch, + srcPitch ); src += hpass * srcPitch; } @@ -2046,24 +2076,25 @@ { #if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char *RADEONMMIO = info->MMIO; - if ( bpp == 2 ) - { - OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl - & ~(RADEON_NONSURF_AP0_SWP_32BPP - | RADEON_NONSURF_AP0_SWP_16BPP)); - } - else /* bpp == 4 */ - { - OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl - | RADEON_NONSURF_AP0_SWP_32BPP) - & ~RADEON_NONSURF_AP0_SWP_16BPP); + unsigned int swapper = info->ModeReg.surface_cntl & + ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | + RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP); + + switch(bpp) { + case 2: + swapper |= RADEON_NONSURF_AP0_SWP_16BPP + | RADEON_NONSURF_AP1_SWP_16BPP; + break; + case 4: + swapper |= RADEON_NONSURF_AP0_SWP_32BPP + | RADEON_NONSURF_AP1_SWP_32BPP; + break; } + OUTREG(RADEON_SURFACE_CNTL, swapper); #endif + w *= bpp; - w *= 2; - - while (h--) - { + while (h--) { memcpy(dst, src, w); src += srcPitch; dst += dstPitch; @@ -2097,13 +2128,13 @@ ScrnInfoPtr pScrn, unsigned char *src, unsigned char *dst, - int srcPitch, - int dstPitch, - int h, - int w + unsigned int srcPitch, + unsigned int dstPitch, + unsigned int h, + unsigned int w ){ CARD32 *dptr; - CARD8 *sptr; + CARD8 *sptr = 0; int i,j; RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI @@ -2113,6 +2144,8 @@ CARD32 bufPitch; unsigned int hpass; + /* XXX Fix endian flip on R300 */ + while ( dptr = ( CARD32* )RADEONHostDataBlit( pScrn, 4, w, dstPitch, &bufPitch, &dst, &h, &hpass ) ) @@ -2171,11 +2204,11 @@ unsigned char *src2, unsigned char *src3, unsigned char *dst1, - int srcPitch, - int srcPitch2, - int dstPitch, - int h, - int w + unsigned int srcPitch, + unsigned int srcPitch2, + unsigned int dstPitch, + unsigned int h, + unsigned int w ){ RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI @@ -2186,6 +2219,8 @@ CARD32 y = 0, bufPitch; unsigned int hpass; + /* XXX Fix endian flip on R300 */ + while ( buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitch, &bufPitch, &dst1, &h, &hpass ) ) { @@ -2249,9 +2284,8 @@ { src2 += srcPitch2; src3 += srcPitch2; - } + } } - #if X_BYTE_ORDER == X_BIG_ENDIAN /* restore byte swapping */ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl); @@ -2259,7 +2293,6 @@ } } - static FBLinearPtr RADEONAllocateMemory( ScrnInfoPtr pScrn, @@ -2267,6 +2300,7 @@ int size ){ ScreenPtr pScreen; + RADEONInfoPtr info = RADEONPTR(pScrn); FBLinearPtr new_linear; if(linear) { @@ -2280,7 +2314,10 @@ } pScreen = screenInfo.screens[pScrn->scrnIndex]; - +#ifdef USE_EXA + if (info->useEXA) + ErrorF("XVideo is not finished with Exa\n"); +#endif new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL, NULL, NULL); @@ -2478,7 +2515,7 @@ RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_OV0_REG_LOAD_CNTL, 1); - if (info->accelOn) info->accel->Sync(pScrn); + if (info->accelOn) RADEON_SYNC(info, pScrn); while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & (1 << 3))); dsr=(double)(1<<0xC)/h_inc; @@ -2721,11 +2758,30 @@ break; } + +#ifdef USE_EXA + new_size = pPriv->doubleBuffer ? (new_size << 1) : new_size; + + if (pPriv->off_screen != NULL && new_size != pPriv->size) { + exaOffscreenFree(pScrn->pScreen, pPriv->off_screen); + pPriv->off_screen = 0; + } + + if (pPriv->off_screen == NULL) { + pPriv->off_screen = exaOffscreenAlloc(pScrn->pScreen, + new_size, + 64, TRUE, ATIVideoSave, pPriv); + if (pPriv->off_screen == NULL) + return BadAlloc; + pPriv->size = new_size; + } +#else if(!(info->videoLinear = RADEONAllocateMemory(pScrn, info->videoLinear, pPriv->doubleBuffer ? (new_size << 1) : new_size))) { return BadAlloc; } +#endif pPriv->currentBuffer ^= 1; @@ -2734,7 +2790,8 @@ left = (xa >> 16) & ~1; npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; - offset = (info->videoLinear->offset * bpp) + (top * dstPitch); + offset = (pPriv->video_offset) + (top * dstPitch); + if(pPriv->doubleBuffer) offset += pPriv->currentBuffer * new_size * bpp; @@ -2861,10 +2918,18 @@ } } else { /* FREE_TIMER */ if(pPriv->freeTime < now) { +#ifdef USE_EXA + if (pPriv->off_screen) { + exaOffscreenFree (pScrn->pScreen, pPriv->off_screen); + pPriv->off_screen = 0; + } +#endif /* USE_EXA */ +#ifdef USE_XAA if(info->videoLinear) { xf86FreeOffscreenLinear(info->videoLinear); info->videoLinear = NULL; } +#endif /* USE_XAA */ pPriv->videoStatus = 0; info->VideoTimerCallback = NULL; } @@ -3116,7 +3181,7 @@ int mult; int vbi_line_width, vbi_start, vbi_end; - info->accel->Sync(pScrn); + RADEON_SYNC(info, pScrn); /* * s2offset, s3offset - byte offsets into U and V plane of the * source where copying starts. Y plane is @@ -3216,10 +3281,36 @@ } new_size = new_size + 0x1f; /* for aligning */ - if(!(info->videoLinear = RADEONAllocateMemory(pScrn, info->videoLinear, new_size*mult+(pPriv->capture_vbi_data?2*2*vbi_line_width*21:0)))) - { - return BadAlloc; - } + +#ifdef USE_EXA + if (info->useEXA) { + new_size = new_size*mult+(pPriv->capture_vbi_data?2*2*vbi_line_width*21:0); + if (pPriv->off_screen != NULL && new_size != pPriv->size) { + exaOffscreenFree(pScrn->pScreen, pPriv->off_screen); + pPriv->off_screen = NULL; + } + + if (pPriv->off_screen == NULL) { + pPriv->off_screen = exaOffscreenAlloc(pScrn->pScreen, new_size, + 64, TRUE, ATIVideoSave, + pPriv); + } + if (pPriv->off_screen == NULL) + return BadAlloc; + + pPriv->video_offset = pPriv->off_screen->offset; + pPriv->size = new_size; + } +#endif +#ifdef USE_XAA + if (!info->useEXA) { + info->videoLinear = RADEONAllocateMemory(pScrn, info->videoLinear, + new_size*mult+(pPriv->capture_vbi_data?2*2*vbi_line_width*21:0)); + if (info->videoLinear == NULL) + return BadAlloc; + pPriv->video_offset = info->videoLinear->offset * bpp; + } +#endif /* I have suspicion that capture engine must be active _before_ Rage Theatre is being manipulated with.. */ @@ -3232,20 +3323,20 @@ switch(pPriv->overlay_deinterlacing_method){ case METHOD_BOB: case METHOD_SINGLE: - offset1 = (info->videoLinear->offset*bpp+0xf) & (~0xf); - offset2 = ((info->videoLinear->offset+new_size)*bpp + 0xf) & (~0xf); + offset1 = (pPriv->video_offset + 0xf) & (~0xf); + offset2 = (pPriv->video_offset + new_size * bpp + 0xf) & (~0xf); offset3 = offset1; offset4 = offset2; break; case METHOD_WEAVE: - offset1 = (info->videoLinear->offset*bpp+0xf) & (~0xf); + offset1 = (pPriv->video_offset + 0xf) & (~0xf); offset2 = offset1+dstPitch; - offset3 = ((info->videoLinear->offset+2*new_size)*bpp + 0xf) & (~0xf); + offset3 = (pPriv->video_offset + 2 * new_size * bpp + 0xf) & (~0xf); offset4 = offset3+dstPitch; break; default: - offset1 = (info->videoLinear->offset*bpp+0xf) & (~0xf); - offset2 = ((info->videoLinear->offset+new_size)*bpp + 0xf) & (~0xf); + offset1 = (pPriv->video_offset + 0xf) & (~0xf); + offset2 = (pPriv->video_offset + new_size * bpp + 0xf) & (~0xf); offset3 = offset1; offset4 = offset2; } @@ -3268,8 +3359,7 @@ vbi_end = 20; } - - vbi_offset0 = ((info->videoLinear->offset+mult*new_size)*bpp+0xf) & (~0xf); + vbi_offset0 = (pPriv->video_offset + mult * new_size * bpp + 0xf) & (~0xf); vbi_offset1 = vbi_offset0 + dstPitch*20; OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base); OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base); diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.h xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.h --- xc-HEAD.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.h 2005-08-17 11:55:37.000000000 +1000 +++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.h 2005-08-29 07:51:47.000000000 +1000 @@ -81,6 +81,13 @@ Bool autopaint_colorkey; Bool crt2; /* 0=CRT1, 1=CRT2 */ +#ifdef USE_EXA + int size; + ExaOffscreenArea *off_screen; +#endif + + int video_offset; + Atom device_id, location_id, instance_id; } RADEONPortPrivRec, *RADEONPortPrivPtr;