> > to the Rage128's CCE engine. Although it only accelerates SolidFill and > > ScreenToScreenCopies it should help a lot. > > Hmm, maybe it's easy for someone who doesn't touch the dri code for the > first time, but not for me. I've tried, the code builds and doesn't > crash, but doesn't work. Can someone have a look at it please? Uhm, well, with r128_cce_indirect not implemented yet in th kernel it can't work. New version + kernel patch, working this time. Gerd
diff -ur /suse/kraxel/r128/ati.orig/r128.h xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h --- /suse/kraxel/r128/ati.orig/r128.h Thu Sep 13 18:19:17 2001 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h Mon Sep 17 11:40:23 2001 @@ -295,7 +295,6 @@ int CCEFifoSize; /* Size of the CCE command FIFO */ Bool CCESecure; /* CCE security enabled */ int CCEusecTimeout; /* CCE timeout in usecs */ - Bool CCE2D; /* CCE is used for X server 2D prims */ /* CCE ring buffer data */ unsigned long ringStart; /* Offset into AGP space */ @@ -327,6 +326,10 @@ unsigned char *agpTex; /* Map */ int log2AGPTexGran; + /* CCE 2D accleration */ + drmBufPtr indirectBuffer; + int indirectStart; + /* DRI screen private data */ int fbX; int fbY; @@ -351,6 +354,10 @@ CARD32 sc_right; CARD32 sc_top; CARD32 sc_bottom; + + CARD32 re_top_left; + CARD32 re_width_height; + CARD32 aux_sc_cntl; #endif @@ -396,7 +403,6 @@ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CCE start %d\n", __FUNCTION__, _ret); \ } \ - info->CCEInUse = TRUE; \ } while (0) #define R128CCE_STOP(pScrn, info) \ @@ -406,7 +412,6 @@ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CCE stop %d\n", __FUNCTION__, _ret); \ } \ - info->CCEInUse = FALSE; \ } while (0) #define R128CCE_RESET(pScrn, info) \ @@ -419,29 +424,100 @@ "%s: CCE reset %d\n", __FUNCTION__, _ret); \ } \ } \ - info->CCEInUse = FALSE; \ } while (0) -#define R128CCE_TO_MMIO(pScrn, info) \ +#endif + +extern drmBufPtr R128CCEGetBuffer(ScrnInfoPtr pScrn); +extern void R128CCEFlushIndirect(ScrnInfoPtr pScrn); +extern void R128CCEReleaseIndirect(ScrnInfoPtr pScrn); +extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); + + +#define CP_PACKET0( reg, n ) \ + (R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2)) +#define CP_PACKET1( reg0, reg1 ) \ + (R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) +#define CP_PACKET2() \ + (R128_CCE_PACKET2) +#define CP_PACKET3( pkt, n ) \ + (R128_CCE_PACKET3 | (pkt) | ((n) << 16)) + + +#define R128_VERBOSE 0 + +#define RING_LOCALS CARD32 *__head; int __count; +#define RING_THRESHOLD 256 + +#define R128CCE_REFRESH(pScrn, info) \ do { \ - if (info->CCEInUse) { \ - R128CCE_STOP(pScrn, info); \ - \ - R128WaitForFifo(pScrn, 5); \ - OUTREG(R128_SC_LEFT, info->sc_left); \ - OUTREG(R128_SC_RIGHT, info->sc_right); \ - OUTREG(R128_SC_TOP, info->sc_top); \ - OUTREG(R128_SC_BOTTOM, info->sc_bottom); \ - OUTREG(R128_AUX_SC_CNTL, info->aux_sc_cntl); \ - } \ + if ( R128_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, "REFRESH( %d ) in %s\n", \ + !info->CCEInUse , __FUNCTION__ ); \ + } \ + if ( !info->CCEInUse ) { \ + R128CCEWaitForIdle(pScrn); \ + BEGIN_RING( 6 ); \ + OUT_RING_REG( R128_RE_TOP_LEFT, info->re_top_left ); \ + OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height ); \ + OUT_RING_REG( R128_AUX_SC_CNTL, info->aux_sc_cntl ); \ + ADVANCE_RING(); \ + info->CCEInUse = TRUE; \ + } \ +} while (0) + +#define BEGIN_RING( n ) do { \ + if ( R128_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \ + } \ + if ( !info->indirectBuffer ) { \ + info->indirectBuffer = R128CCEGetBuffer( pScrn ); \ + info->indirectStart = 0; \ + } else if ( info->indirectBuffer->used - info->indirectStart + \ + (n) * (int)sizeof(CARD32) > RING_THRESHOLD ) { \ + R128CCEFlushIndirect( pScrn ); \ + } \ + __head = (pointer)((char *)info->indirectBuffer->address + \ + info->indirectBuffer->used); \ + __count = 0; \ +} while (0) + +#define ADVANCE_RING() do { \ + if ( R128_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "ADVANCE_RING() used: %d+%d=%d/%d\n", \ + info->indirectBuffer->used - info->indirectStart, \ + __count * sizeof(CARD32), \ + info->indirectBuffer->used - info->indirectStart + \ + __count * sizeof(CARD32), \ + RING_THRESHOLD ); \ + } \ + info->indirectBuffer->used += __count * (int)sizeof(CARD32); \ +} while (0) + +#define OUT_RING( x ) do { \ + if ( R128_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + " OUT_RING( 0x%08x )\n", (unsigned int)(x) ); \ + } \ + __head[__count++] = (x); \ } while (0) -#define R128MMIO_TO_CCE(pScrn, info) \ +#define OUT_RING_REG( reg, val ) \ do { \ - if (!info->CCEInUse) { \ - R128CCE_START(pScrn, info); \ - } \ + OUT_RING( CP_PACKET0( reg, 0 ) ); \ + OUT_RING( val ); \ +} while (0) + +#define FLUSH_RING() \ +do { \ + if ( R128_VERBOSE ) \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "FLUSH_RING in %s\n", __FUNCTION__ ); \ + if ( info->indirectBuffer ) { \ + R128CCEFlushIndirect( pScrn ); \ + } \ } while (0) -#endif #endif diff -ur /suse/kraxel/r128/ati.orig/r128_accel.c xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c --- /suse/kraxel/r128/ati.orig/r128_accel.c Thu Aug 9 21:14:12 2001 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c Mon Sep 17 11:37:51 +2001 @@ -82,6 +82,7 @@ /* Driver data structures */ #include "r128.h" #include "r128_reg.h" +#include "r128_sarea.h" #ifdef XF86DRI #define _XF86DRI_SERVER_ #include "r128_dri.h" @@ -179,7 +180,7 @@ R128EngineReset(pScrn); #ifdef XF86DRI R128CCE_RESET(pScrn, info); - if (info->CCE2D) { + if (info->directRenderingEnabled) { R128CCE_START(pScrn, info); } #endif @@ -213,7 +214,7 @@ R128EngineReset(pScrn); #ifdef XF86DRI R128CCE_RESET(pScrn, info); - if (info->CCE2D) { + if (info->directRenderingEnabled) { R128CCE_START(pScrn, info); } #endif @@ -224,12 +225,14 @@ /* Wait until the CCE is completely idle: the FIFO has drained and the * CCE is idle. */ -static void R128CCEWaitForIdle(ScrnInfoPtr pScrn) +void R128CCEWaitForIdle(ScrnInfoPtr pScrn) { R128InfoPtr info = R128PTR(pScrn); int ret; int i = 0; + FLUSH_RING(); + for (;;) { do { ret = drmR128WaitForIdleCCE(info->drmFD); @@ -259,10 +262,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 4); OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl | R128_GMC_BRUSH_SOLID_COLOR @@ -284,10 +283,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 2); OUTREG(R128_DST_Y_X, (y << 16) | x); OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h); @@ -300,10 +295,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 3); OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl | R128_GMC_BRUSH_SOLID_COLOR @@ -336,10 +327,6 @@ unsigned char *R128MMIO = info->MMIO; int flags = 0; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; @@ -366,10 +353,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 1); OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM)); @@ -404,10 +387,6 @@ unsigned char *R128MMIO = info->MMIO; CARD32 pat = *(CARD32 *)(pointer)pattern; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - #if X_BYTE_ORDER == X_LITTLE_ENDIAN # define PAT_SHIFT(pat,n) pat << n #else @@ -445,10 +424,6 @@ unsigned char *R128MMIO = info->MMIO; int flags = 0; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; @@ -486,10 +461,6 @@ int origdxL = dxL; int origdxR = dxR; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128TRACE(("Trap %d %d; L %d %d %d %d; R %d %d %d %d\n", y, h, left, dxL, dyL, eL, @@ -540,10 +511,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - info->xdir = xdir; info->ydir = ydir; R128WaitForFifo(pScrn, 3); @@ -577,10 +544,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - if (info->xdir < 0) xa += w - 1, xb += w - 1; if (info->ydir < 0) ya += h - 1, yb += h - 1; @@ -610,10 +573,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 6); OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl | (bg == -1 @@ -637,10 +596,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 3); OUTREG(R128_BRUSH_Y_X, (patterny << 8) | patternx); OUTREG(R128_DST_Y_X, (y << 16) | x); @@ -660,10 +615,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128TRACE(("Color8x8 %d %d %d\n", trans_color, patx, paty)); R128WaitForFifo(pScrn, 2); @@ -692,10 +643,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128TRACE(("Color8x8 %d,%d %d,%d %d %d\n", patx, paty, x, y, w, h)); R128WaitForFifo(pScrn, 3); OUTREG(R128_SRC_Y_X, (paty << 16) | patx); @@ -756,10 +703,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - R128WaitForFifo(pScrn, 4); OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl | R128_GMC_DST_CLIPPING @@ -787,10 +730,6 @@ int x1clip = x+skipleft; int x2clip = x+w; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - info->scanline_h = h; info->scanline_words = (w + 31) >> 5; @@ -837,10 +776,6 @@ int left = info->scanline_words; volatile CARD32 *d; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - if (info->scanline_direct) return; --info->scanline_h; while (left) { @@ -887,10 +822,6 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - info->scanline_bpp = bpp; R128WaitForFifo(pScrn, 2); @@ -927,10 +858,6 @@ int shift = 0; /* 32bpp */ -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - if (pScrn->bitsPerPixel == 8) shift = 3; else if (pScrn->bitsPerPixel == 16) shift = 1; @@ -979,10 +906,6 @@ int left = info->scanline_words; volatile CARD32 *d; -#ifdef XF86DRI - R128CCE_TO_MMIO(pScrn, info); -#endif - if (info->scanline_direct) return; --info->scanline_h; while (left) { @@ -1075,18 +998,269 @@ OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN); #endif +#ifdef XF86DRI + info->sc_left = 0x00000000; + info->sc_right = R128_DEFAULT_SC_RIGHT_MAX; + info->sc_top = 0x00000000; + info->sc_bottom = R128_DEFAULT_SC_BOTTOM_MAX; + + info->re_top_left = 0x00000000; + info->re_width_height = ((0x7ff << R128_RE_WIDTH_SHIFT) | + (0x7ff << R128_RE_HEIGHT_SHIFT)); + + info->aux_sc_cntl = 0x00000000; +#endif + R128WaitForIdle(pScrn); } #ifdef XF86DRI - /* FIXME: When direct rendering is enabled, we should use the CCE to - draw 2D commands */ -static void R128CCEAccelInit(XAAInfoRecPtr a) + +/* Setup for XAA SolidFill. */ +static void R128CCESetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 8 ); + + OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern) ); + + OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, color ); + OUT_RING_REG( R128_DP_WRITE_MASK, planemask ); + OUT_RING_REG( R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT | + R128_DST_Y_TOP_TO_BOTTOM)); + ADVANCE_RING(); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void R128CCESubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) { - a->Flags = 0; + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 4 ); + + OUT_RING_REG( R128_DST_Y_X, (y << 16) | x ); + OUT_RING_REG( R128_DST_WIDTH_HEIGHT, (w << 16) | h ); + + ADVANCE_RING(); +} + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void R128CCESetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + info->xdir = xdir; + info->ydir = ydir; + + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | R128_GMC_BRUSH_NONE + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY) ); + + OUT_RING_REG( R128_DP_WRITE_MASK, planemask ); + OUT_RING_REG( R128_DP_CNTL, + ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) | + (ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0)) ); + + ADVANCE_RING(); + + if ((trans_color != -1) || (info->XAAForceTransBlit == TRUE)) { + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_CLR_CMP_CLR_SRC, trans_color ); + OUT_RING_REG( R128_CLR_CMP_MASK, R128_CLR_CMP_MSK ); + OUT_RING_REG( R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR | + R128_CLR_CMP_SRC_SOURCE) ); + + ADVANCE_RING(); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void R128CCESubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_SRC_Y_X, (ya << 16) | xa ); + OUT_RING_REG( R128_DST_Y_X, (yb << 16) | xb ); + OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (h << 16) | w ); + + ADVANCE_RING(); +} + +/* Get an indirect buffer for the CP 2D acceleration commands. + */ +drmBufPtr R128CCEGetBuffer( ScrnInfoPtr pScrn ) +{ + R128InfoPtr info = R128PTR(pScrn); + drmDMAReq dma; + drmBufPtr buf = NULL; + int indx = 0; + int size = 0; + int ret, i = 0; + +#if 0 + /* FIXME: pScrn->pScreen has not been initialized when this is first + called from RADEONSelectBuffer via RADEONDRICPInit. We could use + the screen index from pScrn, which is initialized, and then get + the screen from screenInfo.screens[index], but that is a hack. */ + dma.context = DRIGetContext(pScrn->pScreen); +#else + dma.context = 0x00000001; /* This is the X server's context */ +#endif + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = R128_BUFFER_SIZE; + dma.request_list = &indx; + dma.request_sizes = &size; + dma.granted_count = 0; + + while ( 1 ) { + do { + ret = drmDMA( info->drmFD, &dma ); + if ( ret && ret != -EBUSY ) { + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "%s: CCE GetBuffer %d\n", __FUNCTION__, ret ); + } + } while ( ( ret == -EBUSY ) && ( i++ < R128_TIMEOUT ) ); + + if ( ret == 0 ) { + buf = &info->buffers->list[indx]; + buf->used = 0; + if ( R128_VERBOSE ) { + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + " GetBuffer returning %d\n", buf->idx ); + } + return buf; + } + + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "GetBuffer timed out, resetting engine...\n"); + R128EngineReset( pScrn ); + /* R128EngineRestore( pScrn ); FIXME ??? */ + + /* Always restart the engine when doing CP 2D acceleration */ + R128CCE_RESET( pScrn, info ); + R128CCE_START( pScrn, info ); + } +} + +/* Flush the indirect buffer to the kernel for submission to the card. + */ +void R128CCEFlushIndirect( ScrnInfoPtr pScrn ) +{ + R128InfoPtr info = R128PTR(pScrn); + drmBufPtr buffer = info->indirectBuffer; + int start = info->indirectStart; + int discard; + + if ( !buffer ) + return; + + if ( start == buffer->used ) + return; + + discard = ( buffer->used + RING_THRESHOLD > buffer->total ); + + drmR128FlushIndirectBuffer( info->drmFD, buffer->idx, + start, buffer->used, discard ); + + if ( discard ) { + info->indirectBuffer = R128CCEGetBuffer( pScrn ); + info->indirectStart = 0; + } else { + info->indirectStart = buffer->used; + } +} + +/* Flush and release the indirect buffer. + */ +void R128CCEReleaseIndirect( ScrnInfoPtr pScrn ) +{ + R128InfoPtr info = R128PTR(pScrn); + drmBufPtr buffer = info->indirectBuffer; + int start = info->indirectStart; + + info->indirectBuffer = NULL; + info->indirectStart = 0; + + if ( !buffer ) + return; + + drmR128FlushIndirectBuffer( info->drmFD, buffer->idx, + start, buffer->used, 1 ); +} + +static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); /* Sync */ a->Sync = R128CCEWaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = R128CCESetupForSolidFill; + a->SubsequentSolidFillRect = R128CCESubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + /* Transparency uses the wrong colors for + 24 bpp mode -- the transparent part is + correct, but the opaque color is wrong. + This can be seen with netscape's I-bar + cursor when editing in the URL location + box. */ + a->ScreenToScreenCopyFlags = ((pScrn->bitsPerPixel == 24) + ? NO_TRANSPARENCY + : 0); + a->SetupForScreenToScreenCopy = R128CCESetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = R128CCESubsequentScreenToScreenCopy; } #endif @@ -1189,7 +1363,8 @@ #ifdef XF86DRI /* FIXME: When direct rendering is enabled, we should use the CCE to draw 2D commands */ - if (info->CCE2D) R128CCEAccelInit(a); + if (info->directRenderingEnabled) + R128CCEAccelInit(pScrn, a); else #endif R128MMIOAccelInit(pScrn, a); diff -ur /suse/kraxel/r128/ati.orig/r128_dri.c xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c --- /suse/kraxel/r128/ati.orig/r128_dri.c Sat Aug 18 19:25:51 2001 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c Mon Sep 17 10:29:04 +2001 @@ -294,7 +294,7 @@ R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; - if (!info->CCE2D) { + if (!info->directRenderingEnabled) { if (!info->CCEInUse) { /* Save all hardware scissors */ info->sc_left = INREG(R128_SC_LEFT); @@ -303,8 +303,6 @@ info->sc_bottom = INREG(R128_SC_BOTTOM); info->aux_sc_cntl = INREG(R128_SC_BOTTOM); } - - R128MMIO_TO_CCE(pScrn, info); } } @@ -338,7 +336,8 @@ int depth; /* FIXME: Use accel when CCE 2D code is written */ - if (info->CCE2D) return; + if (info->directRenderingEnabled) + return; /* FIXME: This should be based on the __GLXvisualConfig info */ switch (pScrn->bitsPerPixel) { @@ -399,7 +398,8 @@ that request them */ /* FIXME: Use accel when CCE 2D code is written */ - if (info->CCE2D) return; + if (info->directRenderingEnabled) + return; } /* Initialize the AGP state. Request memory for use in AGP space, and @@ -852,7 +852,7 @@ case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; } - if (info->CCE2D) { + if (info->directRenderingEnabled) { /* Make sure the CCE is on for the X server */ R128CCE_START(pScrn, info); } else { @@ -1122,7 +1122,7 @@ R128InfoPtr info = R128PTR(pScrn); /* Stop the CCE if it is still in use */ - if (info->CCE2D) { + if (info->directRenderingEnabled) { R128CCE_STOP(pScrn, info); } diff -ur /suse/kraxel/r128/ati.orig/r128_driver.c xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c --- /suse/kraxel/r128/ati.orig/r128_driver.c Thu Sep 13 10:16:29 2001 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c Sun Sep 16 19:17:37 +2001 @@ -133,7 +133,6 @@ OPTION_AGP_SIZE, OPTION_RING_SIZE, OPTION_BUFFER_SIZE, - OPTION_USE_CCE_2D, #endif #if USE_CRT_ONLY /* FIXME: Disable CRTOnly until it is tested */ @@ -162,7 +161,6 @@ { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_USE_CCE_2D, "UseCCEfor2D", OPTV_BOOLEAN, {0}, FALSE }, #endif { OPTION_DISPLAY, "Display", OPTV_STRING, {0}, FALSE }, { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, @@ -278,12 +276,14 @@ "drmGetVersion", "drmMap", "drmMapBufs", + "drmDMA", "drmR128CleanupCCE", "drmR128InitCCE", "drmR128ResetCCE", "drmR128StartCCE", "drmR128StopCCE", "drmR128WaitForIdleCCE", + "drmR128FlushIndirectBuffer", "drmScatterGatherAlloc", "drmScatterGatherFree", "drmUnmap", @@ -1219,13 +1219,6 @@ info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; } else { info->CCEMode = R128_DEFAULT_CCE_BM_MODE; - } - - if (xf86ReturnOptValBool(info->Options, OPTION_USE_CCE_2D, FALSE)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CCE for 2D\n"); - info->CCE2D = TRUE; - } else { - info->CCE2D = FALSE; } if (xf86ReturnOptValBool(info->Options, OPTION_NO_SECURITY, FALSE)) { diff -ur /suse/kraxel/r128/ati.orig/r128_reg.h xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h --- /suse/kraxel/r128/ati.orig/r128_reg.h Tue Apr 10 18:07:59 2001 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h Mon Sep 17 10:02:23 +2001 @@ -1484,4 +1484,12 @@ #define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 #define R128_CCE_VC_CNTL_NUM_SHIFT 16 +/* hmm copyed blindly (no specs) from radeon.h ... */ +#define R128_RE_TOP_LEFT 0x26c0 +# define R128_RE_LEFT_SHIFT 0 +# define R128_RE_TOP_SHIFT 16 +#define R128_RE_WIDTH_HEIGHT 0x1c44 +# define R128_RE_WIDTH_SHIFT 0 +# define R128_RE_HEIGHT_SHIFT 16 + #endif
diff -ur vanilla-2.4.10-pre9/drivers/char/drm/r128_state.c 2.4.10-pre9/drivers/char/drm/r128_state.c --- vanilla-2.4.10-pre9/drivers/char/drm/r128_state.c Wed Aug 8 18:42:15 2001 +++ 2.4.10-pre9/drivers/char/drm/r128_state.c Mon Sep 17 11:24:42 2001 @@ -1519,10 +1519,75 @@ { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + drm_r128_indirect_t indirect; +#if 0 + RING_LOCALS; +#endif LOCK_TEST_WITH_RETURN( dev ); - /* Indirect buffer firing is not supported at this time. + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &indirect, (drm_r128_indirect_t *)arg, + sizeof(indirect) ) ) + return -EFAULT; + + DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, + indirect.end, indirect.discard ); + + if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1 ); + return -EINVAL; + } + + buf = dma->buflist[indirect.idx]; + buf_priv = buf->dev_private; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + return -EINVAL; + } + + if ( indirect.start < buf->used ) { + DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used ); + return -EINVAL; + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf->used = indirect.end; + buf_priv->discard = indirect.discard; + +#if 0 + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. */ - return -EINVAL; + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); +#endif + + /* Dispatch the indirect buffer full of commands from the + * X server. This is insecure and is thus only available to + * privileged clients. + */ + r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + + return 0; }