Merge branch 'crestline' into crestline-qa

This commit is contained in:
Nian Wu 2006-12-17 10:49:43 -08:00
commit ead0f46d5f
23 changed files with 356 additions and 793 deletions

View file

@ -24,11 +24,11 @@ PROGS = glthreads \
pbinfo \
pbdemo \
wincopy \
xdemo \
xfont \
xrotfontdemo \
yuvrect_client
# omit this XMesa API demo: xdemo
##### RULES #####

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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 */

View file

@ -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
*/

View file

@ -82,14 +82,15 @@ 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;
}
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] );
}
}

View file

@ -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 {

View file

@ -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, &regs->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();
}

View file

@ -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 );

View file

@ -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<<log2sz) > 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;
}

View file

@ -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, &regs->tex_size_pitch,
MACH64_NR_TEXTURE_REGS * sizeof(GLuint) );
}

View file

@ -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 );

View file

@ -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;

View file

@ -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__ );

View file

@ -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++;
}