diff options
author | mdaenzer <mdaenzer> | 2001-12-29 18:58:19 +0000 |
---|---|---|
committer | mdaenzer <mdaenzer> | 2001-12-29 18:58:19 +0000 |
commit | c83bcec33aff9fb1516bf09bdc75929d26e05820 (patch) | |
tree | 52f68887e1abd25024f8ad0b3d6b09667d9b9c31 | |
parent | 5d6db47ea4d2daf65229e93caa0910684978cf41 (diff) |
- get rid of RING_THRESHOLD and clean up CCE code a bit
- implement color expansion for CCE and change non-CCE color expansion to
have the chip swap bytes on big endian machines
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h | 25 | ||||
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c | 214 |
2 files changed, 202 insertions, 37 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h index c438350c2..126957d2c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h @@ -253,8 +253,16 @@ typedef struct { unsigned char *scratch_save; int scanline_x; int scanline_y; + int scanline_w; int scanline_h; - int scanline_h_w; +#ifdef XF86DRI + int scanline_hpass; + int scanline_x1clip; + int scanline_x2clip; + int scanline_rop; + int scanline_fg; + int scanline_bg; +#endif /* XF86DRI */ int scanline_words; int scanline_direct; int scanline_bpp; /* Only used for ImageWrite */ @@ -430,7 +438,7 @@ do { \ #endif extern drmBufPtr R128CCEGetBuffer(ScrnInfoPtr pScrn); -extern void R128CCEFlushIndirect(ScrnInfoPtr pScrn); +extern void R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard); extern void R128CCEReleaseIndirect(ScrnInfoPtr pScrn); extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); @@ -448,7 +456,6 @@ extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); #define R128_VERBOSE 0 #define RING_LOCALS CARD32 *__head; int __count; -#define RING_THRESHOLD 256 #define R128CCE_REFRESH(pScrn, info) \ do { \ @@ -473,11 +480,11 @@ do { \ "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \ } \ if ( !info->indirectBuffer ) { \ - info->indirectBuffer = R128CCEGetBuffer( pScrn ); \ + info->indirectBuffer = R128CCEGetBuffer( pScrn ); \ info->indirectStart = 0; \ - } else if ( info->indirectBuffer->used - info->indirectStart + \ - (n) * (int)sizeof(CARD32) > RING_THRESHOLD ) { \ - R128CCEFlushIndirect( pScrn ); \ + } else if ( (info->indirectBuffer->used + 4*(n)) > \ + info->indirectBuffer->total ) { \ + R128CCEFlushIndirect( pScrn, 1 ); \ } \ __head = (pointer)((char *)info->indirectBuffer->address + \ info->indirectBuffer->used); \ @@ -492,7 +499,7 @@ do { \ __count * sizeof(CARD32), \ info->indirectBuffer->used - info->indirectStart + \ __count * sizeof(CARD32), \ - RING_THRESHOLD ); \ + info->indirectBuffer->total - info->indirectStart ); \ } \ info->indirectBuffer->used += __count * (int)sizeof(CARD32); \ } while (0) @@ -517,7 +524,7 @@ do { \ xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ "FLUSH_RING in %s\n", __FUNCTION__ ); \ if ( info->indirectBuffer ) { \ - R128CCEFlushIndirect( pScrn ); \ + R128CCEFlushIndirect( pScrn, 0 ); \ } \ } while (0) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c index 4a6708953..fb05ed8f1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c @@ -229,18 +229,16 @@ void R128CCEWaitForIdle(ScrnInfoPtr pScrn) { R128InfoPtr info = R128PTR(pScrn); int ret; - int i = 0; FLUSH_RING(); for (;;) { - do { - ret = drmR128WaitForIdleCCE(info->drmFD); - if (ret && ret != -EBUSY) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "%s: CCE idle %d\n", __FUNCTION__, ret); - } - } while ((ret == -EBUSY) && (i++ < R128_TIMEOUT)); + /* The ioctl already has a timeout */ + ret = drmR128WaitForIdleCCE(info->drmFD); + if (ret && ret != -EBUSY) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "%s: CCE idle %d\n", __FUNCTION__, ret); + } if (ret == 0) return; @@ -704,6 +702,7 @@ static void R128SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, unsigned char *R128MMIO = info->MMIO; R128WaitForFifo(pScrn, 4); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl | R128_GMC_DST_CLIPPING | R128_GMC_BRUSH_NONE @@ -713,6 +712,16 @@ static void R128SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, | R128_ROP[rop].rop | R128_GMC_BYTE_LSB_TO_MSB | R128_DP_SRC_SOURCE_HOST_DATA)); +#else /* X_BYTE_ORDER == X_BIG_ENDIAN */ + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_HOST_DATA)); +#endif OUTREG(R128_DP_WRITE_MASK, planemask); OUTREG(R128_DP_SRC_FRGD_CLR, fg); OUTREG(R128_DP_SRC_BKGD_CLR, bg); @@ -1129,6 +1138,150 @@ static void R128CCESubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, ADVANCE_RING(); } + +/* + * XAA scanline color expansion + * + * We use HOSTDATA_BLT CCE packets, dividing the image in chunks that fit into + * the indirect buffer if necessary. + */ +static void R128CCESetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 2 ); + OUT_RING_REG(R128_DP_WRITE_MASK, planemask); + ADVANCE_RING(); + + info->scanline_rop = rop; + info->scanline_fg = fg; + info->scanline_bg = bg; +} + +/* Helper function to write out a HOSTDATA_BLT packet into the indirect buffer + and set the XAA scratch buffer address appropriately */ +static void R128CCEScanlineCPUToScreenColorExpandFillPacket(ScrnInfoPtr pScrn, + int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + int chunk_words = info->scanline_hpass * info->scanline_words; + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( chunk_words+9 ); + + OUT_RING( CCE_PACKET3( R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, chunk_words+9-2 ) ); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + OUT_RING( (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (info->scanline_bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[info->scanline_rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); +#else /* X_BYTE_ORDER == X_BIG_ENDIAN */ + OUT_RING( (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (info->scanline_bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[info->scanline_rop].rop + | R128_DP_SRC_SOURCE_HOST_DATA)); +#endif + OUT_RING( (info->scanline_y << 16) | (info->scanline_x1clip & 0xffff) ); + OUT_RING( ((info->scanline_y+info->scanline_hpass-1) << 16) | ((info->scanline_x2clip-1) & 0xffff) ); + OUT_RING( info->scanline_fg ); + OUT_RING( info->scanline_bg ); + OUT_RING( (info->scanline_y << 16) | (info->scanline_x & 0xffff)); + + /* Have to pad the width here and use clipping engine */ + OUT_RING( (info->scanline_hpass << 16) | ((info->scanline_w + 31) & ~31)); + + OUT_RING( chunk_words ); + + info->scratch_buffer[bufno] = (unsigned char *) &__head[__count]; + __count += chunk_words; + + ADVANCE_RING(); + + info->scanline_y += info->scanline_hpass; + info->scanline_h -= info->scanline_hpass; + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s: hpass=%d, words=%d => chunk_words=%d, y=%d, h=%d\n", + __FUNCTION__, info->scanline_hpass, info->scanline_words, + chunk_words, info->scanline_y, info->scanline_h ); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void R128CCESubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + +#define BUFSIZE ( R128_BUFFER_SIZE/4-9 ) + + info->scanline_x = x; + info->scanline_y = y; + info->scanline_w = w; + info->scanline_h = h; + + info->scanline_x1clip = x+skipleft; + info->scanline_x2clip = x+w; + + info->scanline_words = (w + 31) >> 5; + info->scanline_hpass = min(h,(BUFSIZE/info->scanline_words)); + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s: x=%d, y=%d, w=%d, h=%d, skipleft=%d => x1clip=%d, x2clip=%d, hpass=%d, words=%d\n", + __FUNCTION__, x, y, w, h, skipleft, info->scanline_x1clip, info->scanline_x2clip, + info->scanline_hpass, info->scanline_words ); + + R128CCEScanlineCPUToScreenColorExpandFillPacket(pScrn, 0); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is called + once for each scanline. */ +static void R128CCESubsequentColorExpandScanline(ScrnInfoPtr pScrn, + int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s enter: scanline_hpass=%d, scanline_h=%d\n", + __FUNCTION__, info->scanline_hpass, info->scanline_h ); + + if (--info->scanline_hpass) { + info->scratch_buffer[bufno] += 4 * info->scanline_words; + } + else if(info->scanline_h) { + info->scanline_hpass = min(info->scanline_h,(BUFSIZE/info->scanline_words)); + R128CCEScanlineCPUToScreenColorExpandFillPacket(pScrn, bufno); + } + + if ( R128_VERBOSE ) + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "%s exit: scanline_hpass=%d, scanline_h=%d\n", + __FUNCTION__, info->scanline_hpass, info->scanline_h ); +} + /* Solid lines */ static void R128CCESetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) @@ -1377,30 +1530,29 @@ drmBufPtr R128CCEGetBuffer( ScrnInfoPtr pScrn ) /* Flush the indirect buffer to the kernel for submission to the card. */ -void R128CCEFlushIndirect( ScrnInfoPtr pScrn ) +void R128CCEFlushIndirect( ScrnInfoPtr pScrn, int discard ) { 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 ); + if ( (start == buffer->used) && !discard ) + return; drmR128FlushIndirectBuffer( info->drmFD, buffer->idx, start, buffer->used, discard ); - if ( discard ) { - info->indirectBuffer = R128CCEGetBuffer( pScrn ); - info->indirectStart = 0; - } else { - info->indirectStart = buffer->used; - } + if ( discard ) + buffer = info->indirectBuffer = R128CCEGetBuffer( pScrn ); + + /* pad to an even number of dwords */ + if (buffer->used & 7) + buffer->used = ( buffer->used+7 ) & ~7; + + info->indirectStart = buffer->used; } /* Flush and release the indirect buffer. @@ -1423,6 +1575,8 @@ void R128CCEReleaseIndirect( ScrnInfoPtr pScrn ) static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) { + R128InfoPtr info = R128PTR(pScrn); + a->Flags = (PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER); @@ -1448,6 +1602,18 @@ static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) a->SetupForScreenToScreenCopy = R128CCESetupForScreenToScreenCopy; a->SubsequentScreenToScreenCopy = R128CCESubsequentScreenToScreenCopy; + /* Indirect CPU-To-Screen Color Expand */ + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_buffer[0] = NULL; + a->SetupForScanlineCPUToScreenColorExpandFill + = R128CCESetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = R128CCESubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = R128CCESubsequentColorExpandScanline; + /* Bresenham Solid Lines */ a->SetupForSolidLine = R128CCESetupForSolidLine; a->SubsequentSolidBresenhamLine = R128CCESubsequentSolidBresenhamLine; @@ -1508,14 +1674,8 @@ static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) | BIT_ORDER_IN_BYTE_LSBFIRST); /* Indirect CPU-To-Screen Color Expand */ -#if X_BYTE_ORDER == X_LITTLE_ENDIAN a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X; -#else - a->ScanlineCPUToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST - | LEFT_EDGE_CLIPPING - | LEFT_EDGE_CLIPPING_NEGATIVE_X; -#endif a->NumScanlineColorExpandBuffers = 1; a->ScanlineColorExpandBuffers = info->scratch_buffer; info->scratch_save = xalloc(((pScrn->virtualX+31)/32*4) @@ -1567,8 +1727,6 @@ Bool R128AccelInit(ScreenPtr pScreen) if (!(a = info->accel = XAACreateInfoRec())) return FALSE; #ifdef XF86DRI - /* FIXME: When direct rendering is enabled, we should use the CCE to - draw 2D commands */ if (info->directRenderingEnabled) R128CCEAccelInit(pScrn, a); else |