summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoridr <idr>2003-01-26 07:43:44 +0000
committeridr <idr>2003-01-26 07:43:44 +0000
commit864aafbf04464e57ae750693b39a5f2ecece06b8 (patch)
tree68bf688f251cc10f76a39c3e10b9f91f1e10b668
parent6bf960e3e83d69c53b3706324dca7d6c152017f7 (diff)
-rw-r--r--xc/extras/Mesa/src/X86/common_x86_asm.S6
-rw-r--r--xc/extras/Mesa/src/context.c2
-rw-r--r--xc/extras/Mesa/src/glthread.h10
-rw-r--r--xc/extras/Mesa/src/hash.c1
-rw-r--r--xc/extras/Mesa/src/texobj.c3
-rw-r--r--xc/extras/Mesa/src/texstate.c3
-rw-r--r--xc/extras/Mesa/src/tnl/t_imm_api.c9
-rw-r--r--xc/extras/Mesa/src/tnl_dd/t_dd_vbtmp.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/common/texmem.c140
-rw-r--r--xc/lib/GL/mesa/src/drv/common/texmem.h3
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c15
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgacontext.h11
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_context.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_context.h1
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c17
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_lock.c5
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_sanity.c7
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_state.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_state_init.c9
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_tex.c16
-rw-r--r--xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c27
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c19
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_state.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c28
-rw-r--r--xc/programs/Xserver/GL/dri/xf86dri.c59
-rw-r--r--xc/programs/Xserver/GL/glx/glxcmds.c10
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux/agp.c13
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h1
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c70
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c56
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c82
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h53
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h153
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h11
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h65
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h67
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h54
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h5
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_ds.c22
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_cp.c39
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h1
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_mem.c324
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_state.c201
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h2
51 files changed, 1183 insertions, 516 deletions
diff --git a/xc/extras/Mesa/src/X86/common_x86_asm.S b/xc/extras/Mesa/src/X86/common_x86_asm.S
index 3b97dc15a..4dfac4157 100644
--- a/xc/extras/Mesa/src/X86/common_x86_asm.S
+++ b/xc/extras/Mesa/src/X86/common_x86_asm.S
@@ -1,9 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 5.0.1
*
- * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2003 Brian Paul 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"),
@@ -225,8 +225,6 @@ GLNAME( _mesa_test_os_sse_exception_support ):
MOVUPS ( REGIND( ESP ), XMM1 )
- ADD_L ( CONST( 32 ), ESP )
-
DIVPS ( XMM0, XMM1 )
/* Restore the original MXCSR register value.
diff --git a/xc/extras/Mesa/src/context.c b/xc/extras/Mesa/src/context.c
index 3f3edf31d..82037a2f6 100644
--- a/xc/extras/Mesa/src/context.c
+++ b/xc/extras/Mesa/src/context.c
@@ -745,6 +745,8 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->VertexPrograms);
#endif
+ _glthread_DESTROY_MUTEX(ss->Mutex);
+
FREE(ss);
}
diff --git a/xc/extras/Mesa/src/glthread.h b/xc/extras/Mesa/src/glthread.h
index 345bdd2ee..051965446 100644
--- a/xc/extras/Mesa/src/glthread.h
+++ b/xc/extras/Mesa/src/glthread.h
@@ -100,6 +100,9 @@ typedef pthread_mutex_t _glthread_Mutex;
#define _glthread_INIT_MUTEX(name) \
pthread_mutex_init(&(name), NULL)
+#define _glthread_DESTROY_MUTEX(name) \
+ pthread_mutex_destroy(&(name))
+
#define _glthread_LOCK_MUTEX(name) \
(void) pthread_mutex_lock(&(name))
@@ -133,6 +136,7 @@ typedef mutex_t _glthread_Mutex;
/* XXX need to really implement mutex-related macros */
#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0
#define _glthread_INIT_MUTEX(name) (void) name
+#define _glthread_DESTROY_MUTEX(name) (void) name
#define _glthread_LOCK_MUTEX(name) (void) name
#define _glthread_UNLOCK_MUTEX(name) (void) name
@@ -161,6 +165,7 @@ typedef CRITICAL_SECTION _glthread_Mutex;
/* XXX need to really implement mutex-related macros */
#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0
#define _glthread_INIT_MUTEX(name) (void) name
+#define _glthread_DESTROY_MUTEX(name) (void) name
#define _glthread_LOCK_MUTEX(name) (void) name
#define _glthread_UNLOCK_MUTEX(name) (void) name
@@ -196,6 +201,9 @@ typedef xmutex_rec _glthread_Mutex;
#define _glthread_INIT_MUTEX(name) \
xmutex_init(&(name))
+#define _glthread_DESTROY_MUTEX(name) \
+ xmutex_clear(&(name))
+
#define _glthread_LOCK_MUTEX(name) \
(void) xmutex_lock(&(name))
@@ -253,6 +261,8 @@ typedef GLuint _glthread_Mutex;
#define _glthread_INIT_MUTEX(name) (void) name
+#define _glthread_DESTROY_MUTEX(name) (void) name
+
#define _glthread_LOCK_MUTEX(name) (void) name
#define _glthread_UNLOCK_MUTEX(name) (void) name
diff --git a/xc/extras/Mesa/src/hash.c b/xc/extras/Mesa/src/hash.c
index d5d757ce8..32e37a268 100644
--- a/xc/extras/Mesa/src/hash.c
+++ b/xc/extras/Mesa/src/hash.c
@@ -93,6 +93,7 @@ void _mesa_DeleteHashTable(struct _mesa_HashTable *table)
entry = next;
}
}
+ _glthread_DESTROY_MUTEX(table->Mutex);
FREE(table);
}
diff --git a/xc/extras/Mesa/src/texobj.c b/xc/extras/Mesa/src/texobj.c
index 905918ff9..75c92be18 100644
--- a/xc/extras/Mesa/src/texobj.c
+++ b/xc/extras/Mesa/src/texobj.c
@@ -163,6 +163,9 @@ void _mesa_free_texture_object( struct gl_shared_state *shared,
}
}
+ /* destroy the mutex -- it may have allocated memory (eg on bsd) */
+ _glthread_DESTROY_MUTEX(t->Mutex);
+
/* free this object */
FREE( t );
}
diff --git a/xc/extras/Mesa/src/texstate.c b/xc/extras/Mesa/src/texstate.c
index 6802b7176..0d7388c1a 100644
--- a/xc/extras/Mesa/src/texstate.c
+++ b/xc/extras/Mesa/src/texstate.c
@@ -2397,7 +2397,8 @@ _mesa_ActiveTextureARB( GLenum target )
_mesa_debug(ctx, "glActiveTexture %s\n",
_mesa_lookup_enum_by_nr(target));
- if (texUnit > ctx->Const.MaxTextureUnits) {
+ /* Cater for texture unit 0 is first, therefore use >= */
+ if (texUnit >= ctx->Const.MaxTextureUnits) {
_mesa_error(ctx, GL_INVALID_ENUM, "glActiveTextureARB(target)");
return;
}
diff --git a/xc/extras/Mesa/src/tnl/t_imm_api.c b/xc/extras/Mesa/src/tnl/t_imm_api.c
index 32ea81135..9e073f162 100644
--- a/xc/extras/Mesa/src/tnl/t_imm_api.c
+++ b/xc/extras/Mesa/src/tnl/t_imm_api.c
@@ -204,8 +204,8 @@ _tnl_Begin( GLenum mode )
return;
}
- assert( IM->SavedBeginState == 0 );
- assert( IM->BeginState == 0 );
+ assert( (IM->SavedBeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) == 0 );
+ assert( (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) == 0 );
/* Not quite right. Need to use the fallback '_aa_ArrayElement'
* when not known to be inside begin/end and arrays are
@@ -331,7 +331,10 @@ _tnl_end( GLcontext *ctx )
GLuint state = IM->BeginState;
GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1);
- assert( ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES );
+ /* Not the case if vertices emitted without calling glBegin first:
+ */
+/* assert( ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES ); */
+
state |= inflags << 2; /* errors */
diff --git a/xc/extras/Mesa/src/tnl_dd/t_dd_vbtmp.h b/xc/extras/Mesa/src/tnl_dd/t_dd_vbtmp.h
index 35ac9fcfa..0fc1a64e2 100644
--- a/xc/extras/Mesa/src/tnl_dd/t_dd_vbtmp.h
+++ b/xc/extras/Mesa/src/tnl_dd/t_dd_vbtmp.h
@@ -215,7 +215,7 @@ static void TAG(emit)( GLcontext *ctx,
}
}
- if (VB->importable_data) {
+ if (VB->importable_data || (DO_SPEC && !spec_stride) || (DO_FOG && !fog_stride)) {
/* May have nonstandard strides:
*/
if (start) {
@@ -234,7 +234,7 @@ static void TAG(emit)( GLcontext *ctx,
STRIDE_4UB(spec, start * spec_stride);
if (DO_FOG)
/*STRIDE_F(fog, start * fog_stride);*/
- fog = (GLfloat (*)[4])((GLfloat *)fog + start * fog_stride);
+ fog = (GLfloat (*)[4])((GLubyte *)fog + start * fog_stride);
}
for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
@@ -270,7 +270,7 @@ static void TAG(emit)( GLcontext *ctx,
if (DO_FOG) {
v->v.specular.alpha = fog[0][0] * 255.0;
/*STRIDE_F(fog, fog_stride);*/
- fog = (GLfloat (*)[4])((GLfloat *)fog + fog_stride);
+ fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
}
if (DO_TEX0) {
v->v.u0 = tc0[0][0];
diff --git a/xc/lib/GL/mesa/src/drv/common/texmem.c b/xc/lib/GL/mesa/src/drv/common/texmem.c
index 130004815..5fb8022eb 100644
--- a/xc/lib/GL/mesa/src/drv/common/texmem.c
+++ b/xc/lib/GL/mesa/src/drv/common/texmem.c
@@ -927,3 +927,143 @@ void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped,
ctx->Texture.CurrentUnit = tmp;
}
+
+
+
+
+/**
+ * Verify that the specified texture is in the specificed heap.
+ *
+ * \param tex Texture to be tested.
+ * \param heap Texture memory heap to be tested.
+ * \returns True if the texture is in the heap, false otherwise.
+ */
+
+static GLboolean
+check_in_heap( const driTextureObject * tex, const driTexHeap * heap )
+{
+#if 1
+ return tex->heap == heap;
+#else
+ driTextureObject * curr;
+
+ foreach( curr, & heap->texture_objects ) {
+ if ( curr == tex ) {
+ break;
+ }
+ }
+
+ return curr == tex;
+#endif
+}
+
+
+
+/****************************************************************************/
+/**
+ * Validate the consistency of a set of texture heaps.
+ * Original version by Keith Whitwell in r200/r200_sanity.c.
+ */
+
+GLboolean
+driValidateTextureHeaps( driTexHeap * const * texture_heaps,
+ unsigned nr_heaps, const driTextureObject * swapped )
+{
+ driTextureObject *t;
+ unsigned i;
+
+ for ( i = 0 ; i < nr_heaps ; i++ ) {
+ int last_end = 0;
+ unsigned textures_in_heap = 0;
+ unsigned blocks_in_mempool = 0;
+ const driTexHeap * heap = texture_heaps[i];
+ const memHeap_t * p = heap->memory_heap;
+
+ /* Check each texture object has a MemBlock, and is linked into
+ * the correct heap.
+ *
+ * Check the texobj base address corresponds to the MemBlock
+ * range. Check the texobj size (recalculate???) fits within
+ * the MemBlock.
+ *
+ * Count the number of texobj's using this heap.
+ */
+
+ foreach ( t, &heap->texture_objects ) {
+ if ( !check_in_heap( t, heap ) ) {
+ fprintf( stderr, "%s memory block for texture object @ %p not "
+ "found in heap #%d\n",
+ __FUNCTION__, t, i );
+ return GL_FALSE;
+ }
+
+
+ if ( t->totalSize > t->memBlock->size ) {
+ fprintf( stderr, "%s: Memory block for texture object @ %p is "
+ "only %u bytes, but %u are required\n",
+ __FUNCTION__, t, t->totalSize, t->memBlock->size );
+ return GL_FALSE;
+ }
+
+ textures_in_heap++;
+ }
+
+ /* Validate the contents of the heap:
+ * - Ordering
+ * - Overlaps
+ * - Bounds
+ */
+
+ while ( p != NULL ) {
+ if (p->reserved) {
+ fprintf( stderr, "%s: Block (%08x,%x), is reserved?!\n",
+ __FUNCTION__, p->ofs, p->size );
+ return GL_FALSE;
+ }
+
+ if (p->ofs != last_end) {
+ fprintf( stderr, "%s: blocks_in_mempool = %d, last_end = %d, p->ofs = %d\n",
+ __FUNCTION__, blocks_in_mempool, last_end, p->ofs );
+ return GL_FALSE;
+ }
+
+ if (!p->reserved && !p->free) {
+ blocks_in_mempool++;
+ }
+
+ last_end = p->ofs + p->size;
+ p = p->next;
+ }
+
+ if (textures_in_heap != blocks_in_mempool) {
+ fprintf( stderr, "%s: Different number of textures objects (%u) and "
+ "inuse memory blocks (%u)\n",
+ __FUNCTION__, textures_in_heap, blocks_in_mempool );
+ return GL_FALSE;
+ }
+
+#if 0
+ fprintf( stderr, "%s: textures_in_heap = %u\n",
+ __FUNCTION__, textures_in_heap );
+#endif
+ }
+
+
+ /* Check swapped texobj's have zero memblocks
+ */
+ i = 0;
+ foreach ( t, swapped ) {
+ if ( t->memBlock != NULL ) {
+ fprintf( stderr, "%s: Swapped texobj %p has non-NULL memblock %p\n",
+ __FUNCTION__, t, t->memBlock );
+ return GL_FALSE;
+ }
+ i++;
+ }
+
+#if 0
+ fprintf( stderr, "%s: swapped texture count = %u\n", i );
+#endif
+
+ return GL_TRUE;
+}
diff --git a/xc/lib/GL/mesa/src/drv/common/texmem.h b/xc/lib/GL/mesa/src/drv/common/texmem.h
index 35c9a4984..5807672b6 100644
--- a/xc/lib/GL/mesa/src/drv/common/texmem.h
+++ b/xc/lib/GL/mesa/src/drv/common/texmem.h
@@ -272,4 +272,7 @@ driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter );
void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped,
GLuint targets );
+GLboolean driValidateTextureHeaps( driTexHeap * const * texture_heaps,
+ unsigned nr_heaps, const driTextureObject * swapped );
+
#endif /* DRI_TEXMEM_H */
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
index 67dec6479..98cfb8608 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
@@ -202,21 +202,6 @@ mgaInitDriver(__DRIscreenPrivate *sPriv)
}
mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;
- if (sPriv->drmMinor >= 1) {
- int ret;
- drmMGAGetParam gp;
-
- gp.param = MGA_PARAM_IRQ_NR;
- gp.value = &mgaScreen->irq;
-
- ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
- &gp, sizeof(gp));
- if (ret) {
- fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
- return GL_FALSE;
- }
- }
-
return GL_TRUE;
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h
index 826a5d7d3..41a192980 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h
@@ -60,17 +60,6 @@
#define MGA_FALLBACK_DEPTH 0x40
-/* For mgaCtx->new_state.
- */
-/*#define MGA_NEW_DEPTH 0x01*/
-#define MGA_NEW_ALPHA 0x02
-/*#define MGA_NEW_CLIP 0x04*/
-/*#define MGA_NEW_TEXTURE 0x08*/
-/*#define MGA_NEW_CULL 0x10*/
-/*#define MGA_NEW_WARP 0x20*/
-/*#define MGA_NEW_STENCIL 0x40*/
-/*#define MGA_NEW_CONTEXT 0x80*/
-
/* Use the templated vertex formats:
*/
#define TAG(x) mga##x
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_context.c b/xc/lib/GL/mesa/src/drv/r200/r200_context.c
index 1752cb1b0..82cd33894 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_context.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_context.c
@@ -219,6 +219,7 @@ static const struct dri_debug_control debug_control[] =
{ "san", DEBUG_SANITY },
{ "sync", DEBUG_SYNC },
{ "pix", DEBUG_PIXEL },
+ { "mem", DEBUG_MEMORY },
{ NULL, 0 }
};
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_context.h b/xc/lib/GL/mesa/src/drv/r200/r200_context.h
index 875c098e7..e1191bda6 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_context.h
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_context.h
@@ -919,6 +919,7 @@ extern int R200_DEBUG;
#define DEBUG_SANITY 0x800
#define DEBUG_SYNC 0x1000
#define DEBUG_PIXEL 0x2000
+#define DEBUG_MEMORY 0x4000
#endif
#endif /* __R200_CONTEXT_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c
index b2cb3a0b3..a0b94102e 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c
@@ -56,7 +56,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void do_usleep( int nr, const char *caller )
{
- if (0) fprintf(stderr, "usleep %d in %s\n", nr, caller );
+ if (1) fprintf(stderr, "usleep %d in %s\n", nr, caller );
if (1) usleep( nr );
}
@@ -98,6 +98,15 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller )
}
+ if (R200_DEBUG & DEBUG_MEMORY) {
+ if (! driValidateTextureHeaps( rmesa->texture_heaps, rmesa->nr_heaps,
+ & rmesa->swapped ) ) {
+ fprintf( stderr, "%s: texture memory is inconsistent - expect "
+ "mangled textures\n", __FUNCTION__ );
+ }
+ }
+
+
cmd.bufsz = rmesa->store.cmd_used;
cmd.buf = rmesa->store.cmd_buf;
@@ -485,10 +494,6 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
r200WaitForFrameCompletion( rmesa );
r200WaitForVBlank( rmesa );
- r200WaitForVBlank( rmesa );
-
- r200WaitForVBlank( rmesa );
-
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
UNLOCK_HARDWARE( rmesa );
@@ -596,7 +601,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
/* Clear throttling needs more thought.
*/
- if ( rmesa->sarea->last_clear - clear <= 8 ) {
+ if ( rmesa->sarea->last_clear - clear <= 25 ) {
break;
}
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_lock.c b/xc/lib/GL/mesa/src/drv/r200/r200_lock.c
index 725f32fe7..029142c59 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_lock.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_lock.c
@@ -83,6 +83,7 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags )
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
__DRIscreenPrivate *sPriv = rmesa->dri.screen;
RADEONSAREAPrivPtr sarea = rmesa->sarea;
+ int i;
drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
@@ -109,4 +110,8 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags )
if ( sarea->ctxOwner != rmesa->dri.hwContext ) {
sarea->ctxOwner = rmesa->dri.hwContext;
}
+
+ for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
+ DRI_AGE_TEXTURES( rmesa->texture_heaps[ i ] );
+ }
}
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c
index 3cd98c555..1de248633 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c
@@ -1310,10 +1310,3 @@ int r200SanityCmdBuffer( r200ContextPtr rmesa,
return 0;
}
-
-
-/* Do the same job to a native command stream
- * -- pull apart packets after they are built.
- * -- understand SCALAR, VECTOR stores
- * -- understand INDIRECT registers & trace down into indirect buffers.
- */
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state.c b/xc/lib/GL/mesa/src/drv/r200/r200_state.c
index 3d476eb41..fba9e84f6 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_state.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_state.c
@@ -448,7 +448,7 @@ void r200RecalcScissorRects( r200ContextPtr rmesa )
MALLOC( rmesa->state.scissor.numAllocedClipRects *
sizeof(XF86DRIClipRectRec) );
- if (!rmesa->state.scissor.numAllocedClipRects) {
+ if ( rmesa->state.scissor.pClipRects == NULL ) {
rmesa->state.scissor.numAllocedClipRects = 0;
return;
}
@@ -570,7 +570,7 @@ static void r200FrontFace( GLcontext *ctx, GLenum mode )
*/
static void r200PointSize( GLcontext *ctx, GLfloat size )
{
- fprintf(stderr, "%s: %f\n", __FUNCTION__, size );
+ if (0) fprintf(stderr, "%s: %f\n", __FUNCTION__, size );
}
/* =============================================================
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c b/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c
index 8aac0e16e..a9b6a0063 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c
@@ -130,13 +130,6 @@ static GLboolean check_##NM( GLcontext *ctx, int idx ) \
}
-static GLboolean check_firsttime( GLcontext *ctx, int idx )
-{
- static int firsttime = 1;
- int i = firsttime;
- firsttime = 0;
- return i;
-}
CHECK( always, GL_TRUE )
CHECK( tex_any, ctx->Texture._EnabledUnits )
@@ -247,7 +240,7 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( vap, always, VAP_STATE_SIZE, "VAP/vap", 0 );
ALLOC_STATE( vte, always, VTE_STATE_SIZE, "VTE/vte", 0 );
ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 );
- ALLOC_STATE( cst, firsttime, CST_STATE_SIZE, "CST/constant", 0 );
+ ALLOC_STATE( cst, always, CST_STATE_SIZE, "CST/constant", 0 );
ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 );
ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 );
ALLOC_STATE( tf, tex_any, TF_STATE_SIZE, "TF/tfactor", 0 );
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tex.c b/xc/lib/GL/mesa/src/drv/r200/r200_tex.c
index 0f4d44fb1..de57da704 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_tex.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_tex.c
@@ -645,21 +645,6 @@ static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
face = 0;
}
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
assert( t ); /* this _should_ be true */
if ( t ) {
driSwapOutTextureObject( t );
@@ -774,6 +759,7 @@ r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
#endif
+
static void r200TexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c
index 4caaab3a9..1a220ac34 100644
--- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c
+++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c
@@ -570,6 +570,9 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
return GL_FALSE;
+
+ if (!_glapi_Context)
+ return GL_FALSE;
if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
@@ -1092,23 +1095,15 @@ void r200VtxfmtMakeCurrent( GLcontext *ctx )
r200ContextPtr rmesa = R200_CONTEXT( ctx );
#if defined(THREADS)
- static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */
- if (!ThreadSafe) {
- static unsigned long knownID;
- static GLboolean firstCall = GL_TRUE;
- if (firstCall) {
- knownID = _glthread_GetID();
- firstCall = GL_FALSE;
- }
- else if (knownID != _glthread_GetID()) {
- ThreadSafe = GL_TRUE;
-
- if (R200_DEBUG & (DEBUG_DRI|DEBUG_VFMT))
- fprintf(stderr, "**** Multithread situation!\n");
- }
- }
- if (ThreadSafe)
+ /* Insider knowledge: this value is zero when multithreading has
+ * been detected.
+ */
+ if (_glapi_Context == 0) {
+ if (R200_DEBUG & (DEBUG_DRI|DEBUG_VFMT))
+ fprintf(stderr, "**** Multithreading: disabling vtxfmt!\n");
+ TNL_CONTEXT(ctx)->Driver.NotifyBegin = 0;
return;
+ }
#endif
if (rmesa->vb.enabled) {
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
index 6fb746f0e..f22ff2d14 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
@@ -85,6 +85,25 @@ static void radeon_emit_state_list( radeonContextPtr rmesa,
struct radeon_state_atom *state, *tmp;
char *dest;
+ /* From Felix Kuhling: similar to some other lockups, glaxium will
+ * lock with what we believe to be a normal command stream, but
+ * sprinkling some magic waits arounds allows it to run
+ * uninterrupted. This has a slight effect on q3 framerates, but
+ * it might now be possible to remove the zbs hack, below.
+ *
+ * Felix reports that this can be narrowed down to just
+ * tcl,tex0,tex1 state, but that's pretty much every statechange,
+ * so let's just put the wait in always (unless Felix wants to
+ * narrow it down further...)
+ */
+ if (1) {
+ drmRadeonCmdHeader *cmd;
+ cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd),
+ __FUNCTION__ );
+ cmd->wait.cmd_type = RADEON_CMD_WAIT;
+ cmd->wait.flags = RADEON_WAIT_3D;
+ }
+
foreach_s( state, tmp, list ) {
if (state->check( rmesa->glCtx )) {
dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c
index 4f9feb2c9..d2f7af768 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c
@@ -70,7 +70,7 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
radeonScreenPtr screen;
RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
- if ( ! driCheckDriDdxDrmVersions( sPriv, "Radeon", 4, 0, 4, 0, 1, 0 ) )
+ if ( ! driCheckDriDdxDrmVersions( sPriv, "Radeon", 4, 0, 4, 0, 1, 3 ) )
return NULL;
/* Allocate the private area */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
index b2b84932c..2172fb3fb 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
@@ -444,7 +444,7 @@ void radeonRecalcScissorRects( radeonContextPtr rmesa )
MALLOC( rmesa->state.scissor.numAllocedClipRects *
sizeof(XF86DRIClipRectRec) );
- if (!rmesa->state.scissor.numAllocedClipRects) {
+ if ( rmesa->state.scissor.pClipRects == NULL ) {
rmesa->state.scissor.numAllocedClipRects = 0;
return;
}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
index 432e405fc..f49306ed2 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
@@ -549,6 +549,9 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
return GL_FALSE;
+ if (!_glapi_Context)
+ return GL_FALSE;
+
if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
@@ -1068,25 +1071,18 @@ void radeonVtxfmtMakeCurrent( GLcontext *ctx )
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
#if defined(THREADS)
- static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */
- if (!ThreadSafe) {
- static unsigned long knownID;
- static GLboolean firstCall = GL_TRUE;
- if (firstCall) {
- knownID = _glthread_GetID();
- firstCall = GL_FALSE;
- }
- else if (knownID != _glthread_GetID()) {
- ThreadSafe = GL_TRUE;
-
- if (RADEON_DEBUG & (DEBUG_DRI|DEBUG_VFMT))
- fprintf(stderr, "**** Multithread situation!\n");
- }
- }
- if (ThreadSafe)
+ /* Insider knowledge: this value is zero when multithreading has
+ * been detected.
+ */
+ if (_glapi_Context == 0) {
+ if (RADEON_DEBUG & (DEBUG_DRI|DEBUG_VFMT))
+ fprintf(stderr, "**** Multithreading: disabling vtxfmt!\n");
+ TNL_CONTEXT(ctx)->Driver.NotifyBegin = 0;
return;
+ }
#endif
+
if (rmesa->vb.enabled) {
TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin;
}
diff --git a/xc/programs/Xserver/GL/dri/xf86dri.c b/xc/programs/Xserver/GL/dri/xf86dri.c
index 6109b24ae..c7cf37344 100644
--- a/xc/programs/Xserver/GL/dri/xf86dri.c
+++ b/xc/programs/Xserver/GL/dri/xf86dri.c
@@ -155,6 +155,11 @@ ProcXF86DRIQueryDirectRenderingCapable(
REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -184,6 +189,10 @@ ProcXF86DRIOpenConnection(
REQUEST(xXF86DRIOpenConnectionReq);
REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
&hSAREA,
@@ -221,6 +230,10 @@ ProcXF86DRIAuthConnection(
REQUEST(xXF86DRIAuthConnectionReq);
REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
rep.type = X_Reply;
rep.length = 0;
@@ -242,6 +255,10 @@ ProcXF86DRICloseConnection(
{
REQUEST(xXF86DRICloseConnectionReq);
REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
DRICloseConnection( screenInfo.screens[stuff->screen]);
@@ -258,6 +275,10 @@ ProcXF86DRIGetClientDriverName(
REQUEST(xXF86DRIGetClientDriverNameReq);
REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
DRIGetClientDriverName( screenInfo.screens[stuff->screen],
(int *)&rep.ddxDriverMajorVersion,
@@ -295,6 +316,11 @@ ProcXF86DRICreateContext(
REQUEST(xXF86DRICreateContextReq);
REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -329,6 +355,10 @@ ProcXF86DRIDestroyContext(
{
REQUEST(xXF86DRIDestroyContextReq);
REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
stuff->context)) {
@@ -348,6 +378,11 @@ ProcXF86DRICreateDrawable(
REQUEST(xXF86DRICreateDrawableReq);
REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -378,6 +413,10 @@ ProcXF86DRIDestroyDrawable(
REQUEST(xXF86DRIDestroyDrawableReq);
DrawablePtr pDrawable;
REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
if (!(pDrawable = (DrawablePtr)SecurityLookupDrawable(
(Drawable)stuff->drawable,
@@ -409,6 +448,11 @@ ProcXF86DRIGetDrawableInfo(
REQUEST(xXF86DRIGetDrawableInfoReq);
REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -483,6 +527,11 @@ ProcXF86DRIGetDeviceInfo(
REQUEST(xXF86DRIGetDeviceInfoReq);
REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -528,6 +577,11 @@ ProcXF86DRIOpenFullScreen (
DrawablePtr pDrawable;
REQUEST_SIZE_MATCH(xXF86DRIOpenFullScreenReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -554,6 +608,11 @@ ProcXF86DRICloseFullScreen (
DrawablePtr pDrawable;
REQUEST_SIZE_MATCH(xXF86DRICloseFullScreenReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
diff --git a/xc/programs/Xserver/GL/glx/glxcmds.c b/xc/programs/Xserver/GL/glx/glxcmds.c
index 84cc06376..095791f25 100644
--- a/xc/programs/Xserver/GL/glx/glxcmds.c
+++ b/xc/programs/Xserver/GL/glx/glxcmds.c
@@ -761,7 +761,7 @@ int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
int i, p;
screen = req->screen;
- if (screen > screenInfo.numScreens) {
+ if (screen >= screenInfo.numScreens) {
/* The client library must send a valid screen number. */
client->errorValue = screen;
return BadValue;
@@ -1466,7 +1466,7 @@ int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
ClientPtr client = cl->client;
xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
xGLXQueryExtensionsStringReply reply;
- GLint screen;
+ GLuint screen;
size_t n, length;
const char *ptr;
char *buf;
@@ -1475,7 +1475,7 @@ int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
/*
** Check if screen exists.
*/
- if ((screen < 0) || (screen >= screenInfo.numScreens)) {
+ if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return BadValue;
}
@@ -1511,7 +1511,7 @@ int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
xGLXQueryServerStringReply reply;
int name;
- GLint screen;
+ GLuint screen;
size_t n, length;
const char *ptr;
char *buf;
@@ -1521,7 +1521,7 @@ int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
/*
** Check if screen exists.
*/
- if ((screen < 0) || (screen >= screenInfo.numScreens)) {
+ if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return BadValue;
}
diff --git a/xc/programs/Xserver/hw/kdrive/linux/agp.c b/xc/programs/Xserver/hw/kdrive/linux/agp.c
index ea34e7c40..3d65cc264 100644
--- a/xc/programs/Xserver/hw/kdrive/linux/agp.c
+++ b/xc/programs/Xserver/hw/kdrive/linux/agp.c
@@ -120,9 +120,16 @@ GARTInit()
KdReleaseGART(-1);
#if defined(linux)
- /* Should this look for version >= rather than version == ? */
- if (agpinf.version.major != AGPGART_MAJOR_VERSION &&
- agpinf.version.minor != AGPGART_MINOR_VERSION) {
+ /* Per Dave Jones, every effort will be made to keep the
+ * agpgart interface backwards compatible, so allow all
+ * future versions.
+ */
+ if (
+#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
+ agpinf.version.major < AGPGART_MAJOR_VERSION ||
+#endif
+ (agpinf.version.major == AGPGART_MAJOR_VERSION &&
+ agpinf.version.minor < AGPGART_MINOR_VERSION)) {
fprintf(stderr,
"Kernel agpgart driver version is not current"
" (%d.%d vs %d.%d)\n",
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
index 224bd7a2b..983d75ef9 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
@@ -509,7 +509,6 @@ typedef struct {
CARD32 aux_sc_cntl;
int irq;
- CARD32 gen_int_cntl;
#ifdef PER_CONTEXT_SAREA
int perctx_sarea_size;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c
index 9b5d3b505..d0b01db8e 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c
@@ -106,11 +106,43 @@ void
FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
int i = 0;
-#ifdef ACCEL_MMIO
+#ifdef ACCEL_CP
- unsigned char *RADEONMMIO = info->MMIO;
+ int ret;
+
+ /* Make sure the CP is idle first */
+
+ if (info->CPStarted) {
+ FLUSH_RING();
+
+ for (;;) {
+ do {
+ ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE);
+ if (ret && ret != -EBUSY) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "%s: CP idle %d\n", __FUNCTION__, ret);
+ }
+ } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));
+
+ if (ret == 0) return;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Idle timed out, resetting engine...\n");
+ RADEONEngineReset(pScrn);
+ RADEONEngineRestore(pScrn);
+
+ /* Always restart the engine when doing CP 2D acceleration */
+ RADEONCP_RESET(pScrn, info);
+ RADEONCP_START(pScrn, info);
+ }
+ }
+
+#endif
+
+ /* Wait for the engine to go idle */
RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n",
INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
@@ -139,40 +171,6 @@ FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
}
#endif
}
-
-#else /* ACCEL_CP */
-
- int ret;
-
- if (!info->CPStarted) {
- RADEONWaitForIdleMMIO(pScrn);
- return;
- }
-
- FLUSH_RING();
-
- for (;;) {
- do {
- ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE);
- if (ret && ret != -EBUSY) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "%s: CP idle %d\n", __FUNCTION__, ret);
- }
- } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));
-
- if (ret == 0) return;
-
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Idle timed out, resetting engine...\n");
- RADEONEngineReset(pScrn);
- RADEONEngineRestore(pScrn);
-
- /* Always restart the engine when doing CP 2D acceleration */
- RADEONCP_RESET(pScrn, info);
- RADEONCP_START(pScrn, info);
- }
-
-#endif
}
/* This callback is required for multiheader cards using XAA */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
index 26af984b6..02e2603cf 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
@@ -49,7 +49,7 @@
#include "xf86PciInfo.h"
-#include "shadow.h"
+#include "shadowfb.h"
/* GLX/DRI/DRM definitions */
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
@@ -80,7 +80,7 @@ static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
-static void RADEONDRIShadowUpdate(ScreenPtr pScreen, shadowBufPtr pBuf);
+static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
/* Initialize the visual configs that are supported by the hardware.
* These are combined with the visual configs that the indirect
@@ -708,7 +708,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
/* Workaround for some hardware bugs */
if (info->ChipFamily < CHIP_FAMILY_R200)
- OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0020);
+ OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);
/* Modify the mode if the default mode
* is not appropriate for this
@@ -1148,7 +1148,7 @@ static void RADEONDRIIrqInit(RADEONInfoPtr info, ScreenPtr pScreen)
info->irq = 0;
} else {
unsigned char *RADEONMMIO = info->MMIO;
- info->gen_int_cntl = INREG( RADEON_GEN_INT_CNTL );
+ info->ModeReg.gen_int_cntl = INREG( RADEON_GEN_INT_CNTL );
}
}
@@ -1556,10 +1556,9 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
pRADEONDRI->perctx_sarea_size = info->perctx_sarea_size;
#endif
- /* Have shadow run only while there is 3d active */
- if (info->allowPageFlip /* && info->drmMinor >= 3 */) {
- shadowSetup (pScreen);
- shadowAdd( pScreen, 0, RADEONDRIShadowUpdate, 0, 0, 0 );
+ /* Have shadowfb run only while there is 3d active. */
+ if (info->allowPageFlip /* && info->drmMinor >= 3 */) {
+ ShadowFBInit2( pScreen, NULL, RADEONDRIRefreshArea, FALSE );
} else {
info->allowPageFlip = 0;
}
@@ -1685,30 +1684,22 @@ static Bool RADEONDRICloseFullScreen(ScreenPtr pScreen)
*/
-/* Use the miext/shadow module to maintain a list of dirty rectangles.
+/* Use the shadowfb module to maintain a list of dirty rectangles.
* These are blitted to the back buffer to keep both buffers clean
* during page-flipping when the 3d application isn't fullscreen.
*
- * Unlike most use of the shadow code, both buffers are in video memory.
- *
- * An alternative to this would be to organize for all on-screen drawing
- * operations to be duplicated for the two buffers. That might be
- * faster, but seems like a lot more work...
+ * Unlike most use of the shadowfb code, both buffers are in video memory.
*/
/* This should be done *before* XAA syncs or fires its buffer.
* Otherwise will have to fire it again???
*/
-static void RADEONDRIShadowUpdate(ScreenPtr pScreen, shadowBufPtr pBuf)
+static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- RegionPtr damage = &pBuf->damage;
int i;
- int num = REGION_NUM_RECTS(damage);
- BoxPtr pbox = REGION_RECTS(damage);
- RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
/* Don't want to do this when no 3d is active and pages are
* right-way-round
@@ -1721,13 +1712,16 @@ static void RADEONDRIShadowUpdate(ScreenPtr pScreen, shadowBufPtr pBuf)
(CARD32)(-1), -1);
for (i = 0 ; i < num ; i++, pbox++) {
- (*info->accel->SubsequentScreenToScreenCopy)(pScrn,
- pbox->x1,
- pbox->y1,
- pbox->x1 + info->backX,
- pbox->y1 + info->backY,
- pbox->x2 - pbox->x1 + 1,
- pbox->y2 - pbox->y1 + 1);
+ int x1 = max(pbox->x1, 0), y1 = max(pbox->y1, 0);
+ int x2 = min(pbox->x2, pScrn->virtualX-1), y2 = min(pbox->y2, pScrn->virtualY-1);
+
+ if (x1 <= x2 && y1 <= y2) {
+ (*info->accel->SubsequentScreenToScreenCopy)(pScrn, x1, y1,
+ x1 + info->backX,
+ y1 + info->backY,
+ x2 - x1 + 1,
+ y2 - y1 + 1);
+ }
}
}
@@ -1757,6 +1751,10 @@ static void RADEONEnablePageFlip(ScreenPtr pScreen)
static void RADEONDisablePageFlip(ScreenPtr pScreen)
{
+ /* Tell the clients not to pageflip. How?
+ * -- Field in sarea, plus bumping the window counters.
+ * -- DRM needs to cope with Front-to-Back swapbuffers.
+ */
RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
pSAREAPriv->pfAllowPageFlip = 0;
@@ -1764,10 +1762,6 @@ static void RADEONDisablePageFlip(ScreenPtr pScreen)
static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen)
{
- /* Tell the clients not to pageflip. How?
- * -- Field in sarea, plus bumping the window counters.
- * -- DRM needs to cope with Front-to-Back swapbuffers.
- */
RADEONDisablePageFlip(pScreen);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
index f817e4a65..a423347bc 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
@@ -52,7 +52,7 @@
* This server does not yet support these XFree86 4.0 features:
* !!!! FIXME !!!!
* DDC1 & DDC2
- * shadowfb (Note: dri uses shadow for another purpose in radeon_dri.c)
+ * shadowfb (Note: dri uses shadowfb for another purpose in radeon_dri.c)
* overlay planes
*
* Modified by Marc Aurele La France (tsi@xfree86.org) for ATI driver merge.
@@ -319,8 +319,8 @@ static const char *driSymbols[] = {
NULL
};
-static const char *driShadowSymbols[] = {
- "shadowInit",
+static const char *driShadowFBSymbols[] = {
+ "ShadowFBInit2",
NULL
};
#endif
@@ -370,7 +370,7 @@ void RADEONLoaderRefSymLists(void)
int10Symbols,
ddcSymbols,
/* i2csymbols, */
- /* shadowSymbols, */
+ /* driShadowFBSymbols, */
NULL);
}
@@ -2979,14 +2979,14 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
OPTION_NO_BACKBUFFER,
FALSE);
- if (!xf86LoadSubModule(pScrn, "shadow")) {
+ if (info->noBackBuffer) {
+ info->allowPageFlip = 0;
+ } else if (!xf86LoadSubModule(pScrn, "shadowfb")) {
info->allowPageFlip = 0;
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Couldn't load shadowfb module: disabling page flipping\n");
- } else if (info->noBackBuffer) {
- info->allowPageFlip = 0;
} else {
- xf86LoaderReqSymLists(driShadowSymbols, NULL);
+ xf86LoaderReqSymLists(driShadowFBSymbols, NULL);
if ((info->allowPageFlip = xf86ReturnOptValBool(info->Options,
OPTION_PAGE_FLIP,
@@ -3944,6 +3944,31 @@ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
}
}
+/* Write miscellaneous registers which might have been destroyed by an fbdevHW
+ * call
+ */
+static void RADEONRestoreFBDevRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+#ifdef XF86DRI
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* Restore register for vertical blank interrupts */
+ if (info->irq) {
+ OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl);
+ }
+
+ /* Restore registers for page flipping */
+ if (info->allowPageFlip) {
+ OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
+ if (info->HasCRTC2) {
+ OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
+ }
+ }
+#endif
+}
+
/* Write CRTC registers */
static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore)
@@ -4369,6 +4394,28 @@ static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->surface_cntl = INREG(RADEON_SURFACE_CNTL);
}
+/* Read miscellaneous registers which might be destroyed by an fbdevHW call */
+static void RADEONSaveFBDevRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+#ifdef XF86DRI
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* Save register for vertical blank interrupts */
+ if (info->irq) {
+ save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
+ }
+
+ /* Save registers for page flipping */
+ if (info->allowPageFlip) {
+ save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
+ if (info->HasCRTC2) {
+ save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
+ }
+ }
+#endif
+}
+
/* Read CRTC registers */
static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
@@ -4646,7 +4693,6 @@ static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
save->cap0_trig_cntl = 0;
save->cap1_trig_cntl = 0;
save->bus_cntl = info->BusCntl;
- save->gen_int_cntl = info->gen_int_cntl;
/*
* If bursts are enabled, turn on discards
* Radeon doesn't have write bursts
@@ -4782,7 +4828,8 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
(pScrn->bitsPerPixel * 8));
save->crtc_pitch |= save->crtc_pitch << 16;
- save->surface_cntl = RADEON_SURF_TRANSLATION_DIS;
+ save->surface_cntl = 0;
+
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch (pScrn->bitsPerPixel) {
case 16:
@@ -5346,7 +5393,11 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
if (info->accelOn) info->accel->Sync(pScrn);
if (info->FBDev) {
+ RADEONSaveFBDevRegisters(pScrn, &info->ModeReg);
+
ret = fbdevHWSwitchMode(scrnIndex, mode, flags);
+
+ RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
} else {
info->IsSwitching = TRUE;
if (info->Clone && info->CloneModes) {
@@ -5520,6 +5571,8 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE;
info->PaletteSavedOnVT = FALSE;
info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
+
+ RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
} else
if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
@@ -5528,12 +5581,6 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
#ifdef XF86DRI
if (info->directRenderingEnabled) {
- if (info->irq) {
- /* Need to make sure interrupts are enabled */
- unsigned char *RADEONMMIO = info->MMIO;
- OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
- }
-
RADEONCP_START(pScrn, info);
DRIUnlock(pScrn->pScreen);
}
@@ -5567,6 +5614,9 @@ void RADEONLeaveVT(int scrnIndex, int flags)
if (info->FBDev) {
RADEONSavePalette(pScrn, save);
info->PaletteSavedOnVT = TRUE;
+
+ RADEONSaveFBDevRegisters(pScrn, &info->ModeReg);
+
fbdevHWLeaveVT(scrnIndex,flags);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
index 72e0570d7..fab03dde2 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
@@ -1166,6 +1166,10 @@
# define RADEON_TXFORMAT_WIDTH_SHIFT 8
# define RADEON_TXFORMAT_HEIGHT_MASK (15 << 12)
# define RADEON_TXFORMAT_HEIGHT_SHIFT 12
+# define RADEON_TXFORMAT_F5_WIDTH_MASK (15 << 16)
+# define RADEON_TXFORMAT_F5_WIDTH_SHIFT 16
+# define RADEON_TXFORMAT_F5_HEIGHT_MASK (15 << 20)
+# define RADEON_TXFORMAT_F5_HEIGHT_SHIFT 20
# define RADEON_TXFORMAT_ST_ROUTE_STQ0 (0 << 24)
# define RADEON_TXFORMAT_ST_ROUTE_MASK (3 << 24)
# define RADEON_TXFORMAT_ST_ROUTE_STQ1 (1 << 24)
@@ -1178,6 +1182,26 @@
# define RADEON_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29)
# define RADEON_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30)
# define RADEON_TXFORMAT_PERSPECTIVE_ENABLE (1 << 31)
+#define RADEON_PP_CUBIC_FACES_0 0x1d24
+#define RADEON_PP_CUBIC_FACES_1 0x1d28
+#define RADEON_PP_CUBIC_FACES_2 0x1d2c
+# define RADEON_FACE_WIDTH_1_SHIFT 0
+# define RADEON_FACE_HEIGHT_1_SHIFT 4
+# define RADEON_FACE_WIDTH_1_MASK 0xf << 0)
+# define RADEON_FACE_HEIGHT_1_MASK 0xf << 4)
+# define RADEON_FACE_WIDTH_2_SHIFT 8
+# define RADEON_FACE_HEIGHT_2_SHIFT 2
+# define RADEON_FACE_WIDTH_2_MASK 0xf << 8)
+# define RADEON_FACE_HEIGHT_2_MASK 0xf << 12)
+# define RADEON_FACE_WIDTH_3_SHIFT 6
+# define RADEON_FACE_HEIGHT_3_SHIFT 0
+# define RADEON_FACE_WIDTH_3_MASK 0xf << 16)
+# define RADEON_FACE_HEIGHT_3_MASK 0xf << 20)
+# define RADEON_FACE_WIDTH_4_SHIFT 4
+# define RADEON_FACE_HEIGHT_4_SHIFT 8
+# define RADEON_FACE_WIDTH_4_MASK 0xf << 24)
+# define RADEON_FACE_HEIGHT_4_MASK 0xf << 28)
+
#define RADEON_PP_TXOFFSET_0 0x1c5c
#define RADEON_PP_TXOFFSET_1 0x1c74
#define RADEON_PP_TXOFFSET_2 0x1c8c
@@ -1192,6 +1216,35 @@
# define RADEON_TXO_MICRO_TILE_OPT (2 << 3)
# define RADEON_TXO_OFFSET_MASK 0xffffffe0
# define RADEON_TXO_OFFSET_SHIFT 5
+
+#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */
+#define RADEON_PP_CUBIC_OFFSET_T0_1 0x1dd4
+#define RADEON_PP_CUBIC_OFFSET_T0_2 0x1dd8
+#define RADEON_PP_CUBIC_OFFSET_T0_3 0x1ddc
+#define RADEON_PP_CUBIC_OFFSET_T0_4 0x1de0
+#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00
+#define RADEON_PP_CUBIC_OFFSET_T1_1 0x1e04
+#define RADEON_PP_CUBIC_OFFSET_T1_2 0x1e08
+#define RADEON_PP_CUBIC_OFFSET_T1_3 0x1e0c
+#define RADEON_PP_CUBIC_OFFSET_T1_4 0x1e10
+#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14
+#define RADEON_PP_CUBIC_OFFSET_T2_1 0x1e18
+#define RADEON_PP_CUBIC_OFFSET_T2_2 0x1e1c
+#define RADEON_PP_CUBIC_OFFSET_T2_3 0x1e20
+#define RADEON_PP_CUBIC_OFFSET_T2_4 0x1e24
+
+#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
+#define RADEON_PP_TEX_SIZE_1 0x1d0c
+#define RADEON_PP_TEX_SIZE_2 0x1d14
+# define RADEON_TEX_USIZE_MASK (0x7ff << 0)
+# define RADEON_TEX_USIZE_SHIFT 0
+# define RADEON_TEX_VSIZE_MASK (0x7ff << 16)
+# define RADEON_TEX_VSIZE_SHIFT 16
+# define RADEON_SIGNED_RGB_MASK (1 << 30)
+# define RADEON_SIGNED_RGB_SHIFT 30
+# define RADEON_SIGNED_ALPHA_MASK (1 << 31)
+# define RADEON_SIGNED_ALPHA_SHIFT 31
+
#define RADEON_PP_TXCBLEND_0 0x1c60
#define RADEON_PP_TXCBLEND_1 0x1c78
#define RADEON_PP_TXCBLEND_2 0x1c90
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h
index 688769409..d1d669437 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h
@@ -35,8 +35,31 @@
#ifndef _DRM_H_
#define _DRM_H_
+#if defined(__linux__)
+#include <linux/config.h>
+#include <asm/ioctl.h> /* For _IO* macros */
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
+#define DRM_IOC_VOID _IOC_NONE
+#define DRM_IOC_READ _IOC_READ
+#define DRM_IOC_WRITE _IOC_WRITE
+#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) && defined(XFree86Server)
+/* Prevent name collision when including sys/ioccom.h */
+#undef ioctl
#include <sys/ioccom.h>
-#define DRM_IOCTL_NR(n) ((n) & 0xff)
+#define ioctl(a,b,c) xf86ioctl(a,b,c)
+#else
+#include <sys/ioccom.h>
+#endif /* __FreeBSD__ && xf86ioctl */
+#define DRM_IOCTL_NR(n) ((n) & 0xff)
+#define DRM_IOC_VOID IOC_VOID
+#define DRM_IOC_READ IOC_OUT
+#define DRM_IOC_WRITE IOC_IN
+#define DRM_IOC_READWRITE IOC_INOUT
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+#endif
#define XFREE86_VERSION(major,minor,patch,snap) \
((major << 16) | (minor << 8) | patch)
@@ -62,7 +85,7 @@
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
-#define DRM_RAM_PERCENT 50 /* How much system ram can we lock? */
+#define DRM_RAM_PERCENT 10 /* How much system ram can we lock? */
#define _DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */
#define _DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */
@@ -78,6 +101,10 @@ typedef unsigned int drm_magic_t;
/* Warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well */
+/* KW: Actually it's illegal to change either for
+ * backwards-compatibility reasons.
+ */
+
typedef struct drm_clip_rect {
unsigned short x1;
unsigned short y1;
@@ -93,14 +120,6 @@ typedef struct drm_tex_region {
unsigned int age;
} drm_tex_region_t;
-/* Seperate include files for the driver specific structures */
-#include "mga_drm.h"
-#include "i810_drm.h"
-#include "i830_drm.h"
-#include "r128_drm.h"
-#include "radeon_drm.h"
-#include "sis_drm.h"
-
typedef struct drm_version {
int version_major; /* Major version */
int version_minor; /* Minor version */
@@ -326,6 +345,32 @@ typedef struct drm_irq_busid {
int funcnum;
} drm_irq_busid_t;
+typedef enum {
+ _DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
+ _DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */
+ _DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
+} drm_vblank_seq_type_t;
+
+#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
+
+struct drm_wait_vblank_request {
+ drm_vblank_seq_type_t type;
+ unsigned int sequence;
+ unsigned long signal;
+};
+
+struct drm_wait_vblank_reply {
+ drm_vblank_seq_type_t type;
+ unsigned int sequence;
+ long tval_sec;
+ long tval_usec;
+};
+
+typedef union drm_wait_vblank {
+ struct drm_wait_vblank_request request;
+ struct drm_wait_vblank_reply reply;
+} drm_wait_vblank_t;
+
typedef struct drm_agp_mode {
unsigned long mode;
} drm_agp_mode_t;
@@ -365,10 +410,9 @@ typedef struct drm_scatter_gather {
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
-#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
-#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
-#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
-
+#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
@@ -421,81 +465,10 @@ typedef struct drm_scatter_gather {
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
-/* MGA specific ioctls */
-#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
-#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
-#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42)
-#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43)
-#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t)
-#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t)
-#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
-#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
-#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_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_IOWR(0x45, drm_i810_dma_t)
-#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
-#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
-#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
-
-/* Rage 128 specific ioctls */
-#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
-#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
-#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
-#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
-#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
-#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
-#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
-#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
-#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
-#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
-#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
-#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
-#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
-
-/* Radeon specific ioctls */
-#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
-#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
-#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
-#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
-#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
-#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
-#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
-#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
-#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
-#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
-#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
-#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
-#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
-
-/* SiS specific ioctls */
-
-#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
-#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
-#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
-#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
-#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
-#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
-#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
-#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
-
-/* I830 specific ioctls */
-#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t)
-#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t)
-#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t)
-#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43)
-#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44)
-#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t)
-#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
-#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
-#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
+#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
+
+/* Device specfic ioctls should only be in their respective headers
+ * The device specific ioctl range is 0x40 to 0x79. */
+#define DRM_COMMAND_BASE 0x40
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h
index b7b21da4e..541bc2ebe 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h
@@ -392,6 +392,14 @@ typedef struct drm_map_list_entry {
drm_map_t *map;
} drm_map_list_entry_t;
+TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
+typedef struct drm_vbl_sig {
+ TAILQ_ENTRY(drm_vbl_sig) link;
+ unsigned int sequence;
+ int signo;
+ int pid;
+} drm_vbl_sig_t;
+
struct drm_device {
#ifdef __NetBSD__
struct device device; /* NetBSD's softc is an extension of struct device */
@@ -469,6 +477,8 @@ struct drm_device {
#if __HAVE_VBL_IRQ
wait_queue_head_t vbl_queue; /* vbl wait channel */
atomic_t vbl_received;
+ struct drm_vbl_sig_list vbl_sig_list;
+ DRM_SPINTYPE vbl_lock;
#endif
cycles_t ctx_start;
cycles_t lck_start;
@@ -613,6 +623,7 @@ extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
#endif /* __HAVE_DMA */
#if __HAVE_VBL_IRQ
extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
+extern void DRM(vbl_send_signals)( drm_device_t *dev );
#endif
#if __REALLY_HAVE_AGP
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h
index 5632b5a2b..69c66c9a9 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h
@@ -524,6 +524,11 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev);
#endif
+#if __HAVE_VBL_IRQ
+ DRM_SPININIT( dev->vbl_lock, "vblsig" );
+ TAILQ_INIT( &dev->vbl_sig_list );
+#endif
+
/* Before installing handler */
DRM(driver_irq_preinstall)( dev );
@@ -612,21 +617,67 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
sizeof(vblwait) );
- if ( vblwait.type == _DRM_VBLANK_RELATIVE ) {
- vblwait.sequence += atomic_read( &dev->vbl_received );
+ if (vblwait.request.type & _DRM_VBLANK_RELATIVE) {
+ vblwait.request.sequence += atomic_read(&dev->vbl_received);
}
- ret = DRM(vblank_wait)( dev, &vblwait.sequence );
-
- microtime( &now );
- vblwait.tval_sec = now.tv_sec;
- vblwait.tval_usec = now.tv_usec;
+ flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+ if (flags & _DRM_VBLANK_SIGNAL) {
+ drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t));
+ if (vbl_sig == NULL)
+ return ENOMEM;
+ bzero(vbl_sig, sizeof(*vbl_sig));
+
+ vbl_sig->sequence = vblwait.request.sequence;
+ vbl_sig->signo = vblwait.request.signal;
+ vbl_sig->pid = DRM_CURRENTPID;
+
+ vblwait.reply.sequence = atomic_read(&dev->vbl_received);
+
+ DRM_SPINLOCK(&dev->vbl_lock);
+ TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+ ret = 0;
+ } else {
+ ret = DRM(vblank_wait)(dev, &vblwait.request.sequence);
+
+ microtime(&now);
+ vblwait.reply.tval_sec = now.tv_sec;
+ vblwait.reply.tval_usec = now.tv_usec;
+ }
DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
sizeof(vblwait) );
return ret;
}
+
+void DRM(vbl_send_signals)( drm_device_t *dev )
+{
+ drm_vbl_sig_t *vbl_sig;
+ unsigned int vbl_seq = atomic_read( &dev->vbl_received );
+ struct proc *p;
+
+ DRM_SPINLOCK(&dev->vbl_lock);
+
+ vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list);
+ while (vbl_sig != NULL) {
+ drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link);
+
+ if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
+ p = pfind(vbl_sig->pid);
+ if (p != NULL)
+ psignal(p, vbl_sig->signo);
+
+ TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
+ DRM_FREE(vbl_sig);
+ }
+ vbl_sig = next;
+ }
+
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+}
+
#endif /* __HAVE_VBL_IRQ */
#else
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 d3c9f1580..d1d669437 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
@@ -348,7 +348,7 @@ typedef struct drm_irq_busid {
typedef enum {
_DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */
- _DRM_VBLANK_SIGNAL = 0x80000000 /* Send signal instead of blocking */
+ _DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
} drm_vblank_seq_type_t;
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
index 3f51b9b00..010450370 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
@@ -488,7 +488,6 @@ typedef struct drm_agp_mem {
typedef struct drm_agp_head {
agp_kern_info agp_info;
- const char *chipset;
drm_agp_mem_t *memory;
unsigned long mode;
int enabled;
@@ -593,6 +592,7 @@ typedef struct drm_device {
atomic_t vbl_received;
spinlock_t vbl_lock;
drm_vbl_sig_t vbl_sigs;
+ unsigned int vbl_pending;
#endif
cycles_t ctx_start;
cycles_t lck_start;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
index fc0b29aab..6d6b5911f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
@@ -260,60 +260,6 @@ drm_agp_head_t *DRM(agp_init)(void)
return NULL;
}
head->memory = NULL;
- switch (head->agp_info.chipset) {
- case INTEL_GENERIC: head->chipset = "Intel"; break;
- case INTEL_LX: head->chipset = "Intel 440LX"; break;
- case INTEL_BX: head->chipset = "Intel 440BX"; break;
- case INTEL_GX: head->chipset = "Intel 440GX"; break;
- case INTEL_I810: head->chipset = "Intel i810"; break;
-
- case INTEL_I815: head->chipset = "Intel i815"; break;
-#if LINUX_VERSION_CODE >= 0x020415
- case INTEL_I820: head->chipset = "Intel i820"; break;
-#endif
- case INTEL_I840: head->chipset = "Intel i840"; break;
-#if LINUX_VERSION_CODE >= 0x020415
- case INTEL_I845: head->chipset = "Intel i845"; break;
-#endif
- case INTEL_I850: head->chipset = "Intel i850"; break;
-
- case VIA_GENERIC: head->chipset = "VIA"; break;
- case VIA_VP3: head->chipset = "VIA VP3"; break;
- case VIA_MVP3: head->chipset = "VIA MVP3"; break;
- case VIA_MVP4: head->chipset = "VIA MVP4"; break;
- case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133";
- break;
- case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133";
- break;
-
- case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro";
- break;
- case SIS_GENERIC: head->chipset = "SiS"; break;
- case AMD_GENERIC: head->chipset = "AMD"; break;
- case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
- case ALI_GENERIC: head->chipset = "ALi"; break;
- case ALI_M1541: head->chipset = "ALi M1541"; break;
-
-#if LINUX_VERSION_CODE >= 0x020402
- case ALI_M1621: head->chipset = "ALi M1621"; break;
- case ALI_M1631: head->chipset = "ALi M1631"; break;
- case ALI_M1632: head->chipset = "ALi M1632"; break;
- case ALI_M1641: head->chipset = "ALi M1641"; break;
- case ALI_M1647: head->chipset = "ALi M1647"; break;
- case ALI_M1651: head->chipset = "ALi M1651"; break;
-#endif
-
-#if LINUX_VERSION_CODE >= 0x020406
- case SVWRKS_HE: head->chipset = "Serverworks HE";
- break;
- case SVWRKS_LE: head->chipset = "Serverworks LE";
- break;
- case SVWRKS_GENERIC: head->chipset = "Serverworks Generic";
- break;
-#endif
-
- default: head->chipset = "Unknown"; break;
- }
#if LINUX_VERSION_CODE <= 0x020408
head->cant_use_aperture = 0;
head->page_mask = ~(0xfff);
@@ -321,13 +267,12 @@ drm_agp_head_t *DRM(agp_init)(void)
head->cant_use_aperture = head->agp_info.cant_use_aperture;
head->page_mask = head->agp_info.page_mask;
#endif
-
- DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
- head->agp_info.version.major,
- head->agp_info.version.minor,
- head->chipset,
- head->agp_info.aper_base,
- head->agp_info.aper_size);
+
+ DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n",
+ head->agp_info.version.major,
+ head->agp_info.version.minor,
+ head->agp_info.aper_base,
+ head->agp_info.aper_size);
}
return head;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h
index 46393a5db..33af34be2 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h
@@ -544,6 +544,8 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
spin_lock_init( &dev->vbl_lock );
INIT_LIST_HEAD( &dev->vbl_sigs.head );
+
+ dev->vbl_pending = 0;
#endif
/* Before installing handler */
@@ -636,10 +638,38 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
if ( flags & _DRM_VBLANK_SIGNAL ) {
unsigned long irqflags;
- drm_vbl_sig_t *vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) );
+ drm_vbl_sig_t *vbl_sig;
+
+ vblwait.reply.sequence = atomic_read( &dev->vbl_received );
+
+ spin_lock_irqsave( &dev->vbl_lock, irqflags );
+
+ /* Check if this task has already scheduled the same signal
+ * for the same vblank sequence number; nothing to be done in
+ * that case
+ */
+ list_for_each( ( (struct list_head *) vbl_sig ), &dev->vbl_sigs.head ) {
+ if (vbl_sig->sequence == vblwait.request.sequence
+ && vbl_sig->info.si_signo == vblwait.request.signal
+ && vbl_sig->task == current)
+ {
+ spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+ goto done;
+ }
+ }
+
+ if ( dev->vbl_pending >= 100 ) {
+ spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+ return -EBUSY;
+ }
+
+ dev->vbl_pending++;
- if ( !vbl_sig )
+ spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+
+ if ( !( vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) ) ) ) {
return -ENOMEM;
+ }
memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
@@ -647,9 +677,6 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
vbl_sig->info.si_signo = vblwait.request.signal;
vbl_sig->task = current;
- vblwait.reply.sequence = atomic_read( &dev->vbl_received );
-
- /* Hook signal entry into list */
spin_lock_irqsave( &dev->vbl_lock, irqflags );
list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
@@ -663,6 +690,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
vblwait.reply.tval_usec = now.tv_usec;
}
+done:
DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
sizeof(vblwait) );
@@ -671,25 +699,23 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
void DRM(vbl_send_signals)( drm_device_t *dev )
{
- struct list_head *entry, *tmp;
+ struct list_head *tmp;
drm_vbl_sig_t *vbl_sig;
unsigned int vbl_seq = atomic_read( &dev->vbl_received );
unsigned long flags;
spin_lock_irqsave( &dev->vbl_lock, flags );
- list_for_each_safe( entry, tmp, &dev->vbl_sigs.head ) {
-
- vbl_sig = (drm_vbl_sig_t *) entry;
-
+ list_for_each_safe( ( (struct list_head *) vbl_sig ), tmp, &dev->vbl_sigs.head ) {
if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
-
- vbl_sig->info.si_code = atomic_read( &dev->vbl_received );
+ vbl_sig->info.si_code = vbl_seq;
send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
- list_del( entry );
+ list_del( (struct list_head *) vbl_sig );
+
+ DRM_FREE( vbl_sig );
- DRM_FREE( entry );
+ dev->vbl_pending--;
}
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h
index 24e8556fc..d29db7b7b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h
@@ -449,7 +449,8 @@ static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
pgd = pgd_offset(vma->vm_mm, i);
pmd = pmd_offset(pgd, i);
- pte = pte_offset(pmd, i);
+ preempt_disable();
+ pte = pte_offset_map(pmd, i);
if (pte_present(*pte)) {
address = __pa(pte_page(*pte))
+ (i & (PAGE_SIZE-1));
@@ -465,6 +466,8 @@ static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
} else {
DRM_PROC_PRINT(" 0x%08lx\n", i);
}
+ pte_unmap(pte);
+ preempt_enable();
}
#endif
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
index 13f5f64fb..ffb7c7086 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
@@ -38,6 +38,7 @@
#include "i810_drv.h"
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
+#include <linux/pagemap.h>
#ifdef DO_MUNMAP_4_ARGS
#define DO_MUNMAP(m, a, l) do_munmap(m, a, l, 1)
@@ -1184,7 +1185,8 @@ int i810_ov0_info(struct inode *inode, struct file *filp,
data.offset = dev_priv->overlay_offset;
data.physical = dev_priv->overlay_physical;
- copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data));
+ if (copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data)))
+ return -EFAULT;
return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_ds.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_ds.c
index 95880a482..f55cf6ab4 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_ds.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_ds.c
@@ -50,15 +50,16 @@ set_t *setInit(void)
set_t *set;
set = (set_t *)MALLOC(sizeof(set_t));
- for(i = 0; i < SET_SIZE; i++){
- set->list[i].free_next = i+1;
- set->list[i].alloc_next = -1;
- }
- set->list[SET_SIZE-1].free_next = -1;
- set->free = 0;
- set->alloc = -1;
- set->trace = -1;
-
+ if (set) {
+ for(i = 0; i < SET_SIZE; i++){
+ set->list[i].free_next = i+1;
+ set->list[i].alloc_next = -1;
+ }
+ set->list[SET_SIZE-1].free_next = -1;
+ set->free = 0;
+ set->alloc = -1;
+ set->trace = -1;
+ }
return set;
}
@@ -172,7 +173,8 @@ static void *calloc(size_t nmemb, size_t size)
{
void *addr;
addr = kmalloc(nmemb*size, GFP_KERNEL);
- memset(addr, 0, nmemb*size);
+ if (addr)
+ memset(addr, 0, nmemb*size);
return addr;
}
#define free(n) kfree(n)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c
index 5de1089af..fb6ec15df 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c
@@ -89,9 +89,16 @@ GARTInit(int screenNum)
xf86ReleaseGART(-1);
#if defined(linux)
- /* Should this look for version >= rather than version == ? */
- if (agpinf.version.major != AGPGART_MAJOR_VERSION &&
- agpinf.version.minor != AGPGART_MINOR_VERSION) {
+ /* Per Dave Jones, every effort will be made to keep the
+ * agpgart interface backwards compatible, so allow all
+ * future versions.
+ */
+ if (
+#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
+ agpinf.version.major < AGPGART_MAJOR_VERSION ||
+#endif
+ (agpinf.version.major == AGPGART_MAJOR_VERSION &&
+ agpinf.version.minor < AGPGART_MINOR_VERSION)) {
xf86DrvMsg(screenNum, X_ERROR,
"GARTInit: Kernel agpgart driver version is not current"
" (%d.%d vs %d.%d)\n",
@@ -262,6 +269,10 @@ xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
}
pageOffset = offset / AGP_PAGE_SIZE;
+ xf86DrvMsgVerb(screenNum, X_INFO, 3,
+ "xf86BindGARTMemory: bind key %d at 0x%08x "
+ "(pgoffset %d)\n", key, offset, pageOffset);
+
bind.pg_start = pageOffset;
bind.key = key;
@@ -302,6 +313,9 @@ xf86UnbindGARTMemory(int screenNum, int key)
return FALSE;
}
+ xf86DrvMsgVerb(screenNum, X_INFO, 3,
+ "xf86UnbindGARTMemory: unbind key %d\n", key);
+
return TRUE;
}
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 d3c9f1580..d1d669437 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
@@ -348,7 +348,7 @@ typedef struct drm_irq_busid {
typedef enum {
_DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */
- _DRM_VBLANK_SIGNAL = 0x80000000 /* Send signal instead of blocking */
+ _DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
} drm_vblank_seq_type_t;
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h
index fe71687a1..2b5131a9f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h
@@ -51,7 +51,7 @@
#define DRIVER_DATE "20020828"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 7
+#define DRIVER_MINOR 8
#define DRIVER_PATCHLEVEL 0
/* Interface history:
@@ -77,6 +77,7 @@
* and R200_PP_CUBIC_OFFSET_F1_[0..5].
* Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
+ * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
@@ -105,11 +106,6 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
-#define USE_IRQS 1
-#if USE_IRQS
-#define __HAVE_DMA_IRQ 1
-#define __HAVE_VBL_IRQ 1
-#define __HAVE_SHARED_IRQ 1
/* When a client dies:
* - Check for and clean up flipped page state
@@ -117,35 +113,35 @@
*
* DRM infrastructure takes care of reclaiming dma buffers.
*/
-#define DRIVER_PRERELEASE() do { \
+#define DRIVER_PRERELEASE() \
+do { \
if ( dev->dev_private ) { \
drm_radeon_private_t *dev_priv = dev->dev_private; \
if ( dev_priv->page_flipping ) { \
radeon_do_cleanup_pageflip( dev ); \
} \
radeon_mem_release( dev_priv->agp_heap ); \
+ radeon_mem_release( dev_priv->fb_heap ); \
} \
} while (0)
-/* On unloading the module:
- * - Free memory heap structure
- * - Remove mappings made at startup and free dev_private.
+/* When the last client dies, shut down the CP and free dev->dev_priv.
*/
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) { \
- drm_radeon_private_t *dev_priv = dev->dev_private; \
- radeon_mem_takedown( &(dev_priv->agp_heap) ); \
- radeon_do_cleanup_cp( dev ); \
- } \
+#define __HAVE_RELEASE 1
+#define DRIVER_RELEASE() \
+do { \
+ if ( dev->open_count == 1) \
+ radeon_do_release( dev ); \
} while (0)
-#else
-#define __HAVE_DMA_IRQ 0
-#endif
+
/* DMA customization:
*/
#define __HAVE_DMA 1
+#define __HAVE_DMA_IRQ 1
+#define __HAVE_VBL_IRQ 1
+#define __HAVE_SHARED_IRQ 1
/* Buffer customization:
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_cp.c
index 7c869c029..6994fe9eb 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_cp.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_cp.c
@@ -1354,6 +1354,9 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) );
+ if (!dev_priv->cp_running)
+ return 0;
+
/* Flush any pending CP commands. This ensures any outstanding
* commands are exectuted by the engine before we turn it off.
*/
@@ -1381,6 +1384,39 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
return 0;
}
+
+void radeon_do_release( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ if (dev_priv) {
+ if (dev_priv->cp_running) {
+ /* Stop the cp */
+ while ((ret = radeon_do_cp_idle( dev_priv )) != 0) {
+ DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+#ifdef __linux__
+ schedule();
+#else
+ tsleep(&ret, PZERO, "rdnrel", 1);
+#endif
+ }
+ radeon_do_cp_stop( dev_priv );
+ radeon_do_engine_reset( dev );
+ }
+
+ /* Disable *all* interrupts */
+ RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+
+ /* Free memory heap structures */
+ radeon_mem_takedown( &(dev_priv->agp_heap) );
+ radeon_mem_takedown( &(dev_priv->fb_heap) );
+
+ /* deallocate kernel resources */
+ radeon_do_cleanup_cp( dev );
+ }
+}
+
/* Just reset the CP ring. Called as part of an X Server engine reset.
*/
int radeon_cp_reset( DRM_IOCTL_ARGS )
@@ -1412,9 +1448,6 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
-/* if (dev->irq) */
-/* radeon_emit_and_wait_irq( dev ); */
-
return radeon_do_cp_idle( dev_priv );
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h
index 65f3c9265..22c5d04fa 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h
@@ -193,6 +193,7 @@ extern int radeon_emit_and_wait_irq(drm_device_t *dev);
extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
extern int radeon_emit_irq(drm_device_t *dev);
+extern void radeon_do_release(drm_device_t *dev);
/* Flags for stats.boxes
*/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_mem.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_mem.c
new file mode 100644
index 000000000..7ca10753a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_mem.c
@@ -0,0 +1,324 @@
+/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "radeon.h"
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+/* Very simple allocator for agp memory, working on a static range
+ * already mapped into each client's address space.
+ */
+
+static struct mem_block *split_block(struct mem_block *p, int start, int size,
+ int pid )
+{
+ /* Maybe cut off the start of an existing block */
+ if (start > p->start) {
+ struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+ if (!newblock)
+ goto out;
+ newblock->start = start;
+ newblock->size = p->size - (start - p->start);
+ newblock->pid = 0;
+ newblock->next = p->next;
+ newblock->prev = p;
+ p->next->prev = newblock;
+ p->next = newblock;
+ p->size -= newblock->size;
+ p = newblock;
+ }
+
+ /* Maybe cut off the end of an existing block */
+ if (size < p->size) {
+ struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+ if (!newblock)
+ goto out;
+ newblock->start = start + size;
+ newblock->size = p->size - size;
+ newblock->pid = 0;
+ newblock->next = p->next;
+ newblock->prev = p;
+ p->next->prev = newblock;
+ p->next = newblock;
+ p->size = size;
+ }
+
+ out:
+ /* Our block is in the middle */
+ p->pid = pid;
+ return p;
+}
+
+static struct mem_block *alloc_block( struct mem_block *heap, int size,
+ int align2, int pid )
+{
+ struct mem_block *p;
+ int mask = (1 << align2)-1;
+
+ for (p = heap->next ; p != heap ; p = p->next) {
+ int start = (p->start + mask) & ~mask;
+ if (p->pid == 0 && start + size <= p->start + p->size)
+ return split_block( p, start, size, pid );
+ }
+
+ return NULL;
+}
+
+static struct mem_block *find_block( struct mem_block *heap, int start )
+{
+ struct mem_block *p;
+
+ for (p = heap->next ; p != heap ; p = p->next)
+ if (p->start == start)
+ return p;
+
+ return NULL;
+}
+
+
+static void free_block( struct mem_block *p )
+{
+ p->pid = 0;
+
+ /* Assumes a single contiguous range. Needs a special pid in
+ * 'heap' to stop it being subsumed.
+ */
+ if (p->next->pid == 0) {
+ struct mem_block *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ p->next->prev = p;
+ DRM_FREE(q);
+ }
+
+ if (p->prev->pid == 0) {
+ struct mem_block *q = p->prev;
+ q->size += p->size;
+ q->next = p->next;
+ q->next->prev = q;
+ DRM_FREE(p);
+ }
+}
+
+/* Initialize. How to check for an uninitialized heap?
+ */
+static int init_heap(struct mem_block **heap, int start, int size)
+{
+ struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
+
+ if (!blocks)
+ return -ENOMEM;
+
+ *heap = DRM_MALLOC(sizeof(**heap));
+ if (!*heap) {
+ DRM_FREE( blocks );
+ return -ENOMEM;
+ }
+
+ blocks->start = start;
+ blocks->size = size;
+ blocks->pid = 0;
+ blocks->next = blocks->prev = *heap;
+
+ memset( *heap, 0, sizeof(**heap) );
+ (*heap)->pid = -1;
+ (*heap)->next = (*heap)->prev = blocks;
+ return 0;
+}
+
+
+/* Free all blocks associated with the releasing pid.
+ */
+void radeon_mem_release( struct mem_block *heap )
+{
+ int pid = DRM_CURRENTPID;
+ struct mem_block *p;
+
+ if (!heap || !heap->next)
+ return;
+
+ for (p = heap->next ; p != heap ; p = p->next) {
+ if (p->pid == pid)
+ p->pid = 0;
+ }
+
+ /* Assumes a single contiguous range. Needs a special pid in
+ * 'heap' to stop it being subsumed.
+ */
+ for (p = heap->next ; p != heap ; p = p->next) {
+ while (p->pid == 0 && p->next->pid == 0) {
+ struct mem_block *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ p->next->prev = p;
+ DRM_FREE(q);
+ }
+ }
+}
+
+/* Shutdown.
+ */
+void radeon_mem_takedown( struct mem_block **heap )
+{
+ struct mem_block *p;
+
+ if (!*heap)
+ return;
+
+ for (p = (*heap)->next ; p != *heap ; ) {
+ struct mem_block *q = p;
+ p = p->next;
+ DRM_FREE(q);
+ }
+
+ DRM_FREE( *heap );
+ *heap = 0;
+}
+
+
+
+/* IOCTL HANDLERS */
+
+static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
+ int region )
+{
+ switch( region ) {
+ case RADEON_MEM_REGION_AGP:
+ return &dev_priv->agp_heap;
+ case RADEON_MEM_REGION_FB:
+ return &dev_priv->fb_heap;
+ default:
+ return 0;
+ }
+}
+
+int radeon_mem_alloc( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_mem_alloc_t alloc;
+ struct mem_block *block, **heap;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t *)data,
+ sizeof(alloc) );
+
+ heap = get_heap( dev_priv, alloc.region );
+ if (!heap || !*heap)
+ return DRM_ERR(EFAULT);
+
+ /* Make things easier on ourselves: all allocations at least
+ * 4k aligned.
+ */
+ if (alloc.alignment < 12)
+ alloc.alignment = 12;
+
+ block = alloc_block( *heap, alloc.size, alloc.alignment,
+ DRM_CURRENTPID );
+
+ if (!block)
+ return DRM_ERR(ENOMEM);
+
+ if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start,
+ sizeof(int) ) ) {
+ DRM_ERROR( "copy_to_user\n" );
+ return DRM_ERR(EFAULT);
+ }
+
+ return 0;
+}
+
+
+
+int radeon_mem_free( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_mem_free_t memfree;
+ struct mem_block *block, **heap;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t *)data,
+ sizeof(memfree) );
+
+ heap = get_heap( dev_priv, memfree.region );
+ if (!heap || !*heap)
+ return DRM_ERR(EFAULT);
+
+ block = find_block( *heap, memfree.region_offset );
+ if (!block)
+ return DRM_ERR(EFAULT);
+
+ if (block->pid != DRM_CURRENTPID)
+ return DRM_ERR(EPERM);
+
+ free_block( block );
+ return 0;
+}
+
+int radeon_mem_init_heap( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_mem_init_heap_t initheap;
+ struct mem_block **heap;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t *)data,
+ sizeof(initheap) );
+
+ heap = get_heap( dev_priv, initheap.region );
+ if (!heap)
+ return DRM_ERR(EFAULT);
+
+ if (*heap) {
+ DRM_ERROR("heap already initialized?");
+ return DRM_ERR(EFAULT);
+ }
+
+ return init_heap( heap, initheap.start, initheap.size );
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_state.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_state.c
index 7b480a7e9..1fe007b30 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_state.c
@@ -1074,19 +1074,30 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
const u8 *data;
int size, dwords, tex_width, blit_width;
u32 y, height;
- int ret = 0, i;
+ int i;
RING_LOCALS;
dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
- /* FIXME: Be smarter about this...
+ /* Flush the pixel cache. This ensures no pixel data gets mixed
+ * up with the texture data from the host data blit, otherwise
+ * part of the texture image may be corrupted.
*/
- buf = radeon_freelist_get( dev );
- if ( !buf ) return DRM_ERR(EAGAIN);
+ BEGIN_RING( 4 );
+ RADEON_FLUSH_CACHE();
+ RADEON_WAIT_UNTIL_IDLE();
+ ADVANCE_RING();
+
+#ifdef __BIG_ENDIAN
+ /* The Mesa texture functions provide the data in little endian as the
+ * chip wants it, but we need to compensate for the fact that the CP
+ * ring gets byte-swapped
+ */
+ BEGIN_RING( 2 );
+ OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT );
+ ADVANCE_RING();
+#endif
- DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
- tex->offset >> 10, tex->pitch, tex->format,
- image->x, image->y, image->width, image->height );
/* The compiler won't optimize away a division by a variable,
* even if the only legal values are powers of two. Thus, we'll
@@ -1120,127 +1131,113 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
return DRM_ERR(EINVAL);
}
- DRM_DEBUG( " tex=%dx%d blit=%d\n",
- tex_width, tex->height, blit_width );
-
- /* Flush the pixel cache. This ensures no pixel data gets mixed
- * up with the texture data from the host data blit, otherwise
- * part of the texture image may be corrupted.
- */
- BEGIN_RING( 4 );
-
- RADEON_FLUSH_CACHE();
- RADEON_WAIT_UNTIL_IDLE();
-
- ADVANCE_RING();
-
-#ifdef __BIG_ENDIAN
- /* The Mesa texture functions provide the data in little endian as the
- * chip wants it, but we need to compensate for the fact that the CP
- * ring gets byte-swapped
- */
- BEGIN_RING( 2 );
- OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT );
- ADVANCE_RING();
-#endif
-
- /* Make a copy of the parameters in case we have to update them
- * for a multi-pass texture blit.
- */
- y = image->y;
- height = image->height;
- data = (const u8 *)image->data;
-
- size = height * blit_width;
+ DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width );
- if ( size > RADEON_MAX_TEXTURE_SIZE ) {
- /* Texture image is too large, do a multipass upload */
- ret = DRM_ERR(EAGAIN);
+ do {
+ DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
+ tex->offset >> 10, tex->pitch, tex->format,
+ image->x, image->y, image->width, image->height );
- /* Adjust the blit size to fit the indirect buffer */
- height = RADEON_MAX_TEXTURE_SIZE / blit_width;
+ /* Make a copy of the parameters in case we have to
+ * update them for a multi-pass texture blit.
+ */
+ y = image->y;
+ height = image->height;
+ data = (const u8 *)image->data;
+
size = height * blit_width;
+ if ( size > RADEON_MAX_TEXTURE_SIZE ) {
+ height = RADEON_MAX_TEXTURE_SIZE / blit_width;
+ size = height * blit_width;
+ } else if ( size < 4 && size > 0 ) {
+ size = 4;
+ } else if ( size == 0 ) {
+ return 0;
+ }
+
/* Update the input parameters for next time */
image->y += height;
image->height -= height;
- image->data = (const char *)image->data + size;
+ image->data += size;
- if ( DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ) ) {
- DRM_ERROR( "EFAULT on tex->image\n" );
- return DRM_ERR(EFAULT);
+ buf = radeon_freelist_get( dev );
+ if ( 0 && !buf ) {
+ radeon_do_cp_idle( dev_priv );
+ buf = radeon_freelist_get( dev );
+ }
+ if ( !buf ) {
+ DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
+ DRM_COPY_TO_USER( tex->image, image, sizeof(*image) );
+ return DRM_ERR(EAGAIN);
}
- } else if ( size < 4 && size > 0 ) {
- size = 4;
- }
- dwords = size / 4;
- /* Dispatch the indirect buffer.
- */
- buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
-
- buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
- buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (format << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_S |
- RADEON_DP_SRC_SOURCE_HOST_DATA |
- RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS);
-
- buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
- buffer[3] = 0xffffffff;
- buffer[4] = 0xffffffff;
- buffer[5] = (y << 16) | image->x;
- buffer[6] = (height << 16) | image->width;
- buffer[7] = dwords;
-
- buffer += 8;
-
- if ( tex_width >= 32 ) {
- /* Texture image width is larger than the minimum, so we
- * can upload it directly.
- */
- if ( DRM_COPY_FROM_USER( buffer, data, dwords * sizeof(u32) ) ) {
- DRM_ERROR( "EFAULT on data, %d dwords\n", dwords );
- return DRM_ERR(EFAULT);
- }
- } else {
- /* Texture image width is less than the minimum, so we
- * need to pad out each image scanline to the minimum
- * width.
+ /* Dispatch the indirect buffer.
*/
- for ( i = 0 ; i < tex->height ; i++ ) {
- if ( DRM_COPY_FROM_USER( buffer, data, tex_width ) ) {
- DRM_ERROR( "EFAULT on pad, %d bytes\n",
- tex_width );
+ buffer = (u32*)((char*)dev_priv->buffers->handle + buf->offset);
+ dwords = size / 4;
+ buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
+ buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (format << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_S |
+ RADEON_DP_SRC_SOURCE_HOST_DATA |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_WR_MSK_DIS);
+
+ buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
+ buffer[3] = 0xffffffff;
+ buffer[4] = 0xffffffff;
+ buffer[5] = (y << 16) | image->x;
+ buffer[6] = (height << 16) | image->width;
+ buffer[7] = dwords;
+ buffer += 8;
+
+ if ( tex_width >= 32 ) {
+ /* Texture image width is larger than the minimum, so we
+ * can upload it directly.
+ */
+ if ( DRM_COPY_FROM_USER( buffer, data,
+ dwords * sizeof(u32) ) ) {
+ DRM_ERROR( "EFAULT on data, %d dwords\n",
+ dwords );
return DRM_ERR(EFAULT);
}
- buffer += 8;
- data += tex_width;
+ } else {
+ /* Texture image width is less than the minimum, so we
+ * need to pad out each image scanline to the minimum
+ * width.
+ */
+ for ( i = 0 ; i < tex->height ; i++ ) {
+ if ( DRM_COPY_FROM_USER( buffer, data,
+ tex_width ) ) {
+ DRM_ERROR( "EFAULT on pad, %d bytes\n",
+ tex_width );
+ return DRM_ERR(EFAULT);
+ }
+ buffer += 8;
+ data += tex_width;
+ }
}
- }
- buf->pid = DRM_CURRENTPID;
- buf->used = (dwords + 8) * sizeof(u32);
+ buf->pid = DRM_CURRENTPID;
+ buf->used = (dwords + 8) * sizeof(u32);
+ radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
+ radeon_cp_discard_buffer( dev, buf );
- radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
- radeon_cp_discard_buffer( dev, buf );
+ } while (image->height > 0);
/* Flush the pixel cache after the blit completes. This ensures
* the texture data is written out to memory before rendering
* continues.
*/
BEGIN_RING( 4 );
-
RADEON_FLUSH_CACHE();
RADEON_WAIT_UNTIL_2D_IDLE();
-
ADVANCE_RING();
-
- return ret;
+ return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
index 331a9d82f..6ae17f1ff 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -232,7 +232,7 @@ typedef struct _drmClipRect {
typedef enum {
DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */
- DRM_VBLANK_SIGNAL = 0x80000000 /* Send signal instead of blocking */
+ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
} drmVBlankSeqType;
typedef struct _drmVBlankReq {