> > 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;
}