From eed1a6de4b396ed6305cf34812a269c10c746d3c Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Thu, 7 Dec 2006 17:53:59 +0200 Subject: [PATCH 01/12] Bug 7790: Polygons incorrectly clipped by mach64 driver un-break strict-aliasing rules --- src/mesa/drivers/dri/mach64/mach64_tris.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mesa/drivers/dri/mach64/mach64_tris.c b/src/mesa/drivers/dri/mach64/mach64_tris.c index 4a0044be88c..08cc1849a12 100644 --- a/src/mesa/drivers/dri/mach64/mach64_tris.c +++ b/src/mesa/drivers/dri/mach64/mach64_tris.c @@ -1583,7 +1583,10 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, mach64ContextPtr mmesa = MACH64_CONTEXT( ctx ); const GLuint vertsize = mmesa->vertex_size; GLint a; - GLfloat ooa; + union { + GLfloat f; + CARD32 u; + } ooa; GLuint xy; const GLuint xyoffset = 9; GLint xx[3], yy[3]; /* 2 fractional bits for hardware */ @@ -1621,7 +1624,7 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, return; } - ooa = 16.0 / a; + ooa.f = 16.0 / a; vb = (CARD32 *)mach64AllocDmaLow( mmesa, vbsiz * sizeof(CARD32) ); vbchk = vb + vbsiz; @@ -1629,7 +1632,7 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, COPY_VERTEX( vb, vertsize, v0, 1 ); COPY_VERTEX( vb, vertsize, v1, 2 ); COPY_VERTEX_OOA( vb, vertsize, v2, 3 ); - LE32_OUT( vb++, *(CARD32 *)&ooa ); + LE32_OUT( vb++, ooa.u ); i = 3; while (1) { @@ -1644,10 +1647,10 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, a = (xx[0] - xx[2]) * (yy[1] - yy[2]) - (yy[0] - yy[2]) * (xx[1] - xx[2]); - ooa = 16.0 / a; + ooa.f = 16.0 / a; COPY_VERTEX_OOA( vb, vertsize, v0, 1 ); - LE32_OUT( vb++, *(CARD32 *)&ooa ); + LE32_OUT( vb++, ooa.u ); if (i >= n) break; @@ -1660,10 +1663,10 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, a = (xx[0] - xx[2]) * (yy[1] - yy[2]) - (yy[0] - yy[2]) * (xx[1] - xx[2]); - ooa = 16.0 / a; + ooa.f = 16.0 / a; COPY_VERTEX_OOA( vb, vertsize, v1, 2 ); - LE32_OUT( vb++, *(CARD32 *)&ooa ); + LE32_OUT( vb++, ooa.u ); } assert( vb == vbchk ); From c180678d92e6427c60acd4e984c11d27853e1304 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Thu, 7 Dec 2006 17:56:47 +0200 Subject: [PATCH 02/12] Bug 7861: mach64 with render acceleration should restore texture state RENDER acceleration uses texturing, thus when RENDER acceleration is enabled, the mach64 DRI driver should restore texture state when acquiring the DRI lock. --- src/mesa/drivers/dri/mach64/mach64_lock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mesa/drivers/dri/mach64/mach64_lock.c b/src/mesa/drivers/dri/mach64/mach64_lock.c index b214495d9a6..26f66f02309 100644 --- a/src/mesa/drivers/dri/mach64/mach64_lock.c +++ b/src/mesa/drivers/dri/mach64/mach64_lock.c @@ -82,6 +82,9 @@ void mach64GetLock( mach64ContextPtr mmesa, GLuint flags ) | MACH64_UPLOAD_MISC | MACH64_UPLOAD_CLIPRECTS); + /* EXA render acceleration uses the texture engine, so restore it */ + mmesa->dirty |= (MACH64_UPLOAD_TEXTURE); + if ( sarea->ctx_owner != mmesa->hHWContext ) { sarea->ctx_owner = mmesa->hHWContext; mmesa->dirty = MACH64_UPLOAD_ALL; From 5b35132b41427798e02a66a8e39583fffbe9d232 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Thu, 7 Dec 2006 18:01:13 +0200 Subject: [PATCH 03/12] Bug 7260: mach64 texture memory mng cleanup mach64 uses its own set of texture memory management routines which are buggy, running a second DRI client kills the first one. This patch ports mach64 code to the stock dri texture managment code. --- src/mesa/drivers/dri/mach64/mach64_context.c | 82 ++- src/mesa/drivers/dri/mach64/mach64_context.h | 59 +- src/mesa/drivers/dri/mach64/mach64_lock.c | 4 +- src/mesa/drivers/dri/mach64/mach64_screen.c | 2 +- src/mesa/drivers/dri/mach64/mach64_tex.c | 131 ++-- src/mesa/drivers/dri/mach64/mach64_tex.h | 10 - src/mesa/drivers/dri/mach64/mach64_texmem.c | 661 ++++-------------- src/mesa/drivers/dri/mach64/mach64_texstate.c | 135 ++-- 8 files changed, 312 insertions(+), 772 deletions(-) diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index 03ec96a222e..2ab1cf2617e 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -102,6 +102,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, mach64ContextPtr mmesa; mach64ScreenPtr mach64Screen; int i, heap; + GLuint *c_textureSwapsPtr = NULL; #if DO_DEBUG MACH64_DEBUG = driParseDebugString(getenv("MACH64_DEBUG"), debug_control); @@ -153,15 +154,28 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, mmesa->CurrentTexObj[0] = NULL; mmesa->CurrentTexObj[1] = NULL; - make_empty_list( &mmesa->SwappedOut ); + (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) ); + make_empty_list( &mmesa->swapped ); mmesa->firstTexHeap = mach64Screen->firstTexHeap; mmesa->lastTexHeap = mach64Screen->firstTexHeap + mach64Screen->numTexHeaps; for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - make_empty_list( &mmesa->TexObjList[i] ); - mmesa->texHeap[i] = mmInit( 0, mach64Screen->texSize[i] ); - mmesa->lastTexAge[i] = -1; + mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa, + mach64Screen->texSize[i], + 6, /* align to 64-byte boundary, use 12 for page-size boundary */ + MACH64_NR_TEX_REGIONS, + (drmTextureRegionPtr)mmesa->sarea->tex_list[i], + &mmesa->sarea->tex_age[i], + &mmesa->swapped, + sizeof( mach64TexObj ), + (destroy_texture_object_t *) mach64DestroyTexObj ); + +#if ENABLE_PERF_BOXES + c_textureSwapsPtr = & mmesa->c_textureSwaps; +#endif + driSetTextureSwapCounterLocation( mmesa->texture_heaps[i], + c_textureSwapsPtr ); } mmesa->RenderIndex = -1; /* Impossible value */ @@ -176,17 +190,25 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, * Test for 2 textures * bytes/texel * size * size. There's no * need to account for mipmaps since we only upload one level. */ - heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP; - - if ( mach64Screen->texSize[heap] >= 2 * mach64Screen->cpp * 1024*1024 ) { - ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */ - } else if ( mach64Screen->texSize[heap] >= 2 * mach64Screen->cpp * 512*512 ) { - ctx->Const.MaxTextureLevels = 10; /* 512x512 */ - } else { - ctx->Const.MaxTextureLevels = 9; /* 256x256 */ - } ctx->Const.MaxTextureUnits = 2; + ctx->Const.MaxTextureImageUnits = 2; + ctx->Const.MaxTextureCoordUnits = 2; + + heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP; + + driCalculateMaxTextureLevels( & mmesa->texture_heaps[heap], + 1, + & ctx->Const, + mach64Screen->cpp, + 10, /* max 2D texture size is 1024x1024 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 1, /* mipmapping unsupported. */ + GL_TRUE, /* need to have both textures in + either local or AGP memory */ + 0 ); #if ENABLE_PERF_BOXES mmesa->boxes = ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL ); @@ -250,31 +272,29 @@ void mach64DestroyContext( __DRIcontextPrivate *driContextPriv ) assert(mmesa); /* should never be null */ if ( mmesa ) { - if (mmesa->glCtx->Shared->RefCount == 1) { - /* This share group is about to go away, free our private - * texture object data. - */ - mach64TexObjPtr t, next_t; - int i; + GLboolean release_texture_heaps; - for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - foreach_s ( t, next_t, &mmesa->TexObjList[i] ) { - mach64DestroyTexObj( mmesa, t ); - } - mmDestroy( mmesa->texHeap[i] ); - mmesa->texHeap[i] = NULL; - } - - foreach_s ( t, next_t, &mmesa->SwappedOut ) { - mach64DestroyTexObj( mmesa, t ); - } - } + release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); _ac_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); + if (release_texture_heaps) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { + driDestroyTextureHeap( mmesa->texture_heaps[i] ); + mmesa->texture_heaps[i] = NULL; + } + + assert( is_empty_list( & mmesa->swapped ) ); + } + mach64FreeVB( mmesa->glCtx ); /* Free the vertex buffer */ diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h index e718b96c188..8d89452412b 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.h +++ b/src/mesa/drivers/dri/mach64/mach64_context.h @@ -134,15 +134,17 @@ typedef void (*mach64_line_func)( mach64ContextPtr, typedef void (*mach64_point_func)( mach64ContextPtr, mach64Vertex * ); -#ifdef TEXMEM struct mach64_texture_object { driTextureObject base; - GLuint offset; + GLuint bufAddr; - GLuint dirty; - GLuint age; + GLint heap; /* same as base.heap->heapId */ + /* For communicating values from mach64AllocTexObj(), mach64SetTexImages() + * to mach64UpdateTextureUnit(). Alternately, we can use the tObj values or + * set the context registers directly. + */ GLint widthLog2; GLint heightLog2; GLint maxLog2; @@ -150,50 +152,14 @@ struct mach64_texture_object { GLint hasAlpha; GLint textureFormat; - /* Have to keep these separate due to how they are programmed. - * FIXME: Why don't we just use the tObj values? - */ GLboolean BilinearMin; GLboolean BilinearMag; GLboolean ClampS; GLboolean ClampT; }; -#else -struct mach64_texture_object { - struct mach64_texture_object *next; - struct mach64_texture_object *prev; - struct gl_texture_object *tObj; - - struct mem_block *memBlock; - GLuint offset; - GLuint size; - - GLuint dirty; - GLuint age; - - GLint bound; - GLint heap; - - GLint widthLog2; - GLint heightLog2; - GLint maxLog2; - - GLint hasAlpha; - GLint textureFormat; - - /* Have to keep these separate due to how they are programmed. - * FIXME: Why don't we just use the tObj values? - */ - GLboolean BilinearMin; - GLboolean BilinearMag; - GLboolean ClampS; - GLboolean ClampT; -}; -#endif typedef struct mach64_texture_object mach64TexObj, *mach64TexObjPtr; - struct mach64_context { GLcontext *glCtx; @@ -229,17 +195,10 @@ struct mach64_context { /* Texture object bookkeeping */ mach64TexObjPtr CurrentTexObj[2]; -#ifdef TEXMEM - unsigned nr_heaps; - driTexHeap * texture_heaps[ R128_NR_TEX_HEAPS ]; - driTextureObject swapped; -#else - mach64TexObj TexObjList[MACH64_NR_TEX_HEAPS]; - mach64TexObj SwappedOut; - struct mem_block *texHeap[MACH64_NR_TEX_HEAPS]; - GLuint lastTexAge[MACH64_NR_TEX_HEAPS]; + GLint firstTexHeap, lastTexHeap; -#endif + driTexHeap *texture_heaps[MACH64_NR_TEX_HEAPS]; + driTextureObject swapped; /* Fallback rasterization functions */ diff --git a/src/mesa/drivers/dri/mach64/mach64_lock.c b/src/mesa/drivers/dri/mach64/mach64_lock.c index 26f66f02309..b73e350111f 100644 --- a/src/mesa/drivers/dri/mach64/mach64_lock.c +++ b/src/mesa/drivers/dri/mach64/mach64_lock.c @@ -91,8 +91,6 @@ void mach64GetLock( mach64ContextPtr mmesa, GLuint flags ) } for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - if ( mmesa->texHeap[i] && (sarea->tex_age[i] != mmesa->lastTexAge[i]) ) { - mach64AgeTextures( mmesa, i ); - } + DRI_AGE_TEXTURES( mmesa->texture_heaps[i] ); } } diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index b17de01acc5..1014b8acd52 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -305,7 +305,7 @@ mach64CreateScreen( __DRIscreenPrivate *sPriv ) mach64Screen->texSize[MACH64_AGP_HEAP] = 0; mach64Screen->logTexGranularity[MACH64_AGP_HEAP] = 0; } else { - if (mach64Screen->texSize[MACH64_CARD_HEAP] > 0) { + if (serverInfo->textureSize > 0) { mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS; mach64Screen->firstTexHeap = MACH64_CARD_HEAP; } else { diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.c b/src/mesa/drivers/dri/mach64/mach64_tex.c index 6459deef784..5288d321ced 100644 --- a/src/mesa/drivers/dri/mach64/mach64_tex.c +++ b/src/mesa/drivers/dri/mach64/mach64_tex.c @@ -116,21 +116,20 @@ mach64AllocTexObj( struct gl_texture_object *texObj ) fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); t = (mach64TexObjPtr) CALLOC_STRUCT( mach64_texture_object ); + texObj->DriverData = t; if ( !t ) return NULL; /* Initialize non-image-dependent parts of the state: */ - t->tObj = texObj; + t->base.tObj = texObj; + t->base.dirty_images[0] = (1 << 0); - t->offset = 0; + t->bufAddr = 0; - t->dirty = 1; - - make_empty_list( t ); + make_empty_list( (driTextureObject *) t ); mach64SetTexWrap( t, texObj->WrapS, texObj->WrapT ); - /*mach64SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/ mach64SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); mach64SetTexBorderColor( t, texObj->_BorderChan ); @@ -251,18 +250,17 @@ static void mach64TexImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_image *texImage ) { mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); - mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - mach64SwapOutTexObj( mmesa, t ); + driSwapOutTextureObject( t ); } else { - t = mach64AllocTexObj(texObj); + t = (driTextureObject *) mach64AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); return; } - texObj->DriverData = t; } /* Note, this will call mach64ChooseTextureFormat */ @@ -285,19 +283,18 @@ static void mach64TexSubImage1D( GLcontext *ctx, struct gl_texture_image *texImage ) { mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); - mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; assert( t ); /* this _should_ be true */ if ( t ) { - mach64SwapOutTexObj( mmesa, t ); + driSwapOutTextureObject( t ); } else { - t = mach64AllocTexObj(texObj); + t = (driTextureObject *) mach64AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, @@ -316,18 +313,17 @@ static void mach64TexImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_image *texImage ) { mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); - mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - mach64SwapOutTexObj( mmesa, t ); + driSwapOutTextureObject( t ); } else { - t = mach64AllocTexObj(texObj); + t = (driTextureObject *) mach64AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - texObj->DriverData = t; } /* Note, this will call mach64ChooseTextureFormat */ @@ -350,19 +346,18 @@ static void mach64TexSubImage2D( GLcontext *ctx, struct gl_texture_image *texImage ) { mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); - mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; assert( t ); /* this _should_ be true */ if ( t ) { - mach64SwapOutTexObj( mmesa, t ); + driSwapOutTextureObject( t ); } else { - t = mach64AllocTexObj(texObj); + t = (driTextureObject *) mach64AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, @@ -372,44 +367,6 @@ static void mach64TexSubImage2D( GLcontext *ctx, mmesa->new_state |= MACH64_NEW_TEXTURE; } -/* Due to the way we must program texture state into the Rage Pro, - * we must leave these calculations to the absolute last minute. - */ -void mach64EmitTexStateLocked( mach64ContextPtr mmesa, - mach64TexObjPtr t0, - mach64TexObjPtr t1 ) -{ - drm_mach64_sarea_t *sarea = mmesa->sarea; - drm_mach64_context_regs_t *regs = &(mmesa->setup); - - /* for multitex, both textures must be local or AGP */ - if ( t0 && t1 ) - assert(t0->heap == t1->heap); - - if ( t0 ) { - if (t0->heap == MACH64_CARD_HEAP) { -#if ENABLE_PERF_BOXES - mmesa->c_texsrc_card++; -#endif - mmesa->setup.tex_cntl &= ~MACH64_TEX_SRC_AGP; - } else { -#if ENABLE_PERF_BOXES - mmesa->c_texsrc_agp++; -#endif - mmesa->setup.tex_cntl |= MACH64_TEX_SRC_AGP; - } - mmesa->setup.tex_offset = t0->offset; - } - - if ( t1 ) { - mmesa->setup.secondary_tex_off = t1->offset; - } - - memcpy( &sarea->context_state.tex_size_pitch, ®s->tex_size_pitch, - MACH64_NR_TEXTURE_REGS * sizeof(GLuint) ); -} - - /* ================================================================ * Device Driver API texture functions */ @@ -491,24 +448,23 @@ static void mach64DDTexParameter( GLcontext *ctx, GLenum target, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexParameter"); return; } - tObj->DriverData = t; } switch ( pname ) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: - if ( t->bound ) FLUSH_BATCH( mmesa ); + if ( t->base.bound ) FLUSH_BATCH( mmesa ); mach64SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: - if ( t->bound ) FLUSH_BATCH( mmesa ); + if ( t->base.bound ) FLUSH_BATCH( mmesa ); mach64SetTexWrap( t, tObj->WrapS, tObj->WrapT ); break; case GL_TEXTURE_BORDER_COLOR: - if ( t->bound ) FLUSH_BATCH( mmesa ); + if ( t->base.bound ) FLUSH_BATCH( mmesa ); mach64SetTexBorderColor( t, tObj->_BorderChan ); break; @@ -522,8 +478,8 @@ static void mach64DDTexParameter( GLcontext *ctx, GLenum target, * For mach64 we're only concerned with the base level * since that's the only texture we upload. */ - if ( t->bound ) FLUSH_BATCH( mmesa ); - mach64SwapOutTexObj( mmesa, t ); + if ( t->base.bound ) FLUSH_BATCH( mmesa ); + driSwapOutTextureObject( (driTextureObject *) t ); break; default: @@ -547,7 +503,7 @@ static void mach64DDBindTexture( GLcontext *ctx, GLenum target, FLUSH_BATCH( mmesa ); if ( mmesa->CurrentTexObj[unit] ) { - mmesa->CurrentTexObj[unit]->bound &= ~(unit+1); + mmesa->CurrentTexObj[unit]->base.bound &= ~(1 << unit); mmesa->CurrentTexObj[unit] = NULL; } @@ -558,33 +514,37 @@ static void mach64DDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); - mach64TexObjPtr t = (mach64TexObjPtr)tObj->DriverData; + driTextureObject * t = (driTextureObject *) tObj->DriverData; if ( t ) { if ( t->bound && mmesa ) { FLUSH_BATCH( mmesa ); - mmesa->CurrentTexObj[t->bound-1] = 0; mmesa->new_state |= MACH64_NEW_TEXTURE; } - mach64DestroyTexObj( mmesa, t ); - tObj->DriverData = NULL; + driDestroyTextureObject( t ); + /* Free mipmap images and the texture object itself */ _mesa_delete_texture_object(ctx, tObj); - } } -static GLboolean mach64DDIsTextureResident( GLcontext *ctx, - struct gl_texture_object *tObj ) +/** + * Allocate a new texture object. + * Called via ctx->Driver.NewTextureObject. + * Note: we could use containment here to 'derive' the driver-specific + * texture object from the core mesa gl_texture_object. Not done at this time. + */ +static struct gl_texture_object * +mach64NewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) { - mach64TexObjPtr t = (mach64TexObjPtr)tObj->DriverData; - - return ( t && t->memBlock ); + struct gl_texture_object *obj; + obj = _mesa_new_texture_object(ctx, name, target); + mach64AllocTexObj( obj ); + return obj; } - void mach64InitTextureFuncs( struct dd_function_table *functions ) { functions->TexEnv = mach64DDTexEnv; @@ -593,18 +553,15 @@ void mach64InitTextureFuncs( struct dd_function_table *functions ) functions->TexSubImage1D = mach64TexSubImage1D; functions->TexImage2D = mach64TexImage2D; functions->TexSubImage2D = mach64TexSubImage2D; - functions->TexImage3D = _mesa_store_teximage3d; - functions->TexSubImage3D = _mesa_store_texsubimage3d; - functions->CopyTexImage1D = _swrast_copy_teximage1d; - functions->CopyTexImage2D = _swrast_copy_teximage2d; - functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d; - functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d; - functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d; functions->TexParameter = mach64DDTexParameter; functions->BindTexture = mach64DDBindTexture; + functions->NewTextureObject = mach64NewTextureObject; functions->DeleteTexture = mach64DDDeleteTexture; + functions->IsTextureResident = driIsTextureResident; + functions->UpdateTexturePalette = NULL; functions->ActiveTexture = NULL; - functions->IsTextureResident = mach64DDIsTextureResident; - functions->PrioritizeTexture = NULL; + functions->PrioritizeTexture = NULL; + + driInitTextureFormats(); } diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.h b/src/mesa/drivers/dri/mach64/mach64_tex.h index d950dd12b44..f6cf1cf8020 100644 --- a/src/mesa/drivers/dri/mach64/mach64_tex.h +++ b/src/mesa/drivers/dri/mach64/mach64_tex.h @@ -34,25 +34,15 @@ extern void mach64UpdateTextureState( GLcontext *ctx ); -extern void mach64SwapOutTexObj( mach64ContextPtr mach64ctx, - mach64TexObjPtr t ); - extern void mach64UploadTexImages( mach64ContextPtr mach64ctx, mach64TexObjPtr t ); extern void mach64UploadMultiTexImages( mach64ContextPtr mach64ctx, mach64TexObjPtr t0, mach64TexObjPtr t1 ); -extern void mach64AgeTextures( mach64ContextPtr mach64ctx, int heap ); extern void mach64DestroyTexObj( mach64ContextPtr mach64ctx, mach64TexObjPtr t ); -extern void mach64UpdateTexLRU( mach64ContextPtr mach64ctx, - mach64TexObjPtr t ); - -extern void mach64PrintLocalLRU( mach64ContextPtr mach64ctx, int heap ); -extern void mach64PrintGlobalLRU( mach64ContextPtr mach64ctx, int heap ); - extern void mach64EmitTexStateLocked( mach64ContextPtr mmesa, mach64TexObjPtr t0, mach64TexObjPtr t1 ); diff --git a/src/mesa/drivers/dri/mach64/mach64_texmem.c b/src/mesa/drivers/dri/mach64/mach64_texmem.c index 017fd3535d5..3b7b93b9842 100644 --- a/src/mesa/drivers/dri/mach64/mach64_texmem.c +++ b/src/mesa/drivers/dri/mach64/mach64_texmem.c @@ -49,333 +49,19 @@ */ void mach64DestroyTexObj( mach64ContextPtr mmesa, mach64TexObjPtr t ) { -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - if (mmesa) - mmesa->c_textureSwaps++; -#endif - if ( !t ) return; + unsigned i; -#if 0 - if ( t->tObj && t->memBlock && mmesa ) { - /* not a placeholder, so release from global LRU if necessary */ - int heap = t->heap; - drmTextureRegion *list = mmesa->sarea->tex_list[heap]; - int log2sz = mmesa->mach64Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap]; - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - /* do we own this block? */ - if (list[i].in_use == mmesa->hHWContext) { - list[i].in_use = 0; - list[i].age = mmesa->lastTexAge[heap]; - - /* remove_from_list(i) */ - list[(GLuint)list[i].next].prev = list[i].prev; - list[(GLuint)list[i].prev].next = list[i].next; - } - } - } -#endif - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) { - t->tObj->DriverData = NULL; - } - - if ( t->bound && mmesa ) - mmesa->CurrentTexObj[t->bound-1] = NULL; - - remove_from_list( t ); - FREE( t ); -} - -/* Keep track of swapped out texture objects. - */ -void mach64SwapOutTexObj( mach64ContextPtr mmesa, - mach64TexObjPtr t ) -{ -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - if (mmesa) - mmesa->c_textureSwaps++; -#endif - -#if 0 - if ( t->tObj && t->memBlock && mmesa ) { - /* not a placeholder, so release from global LRU if necessary */ - int heap = t->heap; - drmTextureRegion *list = mmesa->sarea->tex_list[heap]; - int log2sz = mmesa->mach64Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap]; - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - /* do we own this block? */ - if (list[i].in_use == mmesa->hHWContext) { - list[i].in_use = 0; - list[i].age = mmesa->lastTexAge[heap]; - - /* remove_from_list(i) */ - list[(GLuint)list[i].next].prev = list[i].prev; - list[(GLuint)list[i].prev].next = list[i].next; - } - } - } -#endif - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - t->dirty = ~0; - move_to_tail( &mmesa->SwappedOut, t ); -} - -/* Print out debugging information about texture LRU. - */ -void mach64PrintLocalLRU( mach64ContextPtr mmesa, int heap ) -{ - mach64TexObjPtr t; - int sz = 1 << (mmesa->mach64Screen->logTexGranularity[heap]); - - fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - - foreach( t, &mmesa->TexObjList[heap] ) { - if ( !t->tObj ) { - fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", - t->memBlock->ofs / sz, - t->memBlock->ofs, - t->memBlock->size ); - } else { - fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", - t->bound, - t->memBlock->ofs, - t->memBlock->size ); - } - } - - fprintf( stderr, "\n" ); -} - -void mach64PrintGlobalLRU( mach64ContextPtr mmesa, int heap ) -{ - drm_tex_region_t *list = mmesa->sarea->tex_list[heap]; - int i, j; - - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); - - for ( i = 0, j = MACH64_NR_TEX_REGIONS ; i < MACH64_NR_TEX_REGIONS ; i++ ) { - fprintf( stderr, "list[%d] age %d in_use %d next %d prev %d\n", - j, list[j].age, list[j].in_use, list[j].next, list[j].prev ); - j = list[j].next; - if ( j == MACH64_NR_TEX_REGIONS ) break; - } - - if ( j != MACH64_NR_TEX_REGIONS ) { - fprintf( stderr, "Loop detected in global LRU\n" ); - for ( i = 0 ; i < MACH64_NR_TEX_REGIONS ; i++ ) { - fprintf( stderr, "list[%d] age %d in_use %d next %d prev %d\n", - i, list[i].age, list[i].in_use, list[i].next, list[i].prev ); - } - } - - fprintf( stderr, "\n" ); -} - -/* Reset the global texture LRU. - */ -/* NOTE: This function is only called while holding the hardware lock */ -static void mach64ResetGlobalLRU( mach64ContextPtr mmesa, int heap ) -{ - drm_tex_region_t *list = mmesa->sarea->tex_list[heap]; - int sz = 1 << mmesa->mach64Screen->logTexGranularity[heap]; - int i; - - /* (Re)initialize the global circular LRU list. The last element in - * the array (MACH64_NR_TEX_REGIONS) is the sentinal. Keeping it at - * the end of the array allows it to be addressed rationally when - * looking up objects at a particular location in texture memory. + /* See if it was the driver's current object. */ - for ( i = 0 ; (i+1) * sz <= mmesa->mach64Screen->texSize[heap] ; i++ ) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - list[i].in_use = 0; - } - - i--; - list[0].prev = MACH64_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = MACH64_NR_TEX_REGIONS; - list[MACH64_NR_TEX_REGIONS].prev = i; - list[MACH64_NR_TEX_REGIONS].next = 0; - mmesa->sarea->tex_age[heap] = 0; -} - -/* Update the local and global texture LRUs. - */ -/* NOTE: This function is only called while holding the hardware lock */ -void mach64UpdateTexLRU( mach64ContextPtr mmesa, - mach64TexObjPtr t ) -{ - int heap = t->heap; - drm_tex_region_t *list = mmesa->sarea->tex_list[heap]; - int log2sz = mmesa->mach64Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap]; - - if ( !t->memBlock ) { - fprintf( stderr, "no memblock\n\n" ); - return; - } - - /* Update our local LRU */ - move_to_head( &mmesa->TexObjList[heap], t ); - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - list[i].in_use = mmesa->hHWContext; - list[i].age = mmesa->lastTexAge[heap]; - -#if 0 - /* if this is the last region, it's not in the list */ - if ( !(i*(1< mmesa->mach64Screen->texSize[heap] ) ) { -#endif - /* remove_from_list(i) */ - list[(GLuint)list[i].next].prev = list[i].prev; - list[(GLuint)list[i].prev].next = list[i].next; -#if 0 - } -#endif - - /* insert_at_head(list, i) */ - list[i].prev = MACH64_NR_TEX_REGIONS; - list[i].next = list[MACH64_NR_TEX_REGIONS].next; - list[(GLuint)list[MACH64_NR_TEX_REGIONS].next].prev = i; - list[MACH64_NR_TEX_REGIONS].next = i; - } - - if ( MACH64_DEBUG & DEBUG_VERBOSE_LRU ) { - mach64PrintGlobalLRU( mmesa, t->heap ); - mach64PrintLocalLRU( mmesa, t->heap ); - } -} - -/* Update our notion of what textures have been changed since we last - * held the lock. This pertains to both our local textures and the - * textures belonging to other clients. Keep track of other client's - * textures by pushing a placeholder texture onto the LRU list -- these - * are denoted by (tObj == NULL). - */ -/* NOTE: This function is only called while holding the hardware lock */ -static void mach64TexturesGone( mach64ContextPtr mmesa, int heap, - int offset, int size, int in_use ) -{ - mach64TexObjPtr t, tmp; - - foreach_s ( t, tmp, &mmesa->TexObjList[heap] ) { - if ( t->memBlock->ofs >= offset + size || - t->memBlock->ofs + t->memBlock->size <= offset ) - continue; - - /* It overlaps - kick it out. Need to hold onto the currently - * bound objects, however. - */ - if ( t->bound ) { - mach64SwapOutTexObj( mmesa, t ); - } else { - mach64DestroyTexObj( mmesa, t ); - } - } - - if ( in_use > 0 && in_use != mmesa->hHWContext ) { - t = (mach64TexObjPtr) CALLOC( sizeof(*t) ); - if (!t) return; - - t->memBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset ); - if ( !t->memBlock ) { - fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset ); - mmDumpMemInfo( mmesa->texHeap[heap] ); - return; - } - insert_at_head( &mmesa->TexObjList[heap], t ); - } -} - -/* Update our client's shared texture state. If another client has - * modified a region in which we have textures, then we need to figure - * out which of our textures has been removed, and update our global - * LRU. - */ -void mach64AgeTextures( mach64ContextPtr mmesa, int heap ) -{ - drm_mach64_sarea_t *sarea = mmesa->sarea; - - if ( sarea->tex_age[heap] != mmesa->lastTexAge[heap] ) { - int sz = 1 << mmesa->mach64Screen->logTexGranularity[heap]; - int nr = 0; - int idx; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... Fix with a cursor pointer. - */ - for ( idx = sarea->tex_list[heap][MACH64_NR_TEX_REGIONS].prev ; - idx != MACH64_NR_TEX_REGIONS && nr < MACH64_NR_TEX_REGIONS ; - idx = sarea->tex_list[heap][idx].prev, nr++ ) + if ( mmesa != NULL ) + { + for ( i = 0 ; i < mmesa->glCtx->Const.MaxTextureUnits ; i++ ) { - /* If switching texturing schemes, then the SAREA might not - * have been properly cleared, so we need to reset the - * global texture LRU. - */ - if ( idx * sz > mmesa->mach64Screen->texSize[heap] ) { - nr = MACH64_NR_TEX_REGIONS; - break; - } - - if ( sarea->tex_list[heap][idx].age > mmesa->lastTexAge[heap] ) { - mach64TexturesGone( mmesa, heap, idx * sz, sz, - sarea->tex_list[heap][idx].in_use ); - } + if ( t == mmesa->CurrentTexObj[ i ] ) { + assert( t->base.bound & (1 << i) ); + mmesa->CurrentTexObj[ i ] = NULL; + } } - - /* If switching texturing schemes, then the SAREA might not - * have been properly cleared, so we need to reset the - * global texture LRU. - */ - if ( nr == MACH64_NR_TEX_REGIONS ) { - mach64TexturesGone( mmesa, heap, 0, - mmesa->mach64Screen->texSize[heap], 0 ); - mach64ResetGlobalLRU( mmesa, heap ); - } - - if ( 0 ) { - mach64PrintGlobalLRU( mmesa, heap ); - mach64PrintLocalLRU( mmesa, heap ); - } - - mmesa->dirty |= (MACH64_UPLOAD_CONTEXT | - MACH64_UPLOAD_TEX0IMAGE | - MACH64_UPLOAD_TEX1IMAGE); - mmesa->lastTexAge[heap] = sarea->tex_age[heap]; } } @@ -395,7 +81,7 @@ static void mach64UploadAGPSubImage( mach64ContextPtr mmesa, if ( ( level < 0 ) || ( level > mmesa->glCtx->Const.MaxTextureLevels ) ) return; - image = t->tObj->Image[0][level]; + image = t->base.tObj->Image[0][level]; if ( !image ) return; @@ -424,14 +110,13 @@ static void mach64UploadAGPSubImage( mach64ContextPtr mmesa, fprintf( stderr, "mach64UploadSubImage: %d,%d of %d,%d at %d,%d\n", width, height, image->Width, image->Height, x, y ); fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d\n", - (GLuint)t->offset, (GLint)width, dwords ); - mmDumpMemInfo( mmesa->texHeap[t->heap] ); + (GLuint)t->bufAddr, (GLint)width, dwords ); } assert(image->Data); { - CARD32 *dst = (CARD32 *)((char *)mach64Screen->agpTextures.map + t->memBlock->ofs); + CARD32 *dst = (CARD32 *)((char *)mach64Screen->agpTextures.map + t->base.memBlock->ofs); const GLubyte *src = (const GLubyte *) image->Data + (y * image->Width + x) * image->TexFormat->TexelBytes; const GLuint bytes = width * height * image->TexFormat->TexelBytes; @@ -460,7 +145,7 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa, if ( ( level < 0 ) || ( level > mmesa->glCtx->Const.MaxTextureLevels ) ) return; - image = t->tObj->Image[0][level]; + image = t->base.tObj->Image[0][level]; if ( !image ) return; @@ -543,7 +228,7 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa, } dwords = width * height / texelsPerDword; - offset = t->offset; + offset = t->bufAddr; #if ENABLE_PERF_BOXES /* Bump the performance counter */ @@ -555,7 +240,6 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa, width, height, image->Width, image->Height, x, y ); fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d\n", (GLuint)offset, (GLint)width, dwords ); - mmDumpMemInfo( mmesa->texHeap[t->heap] ); } /* Subdivide the texture if required (account for the registers added by the drm) */ @@ -594,78 +278,32 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa, */ void mach64UploadTexImages( mach64ContextPtr mmesa, mach64TexObjPtr t ) { - GLint heap; - if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, mmesa->glCtx, t ); } assert(t); - assert(t->tObj); + assert(t->base.tObj); - /* Choose the heap appropriately */ - heap = MACH64_CARD_HEAP; + if ( !t->base.memBlock ) { + int heap; - if ( !mmesa->mach64Screen->IsPCI && - t->size > mmesa->mach64Screen->texSize[heap] ) { - heap = MACH64_AGP_HEAP; - } + /* NULL heaps are skipped */ + heap = driAllocateTexture( mmesa->texture_heaps, MACH64_NR_TEX_HEAPS, + (driTextureObject *) t ); + + if ( heap == -1 ) { + fprintf( stderr, "%s: upload texture failure, sz=%d\n", __FUNCTION__, + t->base.totalSize ); + exit(-1); + return; + } - /* Do we need to eject LRU texture objects? */ - if ( !t->memBlock ) { t->heap = heap; - /* Allocate a memory block on a 64-byte boundary */ - t->memBlock = mmAllocMem( mmesa->texHeap[heap], t->size, 6, 0 ); - - /* Try AGP before kicking anything out of local mem */ - if ( !mmesa->mach64Screen->IsPCI && !t->memBlock && heap == MACH64_CARD_HEAP ) { - t->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], - t->size, 6, 0 ); - - if ( t->memBlock ) - heap = t->heap = MACH64_AGP_HEAP; - } - - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - if ( mmesa->TexObjList[heap].prev->bound ) { - fprintf( stderr, - "mach64UploadTexImages: ran into bound texture\n" ); - return; - } - if ( mmesa->TexObjList[heap].prev == &mmesa->TexObjList[heap] ) { - if ( mmesa->mach64Screen->IsPCI ) { - fprintf( stderr, "%s: upload texture failure on " - "local texture heaps, sz=%d\n", __FUNCTION__, - t->size ); - return; - } else if ( heap == MACH64_CARD_HEAP ) { - heap = t->heap = MACH64_AGP_HEAP; - continue; - } else { - int i; - fprintf( stderr, "%s: upload texture failure on " - "%sAGP texture heaps, sz=%d\n", __FUNCTION__, - mmesa->firstTexHeap == MACH64_CARD_HEAP ? "both local and " : "", - t->size ); - for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - mach64PrintLocalLRU( mmesa, i ); - mmDumpMemInfo( mmesa->texHeap[i] ); - } - exit(-1); - return; - } - } - - mach64SwapOutTexObj( mmesa, mmesa->TexObjList[heap].prev ); - - t->memBlock = mmAllocMem( mmesa->texHeap[heap], t->size, 6, 0 ); - } - /* Set the base offset of the texture image */ - t->offset = mmesa->mach64Screen->texOffset[heap] + t->memBlock->ofs; + t->bufAddr = mmesa->mach64Screen->texOffset[heap] + t->base.memBlock->ofs; /* Force loading the new state into the hardware */ mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL | @@ -673,142 +311,152 @@ void mach64UploadTexImages( mach64ContextPtr mmesa, mach64TexObjPtr t ) } /* Let the world know we've used this memory recently */ - mach64UpdateTexLRU( mmesa, t ); + driUpdateTextureLRU( (driTextureObject *) t ); /* Upload any images that are new */ - if ( t->dirty ) { + if ( t->base.dirty_images[0] ) { + const GLint j = t->base.tObj->BaseLevel; if (t->heap == MACH64_AGP_HEAP) { /* Need to make sure any vertex buffers in the queue complete */ mach64WaitForIdleLocked( mmesa ); - mach64UploadAGPSubImage( mmesa, t, t->tObj->BaseLevel, 0, 0, - t->tObj->Image[0][t->tObj->BaseLevel]->Width, - t->tObj->Image[0][t->tObj->BaseLevel]->Height ); + mach64UploadAGPSubImage( mmesa, t, j, 0, 0, + t->base.tObj->Image[0][j]->Width, + t->base.tObj->Image[0][j]->Height ); } else { - mach64UploadLocalSubImage( mmesa, t, t->tObj->BaseLevel, 0, 0, - t->tObj->Image[0][t->tObj->BaseLevel]->Width, - t->tObj->Image[0][t->tObj->BaseLevel]->Height ); + mach64UploadLocalSubImage( mmesa, t, j, 0, 0, + t->base.tObj->Image[0][j]->Width, + t->base.tObj->Image[0][j]->Height ); } mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH; + t->base.dirty_images[0] = 0; } mmesa->dirty |= MACH64_UPLOAD_TEXTURE; +} - t->dirty = 0; + +/* Allocate memory from the same texture heap `heap' for both textures + * `u0' and `u1'. + */ +static int mach64AllocateMultiTex( mach64ContextPtr mmesa, + mach64TexObjPtr u0, + mach64TexObjPtr u1, + int heap, GLboolean alloc_u0 ) +{ + /* Both objects should be bound */ + assert( u0->base.bound && u1->base.bound ); + + if ( alloc_u0 ) { + /* Evict u0 from its current heap */ + if ( u0->base.memBlock ) { + assert( u0->heap != heap ); + driSwapOutTextureObject( (driTextureObject *) u0 ); + } + + /* Try to allocate u0 in the chosen heap */ + u0->heap = driAllocateTexture( &mmesa->texture_heaps[heap], 1, + (driTextureObject *) u0 ); + + if ( u0->heap == -1 ) { + return -1; + } + } + + /* Evict u1 from its current heap */ + if ( u1->base.memBlock ) { + assert( u1->heap != heap ); + driSwapOutTextureObject( (driTextureObject *) u1 ); + } + + /* Try to allocate u1 in the same heap as u0 */ + u1->heap = driAllocateTexture( &mmesa->texture_heaps[heap], 1, + (driTextureObject *) u1 ); + + if ( u1->heap == -1 ) { + return -1; + } + + /* Bound objects are not evicted */ + assert( u0->base.memBlock && u1->base.memBlock ); + assert( u0->heap == u1->heap ); + + return heap; } /* The mach64 needs to have both primary and secondary textures in either * local or AGP memory, so we need a "buddy system" to make sure that allocation * succeeds or fails for both textures. - * FIXME: This needs to be optimized better. */ void mach64UploadMultiTexImages( mach64ContextPtr mmesa, mach64TexObjPtr t0, mach64TexObjPtr t1 ) { - GLint heap; - if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %p %p )\n", __FUNCTION__, mmesa->glCtx, t0, t1 ); } assert(t0 && t1); - assert(t0->tObj && t1->tObj); + assert(t0->base.tObj && t1->base.tObj); - /* Choose the heap appropriately */ - heap = MACH64_CARD_HEAP; + if ( !t0->base.memBlock || !t1->base.memBlock || t0->heap != t1->heap ) { + mach64TexObjPtr u0 = NULL; + mach64TexObjPtr u1 = NULL; + unsigned totalSize = t0->base.totalSize + t1->base.totalSize; - if ( !mmesa->mach64Screen->IsPCI && - ((t0->size + t1->size) > mmesa->mach64Screen->texSize[heap]) ) { - heap = MACH64_AGP_HEAP; - } + int heap, ret; - /* Do we need to eject LRU texture objects? */ - if ( !t0->memBlock || !t1->memBlock || t0->heap != t1->heap ) { - /* FIXME: starting from scratch for now to keep it simple */ - if ( t0->memBlock ) { - mach64SwapOutTexObj( mmesa, t0 ); - } - if ( t1->memBlock ) { - mach64SwapOutTexObj( mmesa, t1 ); - } - t0->heap = t1->heap = heap; - /* Allocate a memory block on a 64-byte boundary */ - t0->memBlock = mmAllocMem( mmesa->texHeap[heap], t0->size, 6, 0 ); - if ( t0->memBlock ) { - t1->memBlock = mmAllocMem( mmesa->texHeap[heap], t1->size, 6, 0 ); - if ( !t1->memBlock ) { - mmFreeMem( t0->memBlock ); - t0->memBlock = NULL; - } - } - /* Try AGP before kicking anything out of local mem */ - if ( (!t0->memBlock || !t1->memBlock) && heap == MACH64_CARD_HEAP ) { - t0->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], t0->size, 6, 0 ); - if ( t0->memBlock ) { - t1->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], t1->size, 6, 0 ); - if ( !t1->memBlock ) { - mmFreeMem( t0->memBlock ); - t0->memBlock = NULL; - } - } - - if ( t0->memBlock && t1->memBlock ) - heap = t0->heap = t1->heap = MACH64_AGP_HEAP; + /* Check if one of the textures is already swapped in a heap and the + * other texture fits in that heap. + */ + if ( t0->base.memBlock && totalSize <= t0->base.heap->size ) { + u0 = t0; + u1 = t1; + } else if ( t1->base.memBlock && totalSize <= t1->base.heap->size ) { + u0 = t1; + u1 = t0; } - /* Kick out textures until the requested texture fits */ - while ( !t0->memBlock || !t1->memBlock ) { - if ( mmesa->TexObjList[heap].prev->bound ) { - fprintf( stderr, - "%s: ran into bound texture\n", __FUNCTION__ ); - return; - } - if ( mmesa->TexObjList[heap].prev == &mmesa->TexObjList[heap] ) { - if ( mmesa->mach64Screen->IsPCI ) { - fprintf( stderr, "%s: upload texture failure on local " - "texture heaps, tex0 sz=%d tex1 sz=%d\n", __FUNCTION__, - t0->size, t1->size ); - return; - } else if ( heap == MACH64_CARD_HEAP ) { - /* If only one allocation succeeded, start over again in AGP */ - if (t0->memBlock) { - mmFreeMem( t0->memBlock ); - t0->memBlock = NULL; - } - if (t1->memBlock) { - mmFreeMem( t1->memBlock ); - t1->memBlock = NULL; - } - heap = t0->heap = t1->heap = MACH64_AGP_HEAP; - continue; - } else { - int i; - fprintf( stderr, "%s: upload texture failure on %s" - "AGP texture heaps, tex0 sz=%d tex1 sz=%d\n", __FUNCTION__, - mmesa->firstTexHeap == MACH64_CARD_HEAP ? "both local and " : "", - t0->size, t1->size ); - for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - mach64PrintLocalLRU( mmesa, i ); - mmDumpMemInfo( mmesa->texHeap[i] ); - } - exit(-1); - return; - } + if ( u0 ) { + heap = u0->heap; + + ret = mach64AllocateMultiTex( mmesa, u0, u1, heap, GL_FALSE ); + } else { + /* Both textures are swapped out or collocation is impossible */ + u0 = t0; + u1 = t1; + + /* Choose the heap appropriately */ + heap = MACH64_CARD_HEAP; + + if ( totalSize > mmesa->texture_heaps[heap]->size ) { + heap = MACH64_AGP_HEAP; } - mach64SwapOutTexObj( mmesa, mmesa->TexObjList[heap].prev ); - - if (!t0->memBlock) - t0->memBlock = mmAllocMem( mmesa->texHeap[heap], t0->size, 6, 0 ); - if (!t1->memBlock) - t1->memBlock = mmAllocMem( mmesa->texHeap[heap], t1->size, 6, 0 ); + ret = mach64AllocateMultiTex( mmesa, u0, u1, heap, GL_TRUE ); + } + + if ( ret == -1 && heap == MACH64_CARD_HEAP ) { + /* Try AGP if local memory failed */ + heap = MACH64_AGP_HEAP; + + ret = mach64AllocateMultiTex( mmesa, u0, u1, heap, GL_TRUE ); + } + + if ( ret == -1 ) { + /* FIXME: + * Swap out all textures from the AGP heap and re-run allocation, this + * should succeed in all cases. + */ + fprintf( stderr, "%s: upload multi-texture failure, sz0=%d sz1=%d\n", + __FUNCTION__, t0->base.totalSize, t1->base.totalSize ); + exit(-1); } /* Set the base offset of the texture image */ - t0->offset = mmesa->mach64Screen->texOffset[heap] + t0->memBlock->ofs; - t1->offset = mmesa->mach64Screen->texOffset[heap] + t1->memBlock->ofs; + t0->bufAddr = mmesa->mach64Screen->texOffset[heap] + t0->base.memBlock->ofs; + t1->bufAddr = mmesa->mach64Screen->texOffset[heap] + t1->base.memBlock->ofs; /* Force loading the new state into the hardware */ mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL | @@ -816,42 +464,43 @@ void mach64UploadMultiTexImages( mach64ContextPtr mmesa, } /* Let the world know we've used this memory recently */ - mach64UpdateTexLRU( mmesa, t0 ); - mach64UpdateTexLRU( mmesa, t1 ); + driUpdateTextureLRU( (driTextureObject *) t0 ); + driUpdateTextureLRU( (driTextureObject *) t1 ); /* Upload any images that are new */ - if ( t0->dirty ) { + if ( t0->base.dirty_images[0] ) { + const GLint j0 = t0->base.tObj->BaseLevel; if (t0->heap == MACH64_AGP_HEAP) { /* Need to make sure any vertex buffers in the queue complete */ mach64WaitForIdleLocked( mmesa ); - mach64UploadAGPSubImage( mmesa, t0, t0->tObj->BaseLevel, 0, 0, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Width, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Height ); + mach64UploadAGPSubImage( mmesa, t0, j0, 0, 0, + t0->base.tObj->Image[0][j0]->Width, + t0->base.tObj->Image[0][j0]->Height ); } else { - mach64UploadLocalSubImage( mmesa, t0, t0->tObj->BaseLevel, 0, 0, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Width, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Height ); + mach64UploadLocalSubImage( mmesa, t0, j0, 0, 0, + t0->base.tObj->Image[0][j0]->Width, + t0->base.tObj->Image[0][j0]->Height ); } mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH; + t0->base.dirty_images[0] = 0; } - if ( t1->dirty ) { + if ( t1->base.dirty_images[0] ) { + const GLint j1 = t1->base.tObj->BaseLevel; if (t1->heap == MACH64_AGP_HEAP) { /* Need to make sure any vertex buffers in the queue complete */ mach64WaitForIdleLocked( mmesa ); - mach64UploadAGPSubImage( mmesa, t1, t1->tObj->BaseLevel, 0, 0, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Width, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Height ); + mach64UploadAGPSubImage( mmesa, t1, j1, 0, 0, + t1->base.tObj->Image[0][j1]->Width, + t1->base.tObj->Image[0][j1]->Height ); } else { - mach64UploadLocalSubImage( mmesa, t1, t1->tObj->BaseLevel, 0, 0, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Width, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Height ); + mach64UploadLocalSubImage( mmesa, t1, j1, 0, 0, + t1->base.tObj->Image[0][j1]->Width, + t1->base.tObj->Image[0][j1]->Height ); } mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH; + t1->base.dirty_images[0] = 0; } mmesa->dirty |= MACH64_UPLOAD_TEXTURE; - - t0->dirty = 0; - t1->dirty = 0; } diff --git a/src/mesa/drivers/dri/mach64/mach64_texstate.c b/src/mesa/drivers/dri/mach64/mach64_texstate.c index b6a9e3f931e..3ace370d70d 100644 --- a/src/mesa/drivers/dri/mach64/mach64_texstate.c +++ b/src/mesa/drivers/dri/mach64/mach64_texstate.c @@ -47,11 +47,6 @@ static void mach64SetTexImages( mach64ContextPtr mmesa, { mach64TexObjPtr t = (mach64TexObjPtr) tObj->DriverData; struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; -#if 0 - int log2Pitch, log2Height, log2Size, log2MinSize; - int i; - GLint firstLevel, lastLevel; -#endif int totalSize; assert(t); @@ -92,77 +87,17 @@ static void mach64SetTexImages( mach64ContextPtr mmesa, _mesa_problem(mmesa->glCtx, "Bad texture format in %s", __FUNCTION__); }; -#if 0 - /* Compute which mipmap levels we really want to send to the hardware. - * This depends on the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. - * Yes, this looks overly complicated, but it's all needed. - */ - firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + totalSize = ( baseImage->Height * + baseImage->Width * + baseImage->TexFormat->TexelBytes ); - log2Pitch = tObj->Image[firstLevel]->WidthLog2; - log2Height = tObj->Image[firstLevel]->HeightLog2; - log2Size = MAX2(log2Pitch, log2Height); - log2MinSize = log2Size; + totalSize = (totalSize + 31) & ~31; - t->dirty = 0; - totalSize = 0; - for ( i = firstLevel; i <= lastLevel; i++ ) { - const struct gl_texture_image *texImage; - - texImage = tObj->Image[i]; - if ( !texImage || !texImage->Data ) { - lastLevel = i - 1; - break; - } - - log2MinSize = texImage->MaxLog2; - - t->image[i - firstLevel].offset = totalSize; - t->image[i - firstLevel].width = tObj->Image[i]->Width; - t->image[i - firstLevel].height = tObj->Image[i]->Height; - - t->dirty |= (1 << i); - - totalSize += (tObj->Image[i]->Height * - tObj->Image[i]->Width * - tObj->Image[i]->TexFormat->TexelBytes); - - /* Offsets must be 32-byte aligned for host data blits and tiling */ - totalSize = (totalSize + 31) & ~31; - } - - t->totalSize = totalSize; - t->firstLevel = firstLevel; - t->lastLevel = lastLevel; + t->base.totalSize = totalSize; + t->base.firstLevel = tObj->BaseLevel; + t->base.lastLevel = tObj->BaseLevel; /* Set the texture format */ - t->setup.tex_cntl &= ~(0xf << 16); - t->setup.tex_cntl |= t->textureFormat; - - t->setup.tex_combine_cntl = 0x00000000; /* XXX is this right? */ - - t->setup.tex_size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) | - (log2Size << R128_TEX_SIZE_SHIFT) | - (log2Height << R128_TEX_HEIGHT_SHIFT) | - (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); - - for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { - t->setup.tex_offset[i] = 0x00000000; - } - - if (firstLevel == lastLevel) - t->setup.tex_cntl |= R128_MIP_MAP_DISABLE; - else - t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE; - -#else if ( ( baseImage->_BaseFormat == GL_RGBA ) || ( baseImage->_BaseFormat == GL_ALPHA ) || ( baseImage->_BaseFormat == GL_LUMINANCE_ALPHA ) ) { @@ -171,15 +106,9 @@ static void mach64SetTexImages( mach64ContextPtr mmesa, t->hasAlpha = 0; } - totalSize = ( baseImage->Width * baseImage->Height * - baseImage->TexFormat->TexelBytes ); - totalSize = (totalSize + 31) & ~31; - t->size = totalSize; t->widthLog2 = baseImage->WidthLog2; t->heightLog2 = baseImage->HeightLog2; t->maxLog2 = baseImage->MaxLog2; - -#endif } static void mach64UpdateTextureEnv( GLcontext *ctx, int unit ) @@ -387,17 +316,17 @@ static void mach64UpdateTextureUnit( GLcontext *ctx, int unit ) } /* Upload teximages */ - if (t->dirty) { + if (t->base.dirty_images[0]) { mach64SetTexImages( mmesa, tObj ); mmesa->dirty |= (MACH64_UPLOAD_TEX0IMAGE << unit); } /* Bind to the given texture unit */ mmesa->CurrentTexObj[unit] = t; - t->bound |= (1 << unit); + t->base.bound |= (1 << unit); - if ( t->memBlock ) - mach64UpdateTexLRU( mmesa, t ); + if ( t->base.memBlock ) + driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ /* register setup */ if ( unit == 0 ) { @@ -515,8 +444,8 @@ void mach64UpdateTextureState( GLcontext *ctx ) FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_FALSE ); /* Unbind any currently bound textures */ - if ( mmesa->CurrentTexObj[0] ) mmesa->CurrentTexObj[0]->bound = 0; - if ( mmesa->CurrentTexObj[1] ) mmesa->CurrentTexObj[1]->bound = 0; + if ( mmesa->CurrentTexObj[0] ) mmesa->CurrentTexObj[0]->base.bound = 0; + if ( mmesa->CurrentTexObj[1] ) mmesa->CurrentTexObj[1]->base.bound = 0; mmesa->CurrentTexObj[0] = NULL; mmesa->CurrentTexObj[1] = NULL; @@ -556,3 +485,41 @@ void mach64UpdateTextureState( GLcontext *ctx ) MACH64_UPLOAD_TEXTURE); } + +/* Due to the way we must program texture state into the Rage Pro, + * we must leave these calculations to the absolute last minute. + */ +void mach64EmitTexStateLocked( mach64ContextPtr mmesa, + mach64TexObjPtr t0, + mach64TexObjPtr t1 ) +{ + drm_mach64_sarea_t *sarea = mmesa->sarea; + drm_mach64_context_regs_t *regs = &(mmesa->setup); + + /* for multitex, both textures must be local or AGP */ + if ( t0 && t1 ) + assert(t0->heap == t1->heap); + + if ( t0 ) { + if (t0->heap == MACH64_CARD_HEAP) { +#if ENABLE_PERF_BOXES + mmesa->c_texsrc_card++; +#endif + mmesa->setup.tex_cntl &= ~MACH64_TEX_SRC_AGP; + } else { +#if ENABLE_PERF_BOXES + mmesa->c_texsrc_agp++; +#endif + mmesa->setup.tex_cntl |= MACH64_TEX_SRC_AGP; + } + mmesa->setup.tex_offset = t0->bufAddr; + } + + if ( t1 ) { + mmesa->setup.secondary_tex_off = t1->bufAddr; + } + + memcpy( &sarea->context_state.tex_size_pitch, ®s->tex_size_pitch, + MACH64_NR_TEXTURE_REGS * sizeof(GLuint) ); +} + From 73eee2402eec80b745141689ecff2d4ecf36035e Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 13 Dec 2006 08:30:26 -0700 Subject: [PATCH 04/12] Use XDisplayName() when reporting errors (bug 8079). --- progs/xdemos/glthreads.c | 2 +- progs/xdemos/glxcontexts.c | 4 ++-- progs/xdemos/glxgears_fbconfig.c | 2 +- progs/xdemos/glxheads.c | 2 +- progs/xdemos/glxinfo.c | 2 +- progs/xdemos/glxswapcontrol.c | 2 +- progs/xdemos/manywin.c | 2 +- progs/xdemos/opencloseopen.c | 2 +- progs/xdemos/pbinfo.c | 2 +- progs/xdemos/yuvrect_client.c | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/progs/xdemos/glthreads.c b/progs/xdemos/glthreads.c index 83413383dd4..989697fbcaa 100644 --- a/progs/xdemos/glthreads.c +++ b/progs/xdemos/glthreads.c @@ -473,7 +473,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(displayName); if (!dpy) { - fprintf(stderr, "Unable to open display %s\n", displayName); + fprintf(stderr, "Unable to open display %s\n", XDisplayName(displayName)); return -1; } } diff --git a/progs/xdemos/glxcontexts.c b/progs/xdemos/glxcontexts.c index fbc296ef625..a9ff326ed5e 100644 --- a/progs/xdemos/glxcontexts.c +++ b/progs/xdemos/glxcontexts.c @@ -587,8 +587,8 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(dpyName); if (!dpy) { - printf("Error: couldn't open display %s\n", - dpyName ? dpyName : getenv("DISPLAY")); + fprintf(stderr, "Error: couldn't open display %s\n", + XDisplayName(dpyName)); return -1; } diff --git a/progs/xdemos/glxgears_fbconfig.c b/progs/xdemos/glxgears_fbconfig.c index acbadd21ac5..2dac00b75d1 100644 --- a/progs/xdemos/glxgears_fbconfig.c +++ b/progs/xdemos/glxgears_fbconfig.c @@ -575,7 +575,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(dpyName); if (!dpy) { - printf("Error: couldn't open display %s\n", dpyName); + printf("Error: couldn't open display %s\n", XDisplayName(dpyName)); return -1; } diff --git a/progs/xdemos/glxheads.c b/progs/xdemos/glxheads.c index 0145a70e91c..b3290e90d51 100644 --- a/progs/xdemos/glxheads.c +++ b/progs/xdemos/glxheads.c @@ -57,7 +57,7 @@ static int NumHeads = 0; static void Error(const char *display, const char *msg) { - fprintf(stderr, "Error on display %s - %s\n", display, msg); + fprintf(stderr, "Error on display %s - %s\n", XDisplayName(display), msg); exit(1); } diff --git a/progs/xdemos/glxinfo.c b/progs/xdemos/glxinfo.c index a1aca5ad31e..3e8e0be5203 100644 --- a/progs/xdemos/glxinfo.c +++ b/progs/xdemos/glxinfo.c @@ -939,7 +939,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(displayName); if (!dpy) { - fprintf(stderr, "Error: unable to open display %s\n", displayName); + fprintf(stderr, "Error: unable to open display %s\n", XDisplayName(displayName)); return -1; } diff --git a/progs/xdemos/glxswapcontrol.c b/progs/xdemos/glxswapcontrol.c index 0ed5ebe4722..d9be984be57 100644 --- a/progs/xdemos/glxswapcontrol.c +++ b/progs/xdemos/glxswapcontrol.c @@ -749,7 +749,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(dpyName); if (!dpy) { - printf("Error: couldn't open display %s\n", dpyName); + printf("Error: couldn't open display %s\n", XDisplayName(dpyName)); return -1; } diff --git a/progs/xdemos/manywin.c b/progs/xdemos/manywin.c index c9cca751341..cfea555210a 100644 --- a/progs/xdemos/manywin.c +++ b/progs/xdemos/manywin.c @@ -59,7 +59,7 @@ static GLuint TexObj = 0; static void Error(const char *display, const char *msg) { - fprintf(stderr, "Error on display %s - %s\n", display, msg); + fprintf(stderr, "Error on display %s - %s\n", XDisplayName(display), msg); exit(1); } diff --git a/progs/xdemos/opencloseopen.c b/progs/xdemos/opencloseopen.c index 2e4de24c71d..0b8d0618431 100644 --- a/progs/xdemos/opencloseopen.c +++ b/progs/xdemos/opencloseopen.c @@ -91,7 +91,7 @@ make_window( const char * dpyName, const char *name, dpy = XOpenDisplay(dpyName); if (!dpy) { - printf("Error: couldn't open display %s\n", dpyName); + printf("Error: couldn't open display %s\n", XDisplayName(dpyName)); exit(1); } diff --git a/progs/xdemos/pbinfo.c b/progs/xdemos/pbinfo.c index 88d93c8da62..b43adf1bb70 100644 --- a/progs/xdemos/pbinfo.c +++ b/progs/xdemos/pbinfo.c @@ -95,7 +95,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(dpyName); if (!dpy) { - printf("Error: couldn't open display %s\n", dpyName ? dpyName : ":0"); + printf("Error: couldn't open display %s\n", XDisplayName(dpyName)); return 1; } diff --git a/progs/xdemos/yuvrect_client.c b/progs/xdemos/yuvrect_client.c index 48f82cb7599..e2b79a7c0e1 100644 --- a/progs/xdemos/yuvrect_client.c +++ b/progs/xdemos/yuvrect_client.c @@ -296,7 +296,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(dpyName); if (!dpy) { printf("Error: couldn't open display %s\n", - dpyName ? dpyName : getenv("DISPLAY")); + XDisplayName(dpyName)); return -1; } From 6c305c083113075a1f11d5081b8c9dd1b98a7b1e Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 13 Dec 2006 08:57:06 -0700 Subject: [PATCH 05/12] Remove the xdemo.c program from PROGS since it doesn't work with GLX/DRI. --- progs/xdemos/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile index 4ca8b107a24..ec85464bec0 100644 --- a/progs/xdemos/Makefile +++ b/progs/xdemos/Makefile @@ -24,11 +24,11 @@ PROGS = glthreads \ pbinfo \ pbdemo \ wincopy \ - xdemo \ xfont \ xrotfontdemo \ yuvrect_client +# omit this XMesa API demo: xdemo ##### RULES ##### From 696fe3f52e0e7893740b430835f8c95611de3dd3 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 13 Dec 2006 13:24:35 -0800 Subject: [PATCH 06/12] if (tex width < 4), mipmap calculation will be out of range --- src/mesa/drivers/dri/i965/brw_tex_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 1353325afff..bf7047f644e 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -138,7 +138,7 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) /* Layout_below: step right after second mipmap. */ - if (level == mt->first_level + 1) { + if (level == mt->first_level + 1 && mt->pitch > 4) { x += mt->pitch / 2; x = (x + 3) & ~ 3; } From aeda4c589ada4e6304577e55d55b5c50bc274793 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 13 Dec 2006 13:25:12 -0800 Subject: [PATCH 07/12] ARB_occlusion_query support --- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/intel_context.c | 34 +++++++++++++++++++ src/mesa/drivers/dri/i965/intel_context.h | 1 + .../drivers/dri/i965/server/i830_common.h | 19 +++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 4707a709e77..e41042d6d27 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -168,7 +168,7 @@ static void upload_wm_unit(struct brw_context *brw ) wm.wm5.line_stipple = 1; } - if (INTEL_DEBUG & DEBUG_STATS) + if (INTEL_DEBUG & DEBUG_STATS || intel->stats_wm) wm.wm4.stats_enable = 1; brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm ); diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 5fc3d7150c3..6bcc984285c 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -70,6 +70,7 @@ int INTEL_DEBUG = (0); #define need_GL_ARB_vertex_buffer_object #define need_GL_ARB_vertex_program #define need_GL_ARB_window_pos +#define need_GL_ARB_occlusion_query #define need_GL_EXT_blend_color #define need_GL_EXT_blend_equation_separate #define need_GL_EXT_blend_func_separate @@ -160,6 +161,7 @@ const struct dri_extension card_extensions[] = { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, @@ -244,6 +246,36 @@ void intelFinish( GLcontext *ctx ) bmFinishFence(intel, bmLockAndFence(intel)); } +static void +intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + struct intel_context *intel = intel_context( ctx ); + GLuint64EXT tmp = 0; + drmI830MMIO io = { + .read_write = MMIO_WRITE, + .reg = MMIO_REGS_PS_DEPTH_COUNT, + .data = &tmp + }; + intel->stats_wm = GL_TRUE; + intelFinish(&intel->ctx); + drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); +} + +static void +intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + struct intel_context *intel = intel_context( ctx ); + drmI830MMIO io = { + .read_write = MMIO_READ, + .reg = MMIO_REGS_PS_DEPTH_COUNT, + .data = &q->Result + }; + intelFinish(&intel->ctx); + drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + q->Ready = GL_TRUE; + intel->stats_wm = GL_FALSE; +} + void intelInitDriverFunctions( struct dd_function_table *functions ) { @@ -253,6 +285,8 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) functions->Finish = intelFinish; functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; + functions->BeginQuery = intelBeginQuery; + functions->EndQuery = intelEndQuery; /* CopyPixels can be accelerated even with the current memory * manager: diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 85e574cdaf4..39eb7753017 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -177,6 +177,7 @@ struct intel_context GLuint second_last_swap_fence; GLboolean aub_wrap; + GLboolean stats_wm; struct intel_batchbuffer *batch; diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h index e3bbdc79070..f320378c2a5 100644 --- a/src/mesa/drivers/dri/i965/server/i830_common.h +++ b/src/mesa/drivers/dri/i965/server/i830_common.h @@ -52,6 +52,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_INIT_HEAP 0x0a #define DRM_I830_CMDBUFFER 0x0b #define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -199,5 +200,23 @@ typedef struct { int region; } drmI830MemDestroyHeap; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; #endif /* _I830_DRM_H_ */ From bce82efe1fc57f88dc050f5c13508b2e442b7a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 11 Dec 2006 17:36:35 +0100 Subject: [PATCH 08/12] minstall: Always remove destination file before (re-)creating it. This avoids issues with overwriting files that are being used. (cherry picked from d71a5647a3ed4aadd46edfa8a031ffc87d88c5f7 commit) --- bin/minstall | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/minstall b/bin/minstall index 9795263f9f1..210c2758d37 100755 --- a/bin/minstall +++ b/bin/minstall @@ -65,6 +65,7 @@ if [ $# -ge 2 ] ; then elif [ -f "$FILE" ] ; then #echo "$FILE" is a regular file + $RM "$DEST/$FILE" cp "$FILE" "$DEST" if [ $MODE ] ; then FILE=`basename "$FILE"` From c9795c6ca253b25b2b15967b064f32d9b822a1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 11 Dec 2006 17:45:06 +0100 Subject: [PATCH 09/12] minstall: Pass correct destination file path to $RM regardless of source path. (cherry picked from 26626c0052cd5442f609659aa9ed25ac78e65b55 commit) --- bin/minstall | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/minstall b/bin/minstall index 210c2758d37..819b2bc7e4a 100755 --- a/bin/minstall +++ b/bin/minstall @@ -65,7 +65,7 @@ if [ $# -ge 2 ] ; then elif [ -f "$FILE" ] ; then #echo "$FILE" is a regular file - $RM "$DEST/$FILE" + $RM "$DEST/`basename $FILE`" cp "$FILE" "$DEST" if [ $MODE ] ; then FILE=`basename "$FILE"` From 4720cd00507f2c13becf318709f7c1fe24ba5146 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Tue, 12 Dec 2006 14:56:59 +0800 Subject: [PATCH 10/12] fix bug #99. prim_count overflow when there is more than 1 cliprect (cherry picked from 84b958d66fe7d3fe03ed12b493e3f3197f656531 commit) --- src/mesa/drivers/dri/i965/brw_exec_api.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c index 470fa6f4177..8b243c60842 100644 --- a/src/mesa/drivers/dri/i965/brw_exec_api.c +++ b/src/mesa/drivers/dri/i965/brw_exec_api.c @@ -42,6 +42,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dispatch.h" #include "brw_exec.h" +#include "intel_context.h" + static void reset_attrfv( struct brw_exec_context *exec ); @@ -522,6 +524,14 @@ static void GLAPIENTRY brw_exec_Begin( GLenum mode ) } +static GLuint brw_max_prim( GLcontext *ctx ) +{ + struct intel_context *intel = intel_context( ctx ); + if (intel->numClipRects <= 1) + return BRW_MAX_PRIM; + return BRW_MAX_PRIM/intel->numClipRects; +} + static void GLAPIENTRY brw_exec_End( void ) { GET_CURRENT_CONTEXT( ctx ); @@ -536,7 +546,7 @@ static void GLAPIENTRY brw_exec_End( void ) ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - if (exec->vtx.prim_count == BRW_MAX_PRIM) + if (exec->vtx.prim_count >= brw_max_prim(ctx)) brw_exec_vtx_flush( exec ); } else From ed7fbad2066f846bf9466b13b184a50d6f87f972 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 13 Dec 2006 15:22:45 +0800 Subject: [PATCH 11/12] Fix bug #93, i965 driver not thread safe. I am not confident of it is 100% thread safe now. bufmgr_fake.c need a total rewrite later (cherry picked from 606632ca27558ee1335be2f4a5906f2baa240a6a commit) --- src/mesa/drivers/dri/i965/bufmgr.h | 2 ++ src/mesa/drivers/dri/i965/bufmgr_fake.c | 16 ++++++++++++++-- src/mesa/drivers/dri/i965/intel_blit.c | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h index 6932522d3d3..e748c0d6d0b 100644 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -199,9 +199,11 @@ void *bmFindVirtual( struct intel_context *intel, * For now they can stay, but will likely change/move before final: */ unsigned bmSetFence( struct intel_context * ); +unsigned bmSetFenceLock( struct intel_context * ); unsigned bmLockAndFence( struct intel_context *intel ); int bmTestFence( struct intel_context *, unsigned fence ); void bmFinishFence( struct intel_context *, unsigned fence ); +void bmFinishFenceLock( struct intel_context *, unsigned fence ); void bm_fake_NotifyContendedLockTake( struct intel_context * ); diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c index ed88ab3797a..205dc722c06 100644 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -338,7 +338,6 @@ static int evict_mru( struct intel_context *intel, GLuint *pool ) } - static int check_fenced( struct intel_context *intel ) { struct bufmgr *bm = intel->bm; @@ -1328,11 +1327,19 @@ unsigned bmSetFence( struct intel_context *intel ) return intel->bm->last_fence; } +unsigned bmSetFenceLock( struct intel_context *intel ) +{ + LOCK(intel->bm); + bmSetFence(intel); + UNLOCK(intel->bm); +} unsigned bmLockAndFence( struct intel_context *intel ) { if (intel->bm->need_fence) { LOCK_HARDWARE(intel); + LOCK(intel->bm); bmSetFence(intel); + UNLOCK(intel->bm); UNLOCK_HARDWARE(intel); } @@ -1350,7 +1357,12 @@ void bmFinishFence( struct intel_context *intel, unsigned fence ) check_fenced(intel); } - +void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) +{ + LOCK(intel->bm); + bmFinishFence(intel, fence); + UNLOCK(intel->bm); +} /* Specifically ignore texture memory sharing. diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index c8c5bf93c95..173d1d5b6c2 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - bmFinishFence(intel, intel->last_swap_fence); + bmFinishFenceLock(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -155,7 +155,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intel_batchbuffer_flush( intel->batch ); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = bmSetFence( intel ); + intel->last_swap_fence = bmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) From 2956a0c8a8395e4d9ae00888aeb88ea5c38b89ad Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 14 Dec 2006 00:34:44 +0100 Subject: [PATCH 12/12] submit vertex weights to make World of Warcraft maybe happy (bug 8250) submit the vertex weights to hw, which will enable broken vertex programs errorneously using them to work. Note however that this will only work if glWeight is used, there is no code in mesa at all to deal with weight vertex array (glWeightPointerARB). --- src/mesa/drivers/dri/r200/r200_context.h | 1 + src/mesa/drivers/dri/r200/r200_maos_arrays.c | 19 ++++++++++++++++++- src/mesa/drivers/dri/r200/r200_vertprog.c | 1 - 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index fa38a78e263..44c67b68cbc 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -735,6 +735,7 @@ struct r200_tcl_info { GLuint *Elts; struct r200_dma_region indexed_verts; + struct r200_dma_region weight; struct r200_dma_region obj; struct r200_dma_region rgba; struct r200_dma_region spec; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 39c1f68911f..270dc35a46a 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -423,7 +423,21 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) count ); } component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + } + + if (inputs & VERT_BIT_WEIGHT) { + if (!rmesa->tcl.weight.buf) + emit_vector( ctx, + &rmesa->tcl.weight, + (char *)VB->AttribPtr[VERT_ATTRIB_WEIGHT]->data, + VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size, + VB->AttribPtr[VERT_ATTRIB_WEIGHT]->stride, + count); + + assert(VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size <= 4); + vfmt0 |= VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size << R200_VTX_WEIGHT_COUNT_SHIFT; + component[nr++] = &rmesa->tcl.weight; } if (inputs & VERT_BIT_NORMAL) { @@ -672,6 +686,9 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) if (newinputs & VERT_BIT_POS) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); + if (newinputs & VERT_BIT_WEIGHT) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.weight, __FUNCTION__ ); + if (newinputs & VERT_BIT_NORMAL) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 899e84caa0f..491701b796e 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -503,7 +503,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { - /* we don't actually handle that later. Then again, we don't have to... */ vp->inputs[VERT_ATTRIB_WEIGHT] = 12; array_count++; }