summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormdaenzer <mdaenzer>2001-12-29 18:58:19 +0000
committermdaenzer <mdaenzer>2001-12-29 18:58:19 +0000
commitc83bcec33aff9fb1516bf09bdc75929d26e05820 (patch)
tree52f68887e1abd25024f8ad0b3d6b09667d9b9c31
parent5d6db47ea4d2daf65229e93caa0910684978cf41 (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.h25
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c214
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