summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgareth <gareth>2000-06-12 14:27:13 +0000
committergareth <gareth>2000-06-12 14:27:13 +0000
commit6c94c4508e050c830c7480f9a87878f3246a7f52 (patch)
treee5dfa34b6a8f2ff2a71057554a75f7bc41c7e5e2
parent55cab1f336a64750c8f83a8a5cf97bf3dc1029b7 (diff)
More performance improvements, general cleanups including:ati-4-1-0-20000613ati-4-1-0-branch
* variable-sized vertices * precalculation of depth scale * removal of user-space command submission functions * initial support for PCI inlined vertex buffers
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.c333
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.h160
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h224
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_clear.c10
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.c18
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.h24
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.c8
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c44
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_init.h12
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_lock.h134
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_screen.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_span.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.c71
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_swap.c17
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.c45
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.c167
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.h20
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h121
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.c81
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.h68
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c24
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h102
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c923
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c737
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c199
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h102
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h80
27 files changed, 3163 insertions, 569 deletions
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.c b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
new file mode 100644
index 000000000..a89d7dc84
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
@@ -0,0 +1,333 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+
+#define R128_TIMEOUT 2000000
+
+typedef drmBufPtr (*r128_get_buffer_func)( r128ContextPtr r128ctx );
+
+static r128_get_buffer_func r128GetBufferLocked;
+r128_fire_vertices_func r128FireVerticesLocked;
+
+
+static void r128RingStatus( r128ContextPtr r128ctx )
+{
+ r128ScreenPtr r128scrn = r128ctx->r128Screen;
+ unsigned char *R128MMIO = r128scrn->mmio;
+
+ fprintf( stderr, "GUI_STAT = 0x%08x\n",
+ (unsigned int) INREG( R128_GUI_STAT ) );
+ fprintf( stderr, "PM4_STAT = 0x%08x\n",
+ (unsigned int) INREG( R128_PM4_STAT ) );
+ fprintf( stderr, "PM4_BUFFER_DL_WPTR = 0x%08x\n",
+ (unsigned int) INREG( R128_PM4_BUFFER_DL_WPTR ) );
+ fprintf( stderr, "PM4_BUFFER_DL_RPTR = 0x%08x\n",
+ (unsigned int) INREG( R128_PM4_BUFFER_DL_RPTR ) );
+ fprintf( stderr, "ringWrite = 0x%08x\n",
+ r128scrn->SAREA->ringWrite );
+ fprintf( stderr, "*ringReadPtr = 0x%08x\n",
+ *r128scrn->ringReadPtr );
+}
+
+
+/* Get a new VB from the pool of vertex buffers in AGP space.
+ */
+static drmBufPtr r128_get_buffer_locked( r128ContextPtr r128ctx )
+{
+ int fd = r128ctx->r128Screen->driScreen->fd;
+ int num;
+ int index = 0;
+ int size = 0;
+ int to = 0;
+ drmBufPtr buf = NULL;
+
+ while ( !buf && ( to++ < r128ctx->CCEtimeout ) ) {
+ num = drmR128GetVertexBuffers( fd, 1, &index, &size );
+
+ if ( num > 0 ) {
+ buf = &r128ctx->r128Screen->vbBufs->list[index];
+ buf->used = 0;
+ return buf;
+ }
+ }
+
+ if ( !buf ) {
+ drmR128EngineReset( fd );
+ fprintf( stderr, "Error: Could not get new VB... exiting\n" );
+ exit( -1 );
+ }
+
+ return buf;
+}
+
+static void r128_fire_vertices_locked( r128ContextPtr r128ctx )
+{
+ int vertsize = r128ctx->vertsize;
+ int format = r128ctx->vc_format;
+ int index = r128ctx->vert_buf->idx;
+ int offset = r128ctx->r128Screen->vbOffset +
+ index * r128ctx->r128Screen->vbBufSize;
+ int size = r128ctx->vert_buf->used / (vertsize * sizeof(GLuint));
+ int fd = r128ctx->r128Screen->driScreen->fd;
+ int to = 0;
+ int ret;
+ CARD32 prim;
+
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST;
+
+ /* Send the vertex buffer to the hardware */
+ BEGIN_CLIP_LOOP( r128ctx );
+ {
+ R128CCE3( R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3 );
+ R128CCE( offset );
+ R128CCE( size );
+ R128CCE( format );
+ R128CCE( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
+ (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
+
+ R128CCE_SUBMIT_PACKET();
+ }
+ END_CLIP_LOOP( r128ctx );
+
+ /* Tell the kernel to release the vertex buffer */
+ do {
+ ret = drmR128FlushVertexBuffers( fd, 1, &index, &size, 0 );
+ } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) );
+
+ if ( ret < 0 ) {
+ drmR128EngineReset( fd );
+ fprintf( stderr, "Error: Could not flush VB... exiting\n" );
+ exit( -1 );
+ }
+
+ r128ctx->vert_buf = NULL;
+}
+
+static drmBufPtr r128_get_ring_locked( r128ContextPtr r128ctx )
+{
+ r128ScreenPtr r128scrn = r128ctx->r128Screen;
+ drmBufPtr buf = NULL;
+
+ buf = (drmBufPtr) malloc( sizeof(*buf) );
+
+ buf->idx = -666;
+ buf->total = r128scrn->vbBufSize;
+ buf->used = 0;
+ buf->address = (drmAddress *) malloc( r128scrn->vbBufSize );
+
+ return buf;
+}
+
+static void r128_fire_ring_locked( r128ContextPtr r128ctx )
+{
+ int vertsize = r128ctx->vertsize;
+ int format = r128ctx->vc_format;
+ int size = r128ctx->vert_buf->used / (vertsize * sizeof(GLuint));
+ drmBufPtr buf = r128ctx->vert_buf;
+ CARD32 prim;
+
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST;
+
+ /* Send the vertex buffer to the hardware */
+ BEGIN_CLIP_LOOP( r128ctx );
+ {
+ R128CCE3( R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 3 );
+ R128CCE( format );
+ R128CCE( prim | R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
+
+ memcpy( &r128ctx->CCEbuf[r128ctx->CCEcount], buf->address, buf->used );
+ r128ctx->CCEcount += (buf->used >> 2);
+
+ R128CCE_SUBMIT_PACKET();
+ }
+ END_CLIP_LOOP( r128ctx );
+
+ free( buf->address );
+ free( buf );
+
+ r128ctx->vert_buf = NULL;
+}
+
+
+void r128FlushVerticesLocked( r128ContextPtr r128ctx )
+{
+ if ( r128ctx->vert_buf && r128ctx->vert_buf->used ) {
+ r128FireVerticesLocked( r128ctx );
+ }
+}
+
+CARD32 *r128AllocVertexDwords( r128ContextPtr r128ctx, int dwords )
+{
+ int bytes = dwords * 4;
+ CARD32 *head;
+
+ if ( !r128ctx->vert_buf ) {
+ LOCK_HARDWARE( r128ctx );
+
+ if ( r128ctx->first_elt != r128ctx->next_elt ) {
+ r128FlushEltsLocked( r128ctx );
+ }
+ r128ctx->vert_buf = r128GetBufferLocked( r128ctx );
+
+ UNLOCK_HARDWARE( r128ctx );
+ } else if ( r128ctx->vert_buf->used + bytes > r128ctx->vert_buf->total ) {
+ LOCK_HARDWARE( r128ctx );
+
+ r128FlushVerticesLocked( r128ctx );
+ r128ctx->vert_buf = r128GetBufferLocked( r128ctx );
+
+ UNLOCK_HARDWARE( r128ctx );
+ }
+
+ head = (CARD32 *)((char *)r128ctx->vert_buf->address +
+ r128ctx->vert_buf->used);
+
+ r128ctx->vert_buf->used += bytes;
+ return head;
+}
+
+
+/* ================================================================ */
+
+
+void r128GetEltBufLocked( r128ContextPtr r128ctx )
+{
+ r128ctx->elt_buf = r128GetBufferLocked( r128ctx );
+}
+
+void r128FireEltsLocked( r128ContextPtr r128ctx,
+ GLuint num_elts, GLuint discard )
+{
+ int vertsize = r128ctx->vertsize;
+ int format = r128ctx->vc_format;
+ int index = r128ctx->vert_buf->idx;
+ int offset = r128ctx->r128Screen->vbOffset +
+ index * r128ctx->r128Screen->vbBufSize;
+ int size = r128ctx->vert_buf->used / (vertsize * sizeof(GLuint));
+ int fd = r128ctx->r128Screen->driScreen->fd;
+ int to = 0;
+ int ret;
+ CARD32 prim;
+
+ fprintf( stderr, "Error: elt buffers not supported at this time...\n" );
+ return;
+
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST;
+
+ /* Send the vertex buffer to the hardware */
+ BEGIN_CLIP_LOOP( r128ctx );
+ {
+ R128CCE3( R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3 );
+ R128CCE( offset );
+ R128CCE( size );
+ R128CCE( format );
+ R128CCE( prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
+ (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
+
+ R128CCE_SUBMIT_PACKET();
+ }
+ END_CLIP_LOOP( r128ctx );
+
+ if ( discard ) {
+ /* Tell the kernel to release the vertex buffer */
+ do {
+ ret = drmR128FlushVertexBuffers( fd, 1, &index, &size, 0 );
+ } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) );
+
+ if ( ret < 0 ) {
+ drmR128EngineReset( fd );
+ fprintf( stderr, "Error: Could not flush VB... exiting\n" );
+ exit( -1 );
+ }
+ }
+
+ r128ctx->vert_buf = NULL;
+}
+
+void r128FlushEltsLocked( r128ContextPtr r128ctx )
+{
+ if ( r128ctx->first_elt != r128ctx->next_elt ) {
+ r128FireEltsLocked( r128ctx,
+ (GLuint)r128ctx->next_elt -
+ (GLuint)r128ctx->first_elt,
+ 0 );
+ r128ctx->first_elt = r128ctx->next_elt;
+ }
+}
+
+void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer )
+{
+ int index;
+ int size;
+ int fd = r128ctx->r128Screen->driScreen->fd;
+ int to = 0;
+ int ret;
+
+ if ( !buffer ) return;
+
+ index = buffer->idx;
+ size = buffer->used = 0;
+
+ /* Tell the kernel to release the vertex buffer */
+ do {
+ ret = drmR128FlushVertexBuffers( fd, 1, &index, &size, 0 );
+ } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) );
+
+ if ( ret < 0 ) {
+ drmR128EngineReset( fd );
+ fprintf( stderr, "Error: Could not release VB... exiting\n" );
+ exit( -1 );
+ }
+}
+
+
+void r128InitVertexBuffers( r128ScreenPtr r128scrn )
+{
+ if ( !r128scrn->IsPCI ) {
+ r128GetBufferLocked = r128_get_buffer_locked;
+ r128FireVerticesLocked = r128_fire_vertices_locked;
+ } else {
+ r128GetBufferLocked = r128_get_ring_locked;
+ r128FireVerticesLocked = r128_fire_ring_locked;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.h b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
new file mode 100644
index 000000000..768151971
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
@@ -0,0 +1,160 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CCE_H_
+#define _R128_CCE_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_dri.h"
+#include "r128_reg.h"
+
+#include "xf86drmR128.h"
+
+#define R128_DEFAULT_TOTAL_CCE_TIMEOUT 1000000 /* usecs */
+
+typedef union {
+ float f;
+ int i;
+} floatTOint;
+
+/* Insert an integer value into the CCE ring buffer. */
+#define R128CCE(v) \
+do { \
+ r128ctx->CCEbuf[r128ctx->CCEcount] = (v); \
+ r128ctx->CCEcount++; \
+} while (0)
+
+/* Insert an floating point value into the CCE ring buffer. */
+#define R128CCEF(v) \
+do { \
+ floatTOint fTi; \
+ fTi.f = (v); \
+ r128ctx->CCEbuf[r128ctx->CCEcount] = fTi.i; \
+ r128ctx->CCEcount++; \
+} while (0)
+
+/* Insert a type-[0123] packet header into the ring buffer */
+#define R128CCE0(p,r,n) R128CCE((p) | ((n) << 16) | ((r) >> 2))
+#define R128CCE1(p,r1,r2) R128CCE((p) | (((r2) >> 2) << 11) | ((r1) >> 2))
+#define R128CCE2(p) R128CCE((p))
+#define R128CCE3(p,n) R128CCE((p) | ((n) << 16))
+
+#define R128CCE_SUBMIT_PACKET() \
+do { \
+ r128SubmitPacketLocked( r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount ); \
+ r128ctx->CCEcount = 0; \
+} while (0)
+
+static __inline void r128SubmitPacketLocked( r128ContextPtr r128ctx,
+ CARD32 *buf, GLuint count )
+{
+ CARD32 *b;
+ int c = count;
+ int fd = r128ctx->r128Screen->driScreen->fd;
+ int to = 0;
+ int ret;
+
+ do {
+ b = buf + (count - c);
+ ret = drmR128SubmitPacket( fd, b, &c, 0 );
+ } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) );
+
+ if ( ret < 0 ) {
+ drmR128EngineReset( fd );
+ fprintf( stderr, "Error: Could not submit packet... exiting\n" );
+ exit( -1 );
+ }
+}
+
+static __inline void r128WaitForIdleLocked( r128ContextPtr r128ctx )
+{
+ int fd = r128ctx->r128Screen->driScreen->fd;
+ int to = 0;
+ int ret;
+
+ drmR128EngineFlush( fd );
+
+ do {
+ ret = drmR128WaitForIdle( fd );
+ } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) );
+
+ if ( ret < 0 ) {
+ drmR128EngineReset( fd );
+ fprintf( stderr, "Error: Rage 128 timed out... exiting\n" );
+ exit( -1 );
+ }
+}
+
+#define r128WaitForIdle( r128ctx ) \
+do { \
+ LOCK_HARDWARE( r128ctx ); \
+ r128WaitForIdleLocked( r128ctx ); \
+ UNLOCK_HARDWARE( r128ctx ); \
+} while (0)
+
+
+extern CARD32 *r128AllocVertexDwords( r128ContextPtr r128ctx, int dwords );
+extern void r128FlushVerticesLocked( r128ContextPtr r128ctx );
+
+typedef void (*r128_fire_vertices_func)( r128ContextPtr r128ctx );
+extern r128_fire_vertices_func r128FireVerticesLocked;
+
+#define r128FlushVertices( r128ctx ) \
+do { \
+ LOCK_HARDWARE( r128ctx ); \
+ r128FlushVerticesLocked( r128ctx ); \
+ UNLOCK_HARDWARE( r128ctx ); \
+} while (0)
+
+
+extern void r128GetEltBufLocked( r128ContextPtr r128ctx );
+extern void r128FlushEltsLocked( r128ContextPtr r128ctx );
+extern void r128FireEltsLocked( r128ContextPtr r128ctx,
+ GLuint num_elts, GLuint discard );
+extern void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer );
+
+#define r128FlushElts( r128ctx ) \
+do { \
+ LOCK_HARDWARE( r128ctx ); \
+ r128FlushEltsLocked( r128ctx ); \
+ UNLOCK_HARDWARE( r128ctx ); \
+} while (0)
+
+
+extern void r128InitVertexBuffers( r128ScreenPtr r128scrn );
+
+#endif
+#endif /* _R128_CCE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h
deleted file mode 100644
index a40d5413a..000000000
--- a/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* $XFree86$ */
-/**************************************************************************
-
-Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <kevin@precisioninsight.com>
- *
- */
-
-#ifndef _R128_CCEVB_H_
-#define _R128_CCEVB_H_
-
-#ifdef GLX_DIRECT_RENDERING
-
-#include "xf86drmR128.h"
-
-typedef struct {
- CARD32 *buf; /* Pointer to current VB */
- int index; /* Index of current VB */
- int start; /* in bytes from the beginning of the VB map */
- int size; /* in vertices */
- int count; /* in vertices */
- drmR128PrimType prim; /* Primitive type for vertices in VB */
- int done; /* VB has been sent to ring */
-} r128CCEVertBuf, *r128CCEVertBufPtr;
-
-
-
-/* Flush the CPU's write-combining cache */
-/* FIXME: This code is both processor and compiler specific */
-#define R128_FLUSH_WC_MEMORY() \
- do { \
- int xchangeDummy; \
- \
- __asm__ volatile("push %%eax ;" \
- "xchg %%eax, %0 ;" \
- "pop %%eax" : : "m" (xchangeDummy)); \
- __asm__ volatile("push %%eax ;" \
- "push %%ebx ;" \
- "push %%ecx ;" \
- "push %%edx ;" \
- "movl $0,%%eax ;" \
- "cpuid ;" \
- "pop %%edx ;" \
- "pop %%ecx ;" \
- "pop %%ebx ;" \
- "pop %%eax" : /* no outputs */ : /* no inputs */); \
- } while (0)
-
-
-/* Get a new VB from the pool of vertex buffers in AGP space */
-/* NOTE: By default the primitive type for a VB is set to individual tris */
-#define R128CCE_GET_NEW_VB(r128ctx) \
- do { \
- r128CCEVertBufPtr vb = &r128ctx->vb; \
- int to = 0; \
- int fd = r128ctx->r128Screen->driScreen->fd; \
- int num; \
- int index; \
- int size; \
- \
- vb->buf = NULL; \
- \
- LOCK_HARDWARE(r128ctx); \
- while (!vb->buf && to++ < r128ctx->CCEtimeout) { \
- /* Ask the kernel a new vertex buffer */ \
- num = drmR128GetVertexBuffers(fd, 1, &index, &size); \
- \
- if (num > 0) { \
- vb->buf = (CARD32 *)(r128ctx->r128Screen-> \
- vbBufs->list[index].address); \
- vb->index = index; \
- vb->start = index*r128ctx->r128Screen->vbBufSize; \
- vb->size = size/sizeof(r128_vertex); \
- vb->count = 0; \
- vb->prim = DRM_R128_PRIM_TRI_LIST; \
- vb->done = GL_FALSE; \
- } \
- } \
- UNLOCK_HARDWARE(r128ctx); \
- \
- if (!vb->buf) { \
- (void)drmR128EngineReset(fd); \
- fprintf(stderr, "Error: Could not get new VB... exiting\n"); \
- exit(-1); \
- } \
- } while (0)
-
-/* Submit a VB to the hardware for processing */
-/* NOTE: This macro is only called while holding the hardware lock */
-#define R128CCE_SUBMIT_VB(r128ctx) \
- do { \
- int index = r128ctx->vb.index; \
- int size = r128ctx->vb.count; \
- int fd = r128ctx->r128Screen->driScreen->fd; \
- int to = 0; \
- int ret; \
- CARD32 prim; \
- \
- switch (r128ctx->vb.prim) { \
- case DRM_R128_PRIM_NONE: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \
- break; \
- case DRM_R128_PRIM_POINT: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_POINT; \
- break; \
- case DRM_R128_PRIM_LINE: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_LINE; \
- break; \
- case DRM_R128_PRIM_POLY_LINE: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE; \
- break; \
- case DRM_R128_PRIM_TRI_LIST: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST; \
- break; \
- case DRM_R128_PRIM_TRI_FAN: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN; \
- break; \
- case DRM_R128_PRIM_TRI_STRIP: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP; \
- break; \
- case DRM_R128_PRIM_TRI_TYPE2: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2; \
- break; \
- default: \
- prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \
- break; \
- } \
- \
- /* Send the vertex buffer to the hardware */ \
- BEGIN_CLIP_LOOP(r128ctx); \
- \
- R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3); \
- R128CCE(r128ctx->r128Screen->vbOffset + r128ctx->vb.start); \
- R128CCE(r128ctx->vb.count); \
- R128CCE(R128_TEX1_VERTEX_FORMAT); \
- R128CCE(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | \
- (r128ctx->vb.count << R128_CCE_VC_CNTL_NUM_SHIFT)); \
- R128CCE_SUBMIT_PACKETS(); \
- \
- END_CLIP_LOOP(r128ctx); \
- \
- /* Tell the kernel to release the vertex buffer */ \
- do { \
- ret = drmR128FlushVertexBuffers(fd, 1, &index, &size, \
- r128ctx->vb.prim); \
- } while (ret < 0 && ret == -EBUSY && to++ < r128ctx->CCEtimeout); \
- if (ret < 0) { \
- (void)drmR128EngineReset(fd); \
- fprintf(stderr, "Error: Could not flush VB... exiting\n"); \
- exit(-1); \
- } \
- \
- r128ctx->vb.done = GL_TRUE; \
- } while (0)
-
-/* Flush the vertex buffer (assuming we already hold the lock) */
-#define R128CCE_FLUSH_VB(r128ctx) \
- do { \
- if (r128ctx->vb.count && !r128ctx->vb.done) { \
- /* FIXME: Is this _really_ needed? */ \
- if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) \
- R128CCE_WAIT_FOR_IDLE(r128ctx); \
- \
- R128CCE_SUBMIT_VB(r128ctx); \
- } \
- } while (0)
-
-/* Flush the vertex buffer */
-#define R128CCE_FLUSH_VB_LOCK(r128ctx) \
- do { \
- LOCK_HARDWARE(r128ctx); \
- R128CCE_FLUSH_VB(r128ctx); \
- UNLOCK_HARDWARE(r128ctx); \
- } while (0)
-
-/* Reserve space in a VB to store `n' vertices, and set the pointer `p'
- to point to the next vertex in the current VB. If adding these
- vertices to the VB would exceed the size of the VB, then flush the
- current VB, get a new one from the pool of VBs, reserve space in the
- new VB for the `n' vertices, and set the pointer `p' to point to the
- first vertex in the new VB. */
-#define R128CCE_ALLOC_VB_SPACE(r128ctx, p, n) \
- do { \
- r128CCEVertBufPtr vb = &r128ctx->vb; \
- \
- if (vb->done) R128CCE_GET_NEW_VB(r128ctx); \
- \
- if (vb->count + (n) > vb->size) { \
- R128CCE_FLUSH_VB_LOCK(r128ctx); \
- R128CCE_GET_NEW_VB(r128ctx); \
- } \
- \
- (p) = (r128_vertex *)vb->buf + vb->count; \
- vb->count += (n); \
- } while (0)
-
-#endif
-#endif /* _R128_CCEVB_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.c b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
index a5846b280..725b0caef 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -77,7 +77,7 @@ void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
LOCK_HARDWARE(r128ctx);
/* Flush any outstanding vertex buffers */
- R128CCE_FLUSH_VB(r128ctx);
+ r128FlushVerticesLocked(r128ctx);
/* Init the clip rects here in case they changed during the
LOCK_HARDWARE macro */
@@ -149,7 +149,7 @@ void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
#endif
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
UNLOCK_HARDWARE(r128ctx);
}
@@ -187,7 +187,7 @@ void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
LOCK_HARDWARE(r128ctx);
/* Flush any outstanding vertex buffers */
- R128CCE_FLUSH_VB(r128ctx);
+ r128FlushVerticesLocked(r128ctx);
/* Init the clip rects here in case they changed during the
LOCK_HARDWARE macro */
@@ -249,7 +249,7 @@ void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
R128_CTX_ALPHASTATE);
#endif
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
UNLOCK_HARDWARE(r128ctx);
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
index 3d9ba4ddd..9bbab1dc5 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
@@ -84,12 +84,7 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
r128ctx->useFastPath = GL_FALSE;
- r128ctx->vb.start = 0;
- r128ctx->vb.count = 0;
- r128ctx->vb.size = 0;
- r128ctx->vb.index = 0;
- r128ctx->vb.buf = NULL;
- r128ctx->vb.done = GL_TRUE;
+ r128ctx->vert_buf = NULL;
r128ctx->CCEbuf = (CARD32 *)malloc(sizeof(*r128ctx->CCEbuf) *
r128scrn->ringEntries);
@@ -118,7 +113,10 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
r128ctx->Fallback |= R128_FALLBACK_SWONLY;
/* KW: No vertex buffer code for PCI cards -- for now fallback to
- * software always.
+ * software always.
+ * GTH: There is support there, but I'm seeing strange behaviour
+ * with it enabled. I'll leave the software fallbacks in place
+ * for now.
*/
if (r128scrn->IsPCI)
r128ctx->Fallback |= R128_FALLBACK_SWONLY;
@@ -139,17 +137,17 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
/* KW: Set the maximum texture size small enough that we can
* guarentee that both texture units can bind a maximal texture
* and have them both in on-card memory at once. (Kevin or
- * Gareth: Please check these numbers are OK)
+ * Gareth: Please check these numbers are OK)
*/
if (r128scrn->texSize[0] < 2*1024*1024) {
glCtx->Const.MaxTextureLevels = 9;
glCtx->Const.MaxTextureSize = 1<<8;
} else if (r128scrn->texSize[0] < 8*1024*1024) {
glCtx->Const.MaxTextureLevels = 10;
- glCtx->Const.MaxTextureSize = 1<<9;
+ glCtx->Const.MaxTextureSize = 1<<9;
} else {
glCtx->Const.MaxTextureLevels = 11;
- glCtx->Const.MaxTextureSize = 1<<10;
+ glCtx->Const.MaxTextureSize = 1<<10;
}
glCtx->Const.MaxTextureUnits = 2;
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
index 6e8b7948c..f362338d5 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
@@ -37,9 +37,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
+struct r128_context;
+typedef struct r128_context r128ContextRec;
+typedef struct r128_context *r128ContextPtr;
+
#include "r128_texobj.h"
#include "r128_fastpath.h"
-#include "r128_ccevb.h"
/* Flags for what needs to be updated before a new primitive is rendered */
#define R128_CLEAN 0x0000
@@ -138,11 +141,16 @@ typedef struct {
CARD32 pc_gui_ctlstat; /* 0x1748 */
} r128ContextRegs;
-typedef struct {
+struct r128_context {
GLcontext *glCtx; /* Mesa context */
int dirty; /* Hardware state to be updated */
int dirty_context; /* Context state to be updated */
+ int vertsize; /* Size of current vertices */
+ CARD32 vc_format; /* Format of current vertices */
+ int multitex;
+ GLfloat depth_scale;
+
int SWfallbackDisable; /* Disable software fallbacks */
r128TexObjPtr CurrentTexObj[2]; /* Ptr to current texture
@@ -168,7 +176,15 @@ typedef struct {
int RenderIndex; /* Render state function index */
r128InterpFunc interp; /* Current vert interp function */
- r128CCEVertBuf vb; /* VB currently being filled */
+ drmBufPtr vert_buf; /* VB currently being filled */
+
+ drmBufPtr elt_buf, retained_buf;
+ GLushort *first_elt, *next_elt, *last_elt;
+ GLfloat *next_vert, *last_vert;
+ CARD32 next_vert_index;
+ CARD32 first_vert_index;
+ struct r128_elt_tab *elt_tab;
+ GLfloat device_matrix[16];
points_func PointsFunc; /* Current Points, Line, Triangle */
line_func LineFunc; /* and Quad rendering functions */
@@ -203,7 +219,7 @@ typedef struct {
__DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
r128ScreenPtr r128Screen; /* Screen private DRI data */
-} r128ContextRec, *r128ContextPtr;
+};
#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx)
#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable)
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
index f76b2e3aa..b621954f4 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -110,7 +110,7 @@ static void r128DDFlush(GLcontext *ctx)
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
}
/* Make sure all commands have been sent to the hardware and have
@@ -120,7 +120,7 @@ static void r128DDFinish(GLcontext *ctx)
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
r128DDFlush(ctx);
- R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx);
+ r128WaitForIdle(r128ctx);
}
/* Return various parameters requested by Mesa (this is deprecated) */
@@ -132,7 +132,7 @@ static GLint r128DDGetParameteri(const GLcontext *ctx, GLint param)
* It is less confusing to simply have it never work until it
* is actually fixed.
*/
- case DD_HAVE_HARDWARE_FOG: return 1;
+ case DD_HAVE_HARDWARE_FOG: return 1;
default: return 0;
}
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
index 26d8c8a96..cb0568321 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -45,7 +45,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* FIXME: These routines were copied from the i810 driver, and were only
slightly modified for the Rage 128. They still need to be optmizied
- and cleaned up. Also, support for USE_RHW2 needs to be added.
+ and cleaned up. Also, support for USE_RHW2 needs to be added.
KW: The fastpath never does projective texturing, so RHW2 support
isn't necesary here.
@@ -56,9 +56,9 @@ typedef struct r128_fast_table {
r128InterpFunc interp;
} r128FastPathTable;
-#define POINT(x) r128DrawPointVB(r128ctx, &vert[x].v, psize)
-#define LINE(x,y) r128DrawLineVB(r128ctx, &vert[x].v, &vert[y].v, lwidth)
-#define TRI(x,y,z) r128DrawTriangleVB(r128ctx, &vert[x].v, &vert[y].v, &vert[z].v)
+#define POINT(x) r128DrawPointVB(r128ctx, &vert[x], psize)
+#define LINE(x,y) r128DrawLineVB(r128ctx, &vert[x], &vert[y], lwidth)
+#define TRI(x,y,z) r128DrawTriangleVB(r128ctx, &vert[x], &vert[y], &vert[z])
/* Direct, and no clipping required. The clip funcs have not been
written yet, so this is only useful for the fast path. */
@@ -231,7 +231,7 @@ static void r128TriClip(GLuint **p_elts,
/* Convert the planar polygon to a list of triangles */
out = inlist[in];
-
+
for (i = 2 ; i < n ; i++) {
elts[0] = out[0];
elts[1] = out[i-1];
@@ -361,10 +361,10 @@ do { \
/* Pack rgba and/or texture into the remaining half of a 32 byte vertex.
*/
#define CLIP_UBYTE_COLOR 4
-#define CLIP_UBYTE_B 0
-#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_B 0
+#define CLIP_UBYTE_G 1
#define CLIP_UBYTE_R 2
-#define CLIP_UBYTE_A 3
+#define CLIP_UBYTE_A 3
#define CLIP_S0 6
#define CLIP_T0 7
#define CLIP_S1 8
@@ -409,7 +409,7 @@ static void r128RenderElementsDirect(struct vertex_buffer *VB)
GLuint nr = VB->EltPtr->count;
render_func func = render_tab_r128_smooth_indirect[prim];
GLuint p = 0;
-
+
if (r128ctx->dirty) r128UpdateHWState(r128ctx);
do {
@@ -431,17 +431,8 @@ static void r128ProjectVertices(struct vertex_buffer *VB)
m[MAT_TX] = mat->m[MAT_TX];
m[MAT_SY] = -mat->m[MAT_SY];
m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h;
- m[MAT_SZ] = mat->m[MAT_SZ];
- m[MAT_TZ] = mat->m[MAT_TZ];
-
- /* KW: Please precalculate this scale:
- */
- switch (ctx->Visual->DepthBits) {
- case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
- case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break;
- case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break;
- default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
- }
+ m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale;
+ m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale;
gl_project_v16(r128VB->verts[VB->CopyStart].f,
r128VB->verts[r128VB->last_vert].f,
@@ -462,15 +453,8 @@ static void r128ProjectClippedVertices(struct vertex_buffer *VB)
m[MAT_TX] = mat->m[MAT_TX];
m[MAT_SY] = -mat->m[MAT_SY];
m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h;
- m[MAT_SZ] = mat->m[MAT_SZ];
- m[MAT_TZ] = mat->m[MAT_TZ];
-
- switch (ctx->Visual->DepthBits) {
- case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
- case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break;
- case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break;
- default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
- }
+ m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale;
+ m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale;
gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f,
r128VB->verts[r128VB->last_vert].f,
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_init.h b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
index a091a437e..2d58242a9 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_init.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
@@ -63,6 +63,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
extern int R128_DEBUG_FLAGS;
+#else
+
+#define R128_DEBUG_FLAGS 0
+
+#endif
+
#define DEBUG_VERBOSE_2D 0x0001
#define DEBUG_VERBOSE_CCE 0x0008
#define DEBUG_VERBOSE_OUTREG 0x0010
@@ -76,11 +82,5 @@ extern int R128_DEBUG_FLAGS;
#define DEBUG_VERBOSE_DRI 0x2000
#define DEBUG_VERBOSE_IOCTL 0x4000
-#else
-
-#define R128_DEBUG_FLAGS 0
-
-#endif
-
#endif
#endif /* _R128_INIT_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
new file mode 100644
index 000000000..91a65c210
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
@@ -0,0 +1,134 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_LOCK_H_
+#define _R128_LOCK_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */
+#if DEBUG_LOCKING
+extern char *prevLockFile;
+extern int prevLockLine;
+
+#define DEBUG_LOCK() \
+ do { \
+ prevLockFile = (__FILE__); \
+ prevLockLine = (__LINE__); \
+ } while (0)
+
+#define DEBUG_RESET() \
+ do { \
+ prevLockFile = 0; \
+ prevLockLine = 0; \
+ } while (0)
+
+#define DEBUG_CHECK_LOCK() \
+ do { \
+ if (prevLockFile) { \
+ fprintf(stderr, \
+ "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
+ prevLockFile, prevLockLine, __FILE__, __LINE__); \
+ exit(1); \
+ } \
+ } while (0)
+
+#else
+
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+
+#endif
+
+/*
+ * !!! We may want to separate locks from locks with validation. This
+ * could be used to improve performance for those things commands that
+ * do not do any drawing !!!
+ */
+
+/* Lock the hardware using the current context */
+#define LOCK_HARDWARE(CC) \
+ do { \
+ char __ret = 0; \
+ __DRIcontextPrivate *cPriv = CC->driContext; \
+ __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \
+ \
+ DEBUG_CHECK_LOCK(); \
+ DRM_CAS(&sPriv->pSAREA->lock, cPriv->hHWContext, \
+ DRM_LOCK_HELD|cPriv->hHWContext, __ret); \
+ if (__ret) { \
+ /* We lost the context, so we need to request the lock from \
+ the kernel and update our state. */ \
+ drmGetLock(sPriv->fd, cPriv->hHWContext, 0); \
+ XMesaUpdateState(cPriv); \
+ } \
+ DEBUG_LOCK(); \
+ } while (0)
+
+/* Unlock the hardware using the current context */
+#define UNLOCK_HARDWARE(CC) \
+ do { \
+ __DRIcontextPrivate *cPriv = CC->driContext; \
+ __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \
+ \
+ DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, cPriv->hHWContext); \
+ DEBUG_RESET(); \
+ } while (0)
+
+/*
+ * This pair of macros makes a loop over the drawing operations, so it
+ * is not self contained and does not have the nice single statement
+ * semantics of most macros.
+ */
+#define BEGIN_CLIP_LOOP(CC) \
+ do { \
+ __DRIdrawablePrivate *_dPriv = CC->driDrawable; \
+ XF86DRIClipRectPtr _pc = _dPriv->pClipRects; \
+ int _nc, _sc; \
+ \
+ for (_nc = _dPriv->numClipRects; _nc > 0; _nc -= 3, _pc += 3) { \
+ _sc = (_nc <= 3) ? _nc : 3; \
+ r128SetClipRects(CC, _pc, _sc)
+
+/* FIXME: This should be a function call to turn off aux clipping */
+#define END_CLIP_LOOP(CC) \
+ R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); \
+ R128CCE(0x00000000); \
+ R128CCE_SUBMIT_PACKET(); \
+ } \
+ } while (0)
+
+#endif
+#endif /* _R128_LOCK_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
index b385271f4..3f2f0a17f 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -229,6 +229,8 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv)
r128Screen->driScreen = sPriv;
+ r128InitVertexBuffers(r128Screen);
+
r128FastPathInit();
r128TriangleFuncsInit();
r128SetupInit();
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
index 5aa0ed6d1..97e70b1c3 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -95,7 +95,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define HW_LOCK() \
r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
LOCK_HARDWARE(r128ctx); \
- R128CCE_WAIT_FOR_IDLE(r128ctx);
+ r128WaitForIdleLocked(r128ctx);
#define HW_CLIPLOOP() \
do { \
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
index 66835cbce..981874493 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
@@ -110,7 +110,7 @@ static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID;
- /* Should really use an intermediate value to hold this rather
+ /* Should really use an intermediate value to hold this rather
* than recalculating all the time.
*/
if (prim == GL_POLYGON && ctx->Polygon.CullFlag) {
@@ -124,7 +124,7 @@ static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
}
if (r128ctx->regs.pm4_vc_fpu_setup != f) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.pm4_vc_fpu_setup = f;
/* FIXME: Load into hardware now??? */
@@ -133,7 +133,7 @@ static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
}
}
-static void r128DDClearColor(GLcontext *ctx,
+static void r128DDClearColor(GLcontext *ctx,
GLubyte r, GLubyte g, GLubyte b, GLubyte a)
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
@@ -179,7 +179,8 @@ static GLboolean r128DDSetDrawBuffer(GLcontext *ctx, GLenum mode)
x += r128ctx->drawX;
y += r128ctx->drawY;
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
+
r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
(x << R128_WINDOW_X_SHIFT));
@@ -234,7 +235,7 @@ static GLboolean r128DDColorMask(GLcontext *ctx,
ctx->Color.ColorMask[ACOMP]);
if (r128ctx->regs.plane_3d_mask_c != mask) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.plane_3d_mask_c = mask;
/* FIXME: Load into hardware now??? */
@@ -274,7 +275,7 @@ static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
}
if (r128ctx->regs.misc_3d_state_cntl_reg != a) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.misc_3d_state_cntl_reg = a;
/* FIXME: Load into hardware now??? */
@@ -363,7 +364,7 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
}
if (r128ctx->regs.misc_3d_state_cntl_reg != b) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.misc_3d_state_cntl_reg = b;
/* FIXME: Load into hardware now??? */
@@ -413,7 +414,7 @@ static void r128DDCullFace(GLcontext *ctx, GLenum mode)
}
if (r128ctx->regs.pm4_vc_fpu_setup != f) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.pm4_vc_fpu_setup = f;
/* FIXME: Load into hardware now??? */
@@ -436,7 +437,7 @@ static void r128DDFrontFace(GLcontext *ctx, GLenum mode)
}
if (r128ctx->regs.pm4_vc_fpu_setup != f) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.pm4_vc_fpu_setup = f;
/* FIXME: Load into hardware now??? */
@@ -465,7 +466,7 @@ static void r128DDDepthFunc(GLcontext *ctx, GLenum func)
}
if (r128ctx->regs.z_sten_cntl_c != z) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.z_sten_cntl_c = z;
/* FIXME: Load into hardware now??? */
@@ -483,7 +484,7 @@ static void r128DDDepthMask(GLcontext *ctx, GLboolean flag)
else t &= ~R128_Z_WRITE_ENABLE;
if (r128ctx->regs.tex_cntl_c != t) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.tex_cntl_c = t;
/* FIXME: Load into hardware now??? */
@@ -492,21 +493,21 @@ static void r128DDDepthMask(GLcontext *ctx, GLboolean flag)
}
}
-static void r128DDLightModelfv(GLcontext *ctx, GLenum pname,
+static void r128DDLightModelfv(GLcontext *ctx, GLenum pname,
const GLfloat *param)
{
- if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
- {
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+ {
r128ContextPtr r128ctx = R128_CONTEXT( ctx );
CARD32 t = r128ctx->regs.tex_cntl_c;
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
t |= R128_SPEC_LIGHT_ENABLE;
- else
+ else
t &= ~R128_SPEC_LIGHT_ENABLE;
-
+
if (r128ctx->regs.tex_cntl_c != t) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.tex_cntl_c = t;
/* FIXME: Load into hardware now??? */
@@ -654,7 +655,7 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
}
if (r128ctx->regs.tex_cntl_c != t) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.tex_cntl_c = t;
/* FIXME: Load into hardware now??? */
@@ -662,7 +663,7 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
}
if (r128ctx->regs.pm4_vc_fpu_setup != f) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.pm4_vc_fpu_setup = f;
/* FIXME: Load into hardware now??? */
@@ -688,7 +689,7 @@ static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
case GL_FOG_MODE:
mode = (GLenum)(GLint)*param;
if (r128ctx->FogMode != mode) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->FogMode = mode;
/* FIXME: Load into hardware now??? */
@@ -700,7 +701,7 @@ static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
case GL_FOG_DENSITY:
fog.f = *param;
if (r128ctx->regs.fog_3d_table_density != fog.i) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.fog_3d_table_density = fog.i;
/* FIXME: Load into hardware now??? */
@@ -712,7 +713,7 @@ static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
case GL_FOG_START:
fog.f = *param;
if (r128ctx->regs.fog_3d_table_start != fog.i) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.fog_3d_table_start = fog.i;
/* FIXME: Load into hardware now??? */
@@ -724,7 +725,7 @@ static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
case GL_FOG_END:
fog.f = *param;
if (r128ctx->regs.fog_3d_table_end != fog.i) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.fog_3d_table_end = fog.i;
/* FIXME: Load into hardware now??? */
@@ -737,7 +738,7 @@ static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
FLOAT_RGBA_TO_UBYTE_RGBA(c, ctx->Fog.Color);
col = r128PackColor(32, c[0], c[1], c[2], c[3]);
if (r128ctx->regs.fog_color_c != col) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.fog_color_c = col;
/* FIXME: Load into hardware now??? */
@@ -849,6 +850,14 @@ void r128DDInitState(r128ContextPtr r128ctx)
break;
}
+ /* Precalculate the depth scale while we're here */
+ switch (r128ctx->glCtx->Visual->DepthBits) {
+ case 16: r128ctx->depth_scale = 1.0 / 65536.0; break;
+ case 24: r128ctx->depth_scale = 1.0 / 16777216.0; break;
+ case 32: r128ctx->depth_scale = 1.0 / 4294967296.0; break;
+ default: r128ctx->depth_scale = 1.0 / 65536.0; break;
+ }
+
r128ctx->dirty = R128_ALL_DIRTY;
r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
@@ -1069,15 +1078,15 @@ static void r128UploadFogTable(r128ContextPtr r128ctx)
R128CCE0(R128_CCE_PACKET0_ONE_REG_WR, R128_FOG_TABLE_DATA, 255);
- if (0)
- fprintf(stderr, "uploading fog table for %s\n",
+ if (0)
+ fprintf(stderr, "uploading fog table for %s\n",
gl_lookup_enum_by_nr(r128ctx->FogMode));
/* KW: I'm not sure we're doing enough here - shouldn't density
* play a role in calculating the exp and exp2 tables -- is the
* card really doing exponent calculations of its own? Need to
- * see the spec...
+ * see the spec...
*/
switch (r128ctx->FogMode) {
case GL_LINEAR:
@@ -1132,7 +1141,7 @@ static void r128LoadContext(r128ContextPtr r128ctx)
/* FIXME: Is this _really_ needed? */
if (r128ctx->dirty_context)
if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode))
- R128CCE_WAIT_FOR_IDLE(r128ctx);
+ r128WaitForIdleLocked(r128ctx);
#endif
if (r128ctx->dirty_context & R128_CTX_MISC) {
@@ -1247,7 +1256,7 @@ static void r128LoadContext(r128ContextPtr r128ctx)
}
#endif
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
/* Turn off the texture cache flushing */
r128ctx->regs.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
@@ -1304,7 +1313,7 @@ void r128SetClipRects(r128ContextPtr r128ctx,
R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0);
R128CCE(r128ctx->regs.aux_sc_cntl);
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
}
/* Update the driver's notion of the window position */
@@ -1340,7 +1349,7 @@ static void r128UpdateWindowPosition(r128ContextPtr r128ctx)
static void r128UpdateHWStateLocked(r128ContextPtr r128ctx)
{
if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE)
- R128CCE_WAIT_FOR_IDLE(r128ctx);
+ r128WaitForIdleLocked(r128ctx);
/* Update any state that might have changed recently */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.c b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
index 4effcf9fa..d6467970e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -43,6 +43,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_vb.h"
#include "r128_swap.h"
+static void delay(void) {
+ /* stop the compiler from optimizing our spin loop away */
+}
+
/* Copy the back color buffer to the front color buffer */
void r128SwapBuffers(r128ContextPtr r128ctx)
{
@@ -52,6 +56,7 @@ void r128SwapBuffers(r128ContextPtr r128ctx)
XF86DRIClipRectPtr c;
int dst_bpp;
CARD32 swapAge;
+ int i, to = 0;
switch (r128ctx->r128Screen->bpp) {
case 8:
@@ -73,11 +78,15 @@ void r128SwapBuffers(r128ContextPtr r128ctx)
LOCK_HARDWARE(r128ctx);
/* Flush any outstanding vertex buffers */
- R128CCE_FLUSH_VB(r128ctx);
+ r128FlushVerticesLocked(r128ctx);
/* Throttle the frame rate -- only allow one pending swap buffers
request at a time */
- while (r128ctx->lastSwapAge > (swapAge = INREG(R128_SWAP_AGE_REG)));
+ while ((r128ctx->lastSwapAge > (swapAge = INREG(R128_SWAP_AGE_REG))) &&
+ (to++ < r128ctx->CCEtimeout)) {
+ /* Don't just sit here hammering the register */
+ for (i = 0; i < 1000; i++) delay();
+ }
/* Init the clip rects here in case they changed during the
LOCK_HARDWARE macro */
@@ -118,7 +127,7 @@ void r128SwapBuffers(r128ContextPtr r128ctx)
R128_CTX_ENGINESTATE |
R128_CTX_ALPHASTATE);
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
UNLOCK_HARDWARE(r128ctx);
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
index 47c1c30f2..51f282462 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
@@ -318,7 +318,7 @@ static void r128TexturesGone(r128ContextPtr r128ctx, int heap,
int offset, int size, int in_use)
{
r128TexObjPtr t, tmp;
-
+
foreach_s (t, tmp, &r128ctx->TexObjList[heap]) {
if (t->memBlock->ofs >= offset + size ||
t->memBlock->ofs + t->memBlock->size <= offset)
@@ -714,7 +714,7 @@ static void r128UploadSubImage(r128ContextPtr r128ctx,
R128CCE(r128ctx->regs.pc_gui_ctlstat |
R128_PC_RI_GUI |
R128_PC_FLUSH_GUI);
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
/* Build the CCE host data blit header */
R128CCE3(R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, 0);
@@ -776,10 +776,10 @@ static void r128UploadSubImage(r128ContextPtr r128ctx,
R128CCE(r128ctx->regs.pc_gui_ctlstat | R128_PC_FLUSH_GUI);
/* Save the partial blit header */
- R128CCE_SUBMIT_PACKETS();
+ R128CCE_SUBMIT_PACKET();
r128ctx->CCEcount = 5;
}
-
+
/* Clean up CCE ring buffer */
r128ctx->CCEcount = 0;
}
@@ -887,7 +887,7 @@ int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t)
r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr;
} else {
for (i = maxLevel; i >= minLevel; i--)
- r128ctx->regs.sec_tex_offset[i] =
+ r128ctx->regs.sec_tex_offset[i] =
t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
}
/* Fix AGP texture offsets */
@@ -959,6 +959,8 @@ static void r128UpdateTex0State(r128ContextPtr r128ctx)
return;
}
+ r128ctx->regs.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT;
+
/* If this is the first time the texture has been used, then create
a new texture object for it. */
t = tObj->DriverData;
@@ -1244,7 +1246,7 @@ static void r128UpdateTex0State(r128ContextPtr r128ctx)
int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
R128_TEX_MIN_SIZE_SHIFT);
for (i = maxLevel; i >= minLevel; i--)
- r128ctx->regs.prim_tex_offset[i] =
+ r128ctx->regs.prim_tex_offset[i] =
t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
}
/* Fix AGP texture offsets */
@@ -1281,6 +1283,9 @@ static void r128UpdateTex1State(r128ContextPtr r128ctx)
return;
}
+ /* If te1 is enabled, split the texel cache */
+ r128ctx->regs.scale_3d_cntl |= R128_TEX_CACHE_SPLIT;
+
/* If this is the first time the texture has been used, then create
a new texture object for it. */
t = tObj->DriverData;
@@ -1558,7 +1563,7 @@ static void r128UpdateTex1State(r128ContextPtr r128ctx)
int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
R128_TEX_MIN_SIZE_SHIFT);
for (i = maxLevel; i >= minLevel; i--)
- r128ctx->regs.sec_tex_offset[i] =
+ r128ctx->regs.sec_tex_offset[i] =
t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
}
/* Fix AGP texture offsets */
@@ -1585,7 +1590,7 @@ void r128UpdateTextureState(r128ContextPtr r128ctx)
r128ctx->CurrentTexObj[0] = NULL;
r128ctx->CurrentTexObj[1] = NULL;
- if (r128ctx->glCtx->Enabled & (TEXTURE0_3D|TEXTURE1_3D))
+ if (r128ctx->glCtx->Enabled & (TEXTURE0_3D|TEXTURE1_3D))
r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
/* Update the texture unit 0/1 state */
@@ -1662,13 +1667,13 @@ static void r128DDTexEnv(GLcontext *ctx, GLenum target, GLenum pname,
struct gl_texture_unit *texUnit;
GLubyte c[4];
CARD32 col;
-
+
/* FIXME: Add texture LOD bias extension */
switch (pname) {
case GL_TEXTURE_ENV_MODE:
/* TexEnv modes are handled in UpdateTextureState */
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->dirty |= R128_UPDATE_TEXSTATE;
break;
case GL_TEXTURE_ENV_COLOR:
@@ -1676,7 +1681,7 @@ static void r128DDTexEnv(GLcontext *ctx, GLenum target, GLenum pname,
FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
col = r128PackColor(32, c[0], c[1], c[2], c[3]);
if (r128ctx->regs.constant_color_c != col) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->regs.constant_color_c = col;
/* FIXME: Load into hardware now??? */
@@ -1706,7 +1711,7 @@ static void r128DDTexImage(GLcontext *ctx, GLenum target,
t = (r128TexObjPtr)tObj->DriverData;
if (t) {
- if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ if (t->bound) r128FlushVertices(r128ctx);
/* Destroy the old texture, and upload a new one. The actual
uploading of the texture image occurs in the UploadSubImage
@@ -1737,7 +1742,7 @@ static void r128DDTexSubImage(GLcontext *ctx, GLenum target,
t = (r128TexObjPtr)tObj->DriverData;
if (t) {
- if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ if (t->bound) r128FlushVertices(r128ctx);
LOCK_HARDWARE(r128ctx);
r128UploadSubImage(r128ctx, t, level,
@@ -1769,18 +1774,18 @@ static void r128DDTexParameter(GLcontext *ctx, GLenum target,
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
- if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ if (t->bound) r128FlushVertices(r128ctx);
r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter);
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
- if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ if (t->bound) r128FlushVertices(r128ctx);
r128SetTexWrap(t, tObj->WrapS, tObj->WrapT);
break;
-
+
case GL_TEXTURE_BORDER_COLOR:
- if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ if (t->bound) r128FlushVertices(r128ctx);
r128SetTexBorderColor(t, tObj->BorderColor);
break;
@@ -1797,7 +1802,7 @@ static void r128DDBindTexture(GLcontext *ctx, GLenum target,
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
/* Unbind the old texture */
if (r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]) {
@@ -1818,7 +1823,7 @@ static void r128DDDeleteTexture(GLcontext *ctx,
if (t) {
if (t->bound) {
- R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128FlushVertices(r128ctx);
r128ctx->CurrentTexObj[t->bound-1] = 0;
r128ctx->dirty |= R128_UPDATE_TEXSTATE;
@@ -1831,7 +1836,7 @@ static void r128DDDeleteTexture(GLcontext *ctx,
/* Determine if a texture is currently residing in either AGP/local
texture memory */
-static GLboolean r128DDIsTextureResident(GLcontext *ctx,
+static GLboolean r128DDIsTextureResident(GLcontext *ctx,
struct gl_texture_object *tObj)
{
r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
index e30b2d304..00bbe948e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
@@ -1,4 +1,4 @@
-/* $XFree86$ */
+/* $XFree86$ */ /* -*- c-basic-offset: 4 -*- */
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
@@ -43,74 +43,137 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_tris.h"
#include "r128_state.h"
-static triangle_func tri_tab[0x10];
-static quad_func quad_tab[0x10];
-static line_func line_tab[0x10];
+static triangle_func tri_tab[0x10];
+static quad_func quad_tab[0x10];
+static line_func line_tab[0x10];
static points_func points_tab[0x10];
/* Draw a triangle from the vertices in the vertex buffer */
-void r128DrawTriangleVB(r128ContextPtr r128ctx,
- r128_vertex *v0,
- r128_vertex *v1,
- r128_vertex *v2)
+__inline void r128DrawTriangleVB(r128ContextPtr r128ctx,
+ r128Vertex *v0,
+ r128Vertex *v1,
+ r128Vertex *v2)
{
- r128_vertex *vbptr;
+ int vertsize = r128ctx->vertsize;
+ CARD32 *vb = r128AllocVertexDwords( r128ctx, 3 * vertsize );
+ int j;
- R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+ for (j = 0 ; j < vertsize ; j++)
+ vb[j] = v0->ui[j];
- *vbptr++ = *v0;
- *vbptr++ = *v1;
- *vbptr++ = *v2;
+ vb += vertsize;
+ for (j = 0 ; j < vertsize ; j++)
+ vb[j] = v1->ui[j];
+
+ vb += vertsize;
+ for (j = 0 ; j < vertsize ; j++)
+ vb[j] = v2->ui[j];
}
/* Draw a line from the vertices in the vertex buffer */
-void r128DrawLineVB(r128ContextPtr r128ctx,
- r128_vertex *v0, r128_vertex *v1,
- float width)
+__inline void r128DrawLineVB( r128ContextPtr r128ctx,
+ r128Vertex *tmp0,
+ r128Vertex *tmp1,
+ float width )
{
- float dx, dy, ix, iy;
- r128_vertex *vbptr;
+ int vertsize = r128ctx->vertsize;
+ CARD32 *vb = r128AllocVertexDwords( r128ctx, 6 * vertsize );
+ float dx, dy, ix, iy;
+ int j;
- /* FIXME: Use r128's line primitive for width 1 lines */
+ dx = tmp0->vert1.x - tmp1->vert1.x;
+ dy = tmp0->vert1.y - tmp1->vert1.y;
- R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 6);
+ ix = width * .5; iy = 0;
- dx = v0->x - v1->x;
- dy = v0->y - v1->y;
+ if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width
+ 0.5 also */
- ix = width * 0.5; iy = 0;
- if (dx*dx > dy*dy) {
- iy = ix; ix = 0;
+ if (dx * dx > dy * dy) {
+ iy = ix; ix = 0;
}
- *vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy;
- *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy;
- *++vbptr = *v0; vbptr->x = v0->x + ix; vbptr->y = v0->y + iy;
- *++vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy;
- *++vbptr = *v1; vbptr->x = v1->x - ix; vbptr->y = v1->y - iy;
- *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy;
+ *(float *)&vb[0] = tmp0->vert1.x - ix;
+ *(float *)&vb[1] = tmp0->vert1.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp0->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp1->vert1.x + ix;
+ *(float *)&vb[1] = tmp1->vert1.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp1->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp0->vert1.x + ix;
+ *(float *)&vb[1] = tmp0->vert1.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp0->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp0->vert1.x - ix;
+ *(float *)&vb[1] = tmp0->vert1.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp0->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp1->vert1.x - ix;
+ *(float *)&vb[1] = tmp1->vert1.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp1->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp1->vert1.x + ix;
+ *(float *)&vb[1] = tmp1->vert1.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp1->ui[j];
}
/* Draw a point from the vertices in the vertex buffer */
-void r128DrawPointVB(r128ContextPtr r128ctx,
- r128_vertex *v0, float size)
+__inline void r128DrawPointVB( r128ContextPtr r128ctx,
+ r128Vertex *tmp, float sz )
{
- r128_vertex *vbptr;
-
- /* FIXME: Use r128's point primitive for diameter 1 points */
-
- R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 6);
-
- *vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size;
- *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y - size;
- *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size;
- *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size;
- *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y + size;
- *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size;
+ int vertsize = r128ctx->vertsize;
+ CARD32 *vb = r128AllocVertexDwords( r128ctx, 6 * vertsize );
+ int j;
+
+ *(float *)&vb[0] = tmp->vert1.x - sz;
+ *(float *)&vb[1] = tmp->vert1.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->vert1.x + sz;
+ *(float *)&vb[1] = tmp->vert1.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->vert1.x + sz;
+ *(float *)&vb[1] = tmp->vert1.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->vert1.x + sz;
+ *(float *)&vb[1] = tmp->vert1.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->vert1.x - sz;
+ *(float *)&vb[1] = tmp->vert1.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->vert1.x - sz;
+ *(float *)&vb[1] = tmp->vert1.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
}
-
#define R128_COLOR(to, from) \
do { \
(to)[0] = (from)[2]; \
@@ -172,9 +235,9 @@ void r128ChooseRenderState(GLcontext *ctx)
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
GLuint flags = ctx->TriangleCaps;
- /* KW: Includes handling of SWonly rendering:
+ /* KW: Includes handling of SWonly rendering:
*/
- if (r128ctx->Fallback)
+ if (r128ctx->Fallback)
return;
r128ctx->IndirectTriangles = 0;
@@ -183,20 +246,20 @@ void r128ChooseRenderState(GLcontext *ctx)
CARD32 index = 0;
CARD32 shared = 0;
CARD32 fallback = R128_FALLBACK_BIT;
-
+
/* KW: I'd prefer to remove SWfallbackDisable & just use
* R128_FALLBACK_BIT throughout this routine.
*/
- if (r128ctx->SWfallbackDisable) fallback = 0;
+ if (r128ctx->SWfallbackDisable) fallback = 0;
if (flags & DD_FLATSHADE) shared |= R128_FLAT_BIT;
if (flags & DD_TRI_LIGHT_TWOSIDE) shared |= R128_TWOSIDE_BIT;
/* TODO: Fix mesa so that these can be handled in
- * r128ctx->Fallback.
+ * r128ctx->Fallback.
*/
if (flags & (DD_MULTIDRAW |
- DD_SELECT |
+ DD_SELECT |
DD_FEEDBACK)) shared |= R128_FALLBACK_BIT;
/* Setup PointFunc */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
index 2640d0c8f..4a7a0736e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -44,15 +44,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_TWOSIDE_BIT 0x04
#define R128_FALLBACK_BIT 0x08
-extern void r128DrawTriangleVB(r128ContextPtr r128ctx,
- r128_vertex *v0,
- r128_vertex *v1,
- r128_vertex *v2);
-extern void r128DrawLineVB(r128ContextPtr r128ctx,
- r128_vertex *tmp0, r128_vertex *tmp1,
- float width);
-extern void r128DrawPointVB(r128ContextPtr r128ctx,
- r128_vertex *tmp, float size);
+extern __inline void r128DrawTriangleVB(r128ContextPtr r128ctx,
+ r128Vertex *v0,
+ r128Vertex *v1,
+ r128Vertex *v2);
+extern __inline void r128DrawLineVB(r128ContextPtr r128ctx,
+ r128Vertex *tmp0, r128Vertex *tmp1,
+ float width);
+extern __inline void r128DrawPointVB(r128ContextPtr r128ctx,
+ r128Vertex *tmp, float size);
extern void r128ChooseRenderState(GLcontext *ctx);
extern void r128TriangleFuncsInit(void);
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
index aa0d16b39..51fc9acfb 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -43,63 +43,60 @@ static void TAG(triangle)(GLcontext *ctx,
GLuint pv)
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int vertsize = r128ctx->vertsize;
+ CARD32 *vb = r128AllocVertexDwords(r128ctx,
+ 3 * vertsize);
struct vertex_buffer *VB = ctx->VB;
r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts;
- const r128_vertex *v0 = &r128verts[e0].v;
- const r128_vertex *v1 = &r128verts[e1].v;
- const r128_vertex *v2 = &r128verts[e2].v;
+ const r128Vertex *v[3];
+ int i, j;
#if (IND & R128_OFFSET_BIT)
- GLfloat offset;
+ GLfloat offset = ctx->Polygon.OffsetUnits * r128ctx->depth_scale;
#endif
#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
- int c0 = *(int *)&r128verts[pv].v.dif_argb;
- int c1 = c0;
- int c2 = c0;
-#endif
+ int c[3];
-#if (IND & R128_OFFSET_BIT)
- switch (ctx->Visual->DepthBits) {
- case 16: offset = ctx->Polygon.OffsetUnits / 65536.0; break;
- case 24: offset = ctx->Polygon.OffsetUnits / 16777216.0; break;
- case 32: offset = ctx->Polygon.OffsetUnits / 4294967296.0; break;
- default: offset = ctx->Polygon.OffsetUnits / 65536.0; break;
- }
+ c[0] = c[1] = c[2] = *(int *)&r128verts[pv].vert1.dif_argb;
#endif
-#if (IND & (R128_TWOSIDE_BIT | R128_OFFSET_BIT))
+ v[0] = &r128verts[e0];
+ v[1] = &r128verts[e1];
+ v[2] = &r128verts[e2];
+
+#if (IND & (R128_TWOSIDE_BIT | R128_OFFSET_BIT))
{
- GLfloat ex = v0->x - v2->x;
- GLfloat ey = v0->y - v2->y;
- GLfloat fx = v1->x - v2->x;
- GLfloat fy = v1->y - v2->y;
- GLfloat c = ex*fy - ey*fx;
-
-#if (IND & R128_TWOSIDE_BIT)
+ GLfloat ex = v[0]->vert1.x - v[2]->vert1.x;
+ GLfloat ey = v[0]->vert1.y - v[2]->vert1.y;
+ GLfloat fx = v[1]->vert1.x - v[2]->vert1.x;
+ GLfloat fy = v[1]->vert1.y - v[2]->vert1.y;
+ GLfloat cc = ex*fy - ey*fx;
+
+#if (IND & R128_TWOSIDE_BIT)
{
- GLuint facing = (c > 0.0) ^ ctx->Polygon.FrontBit;
+ GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit;
GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
if (IND & R128_FLAT_BIT) {
- R128_COLOR((char *)&c0, vbcolor[pv]);
- c2 = c1 = c0;
+ R128_COLOR((char *)&c[0], vbcolor[pv]);
+ c[2] = c[1] = c[0];
} else {
- R128_COLOR((char *)&c0, vbcolor[e0]);
- R128_COLOR((char *)&c1, vbcolor[e1]);
- R128_COLOR((char *)&c2, vbcolor[e2]);
+ R128_COLOR((char *)&c[0], vbcolor[e0]);
+ R128_COLOR((char *)&c[1], vbcolor[e1]);
+ R128_COLOR((char *)&c[2], vbcolor[e2]);
}
}
#endif
-
-#if (IND & R128_OFFSET_BIT)
+
+#if (IND & R128_OFFSET_BIT)
{
- if (c * c > 1e-16) {
+ if (cc * cc > 1e-16) {
GLfloat factor = ctx->Polygon.OffsetFactor;
- GLfloat ez = v0->z - v2->z;
- GLfloat fz = v1->z - v2->z;
+ GLfloat ez = v[0]->vert1.z - v[2]->vert1.z;
+ GLfloat fz = v[1]->vert1.z - v[2]->vert1.z;
GLfloat a = ey*fz - ez*fy;
GLfloat b = ez*fx - ex*fz;
- GLfloat ic = 1.0 / c;
+ GLfloat ic = 1.0 / cc;
GLfloat ac = a * ic;
GLfloat bc = b * ic;
if (ac < 0.0f) ac = -ac;
@@ -109,34 +106,18 @@ static void TAG(triangle)(GLcontext *ctx,
}
#endif
}
-#endif
-
- {
- r128_vertex *vbptr;
- R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
-
- vbptr[0] = *v0;
-#if (IND & (R128_FLAT_BIT|R128_TWOSIDE_BIT))
- *((int *)(&vbptr[0].dif_argb)) = c0;
-#endif
-#if (IND & R128_OFFSET_BIT)
- vbptr[0].z = v0->z + offset;
#endif
- vbptr[1] = *v1;
-#if (IND & (R128_FLAT_BIT|R128_TWOSIDE_BIT))
- *((int *)(&vbptr[1].dif_argb)) = c1;
-#endif
-#if (IND & R128_OFFSET_BIT)
- vbptr[1].z = v1->z + offset;
-#endif
+ for (j = 0 ; j < 3 ; j++, vb += vertsize) {
+
+ for (i = 0 ; i < vertsize ; i++)
+ vb[i] = v[j]->ui[i];
- vbptr[2] = *v2;
#if (IND & (R128_FLAT_BIT|R128_TWOSIDE_BIT))
- *((int *)(&vbptr[2].dif_argb)) = c2;
+ vb[4] = c[j]; /* color is the fifth element... */
#endif
#if (IND & R128_OFFSET_BIT)
- vbptr[2].z = v2->z + offset;
+ *(float *)&vb[2] = v[j]->vert1.z + offset;
#endif
}
}
@@ -169,21 +150,21 @@ static void TAG(line)(GLcontext *ctx,
GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data;
if (IND & R128_FLAT_BIT) {
- R128_COLOR((char *)&tmp0.v.dif_argb, vbcolor[pv]);
- *(int *)&tmp1.v.dif_argb = *(int *)&tmp0.v.dif_argb;
+ R128_COLOR((char *)&tmp0.vert1.dif_argb, vbcolor[pv]);
+ *(int *)&tmp1.vert1.dif_argb = *(int *)&tmp0.vert1.dif_argb;
} else {
- R128_COLOR((char *)&tmp0.v.dif_argb, vbcolor[v0]);
- R128_COLOR((char *)&tmp1.v.dif_argb, vbcolor[v1]);
+ R128_COLOR((char *)&tmp0.vert1.dif_argb, vbcolor[v0]);
+ R128_COLOR((char *)&tmp1.vert1.dif_argb, vbcolor[v1]);
}
} else {
- *(int *)&tmp0.v.dif_argb = *(int *)&r128verts[pv].v.dif_argb;
- *(int *)&tmp1.v.dif_argb = *(int *)&r128verts[pv].v.dif_argb;
+ *(int *)&tmp0.vert1.dif_argb = *(int *)&r128verts[pv].vert1.dif_argb;
+ *(int *)&tmp1.vert1.dif_argb = *(int *)&r128verts[pv].vert1.dif_argb;
}
- r128DrawLineVB( r128ctx, &tmp0.v, &tmp1.v, width );
+ r128DrawLineVB( r128ctx, &tmp0, &tmp1, width );
}
else
- r128DrawLineVB( r128ctx, &r128verts[v0].v, &r128verts[v1].v, width );
+ r128DrawLineVB( r128ctx, &r128verts[v0], &r128verts[v1], width );
}
/* Draw a set of points. Note that the device-dependent vertex data
@@ -199,13 +180,13 @@ static void TAG(points)(GLcontext *ctx,
for(i = first; i <= last; i++) {
if(VB->ClipMask[i] == 0) {
- if (IND & R128_TWOSIDE_BIT) {
+ if (IND & R128_TWOSIDE_BIT) {
GLubyte (*vbcolor)[4] = VB->ColorPtr->data;
r128Vertex tmp0 = r128verts[i];
- R128_COLOR((char *)&tmp0.v.dif_argb, vbcolor[i]);
- r128DrawPointVB( r128ctx, &tmp0.v, size );
+ R128_COLOR((char *)&tmp0.vert1.dif_argb, vbcolor[i]);
+ r128DrawPointVB( r128ctx, &tmp0, size );
} else
- r128DrawPointVB( r128ctx, &r128verts[i].v, size );
+ r128DrawPointVB( r128ctx, &r128verts[i], size );
}
}
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
index cf89f6b39..eb04e4473 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -46,32 +46,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define TEX0 \
do { \
- v->v.tu0 = tc0[i][0]; \
- v->v.tv0 = tc0[i][1]; \
+ v->vert1.tu0 = tc0[i][0]; \
+ v->vert1.tv0 = tc0[i][1]; \
} while (0)
#define TEX1 \
do { \
- v->v.tu1 = tc1[i][0]; \
- v->v.tv1 = tc1[i][1]; \
+ v->vert2.tu1 = tc1[i][0]; \
+ v->vert2.tv1 = tc1[i][1]; \
} while (0)
#define SPC \
do { \
GLubyte *spec = &(VB->Spec[0][i][0]); \
- v->v.spec_frgb.r = spec[0]; \
- v->v.spec_frgb.g = spec[1]; \
- v->v.spec_frgb.b = spec[2]; \
+ v->vert1.spec_frgb.r = spec[0]; \
+ v->vert1.spec_frgb.g = spec[1]; \
+ v->vert1.spec_frgb.b = spec[2]; \
} while (0)
#define COL \
do { \
GLubyte *col = &(VB->Color[0]->data[i][0]); \
- v->v.dif_argb.a = col[3]; \
- v->v.dif_argb.r = col[0]; \
- v->v.dif_argb.g = col[1]; \
- v->v.dif_argb.b = col[2]; \
+ v->vert1.dif_argb.a = col[3]; \
+ v->vert1.dif_argb.r = col[0]; \
+ v->vert1.dif_argb.g = col[1]; \
+ v->vert1.dif_argb.b = col[2]; \
} while (0)
#if 1
@@ -86,9 +86,9 @@ do { \
v = &(R128_DRIVER_DATA(VB)->verts[start]); \
for (i = start; i < end; i++, v++) { \
float oow = 1.0 / tc[i][3]; \
- v->v.rhw *= tc[i][3]; \
- v->v.tu0 *= oow; \
- v->v.tv0 *= oow; \
+ v->vert1.rhw *= tc[i][3]; \
+ v->vert1.tu0 *= oow; \
+ v->vert1.tv0 *= oow; \
} \
} \
} while (0)
@@ -101,9 +101,9 @@ do { \
v = &(R128_DRIVER_DATA(VB)->verts[start]); \
for (i = start; i < end; i++, v++) { \
float oow = 1.0 / tc[i][3]; \
- v->v.rhw2 *= tc[i][3]; \
- v->v.tu1 *= oow; \
- v->v.tv1 *= oow; \
+ v->vert3.rhw2 *= tc[i][3]; \
+ v->vert3.tu1 *= oow; \
+ v->vert3.tv1 *= oow; \
} \
} \
} while (0)
@@ -116,19 +116,19 @@ do { \
#define COORD \
do { \
GLfloat *win = VB->Win.data[i]; \
- v->v.x = win[0]; \
- v->v.y = r128height - win[1]; \
- v->v.z = scale * win[2]; \
- v->v.rhw = v->v.rhw2 = win[3]; \
+ v->vert3.x = win[0]; \
+ v->vert3.y = r128height - win[1]; \
+ v->vert3.z = scale * win[2]; \
+ v->vert3.rhw = v->vert3.rhw2 = win[3]; \
} while (0)
#else
#define COORD \
do { \
GLfloat *win = VB->Win.data[i]; \
- v->v.x = win[0]; \
- v->v.y = r128height - win[1]; \
- v->v.z = scale * win[2]; \
- v->v.rhw = win[3]; \
+ v->vert1.x = win[0]; \
+ v->vert1.y = r128height - win[1]; \
+ v->vert1.z = scale * win[2]; \
+ v->vert1.rhw = win[3]; \
} while (0)
#endif
@@ -144,23 +144,16 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
GLfloat (*tc0)[4]; \
GLfloat (*tc1)[4]; \
GLfloat r128height = dPriv->h; \
- GLfloat scale; \
+ GLfloat scale = r128ctx->depth_scale; \
int i; \
\
- (void) r128height; (void) r128ctx; \
+ (void) r128height; (void) r128ctx; (void) scale; \
\
gl_import_client_data(VB, VB->ctx->RenderFlags, \
(VB->ClipOrMask \
? VEC_WRITABLE | VEC_GOOD_STRIDE \
: VEC_GOOD_STRIDE)); \
\
- switch (VB->ctx->Visual->DepthBits) { \
- case 16: scale = 1.0 / 65536.0; break; \
- case 24: scale = 1.0 / 16777216.0; break; \
- case 32: scale = 1.0 / 4294967296.0; break; \
- default: scale = 1.0 / 65536.0; break; \
- } \
- \
tc0 = VB->TexCoordPtr[0]->data; \
tc1 = VB->TexCoordPtr[1]->data; \
\
@@ -264,14 +257,28 @@ void r128ChooseRasterSetupFunc(GLcontext *ctx)
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
int funcIndex = R128_WIN_BIT | R128_RGBA_BIT;
- if (ctx->Texture.Enabled & 0xf) {
+ r128ctx->vertsize = 8;
+ r128ctx->vc_format = R128_TEX0_VERTEX_FORMAT;
+ r128ctx->multitex = 0;
+
+ if (ctx->Texture.Enabled & ENABLE_TEX0) {
if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
funcIndex &= ~R128_RGBA_BIT;
funcIndex |= R128_TEX0_BIT;
}
- if (ctx->Texture.Enabled & 0xf0)
+ if (ctx->Texture.Enabled & ENABLE_TEX1) {
+ /* GTH: we should really only enable the second texture unit
+ * when we're doing true multitexturing. I guess there aren't
+ * that many cases where apps will only bind a texture to the
+ * second texture unit, but it would definitely be a performance
+ * win in those cases.
+ */
+ r128ctx->vertsize = 10;
+ r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT;
+ r128ctx->multitex = 1;
funcIndex |= R128_TEX1_BIT;
+ }
/* FIXME: Verify this works properly */
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
index 4417dcbae..f2244b687 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
@@ -2,7 +2,7 @@
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -45,6 +45,18 @@ typedef struct {
GLubyte a;
} r128Color;
+/* Single texture vertex, single x86 cache line.
+ *
+ * GTH: This is in use now.
+ */
+typedef struct {
+ GLfloat x, y, z; /* Coordinates in screen space */
+ GLfloat rhw; /* Reciprocal homogeneous w */
+ r128Color dif_argb; /* Diffuse color */
+ r128Color spec_frgb; /* Specular color (alpha is fog) */
+ GLfloat tu0, tv0; /* Texture 0 coordinates */
+} r128_vertex1;
+
/* The only vertex format in current use, but unsatisfactory for two
* reasons:
* - Not possible to implement fully conformant rendering
@@ -52,7 +64,7 @@ typedef struct {
* - Performance is lower with this vertex for single-texture
* geometry, as the vertex is unnecessarily larger than
* a cacheline.
- *
+ *
* Switching to single-texture vertices can be accomplished in state
* management, and is relatively trivial. Switching to the rhw2
* format is data-dependent (are there any glTexCoord4f's in the
@@ -60,7 +72,9 @@ typedef struct {
* and rhw2 vertex formats only on the standard path.
*
* The fastpath never requires the rhw2 format, as it already makes
- * the data-dependent checks.
+ * the data-dependent checks.
+ *
+ * GTH: This is fixed.
*/
typedef struct {
GLfloat x, y, z; /* Coordinates in screen space */
@@ -69,12 +83,12 @@ typedef struct {
r128Color spec_frgb; /* Specular color (alpha is fog) */
GLfloat tu0, tv0; /* Texture 0 coordinates */
GLfloat tu1, tv1; /* Texture 1 coordinates */
-} r128_vertex;
+} r128_vertex2;
/* Need to be slightly clever about flushing vertex buffers in order
* to use rhw2 only on demand.
*
- * Not in use.
+ * GTH: This can be used now.
*/
typedef struct {
GLfloat x, y, z; /* Coordinates in screen space */
@@ -83,29 +97,15 @@ typedef struct {
r128Color spec_frgb; /* Specular color (alpha is fog) */
GLfloat tu0, tv0; /* Texture 0 coordinates */
GLfloat tu1, tv1; /* Texture 1 coordinates */
- GLfloat rhw2; /* Reciprocal homogeneous w */
-} r128_rhw2_vertex;
-
-/* Single texture vertex, single cache line.
- *
- * Not in use.
- */
-typedef struct {
- GLfloat x, y, z; /* Coordinates in screen space */
- GLfloat rhw; /* Reciprocal homogeneous w */
- r128Color dif_argb; /* Diffuse color */
- r128Color spec_frgb; /* Specular color (alpha is fog) */
- GLfloat tu0, tv0; /* Texture 0 coordinates */
-} r128_st_vertex;
+ GLfloat rhw2; /* Reciprocal homogeneous w2 */
+} r128_vertex2_rhw2;
/* Format of vertices in r128_vertex struct */
-#define R128_PROJ_TEX1_VERTEX_FORMAT \
+#define R128_TEX0_VERTEX_FORMAT \
R128_CCE_VC_FRMT_RHW | \
R128_CCE_VC_FRMT_DIFFUSE_ARGB | \
R128_CCE_VC_FRMT_SPEC_FRGB | \
- R128_CCE_VC_FRMT_S_T | \
- R128_CCE_VC_FRMT_S2_T2 | \
- R128_CCE_VC_FRMT_RHW2
+ R128_CCE_VC_FRMT_S_T
#define R128_TEX1_VERTEX_FORMAT \
R128_CCE_VC_FRMT_RHW | \
@@ -114,18 +114,26 @@ typedef struct {
R128_CCE_VC_FRMT_S_T | \
R128_CCE_VC_FRMT_S2_T2
-#define R128_TEX0_VERTEX_FORMAT \
+#define R128_PROJ_TEX1_VERTEX_FORMAT \
R128_CCE_VC_FRMT_RHW | \
R128_CCE_VC_FRMT_DIFFUSE_ARGB | \
R128_CCE_VC_FRMT_SPEC_FRGB | \
- R128_CCE_VC_FRMT_S_T
+ R128_CCE_VC_FRMT_S_T | \
+ R128_CCE_VC_FRMT_S2_T2 | \
+ R128_CCE_VC_FRMT_RHW2
/* FIXME: We currently only have assembly for 16-stride vertices */
-typedef union {
- r128_vertex v;
- float f[16];
-} r128Vertex, *r128VertexPtr;
+union r128_vertex_t {
+ r128_vertex1 vert1;
+ r128_vertex2 vert2;
+ r128_vertex2_rhw2 vert3;
+ float f[16];
+ CARD32 ui[16];
+};
+
+typedef union r128_vertex_t r128Vertex;
+typedef union r128_vertex_t *r128VertexPtr;
/* Vertex buffer for use when on the fast path */
typedef struct {
@@ -140,7 +148,7 @@ typedef struct {
#define R128_SPEC_BIT 0x01
#define R128_TEX1_BIT 0x02
-#define R128_TEX0_BIT 0x04
+#define R128_TEX0_BIT 0x04
#define R128_RGBA_BIT 0x08
#define R128_WIN_BIT 0x10
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
index 60d528813..aae13df65 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
@@ -49,19 +49,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef R128_DEBUG_FLAGS
int R128_DEBUG_FLAGS = (0
-#if 0
- | DEBUG_ALWAYS_SYNC
- | DEBUG_VERBOSE_CCE
- | DEBUG_VERBOSE_OUTREG
- | DEBUG_VERBOSE_MSG
- | DEBUG_NO_OUTRING
- | DEBUG_NO_OUTREG
- | DEBUG_VERBOSE_API
- | DEBUG_VERBOSE_2D
- | DEBUG_VERBOSE_DRI
- | DEBUG_VALIDATE_RING
- | DEBUG_VERBOSE_IOCTL
-#endif
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_CCE */
+/* | DEBUG_VERBOSE_OUTREG */
+/* | DEBUG_VERBOSE_MSG */
+/* | DEBUG_NO_OUTRING */
+/* | DEBUG_NO_OUTREG */
+/* | DEBUG_VERBOSE_API */
+/* | DEBUG_VERBOSE_2D */
+/* | DEBUG_VERBOSE_DRI */
+/* | DEBUG_VALIDATE_RING */
+/* | DEBUG_VERBOSE_IOCTL */
);
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index 7b8e88265..c71af2cc6 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -1,8 +1,8 @@
/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
- * Revised: Mon Feb 14 00:15:23 2000 by kevin@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,8 +23,9 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.5 2000/02/23 04:47:26 martin Exp $
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
*
* Acknowledgements:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
@@ -61,6 +62,20 @@ typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
+/* Warning: If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well */
+
+typedef struct drm_clip_rect {
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
+} drm_clip_rect_t;
+
+/* Seperate include files for the i810/mga/r128 specific structures */
+#include "mga_drm.h"
+#include "i810_drm.h"
+#include "r128_drm.h"
typedef struct drm_version {
int version_major; /* Major version */
@@ -101,7 +116,8 @@ typedef struct drm_control {
typedef enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
_DRM_REGISTERS = 1, /* no caching, no core dump */
- _DRM_SHM = 2 /* shared, cached */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3 /* AGP/GART */
} drm_map_type_t;
typedef enum drm_map_flags {
@@ -165,8 +181,11 @@ typedef struct drm_buf_desc {
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
enum {
- DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */
+ _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
} flags;
+ unsigned long agp_start; /* Start address of where the agp buffers
+ * are in the agp aperture */
} drm_buf_desc_t;
typedef struct drm_buf_info {
@@ -237,6 +256,38 @@ typedef struct drm_irq_busid {
int funcnum;
} drm_irq_busid_t;
+typedef struct drm_agp_mode {
+ unsigned long mode;
+} drm_agp_mode_t;
+
+ /* For drm_agp_alloc -- allocated a buffer */
+typedef struct drm_agp_buffer {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for BIND/UNBIND ioctls */
+ unsigned long type; /* Type of memory to allocate */
+ unsigned long physical; /* Physical used by i810 */
+} drm_agp_buffer_t;
+
+ /* For drm_agp_bind */
+typedef struct drm_agp_binding {
+ unsigned long handle; /* From drm_agp_buffer */
+ unsigned long offset; /* In bytes -- will round to page boundary */
+} drm_agp_binding_t;
+
+typedef struct drm_agp_info {
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
+ unsigned short id_vendor;
+ unsigned short id_device;
+} drm_agp_info_t;
+
#define DRM_IOCTL_BASE 'd'
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
@@ -247,7 +298,7 @@ typedef struct drm_irq_busid {
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
-#define DRM_IOCTL_GET_MAGIC DRM_IOW( 0x02, drm_auth_t)
+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
@@ -276,4 +327,39 @@ typedef struct drm_irq_busid {
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+
+/* Mga specific ioctls */
+#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
+#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
+#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
+#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
+#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
+
+/* I810 specific ioctls */
+#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
+#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
+#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+#define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
+
+/* Rage 128 specific ioctls */
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
+#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
+#define DRM_IOCTL_R128_IDLE DRM_IO( 0x43)
+#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c
new file mode 100644
index 000000000..dd416db17
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c
@@ -0,0 +1,923 @@
+/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+ * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "r128_drv.h"
+
+#include <linux/interrupt.h> /* For task queue support */
+#include <linux/delay.h>
+
+
+
+#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
+
+#define DO_REMAPFREE(_m) \
+ do { \
+ if ((_m)->handle && (_m)->size) \
+ drm_ioremapfree((_m)->handle, (_m)->size); \
+ } while (0)
+
+#define DO_FIND_MAP(_m, _o) \
+ do { \
+ int _i; \
+ for (_i = 0; _i < dev->map_count; _i++) { \
+ if (dev->maplist[_i]->offset == _o) { \
+ _m = dev->maplist[_i]; \
+ break; \
+ } \
+ } \
+ } while (0)
+
+
+#define R128_MAX_VBUF_AGE 0x10000000
+#define R128_VB_AGE_REG R128_GUI_SCRATCH_REG0
+
+int R128_READ_PLL(drm_device_t *dev, int addr)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+
+ R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
+ return R128_READ(R128_CLOCK_CNTL_DATA);
+}
+
+static void r128_flush_write_combine(void)
+{
+ int xchangeDummy;
+
+ __asm__ volatile("push %%eax ;"
+ "xchg %%eax, %0 ;"
+ "pop %%eax" : : "m" (xchangeDummy));
+ __asm__ volatile("push %%eax ;"
+ "push %%ebx ;"
+ "push %%ecx ;"
+ "push %%edx ;"
+ "movl $0,%%eax ;"
+ "cpuid ;"
+ "pop %%edx ;"
+ "pop %%ecx ;"
+ "pop %%ebx ;"
+ "pop %%eax" : /* no outputs */ : /* no inputs */ );
+}
+
+static void r128_status(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+
+ printk("GUI_STAT = 0x%08x\n",
+ (unsigned int)R128_READ(R128_GUI_STAT));
+ printk("PM4_STAT = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_STAT));
+ printk("PM4_BUFFER_DL_WPTR = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR));
+ printk("PM4_BUFFER_DL_RPTR = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR));
+}
+
+static int r128_do_cleanup_cce(drm_device_t *dev)
+{
+ if (dev->dev_private) {
+ drm_r128_private_t *dev_priv = dev->dev_private;
+
+ if (!dev_priv->is_pci) {
+ DO_REMAPFREE(dev_priv->agp_ring);
+ DO_REMAPFREE(dev_priv->agp_read_ptr);
+ DO_REMAPFREE(dev_priv->agp_vertbufs);
+ DO_REMAPFREE(dev_priv->agp_indbufs);
+ DO_REMAPFREE(dev_priv->agp_textures);
+ }
+
+ drm_free(dev->dev_private, sizeof(drm_r128_private_t),
+ DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ }
+
+ return 0;
+}
+
+static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init)
+{
+ drm_r128_private_t *dev_priv;
+ int i;
+
+ dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL) return -ENOMEM;
+ dev->dev_private = (void *)dev_priv;
+
+ memset(dev_priv, 0, sizeof(drm_r128_private_t));
+
+ dev_priv->is_pci = init->is_pci;
+
+ dev_priv->usec_timeout = init->usec_timeout;
+ if (dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ dev_priv->cce_mode = init->cce_mode;
+ dev_priv->cce_fifo_size = init->cce_fifo_size;
+ dev_priv->cce_is_bm_mode =
+ ((init->cce_mode == R128_PM4_192BM) ||
+ (init->cce_mode == R128_PM4_128BM_64INDBM) ||
+ (init->cce_mode == R128_PM4_64BM_128INDBM) ||
+ (init->cce_mode == R128_PM4_64BM_64VCBM_64INDBM));
+ dev_priv->cce_secure = init->cce_secure;
+
+ if (dev_priv->cce_is_bm_mode && dev_priv->is_pci) {
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dev->map_count; i++) {
+ if (dev->maplist[i]->type == _DRM_SHM) {
+ dev_priv->sarea = dev->maplist[i];
+ break;
+ }
+ }
+
+ DO_FIND_MAP(dev_priv->fb, init->fb_offset);
+ if (!dev_priv->is_pci) {
+ DO_FIND_MAP(dev_priv->agp_ring, init->agp_ring_offset);
+ DO_FIND_MAP(dev_priv->agp_read_ptr, init->agp_read_ptr_offset);
+ DO_FIND_MAP(dev_priv->agp_vertbufs, init->agp_vertbufs_offset);
+ DO_FIND_MAP(dev_priv->agp_indbufs, init->agp_indbufs_offset);
+ DO_FIND_MAP(dev_priv->agp_textures, init->agp_textures_offset);
+ }
+ DO_FIND_MAP(dev_priv->mmio, init->mmio_offset);
+
+ dev_priv->sarea_priv =
+ (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
+ init->sarea_priv_offset);
+
+ if (!dev_priv->is_pci) {
+ DO_REMAP(dev_priv->agp_ring);
+ DO_REMAP(dev_priv->agp_read_ptr);
+ DO_REMAP(dev_priv->agp_vertbufs);
+#if 0
+ DO_REMAP(dev_priv->agp_indirectbufs);
+ DO_REMAP(dev_priv->agp_textures);
+#endif
+
+ dev_priv->ring_size = init->ring_size;
+ dev_priv->ring_sizel2qw = drm_order(init->ring_size/8);
+ dev_priv->ring_entries = init->ring_size/sizeof(u32);
+ dev_priv->ring_read_ptr = ((__volatile__ u32 *)
+ dev_priv->agp_read_ptr->handle);
+ dev_priv->ring_start = (u32 *)dev_priv->agp_ring->handle;
+ dev_priv->ring_end = ((u32 *)dev_priv->agp_ring->handle
+ + dev_priv->ring_entries);
+ }
+
+ dev_priv->submit_age = 0;
+ R128_WRITE(R128_VB_AGE_REG, dev_priv->submit_age);
+
+ return 0;
+}
+
+int r128_init_cce(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_init_t init;
+
+ copy_from_user_ret(&init, (drm_r128_init_t *)arg, sizeof(init),
+ -EFAULT);
+
+ switch (init.func) {
+ case R128_INIT_CCE:
+ return r128_do_init_cce(dev, &init);
+ case R128_CLEANUP_CCE:
+ return r128_do_cleanup_cce(dev);
+ }
+
+ return -EINVAL;
+}
+
+static void r128_mark_vertbufs_done(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+ buf_priv->age = 0;
+ }
+}
+
+static int r128_do_pixcache_flush(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 tmp;
+ int i;
+
+ tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL;
+ R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -EBUSY;
+}
+
+static int r128_do_wait_for_fifo(drm_device_t *dev, int entries)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
+ if (slots >= entries) return 0;
+ udelay(1);
+ }
+ return -EBUSY;
+}
+
+static int r128_do_wait_for_idle(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i, ret;
+
+ if (!(ret = r128_do_wait_for_fifo(dev, 64))) return ret;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
+ (void)r128_do_pixcache_flush(dev);
+ return 0;
+ }
+ udelay(1);
+ }
+ return -EBUSY;
+}
+
+int r128_do_engine_reset(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
+
+ (void)r128_do_pixcache_flush(dev);
+
+ clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX);
+ mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL);
+
+ R128_WRITE_PLL(R128_MCLK_CNTL,
+ mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP);
+
+ gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL);
+
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
+ (void)R128_READ(R128_GEN_RESET_CNTL);
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
+ (void)R128_READ(R128_GEN_RESET_CNTL);
+
+ R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl);
+ R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl);
+
+ /* For CCE ring buffer only */
+ if (dev_priv->cce_is_bm_mode) {
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
+ R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
+ *dev_priv->ring_read_ptr = 0;
+ dev_priv->sarea_priv->ring_write = 0;
+ }
+
+ /* Reset the CCE mode */
+ (void)r128_do_wait_for_idle(dev);
+ R128_WRITE(R128_PM4_BUFFER_CNTL,
+ dev_priv->cce_mode | dev_priv->ring_sizel2qw);
+ (void)R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */
+ R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
+
+ r128_mark_vertbufs_done(dev);
+ return 0;
+}
+
+int r128_eng_reset(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_eng_reset called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ return r128_do_engine_reset(dev);
+}
+
+static int r128_do_engine_flush(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 tmp;
+
+ tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR);
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp | R128_PM4_BUFFER_DL_DONE);
+
+ return 0;
+}
+
+int r128_eng_flush(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_eng_flush called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ return r128_do_engine_flush(dev);
+}
+
+static int r128_do_cce_wait_for_fifo(drm_device_t *dev, int entries)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots = R128_READ(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK;
+ if (slots >= entries) return 0;
+ udelay(1);
+ }
+ return -EBUSY;
+}
+
+int r128_do_cce_wait_for_idle(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ if (dev_priv->cce_is_bm_mode) {
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (*dev_priv->ring_read_ptr == dev_priv->sarea_priv->ring_write) {
+ int pm4stat = R128_READ(R128_PM4_STAT);
+ if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size &&
+ !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ return r128_do_pixcache_flush(dev);
+ }
+ }
+ udelay(1);
+ }
+ return -EBUSY;
+ } else {
+ int ret = r128_do_cce_wait_for_fifo(dev, dev_priv->cce_fifo_size);
+ if (ret < 0) return ret;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int pm4stat = R128_READ(R128_PM4_STAT);
+ if (!(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ return r128_do_pixcache_flush(dev);
+ }
+ udelay(1);
+ }
+ return -EBUSY;
+ }
+}
+
+int r128_cce_idle(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_wait_idle called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ return r128_do_cce_wait_for_idle(dev);
+}
+
+static int r128_submit_packets_ring_secure(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int write = dev_priv->sarea_priv->ring_write;
+ int *write_ptr = dev_priv->ring_start + write;
+ int c = *count;
+ u32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+ int timeout;
+
+ while (c > 0) {
+ tmp = *commands++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ write++;
+ *write_ptr++ = tmp;
+ }
+ if (write >= dev_priv->ring_entries) {
+ write = 0;
+ write_ptr = dev_priv->ring_start;
+ }
+ timeout = 0;
+ while (write == *dev_priv->ring_read_ptr) {
+ (void)R128_READ(R128_PM4_BUFFER_DL_RPTR);
+ if (timeout++ >= dev_priv->usec_timeout)
+ return -EBUSY;
+ udelay(1);
+ }
+ c--;
+ }
+
+ if (write < 32)
+ memcpy(dev_priv->ring_end,
+ dev_priv->ring_start,
+ write * sizeof(u32));
+
+ /* Make sure WC cache has been flushed */
+ r128_flush_write_combine();
+
+ dev_priv->sarea_priv->ring_write = write;
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write);
+
+ *count = 0;
+
+ return 0;
+}
+
+static int r128_submit_packets_pio_secure(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+ int addr = R128_PM4_FIFO_DATA_EVEN;
+ int ret;
+
+ while (*count > 0) {
+ tmp = *commands++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 1)) < 0)
+ return ret;
+ R128_WRITE(addr, tmp);
+ addr ^= 0x0004;
+ }
+
+ *count -= 1;
+ }
+
+ if (addr == R128_PM4_FIFO_DATA_ODD) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 1)) < 0) return ret;
+ R128_WRITE(addr, R128_CCE_PACKET2);
+ }
+
+ return 0;
+}
+
+static int r128_submit_packets_ring(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int write = dev_priv->sarea_priv->ring_write;
+ int *write_ptr = dev_priv->ring_start + write;
+ int c = *count;
+ int timeout;
+
+ while (c > 0) {
+ write++;
+ *write_ptr++ = *commands++;
+ if (write >= dev_priv->ring_entries) {
+ write = 0;
+ write_ptr = dev_priv->ring_start;
+ }
+ timeout = 0;
+ while (write == *dev_priv->ring_read_ptr) {
+ (void)R128_READ(R128_PM4_BUFFER_DL_RPTR);
+ if (timeout++ >= dev_priv->usec_timeout)
+ return -EBUSY;
+ udelay(1);
+ }
+ c--;
+ }
+
+ if (write < 32)
+ memcpy(dev_priv->ring_end,
+ dev_priv->ring_start,
+ write * sizeof(u32));
+
+ /* Make sure WC cache has been flushed */
+ r128_flush_write_combine();
+
+ dev_priv->sarea_priv->ring_write = write;
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write);
+
+ *count = 0;
+
+ return 0;
+}
+
+static int r128_submit_packets_pio(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ while (*count > 1) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 2)) < 0) return ret;
+ R128_WRITE(R128_PM4_FIFO_DATA_EVEN, *commands++);
+ R128_WRITE(R128_PM4_FIFO_DATA_ODD, *commands++);
+ *count -= 2;
+ }
+
+ if (*count) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 2)) < 0) return ret;
+ R128_WRITE(R128_PM4_FIFO_DATA_EVEN, *commands++);
+ R128_WRITE(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2);
+ *count = 0;
+ }
+
+ return 0;
+}
+
+static int r128_do_submit_packets(drm_device_t *dev, u32 *buffer, int count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int c = count;
+ int ret;
+
+ if (dev_priv->cce_is_bm_mode) {
+ int left = 0;
+
+ if (c >= dev_priv->ring_entries) {
+ c = dev_priv->ring_entries-1;
+ left = count - c;
+ }
+
+ /* Since this is only used by the kernel we can use the
+ insecure ring buffer submit packet routine */
+ ret = r128_submit_packets_ring(dev, buffer, &c);
+
+ c += left;
+ } else {
+ /* Since this is only used by the kernel we can use the
+ insecure PIO submit packet routine */
+ ret = r128_submit_packets_pio(dev, buffer, &c);
+ }
+
+ if (ret < 0) return ret;
+ else return c;
+}
+
+int r128_submit_pkt(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_packet_t packet;
+ u32 *buffer;
+ int c;
+ int size;
+ int ret = 0;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_submit_pkt called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ copy_from_user_ret(&packet, (drm_r128_packet_t *)arg, sizeof(packet),
+ -EFAULT);
+
+ c = packet.count;
+ size = c * sizeof(*buffer);
+
+ if (dev_priv->cce_is_bm_mode) {
+ int left = 0;
+
+ if (c >= dev_priv->ring_entries) {
+ c = dev_priv->ring_entries-1;
+ size = c * sizeof(*buffer);
+ left = packet.count - c;
+ }
+
+ if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM;
+ copy_from_user_ret(buffer, packet.buffer, size, -EFAULT);
+
+ if (dev_priv->cce_secure)
+ ret = r128_submit_packets_ring_secure(dev, buffer, &c);
+ else
+ ret = r128_submit_packets_ring(dev, buffer, &c);
+
+ c += left;
+ } else {
+ if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM;
+ copy_from_user_ret(buffer, packet.buffer, size, -EFAULT);
+
+ if (dev_priv->cce_secure)
+ ret = r128_submit_packets_pio_secure(dev, buffer, &c);
+ else
+ ret = r128_submit_packets_pio(dev, buffer, &c);
+ }
+
+ kfree(buffer);
+
+ packet.count = c;
+ copy_to_user_ret((drm_r128_packet_t *)arg, &packet, sizeof(packet),
+ -EFAULT);
+
+ if (ret) return ret;
+ else if (c > 0) return -EAGAIN;
+
+ return 0;
+}
+
+static int r128_send_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_buf_priv_t *buf_priv;
+ drm_buf_t *buf;
+ int i, ret;
+ u32 cce[2];
+
+ /* Make sure we have valid data */
+ for (i = 0; i < v->send_count; i++) {
+ int idx = v->send_indices[i];
+
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ idx, dma->buf_count - 1);
+ return -EINVAL;
+ }
+ buf = dma->buflist[idx];
+ 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:"
+ " buffer %d, offset %d\n",
+ v->send_indices[i], i);
+ return -EINVAL;
+ }
+ }
+
+ /* Wait for idle, if we've wrapped to make sure that all pending
+ buffers have been processed */
+ if (dev_priv->submit_age == R128_MAX_VBUF_AGE) {
+ if ((ret = r128_do_cce_wait_for_idle(dev)) < 0) return ret;
+ dev_priv->submit_age = 0;
+ r128_mark_vertbufs_done(dev);
+ }
+
+ /* Make sure WC cache has been flushed (if in PIO mode) */
+ if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine();
+
+ /* FIXME: Add support for sending vertex buffer to the CCE here
+ instead of in client code. The v->prim holds the primitive
+ type that should be drawn. Loop over the list buffers in
+ send_indices[] and submit a packet for each VB.
+
+ This will require us to loop over the clip rects here as
+ well, which implies that we extend the kernel driver to allow
+ cliprects to be stored here. Note that the cliprects could
+ possibly come from the X server instead of the client, but
+ this will require additional changes to the DRI to allow for
+ this optimization. */
+
+ /* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */
+ cce[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0);
+ cce[1] = dev_priv->submit_age;
+ if ((ret = r128_do_submit_packets(dev, cce, 2)) < 0) {
+ /* Until we add support for sending VBs to the CCE in
+ this routine, we can recover from this error. After
+ we add that support, we won't be able to easily
+ recover, so we will probably have to implement
+ another mechanism for handling timeouts from packets
+ submitted directly by the kernel. */
+ return ret;
+ }
+
+ /* Now that the submit packet request has succeeded, we can mark
+ the buffers as pending */
+ for (i = 0; i < v->send_count; i++) {
+ buf = dma->buflist[v->send_indices[i]];
+ buf->pending = 1;
+
+ buf_priv = buf->dev_private;
+ buf_priv->age = dev_priv->submit_age;
+ }
+
+ dev_priv->submit_age++;
+
+ return 0;
+}
+
+static drm_buf_t *r128_freelist_get(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_buf_priv_t *buf_priv;
+ drm_buf_t *buf;
+ int i, t;
+
+ /* FIXME: Optimize -- use freelist code */
+
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[i];
+ buf_priv = buf->dev_private;
+ if (buf->pid == 0) return buf;
+ }
+
+ for (t = 0; t < dev_priv->usec_timeout; t++) {
+ u32 done_age = R128_READ(R128_VB_AGE_REG);
+
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[i];
+ buf_priv = buf->dev_private;
+ if (buf->pending && buf_priv->age <= done_age) {
+ /* The buffer has been processed, so it
+ can now be used */
+ buf->pending = 0;
+ return buf;
+ }
+ }
+ udelay(1);
+ }
+
+ r128_status(dev);
+ return NULL;
+}
+
+
+static int r128_get_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v)
+{
+ drm_buf_t *buf;
+ int i;
+
+ for (i = v->granted_count; i < v->request_count; i++) {
+ buf = r128_freelist_get(dev);
+ if (!buf) break;
+ buf->pid = current->pid;
+ copy_to_user_ret(&v->request_indices[i],
+ &buf->idx,
+ sizeof(buf->idx),
+ -EFAULT);
+ copy_to_user_ret(&v->request_sizes[i],
+ &buf->total,
+ sizeof(buf->total),
+ -EFAULT);
+ ++v->granted_count;
+ }
+ return 0;
+}
+
+int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ 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;
+ int retcode = 0;
+ drm_r128_vertex_t v;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_vertex_buf called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ if (!dev_priv || dev_priv->is_pci) {
+ DRM_ERROR("r128_vertex_buf called with a PCI card\n");
+ return -EINVAL;
+ }
+
+ copy_from_user_ret(&v, (drm_r128_vertex_t *)arg, sizeof(v), -EFAULT);
+ DRM_DEBUG("%d: %d send, %d req\n",
+ current->pid, v.send_count, v.request_count);
+
+ if (v.send_count < 0 || v.send_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
+ current->pid, v.send_count, dma->buf_count);
+ return -EINVAL;
+ }
+ if (v.request_count < 0 || v.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ current->pid, v.request_count, dma->buf_count);
+ return -EINVAL;
+ }
+
+ if (v.send_count) {
+ retcode = r128_send_vertbufs(dev, &v);
+ }
+
+ v.granted_count = 0;
+
+ if (!retcode && v.request_count) {
+ retcode = r128_get_vertbufs(dev, &v);
+ }
+
+ DRM_DEBUG("%d returning, granted = %d\n",
+ current->pid, v.granted_count);
+ copy_to_user_ret((drm_r128_vertex_t *)arg, &v, sizeof(v), -EFAULT);
+
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
new file mode 100644
index 000000000..e5a85af90
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
@@ -0,0 +1,737 @@
+/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+ * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#define EXPORT_SYMTAB
+#include "drmP.h"
+#include "r128_drv.h"
+EXPORT_SYMBOL(r128_init);
+EXPORT_SYMBOL(r128_cleanup);
+
+#define R128_NAME "r128"
+#define R128_DESC "r128"
+#define R128_DATE "20000607"
+#define R128_MAJOR 1
+#define R128_MINOR 0
+#define R128_PATCHLEVEL 0
+
+static drm_device_t r128_device;
+drm_ctx_t r128_res_ctx;
+
+static struct file_operations r128_fops = {
+ open: r128_open,
+ flush: drm_flush,
+ release: r128_release,
+ ioctl: r128_ioctl,
+ mmap: drm_mmap,
+ read: drm_read,
+ fasync: drm_fasync,
+ poll: drm_poll,
+};
+
+static struct miscdevice r128_misc = {
+ minor: MISC_DYNAMIC_MINOR,
+ name: R128_NAME,
+ fops: &r128_fops,
+};
+
+static drm_ioctl_desc_t r128_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { r128_version, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { r128_addbufs, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { r128_mapbufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { r128_addctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { r128_rmctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { r128_modctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { r128_getctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { r128_switchctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { r128_newctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { r128_resctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { r128_lock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
+
+#ifdef DRM_AGP
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
+#endif
+
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_eng_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_FLUSH)] = { r128_eng_flush, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_submit_pkt, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_IDLE)] = { r128_cce_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_vertex_buf, 1, 0 },
+};
+#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
+
+#ifdef MODULE
+int init_module(void);
+void cleanup_module(void);
+static char *r128 = NULL;
+
+MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas.");
+MODULE_DESCRIPTION("r128");
+MODULE_PARM(r128, "s");
+
+/* init_module is called when insmod is used to load the module */
+
+int init_module(void)
+{
+ return r128_init();
+}
+
+/* cleanup_module is called when rmmod is used to unload the module */
+
+void cleanup_module(void)
+{
+ r128_cleanup();
+}
+#endif
+
+#ifndef MODULE
+/* r128_setup is called by the kernel to parse command-line options passed
+ * via the boot-loader (e.g., LILO). It calls the insmod option routine,
+ * drm_parse_drm.
+ *
+ * This is not currently supported, since it requires changes to
+ * linux/init/main.c. */
+
+
+void __init r128_setup(char *str, int *ints)
+{
+ if (ints[0] != 0) {
+ DRM_ERROR("Illegal command line format, ignored\n");
+ return;
+ }
+ drm_parse_options(str);
+}
+#endif
+
+static int r128_setup(drm_device_t *dev)
+{
+ int i;
+
+ atomic_set(&dev->ioctl_count, 0);
+ atomic_set(&dev->vma_count, 0);
+ dev->buf_use = 0;
+ atomic_set(&dev->buf_alloc, 0);
+
+ drm_dma_setup(dev);
+
+ atomic_set(&dev->total_open, 0);
+ atomic_set(&dev->total_close, 0);
+ atomic_set(&dev->total_ioctl, 0);
+ atomic_set(&dev->total_irq, 0);
+ atomic_set(&dev->total_ctx, 0);
+ atomic_set(&dev->total_locks, 0);
+ atomic_set(&dev->total_unlocks, 0);
+ atomic_set(&dev->total_contends, 0);
+ atomic_set(&dev->total_sleeps, 0);
+
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ dev->magiclist[i].head = NULL;
+ dev->magiclist[i].tail = NULL;
+ }
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ dev->vmalist = NULL;
+ dev->lock.hw_lock = NULL;
+ init_waitqueue_head(&dev->lock.lock_queue);
+ dev->queue_count = 0;
+ dev->queue_reserved = 0;
+ dev->queue_slots = 0;
+ dev->queuelist = NULL;
+ dev->irq = 0;
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+ dev->last_context = 0;
+ dev->last_switch = 0;
+ dev->last_checked = 0;
+ init_timer(&dev->timer);
+ init_waitqueue_head(&dev->context_wait);
+
+ dev->ctx_start = 0;
+ dev->lck_start = 0;
+
+ dev->buf_rp = dev->buf;
+ dev->buf_wp = dev->buf;
+ dev->buf_end = dev->buf + DRM_BSZ;
+ dev->buf_async = NULL;
+ init_waitqueue_head(&dev->buf_readers);
+ init_waitqueue_head(&dev->buf_writers);
+
+ r128_res_ctx.handle=-1;
+
+ DRM_DEBUG("\n");
+
+ /* The kernel's context could be created here, but is now created
+ in drm_dma_enqueue. This is more resource-efficient for
+ hardware that does not do DMA, but may mean that
+ drm_select_queue fails between the time the interrupt is
+ initialized and the time the queues are initialized. */
+
+ return 0;
+}
+
+
+static int r128_takedown(drm_device_t *dev)
+{
+ int i;
+ drm_magic_entry_t *pt, *next;
+ drm_map_t *map;
+ drm_vma_entry_t *vma, *vma_next;
+
+ DRM_DEBUG("\n");
+
+ down(&dev->struct_sem);
+ del_timer(&dev->timer);
+
+ if (dev->devname) {
+ drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
+ dev->devname = NULL;
+ }
+
+ if (dev->unique) {
+ drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
+ dev->unique = NULL;
+ dev->unique_len = 0;
+ }
+ /* Clear pid list */
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ for (pt = dev->magiclist[i].head; pt; pt = next) {
+ next = pt->next;
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+ }
+ dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ }
+
+#ifdef DRM_AGP
+ /* Clear AGP information */
+ if (dev->agp) {
+ drm_agp_mem_t *entry;
+ drm_agp_mem_t *nexte;
+
+ /* Remove AGP resources, but leave dev->agp
+ intact until r128_cleanup is called. */
+ for (entry = dev->agp->memory; entry; entry = nexte) {
+ nexte = entry->next;
+ if (entry->bound) drm_unbind_agp(entry->memory);
+ drm_free_agp(entry->memory, entry->pages);
+ drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ }
+ dev->agp->memory = NULL;
+
+ if (dev->agp->acquired && drm_agp.release)
+ (*drm_agp.release)();
+
+ dev->agp->acquired = 0;
+ dev->agp->enabled = 0;
+ }
+#endif
+
+ /* Clear vma list (only built for debugging) */
+ if (dev->vmalist) {
+ for (vma = dev->vmalist; vma; vma = vma_next) {
+ vma_next = vma->next;
+ drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
+ }
+ dev->vmalist = NULL;
+ }
+
+ /* Clear map area and mtrr information */
+ if (dev->maplist) {
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef CONFIG_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ drm_ioremapfree(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ drm_free_pages((unsigned long)map->handle,
+ drm_order(map->size)
+ - PAGE_SHIFT,
+ DRM_MEM_SAREA);
+ break;
+ case _DRM_AGP:
+ /* Do nothing here, because this is all
+ handled in the AGP/GART driver. */
+ break;
+ }
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ drm_free(dev->maplist,
+ dev->map_count * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ }
+
+ drm_dma_takedown(dev);
+
+ dev->queue_count = 0;
+ if (dev->lock.hw_lock) {
+ dev->lock.hw_lock = NULL; /* SHM removed */
+ dev->lock.pid = 0;
+ wake_up_interruptible(&dev->lock.lock_queue);
+ }
+ up(&dev->struct_sem);
+
+ return 0;
+}
+
+/* r128_init is called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported). */
+
+int r128_init(void)
+{
+ int retcode;
+ drm_device_t *dev = &r128_device;
+
+ DRM_DEBUG("\n");
+
+ memset((void *)dev, 0, sizeof(*dev));
+ dev->count_lock = SPIN_LOCK_UNLOCKED;
+ sema_init(&dev->struct_sem, 1);
+
+#ifdef MODULE
+ drm_parse_options(r128);
+#endif
+
+ if ((retcode = misc_register(&r128_misc))) {
+ DRM_ERROR("Cannot register \"%s\"\n", R128_NAME);
+ return retcode;
+ }
+ dev->device = MKDEV(MISC_MAJOR, r128_misc.minor);
+ dev->name = R128_NAME;
+
+ drm_mem_init();
+ drm_proc_init(dev);
+
+#ifdef DRM_AGP
+ dev->agp = drm_agp_init();
+
+#ifdef CONFIG_MTRR
+ dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size*1024*1024,
+ MTRR_TYPE_WRCOMB,
+ 1);
+#endif
+#endif
+
+ if((retcode = drm_ctxbitmap_init(dev))) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ drm_proc_cleanup();
+ misc_deregister(&r128_misc);
+ r128_takedown(dev);
+ return retcode;
+ }
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ R128_NAME,
+ R128_MAJOR,
+ R128_MINOR,
+ R128_PATCHLEVEL,
+ R128_DATE,
+ r128_misc.minor);
+
+ return 0;
+}
+
+/* r128_cleanup is called via cleanup_module at module unload time. */
+
+void r128_cleanup(void)
+{
+ drm_device_t *dev = &r128_device;
+
+ DRM_DEBUG("\n");
+
+ drm_proc_cleanup();
+ if (misc_deregister(&r128_misc)) {
+ DRM_ERROR("Cannot unload module\n");
+ } else {
+ DRM_INFO("Module unloaded\n");
+ }
+ drm_ctxbitmap_cleanup(dev);
+ r128_takedown(dev);
+#ifdef DRM_AGP
+ if (dev->agp) {
+ /* FIXME -- free other information, too */
+ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+ dev->agp = NULL;
+ }
+#endif
+}
+
+int r128_version(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_version_t version;
+ int len;
+
+ copy_from_user_ret(&version,
+ (drm_version_t *)arg,
+ sizeof(version),
+ -EFAULT);
+
+#define DRM_COPY(name,value) \
+ len = strlen(value); \
+ if (len > name##_len) len = name##_len; \
+ name##_len = strlen(value); \
+ if (len && name) { \
+ copy_to_user_ret(name, value, len, -EFAULT); \
+ }
+
+ version.version_major = R128_MAJOR;
+ version.version_minor = R128_MINOR;
+ version.version_patchlevel = R128_PATCHLEVEL;
+
+ DRM_COPY(version.name, R128_NAME);
+ DRM_COPY(version.date, R128_DATE);
+ DRM_COPY(version.desc, R128_DESC);
+
+ copy_to_user_ret((drm_version_t *)arg,
+ &version,
+ sizeof(version),
+ -EFAULT);
+ return 0;
+}
+
+int r128_open(struct inode *inode, struct file *filp)
+{
+ drm_device_t *dev = &r128_device;
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+ if (!(retcode = drm_open_helper(inode, filp, dev))) {
+ MOD_INC_USE_COUNT;
+ atomic_inc(&dev->total_open);
+ spin_lock(&dev->count_lock);
+ if (!dev->open_count++) {
+ spin_unlock(&dev->count_lock);
+ return r128_setup(dev);
+ }
+ spin_unlock(&dev->count_lock);
+ }
+ return retcode;
+}
+
+int r128_release(struct inode *inode, struct file *filp)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+ if (!(retcode = drm_release(inode, filp))) {
+ MOD_DEC_USE_COUNT;
+ atomic_inc(&dev->total_close);
+ spin_lock(&dev->count_lock);
+ if (!--dev->open_count) {
+ if (atomic_read(&dev->ioctl_count) || dev->blocked) {
+ DRM_ERROR("Device busy: %d %d\n",
+ atomic_read(&dev->ioctl_count),
+ dev->blocked);
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ spin_unlock(&dev->count_lock);
+ return r128_takedown(dev);
+ }
+ spin_unlock(&dev->count_lock);
+ }
+ return retcode;
+}
+
+/* r128_ioctl is called whenever a process performs an ioctl on /dev/drm. */
+
+int r128_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ int nr = DRM_IOCTL_NR(cmd);
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode = 0;
+ drm_ioctl_desc_t *ioctl;
+ drm_ioctl_t *func;
+
+ atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->total_ioctl);
+ ++priv->ioctl_count;
+
+ DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
+ current->pid, cmd, nr, dev->device, priv->authenticated);
+
+ if (nr >= R128_IOCTL_COUNT) {
+ retcode = -EINVAL;
+ } else {
+ ioctl = &r128_ioctls[nr];
+ func = ioctl->func;
+
+ if (!func) {
+ DRM_DEBUG("no function\n");
+ retcode = -EINVAL;
+ } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
+ || (ioctl->auth_needed && !priv->authenticated)) {
+ retcode = -EACCES;
+ } else {
+ retcode = (func)(inode, filp, cmd, arg);
+ }
+ }
+
+ atomic_dec(&dev->ioctl_count);
+ return retcode;
+}
+
+int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ DECLARE_WAITQUEUE(entry, current);
+ int ret = 0;
+ drm_lock_t lock;
+#if DRM_DMA_HISTOGRAM
+ cycles_t start;
+
+ dev->lck_start = start = get_cycles();
+#endif
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, current->pid, dev->lock.hw_lock->lock,
+ lock.flags);
+
+#if 0
+ /* dev->queue_count == 0 right now for
+ r128. FIXME? */
+ if (lock.context < 0 || lock.context >= dev->queue_count)
+ return -EINVAL;
+#endif
+
+ if (!ret) {
+#if 0
+ if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
+ != lock.context) {
+ long j = jiffies - dev->lock.lock_time;
+
+ if (lock.context == r128_res_ctx.handle &&
+ j >= 0 && j < DRM_LOCK_SLICE) {
+ /* Can't take lock if we just had it and
+ there is contention. */
+ DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
+ lock.context, current->pid, j,
+ dev->lock.lock_time, jiffies);
+ current->state = TASK_INTERRUPTIBLE;
+ current->policy |= SCHED_YIELD;
+ schedule_timeout(DRM_LOCK_SLICE-j);
+ DRM_DEBUG("jiffies=%d\n", jiffies);
+ }
+ }
+#endif
+ add_wait_queue(&dev->lock.lock_queue, &entry);
+ for (;;) {
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ ret = -EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ lock.context)) {
+ dev->lock.pid = current->pid;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->total_locks);
+ break; /* Got lock */
+ }
+
+ /* Contention */
+ atomic_inc(&dev->total_sleeps);
+ current->state = TASK_INTERRUPTIBLE;
+#if 1
+ current->policy |= SCHED_YIELD;
+#endif
+ schedule();
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
+ }
+
+#if 0
+ if (!ret && dev->last_context != lock.context &&
+ lock.context != r128_res_ctx.handle &&
+ dev->last_context != r128_res_ctx.handle) {
+ add_wait_queue(&dev->context_wait, &entry);
+ current->state = TASK_INTERRUPTIBLE;
+ /* PRE: dev->last_context != lock.context */
+ r128_context_switch(dev, dev->last_context, lock.context);
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == lock.context
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ current->policy |= SCHED_YIELD;
+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->context_wait, &entry);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ } else if (dev->last_context != lock.context) {
+ DRM_ERROR("Context mismatch: %d %d\n",
+ dev->last_context, lock.context);
+ }
+ }
+#endif
+
+ if (!ret) {
+ if (lock.flags & _DRM_LOCK_READY) {
+ /* Wait for space in DMA/FIFO */
+ }
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ /* Make hardware quiescent */
+#if 0
+ r128_quiescent(dev);
+#endif
+ }
+ }
+
+#if 0
+ DRM_ERROR("pid = %5d, old counter = %5ld\n",
+ current->pid, current->counter);
+#endif
+ if (lock.context != r128_res_ctx.handle) {
+ current->counter = 5;
+ current->priority = DEF_PRIORITY/4;
+ }
+#if 0
+ while (current->counter > 25)
+ current->counter >>= 1; /* decrease time slice */
+ DRM_ERROR("pid = %5d, new counter = %5ld\n",
+ current->pid, current->counter);
+#endif
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
+#endif
+
+ return ret;
+}
+
+
+int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_lock_t lock;
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("%d frees lock (%d holds)\n",
+ lock.context,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ atomic_inc(&dev->total_unlocks);
+ if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
+ atomic_inc(&dev->total_contends);
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+ /* FIXME: Try to send data to card here */
+ if (!dev->context_flag) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+
+#if 0
+ current->policy |= SCHED_YIELD;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1000);
+#endif
+
+ if (lock.context != r128_res_ctx.handle) {
+ current->counter = 5;
+ current->priority = DEF_PRIORITY;
+ }
+#if 0
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(10);
+#endif
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
new file mode 100644
index 000000000..e08a3185d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
@@ -0,0 +1,199 @@
+/* xf86drmR128.c -- User-level interface to Rage 128 DRM device
+ * Created: Sun Apr 9 18:13:54 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include <sys/sysmacros.h> /* for makedev() */
+#include "xf86drm.h"
+#include "xf86drmR128.h"
+#include "drm.h"
+
+int drmR128InitCCE(int fd, drmR128Init *info)
+{
+ drm_r128_init_t init;
+
+ memset(&init, 0, sizeof(drm_r128_init_t));
+
+ init.func = R128_INIT_CCE;
+ init.sarea_priv_offset = info->sarea_priv_offset;
+ init.is_pci = info->is_pci;
+ init.cce_mode = info->cce_mode;
+ init.cce_fifo_size = info->cce_fifo_size;
+ init.cce_secure = info->cce_secure;
+ init.ring_size = info->ring_size;
+ init.usec_timeout = info->usec_timeout;
+
+ init.fb_offset = info->fb_offset;
+ init.agp_ring_offset = info->agp_ring_offset;
+ init.agp_read_ptr_offset = info->agp_read_ptr_offset;
+ init.agp_vertbufs_offset = info->agp_vertbufs_offset;
+ init.agp_indbufs_offset = info->agp_indbufs_offset;
+ init.agp_textures_offset = info->agp_textures_offset;
+ init.mmio_offset = info->mmio_offset;
+
+ if (ioctl(fd, DRM_IOCTL_R128_INIT, &init)) return -errno;
+
+ return 0;
+}
+
+int drmR128CleanupCCE(int fd)
+{
+ drm_r128_init_t init;
+
+ memset(&init, 0, sizeof(drm_r128_init_t));
+
+ init.func = R128_CLEANUP_CCE;
+
+ if (ioctl(fd, DRM_IOCTL_R128_INIT, &init)) return -errno;
+
+ return 0;
+}
+
+int drmR128EngineReset(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_RESET, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128EngineFlush(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_FLUSH, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128WaitForIdle(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_IDLE, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128SubmitPacket(int fd, CARD32 *buffer, int *count, int flags)
+{
+ drm_r128_packet_t packet;
+ int ret;
+
+ memset(&packet, 0, sizeof(drm_r128_packet_t));
+
+ packet.count = *count;
+ packet.flags = flags;
+
+ while (packet.count > 0) {
+ packet.buffer = buffer + (*count - packet.count);
+ ret = ioctl(fd, DRM_IOCTL_R128_PACKET, &packet);
+ if (ret < 0 && ret != -EAGAIN) {
+ *count = packet.count;
+ return -errno;
+ }
+ }
+
+ *count = 0;
+ return 0;
+}
+
+int drmR128GetVertexBuffers(int fd, int count, int *indices, int *sizes)
+{
+ drm_r128_vertex_t v;
+
+ v.send_count = 0;
+ v.send_indices = NULL;
+ v.send_sizes = NULL;
+ v.prim = DRM_R128_PRIM_NONE;
+ v.request_count = count;
+ v.request_indices = indices;
+ v.request_sizes = sizes;
+ v.granted_count = 0;
+
+ if (ioctl(fd, DRM_IOCTL_R128_VERTEX, &v)) return -errno;
+
+ return v.granted_count;
+}
+
+int drmR128FlushVertexBuffers(int fd, int count, int *indices,
+ int *sizes, drmR128PrimType prim)
+{
+ drm_r128_vertex_t v;
+
+ v.send_count = count;
+ v.send_indices = indices;
+ v.send_sizes = sizes;
+ v.prim = prim;
+ v.request_count = 0;
+ v.request_indices = NULL;
+ v.request_sizes = NULL;
+ v.granted_count = 0;
+
+ if (ioctl(fd, DRM_IOCTL_R128_VERTEX, &v) < 0) return -errno;
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index 7b8e88265..c71af2cc6 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -1,8 +1,8 @@
/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
- * Revised: Mon Feb 14 00:15:23 2000 by kevin@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,8 +23,9 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.5 2000/02/23 04:47:26 martin Exp $
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
*
* Acknowledgements:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
@@ -61,6 +62,20 @@ typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
+/* Warning: If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well */
+
+typedef struct drm_clip_rect {
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
+} drm_clip_rect_t;
+
+/* Seperate include files for the i810/mga/r128 specific structures */
+#include "mga_drm.h"
+#include "i810_drm.h"
+#include "r128_drm.h"
typedef struct drm_version {
int version_major; /* Major version */
@@ -101,7 +116,8 @@ typedef struct drm_control {
typedef enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
_DRM_REGISTERS = 1, /* no caching, no core dump */
- _DRM_SHM = 2 /* shared, cached */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3 /* AGP/GART */
} drm_map_type_t;
typedef enum drm_map_flags {
@@ -165,8 +181,11 @@ typedef struct drm_buf_desc {
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
enum {
- DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */
+ _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
} flags;
+ unsigned long agp_start; /* Start address of where the agp buffers
+ * are in the agp aperture */
} drm_buf_desc_t;
typedef struct drm_buf_info {
@@ -237,6 +256,38 @@ typedef struct drm_irq_busid {
int funcnum;
} drm_irq_busid_t;
+typedef struct drm_agp_mode {
+ unsigned long mode;
+} drm_agp_mode_t;
+
+ /* For drm_agp_alloc -- allocated a buffer */
+typedef struct drm_agp_buffer {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for BIND/UNBIND ioctls */
+ unsigned long type; /* Type of memory to allocate */
+ unsigned long physical; /* Physical used by i810 */
+} drm_agp_buffer_t;
+
+ /* For drm_agp_bind */
+typedef struct drm_agp_binding {
+ unsigned long handle; /* From drm_agp_buffer */
+ unsigned long offset; /* In bytes -- will round to page boundary */
+} drm_agp_binding_t;
+
+typedef struct drm_agp_info {
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
+ unsigned short id_vendor;
+ unsigned short id_device;
+} drm_agp_info_t;
+
#define DRM_IOCTL_BASE 'd'
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
@@ -247,7 +298,7 @@ typedef struct drm_irq_busid {
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
-#define DRM_IOCTL_GET_MAGIC DRM_IOW( 0x02, drm_auth_t)
+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
@@ -276,4 +327,39 @@ typedef struct drm_irq_busid {
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+
+/* Mga specific ioctls */
+#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
+#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
+#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
+#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
+#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
+
+/* I810 specific ioctls */
+#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
+#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
+#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+#define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
+
+/* Rage 128 specific ioctls */
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
+#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
+#define DRM_IOCTL_R128_IDLE DRM_IO( 0x43)
+#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
new file mode 100644
index 000000000..dd430ed87
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
@@ -0,0 +1,80 @@
+/* xf86drm.h -- OS-independent header for DRM user-level library interface
+ * Created: Sun Apr 9 18:16:28 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#ifndef _XF86DRI_R128_H_
+#define _XF86DRI_R128_H_
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (r128_drm.h)
+ */
+
+typedef struct _drmR128Init {
+ int sarea_priv_offset;
+ int is_pci;
+ int cce_mode;
+ int cce_fifo_size;
+ int cce_secure;
+ int ring_size;
+ int usec_timeout;
+
+ int fb_offset;
+ int agp_ring_offset;
+ int agp_read_ptr_offset;
+ int agp_vertbufs_offset;
+ int agp_indbufs_offset;
+ int agp_textures_offset;
+ int mmio_offset;
+} drmR128Init;
+
+typedef enum {
+ DRM_R128_PRIM_NONE = 0x0001,
+ DRM_R128_PRIM_POINT = 0x0002,
+ DRM_R128_PRIM_LINE = 0x0004,
+ DRM_R128_PRIM_POLY_LINE = 0x0008,
+ DRM_R128_PRIM_TRI_LIST = 0x0010,
+ DRM_R128_PRIM_TRI_FAN = 0x0020,
+ DRM_R128_PRIM_TRI_STRIP = 0x0040,
+ DRM_R128_PRIM_TRI_TYPE2 = 0x0080
+} drmR128PrimType;
+
+
+extern int drmR128InitCCE(int fd, drmR128Init *info);
+extern int drmR128CleanupCCE(int fd);
+extern int drmR128EngineReset(int fd);
+extern int drmR128EngineFlush(int fd);
+extern int drmR128WaitForIdle(int fd);
+extern int drmR128SubmitPacket(int fd, CARD32 *buffer, int *count, int flags);
+extern int drmR128GetVertexBuffers(int fd, int count, int *indices,
+ int *sizes);
+extern int drmR128FlushVertexBuffers(int fd, int count, int *indices,
+ int *sizes, drmR128PrimType prim);
+
+#endif