> The Radeon driver has some CP code for 2D that should be easily ported
> 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?

  Gerd

PS: patch against xfree86 cvs.

---------------------- cut here -------------------------
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   Sun Sep 16 19:15:35 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;
@@ -430,8 +433,9 @@
        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_TOP,      info->sc_top);                         \
        OUTREG(R128_SC_BOTTOM,   info->sc_bottom);                      \
+       OUTREG(R128_AUX_SC_CNTL, info->aux_sc_cntl );                   \
        OUTREG(R128_AUX_SC_CNTL, info->aux_sc_cntl);                    \
     }                                                                  \
 } while (0)
@@ -443,5 +447,89 @@
     }                                                                  \
 } while (0)
 #endif
+
+extern drmBufPtr   R128CCEGetBuffer(ScrnInfoPtr pScrn);
+extern void        R128CCEFlushIndirect(ScrnInfoPtr pScrn);
+extern void        R128CCEReleaseIndirect(ScrnInfoPtr pScrn);
+extern void        R128CCEWaitForIdle(ScrnInfoPtr pScrn);
+
+#define R128CCE_REFRESH(pScrn, info)                                   \
+do {                                                                   \
+   if ( !info->CCEInUse ) {                                            \
+      R128CCEWaitForIdle(pScrn);                                               \
+      /* FIXME */;                                                     \
+      info->CCEInUse = TRUE;                                           \
+   }                                                                   \
+} while (0)
+
+
+#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   1
+
+#define RING_LOCALS    CARD32 *__head; int __count;
+#define RING_THRESHOLD 256
+
+#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 OUT_RING_REG( reg, val )                                       \
+do {                                                                   \
+   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
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     Sun Sep 16 18:55:16 
+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,7 +225,7 @@
 /* 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;
@@ -1079,14 +1080,175 @@
 }
 
 #ifdef XF86DRI
-    /* FIXME: When direct rendering is enabled, we should use the CCE to
-       draw 2D commands */
+
+/* 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)
+{
+    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();
+}
+
+/* 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(XAAInfoRecPtr a)
 {
+#if 0
+    a->Flags                            = (PIXMAP_CACHE
+                                          | OFFSCREEN_PIXMAPS
+                                          | LINEAR_FRAMEBUFFER);
+#else
     a->Flags                            = 0;
+#endif
 
                                /* Sync */
     a->Sync                             = R128CCEWaitForIdle;
+
+    /* Solid Filled Rectangle */
+    a->PolyFillRectSolidFlags           = 0;
+    a->SetupForSolidFill                = R128CCESetupForSolidFill;
+    a->SubsequentSolidFillRect          = R128CCESubsequentSolidFillRect;
 }
 #endif
 
@@ -1189,7 +1351,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(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       Sun Sep 16 18:56:41 
+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);
@@ -338,7 +338,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 +400,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 +854,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 +1124,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)) {

_______________________________________________
Dri-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to