diff options
author | idr <idr> | 2003-01-26 07:43:44 +0000 |
---|---|---|
committer | idr <idr> | 2003-01-26 07:43:44 +0000 |
commit | 864aafbf04464e57ae750693b39a5f2ecece06b8 (patch) | |
tree | 68bf688f251cc10f76a39c3e10b9f91f1e10b668 | |
parent | 6bf960e3e83d69c53b3706324dca7d6c152017f7 (diff) |
Merge from trunk.texmem-0-0-1-20030125-trunk-merge
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 { |