diff options
author | kem <kem> | 2001-03-07 21:47:11 +0000 |
---|---|---|
committer | kem <kem> | 2001-03-07 21:47:11 +0000 |
commit | bbfdc489c17ab69c7071acd8f94ce0c9b2a15abb (patch) | |
tree | 052a9299a68f44afdc002196de62837b617d0ee4 /xc/lib/GL | |
parent | 38baaad074b69a17801ab41e8edb1c033f270650 (diff) |
- Merge from trunk into branchsarea-1-0-0-20010307
Diffstat (limited to 'xc/lib/GL')
47 files changed, 5083 insertions, 5097 deletions
diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile index cc88803f4..7ccc16fd7 100644 --- a/xc/lib/GL/mesa/src/Imakefile +++ b/xc/lib/GL/mesa/src/Imakefile @@ -152,6 +152,8 @@ LinkSourceFile(state.c, $(MESASRCDIR)/src) LinkSourceFile(state.h, $(MESASRCDIR)/src) LinkSourceFile(stencil.c, $(MESASRCDIR)/src) LinkSourceFile(stencil.h, $(MESASRCDIR)/src) +LinkSourceFile(texformat.c, $(MESASRCDIR)/src) +LinkSourceFile(texformat.h, $(MESASRCDIR)/src) LinkSourceFile(texgen_tmp.h, $(MESASRCDIR)/src) LinkSourceFile(teximage.c, $(MESASRCDIR)/src) LinkSourceFile(teximage.h, $(MESASRCDIR)/src) @@ -163,6 +165,7 @@ LinkSourceFile(texture.c, $(MESASRCDIR)/src) LinkSourceFile(texture.h, $(MESASRCDIR)/src) LinkSourceFile(texutil.c, $(MESASRCDIR)/src) LinkSourceFile(texutil.h, $(MESASRCDIR)/src) +LinkSourceFile(texutil_tmp.h, $(MESASRCDIR)/src) LinkSourceFile(trans_tmp.h, $(MESASRCDIR)/src) LinkSourceFile(translate.c, $(MESASRCDIR)/src) LinkSourceFile(translate.h, $(MESASRCDIR)/src) @@ -252,6 +255,7 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src) stages.c \ state.c \ stencil.c \ + texformat.c \ teximage.c \ texobj.c \ texstate.c \ @@ -325,6 +329,7 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src) stages.o \ state.o \ stencil.o \ + texformat.o \ teximage.o \ texobj.o \ texstate.o \ @@ -346,8 +351,8 @@ LinkSourceFile(zoom.h, $(MESASRCDIR)/src) zoom.o #ifdef i386Architecture - ASM_SRCS = - ASM_OBJS = + ASM_SRCS = + ASM_OBJS = #if MesaUseMMX MMX_DEFS = -DUSE_MMX_ASM #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h index a7200f1b8..cad45626d 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h @@ -113,8 +113,8 @@ #define LCS_LINEWIDTH_2_0 (0x4<<12) #define LCS_LINEWIDTH_3_0 (0x6<<12) #define LCS_UPDATE_ALPHA_INTERP (0x1<<11) -#define LCS_ALPHA_FLAT (0x0<<10) -#define LCS_ALPHA_INTERP (0x1<<10) +#define LCS_ALPHA_FLAT (0x1<<10) +#define LCS_ALPHA_INTERP (0x0<<10) #define LCS_UPDATE_FOG_INTERP (0x1<<9) #define LCS_FOG_INTERP (0x0<<8) #define LCS_FOG_FLAT (0x1<<8) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c index 2f16e33d7..146b6c1b9 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c @@ -200,7 +200,6 @@ void i810DmaFinish( i810ContextPtr imesa ) FLUSH_BATCH( imesa ); if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { - if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "i810DmaFinish\n"); @@ -214,14 +213,22 @@ void i810DmaFinish( i810ContextPtr imesa ) void i810RegetLockQuiescent( i810ContextPtr imesa ) { + /* XXX I disabled this conditional. Doing so fixes all the readpixels + * problems. The problem was that we'd sometimes read from the frame + * buffer (via the span functions) before rendering was completed. + * Taking out this conditional solves that problem. (BrianP) + * if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { + */ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "i810RegetLockQuiescent\n"); drmUnlock(imesa->driFd, imesa->hHWContext); i810GetLock( imesa, DRM_LOCK_QUIESCENT ); imesa->sarea->last_quiescent = imesa->sarea->last_enqueue; + /* } + */ } void i810WaitAgeLocked( i810ContextPtr imesa, int age ) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c index 9e86e9b68..4bf02ad13 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810span.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c @@ -30,7 +30,7 @@ dPriv->x * 2 + \ dPriv->y * pitch) -#define INIT_MONO_PIXEL(p) +#define INIT_MONO_PIXEL(p) #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ _y >= miny && _y < maxy) @@ -50,6 +50,8 @@ #define HW_LOCK() \ i810ContextPtr imesa = I810_CONTEXT(ctx); \ + FLUSH_BATCH(imesa); \ + i810DmaFinish(imesa); \ LOCK_HARDWARE_QUIESCENT(imesa); #define HW_CLIPLOOP() \ @@ -85,9 +87,9 @@ #define READ_RGBA( rgba, _x, _y ) \ do { \ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ + rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \ + rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \ + rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \ rgba[3] = 255; \ } while(0) @@ -128,7 +130,7 @@ do { \ *(GLushort *)(buf + _x*2 + _y*pitch) = d; #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + _x*2 + _y*pitch); + d = *(GLushort *)(buf + _x*2 + _y*pitch); /* d = 0xffff; */ @@ -144,7 +146,7 @@ void i810DDInitSpanFuncs( GLcontext *ctx ) ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_565; ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_565; ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_565; - ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565; + ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565; ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_565; ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_565; } else { diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c index cdccbd5ec..50a916fb7 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c @@ -182,6 +182,7 @@ static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) GLubyte p[4]; int i,j,k; int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON); + GLuint newMask; FLUSH_BATCH(imesa); ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; @@ -191,10 +192,10 @@ static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; } - p[0] = mask[0] & 0xf; p[0] |= p[0] << 4; - p[1] = mask[4] & 0xf; p[1] |= p[1] << 4; - p[2] = mask[8] & 0xf; p[2] |= p[2] << 4; - p[3] = mask[12] & 0xf; p[3] |= p[3] << 4; + p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; for (k = 0 ; k < 8 ; k++) for (j = 0 ; j < 4; j++) @@ -203,12 +204,19 @@ static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; return; } - + + newMask = ((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12); + if (newMask == 0xffff) { + /* do opaque stipple in software for conformance */ + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + return; + } + imesa->Setup[I810_CTXREG_ST1] &= ~0xffff; - imesa->Setup[I810_CTXREG_ST1] |= ( ((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | - ((p[3] & 0xf) << 12) ); + imesa->Setup[I810_CTXREG_ST1] |= newMask; if (active) imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; @@ -439,26 +447,23 @@ static GLboolean i810DDColorMask(GLcontext *ctx, GLboolean b, GLboolean a ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); - GLuint tmp = 0; - GLuint rv = 1; - - imesa->Fallback &= ~I810_FALLBACK_COLORMASK; + GLuint tmp; - if (r && g && b) { - tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE; - } else if (!r && !g && !b) { - tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE; - } else { - rv = 0; + if (r && g && b) + imesa->Fallback &= ~I810_FALLBACK_COLORMASK; + else imesa->Fallback |= I810_FALLBACK_COLORMASK; - } - + + tmp = imesa->Setup[I810_CTXREG_B2] | + (B2_FB_WRITE_ENABLE | B2_UPDATE_FB_WRITE_ENABLE); + if (tmp != imesa->Setup[I810_CTXREG_B2]) { FLUSH_BATCH(imesa); imesa->Setup[I810_CTXREG_B2] = tmp; + imesa->dirty |= I810_UPLOAD_CTX; } - return rv; + return GL_FALSE; /* makes s/w path always do s/w masking */ } /* Seperate specular not fully implemented in hardware... Needs @@ -625,16 +630,6 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_TEXTURE_2D: FLUSH_BATCH(imesa); imesa->new_state |= I810_NEW_TEXTURE; - imesa->dirty |= I810_UPLOAD_CTX; - if (ctx->Texture.CurrentUnit == 0) { - imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; - if (state) - imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; - } else { - imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; - if (state) - imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; - } break; case GL_COLOR_LOGIC_OP: FLUSH_BATCH( imesa ); @@ -995,8 +990,8 @@ void i810DDInitState( i810ContextPtr imesa ) #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ NEW_TEXTURE_MATRIX|\ - NEW_USER_CLIP|NEW_CLIENT_STATE|\ - NEW_TEXTURE_ENABLE)) + NEW_USER_CLIP|NEW_CLIENT_STATE)) + void i810DDUpdateState( GLcontext *ctx ) { diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c index 5c1615128..ff537aece 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c @@ -705,44 +705,50 @@ static void i810UpdateTex0State( GLcontext *ctx ) struct gl_texture_object *tObj; i810TextureObjectPtr t; int ma_modulate_op; + int format; - - tObj = ctx->Texture.Unit[0].Current; - - if ( tObj != ctx->Texture.Unit[0].CurrentD[2] ) - tObj = 0; - - + /* disable */ + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ITERATED_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ); - + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ); imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ); - + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + if (ctx->Texture.Unit[0].ReallyEnabled == 0) { + return; + } - if (!(ctx->Texture.ReallyEnabled & 0xf) || !tObj || !tObj->Complete) { + tObj = ctx->Texture.Unit[0].Current; + if (ctx->Texture.Unit[0].ReallyEnabled != TEXTURE0_2D || + tObj->Image[tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + imesa->Fallback |= I810_FALLBACK_TEXTURE; return; } + /* Do 2D texture setup */ + + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; + t = tObj->DriverData; - if (!t) { t = i810CreateTexObj( imesa, tObj ); - if (!t) return; + if (!t) + return; } if (t->current_unit != 0) @@ -757,9 +763,11 @@ static void i810UpdateTex0State( GLcontext *ctx ) if (t->MemBlock) i810UpdateTexLRU( imesa, t ); + format = t->image[0].internalFormat; + switch (ctx->Texture.Unit[0].EnvMode) { case GL_REPLACE: - if (t->image[0].internalFormat == GL_ALPHA) + if (format == GL_ALPHA) imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | @@ -782,7 +790,7 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_ARG1 ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_ARG2; @@ -809,7 +817,7 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_MODULATE ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_MODULATE; @@ -826,30 +834,74 @@ static void i810UpdateTex0State( GLcontext *ctx ) break; case GL_ADD: - imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_ADD ); + if (format == GL_ALPHA) { + /* Cv = Cf */ + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ARG2 ); + } + else { + /* Cv = Cf + Ct */ + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ADD ); + } - imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ADD ); + /* alpha */ + if (format == GL_ALPHA || + format == GL_LUMINANCE_ALPHA || + format == GL_RGBA) { + /* Av = Af * At */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_MODULATE ); + } + else if (format == GL_LUMINANCE || format == GL_RGB) { + /* Av = Af */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); + } + else { + /* Av = Af + At */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ADD ); + } break; case GL_DECAL: - - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { + /* C = Ct */ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | @@ -862,29 +914,32 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_OP_ARG2 ); } else { + /* RGBA or undefined result */ + /* C = Cf*(1-At)+Ct*At */ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | MC_DEST_CURRENT | MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | + MC_ARG1_TEX0_COLOR | MC_UPDATE_ARG2 | - MC_ARG2_TEX0_COLOR | + MC_ARG2_ITERATED_COLOR | MC_UPDATE_OP | MC_OP_LIN_BLEND_TEX0_ALPHA ); } + /* Av = Af */ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | + MA_ARG1_ITERATED_ALPHA | MA_UPDATE_ARG2 | - MA_ARG2_ALPHA_FACTOR | + MA_ARG2_ITERATED_ALPHA | MA_UPDATE_OP | MA_OP_ARG1 ); break; case GL_BLEND: - if (t->image[0].internalFormat == GL_ALPHA) + if (format == GL_ALPHA) imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | @@ -907,7 +962,20 @@ static void i810UpdateTex0State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_LIN_BLEND_TEX0_COLOR ); - if (t->image[0].internalFormat == GL_RGB) { + /* alpha */ + if (format == GL_LUMINANCE || format == GL_RGB) { + /* Av = Af */ + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); + } + else if (format == GL_INTENSITY) { + /* Av = Af(1-It)+AcIt */ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | @@ -915,16 +983,17 @@ static void i810UpdateTex0State( GLcontext *ctx ) MA_UPDATE_ARG2 | MA_ARG2_ITERATED_ALPHA | MA_UPDATE_OP | - MA_OP_ARG1 ); + MA_OP_LIN_BLEND_TEX0_ALPHA ); } else { + /* Av = AfAt */ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | + MA_ARG1_TEX0_ALPHA | MA_UPDATE_ARG2 | MA_ARG2_ITERATED_ALPHA | MA_UPDATE_OP | - MA_OP_LIN_BLEND_TEX0_ALPHA ); + MA_OP_MODULATE ); } break; @@ -942,50 +1011,56 @@ static void i810UpdateTex1State( GLcontext *ctx ) i810ContextPtr imesa = I810_CONTEXT(ctx); struct gl_texture_object *tObj; i810TextureObjectPtr t; - int ma_modulate_op; - - - tObj = ctx->Texture.Unit[1].Current; - - if ( tObj != ctx->Texture.Unit[1].CurrentD[2] ) - tObj = 0; - + int ma_modulate_op, format; + /* disable */ + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ONE | - MC_ARG1_DONT_REPLICATE_ALPHA | - MC_ARG1_DONT_INVERT | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_ARG2_DONT_REPLICATE_ALPHA | - MC_ARG2_DONT_INVERT | - MC_UPDATE_OP | - MC_OP_DISABLE ); - + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ONE | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_ARG1_DONT_INVERT | - MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_ARG2_DONT_INVERT | - MA_UPDATE_OP | - MA_OP_ARG1 ); - - if (!(ctx->Texture.ReallyEnabled & 0xf0) || !tObj || !tObj->Complete) { + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + if (ctx->Texture.Unit[1].ReallyEnabled == 0) { + return; + } + + tObj = ctx->Texture.Unit[1].Current; + if (ctx->Texture.Unit[1].ReallyEnabled != TEXTURE0_2D || + tObj->Image[tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + imesa->Fallback |= I810_FALLBACK_TEXTURE; return; } + /* Do 2D texture setup */ + + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; + t = tObj->DriverData; - if (!t) { t = i810CreateTexObj( imesa, tObj ); - if (!t) return; + if (!t) + return; } if (t->current_unit != 1) @@ -1000,6 +1075,8 @@ static void i810UpdateTex1State( GLcontext *ctx ) if (t->MemBlock) i810UpdateTexLRU( imesa, t ); + format = t->image[0].internalFormat; + switch (ctx->Texture.Unit[1].EnvMode) { case GL_REPLACE: imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | @@ -1013,7 +1090,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_ARG1 ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_ARG2; @@ -1040,7 +1117,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_MODULATE ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_MODULATE; @@ -1068,7 +1145,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_ADD ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { ma_modulate_op = MA_OP_ARG1; } else { ma_modulate_op = MA_OP_ADD; @@ -1086,7 +1163,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) case GL_DECAL: - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | MC_STAGE_1 | MC_UPDATE_DEST | @@ -1133,7 +1210,7 @@ static void i810UpdateTex1State( GLcontext *ctx ) MC_UPDATE_OP | MC_OP_LIN_BLEND_TEX1_COLOR ); - if (t->image[0].internalFormat == GL_RGB) { + if (format == GL_RGB) { imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_1 | MA_UPDATE_ARG1 | @@ -1169,11 +1246,12 @@ void i810UpdateTextureState( GLcontext *ctx ) if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0; imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; + imesa->Fallback &= ~I810_FALLBACK_TEXTURE; i810UpdateTex0State( ctx ); i810UpdateTex1State( ctx ); I810_CONTEXT( ctx )->dirty |= (I810_UPLOAD_CTX | - I810_UPLOAD_TEX0 | - I810_UPLOAD_TEX1); + I810_UPLOAD_TEX0 | + I810_UPLOAD_TEX1); } @@ -1196,13 +1274,17 @@ static void i810TexEnv( GLcontext *ctx, GLenum target, struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLfloat *fc = texUnit->EnvColor; - GLuint col; - - col = ((((GLubyte)fc[3])<<24) | - (((GLubyte)fc[0])<<16) | - (((GLubyte)fc[1])<<8) | - (((GLubyte)fc[2])<<0)); + const GLfloat *fc = texUnit->EnvColor; + GLuint r, g, b, a, col; + FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[0]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[1]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[2]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[3]); + + col = ((a << 24) | + (r << 16) | + (g << 8) | + (b << 0)); if (imesa->Setup[I810_CTXREG_CF1] != col) { FLUSH_BATCH(imesa); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h index a83adad95..a416f82dc 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h @@ -87,40 +87,42 @@ static __inline__ void i810_draw_point( i810ContextPtr imesa, { int vertsize = imesa->vertsize; GLuint *vb = i810AllocDwordsInline( imesa, 6 * vertsize ); + const GLfloat x = tmp->v.x + 0.125; + const GLfloat y = tmp->v.y - 0.5F; int j; - *(float *)&vb[0] = tmp->v.x - sz; - *(float *)&vb[1] = tmp->v.y - sz; + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y - sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x + sz; - *(float *)&vb[1] = tmp->v.y - sz; + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y - sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x + sz; - *(float *)&vb[1] = tmp->v.y + sz; + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y + sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x + sz; - *(float *)&vb[1] = tmp->v.y + sz; + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y + sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x - sz; - *(float *)&vb[1] = tmp->v.y + sz; + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y + sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; vb += vertsize; - *(float *)&vb[0] = tmp->v.x - sz; - *(float *)&vb[1] = tmp->v.y - sz; + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y - sz; for (j = 2 ; j < vertsize ; j++) vb[j] = tmp->ui[j]; } @@ -143,13 +145,33 @@ static __inline__ void i810_draw_line( i810ContextPtr imesa, : "=%c" (j) : "0" (vertsize), "S" ((long)v1) : "memory" ); +#elif 0 + for (j = 0 ; j < vertsize ; j++) + vb[j] = v0->ui[j]; + + vb += vertsize; + for (j = 0 ; j < vertsize ; j++) + vb[j] = v1->ui[j]; #else + const GLfloat dx = -0.5; + const GLfloat dy = -0.5; + + v0->v.x += dx; + v0->v.y += dy; + v1->v.x += dx; + v1->v.y += dy; + for (j = 0 ; j < vertsize ; j++) vb[j] = v0->ui[j]; vb += vertsize; for (j = 0 ; j < vertsize ; j++) vb[j] = v1->ui[j]; + + v0->v.x -= dx; + v0->v.y -= dy; + v1->v.x -= dx; + v1->v.y -= dy; #endif } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c index a6ad760a6..5ecc3e2af 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c @@ -87,15 +87,18 @@ #define COORD \ GLfloat *win = VB->Win.data[i]; \ - v->v.x = win[0]; \ - v->v.y = i810height - win[1]; \ - v->v.z = (1.0/0x10000) * win[2]; \ + v->v.x = xoffset + win[0]; \ + v->v.y = yoffset - win[1]; \ + v->v.z = (1.0/0x10000) * win[2]; \ v->v.oow = win[3]; #define NOP +#define SUBPIXEL_X -0.5 +#define SUBPIXEL_Y -0.375 + #define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ @@ -105,9 +108,12 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ i810VertexPtr v; \ GLfloat (*tc0)[4]; \ GLfloat (*tc1)[4]; \ - GLfloat i810height = dPriv->h; \ + const GLfloat xoffset = SUBPIXEL_X; \ + const GLfloat yoffset = dPriv->h + SUBPIXEL_Y; \ int i; \ - (void) i810height; (void) imesa; \ + (void) xoffset; \ + (void) yoffset; \ + (void) imesa; \ \ \ gl_import_client_data( VB, VB->ctx->RenderFlags, \ @@ -269,7 +275,7 @@ void i810ChooseRasterSetupFunc(GLcontext *ctx) funcindex |= I810_TEX0_BIT; if (ctx->Texture.ReallyEnabled & 0xf0) { - funcindex |= I810_TEX1_BIT; + funcindex |= (I810_TEX0_BIT | I810_TEX1_BIT); imesa->vertsize = 10; imesa->Setup[I810_CTXREG_VF] = I810_VFMT_T0T1; } diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile index 2630d8159..e4c73ddc0 100644 --- a/xc/lib/GL/mesa/src/drv/mga/Imakefile +++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile @@ -151,6 +151,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ ../../stages.c \ ../../state.c \ ../../stencil.c \ + ../../texformat.c \ ../../teximage.c \ ../../texobj.c \ ../../texstate.c \ @@ -224,6 +225,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ ../../stages.o \ ../../state.o \ ../../stencil.o \ + ../../texformat.o \ ../../teximage.o \ ../../texobj.o \ ../../texstate.o \ diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index f428614f0..8e7bb0f24 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -314,6 +314,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, mmesa->hHWContext = driContextPriv->hHWContext; mmesa->driFd = sPriv->fd; mmesa->driHwLock = &sPriv->pSAREA->lock; + mmesa->mgaScreen = mgaScreen; mmesa->driScreen = sPriv; mmesa->sarea = saPriv; @@ -374,7 +375,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, break; }; - + mmesa->canDoStipple = GL_FALSE; mmesa->renderindex = -1; /* impossible value */ mmesa->new_state = ~0; mmesa->dirty = ~0; @@ -444,14 +445,16 @@ GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, __DRIdrawablePrivate *driDrawPriv, GLvisual *mesaVis) { + GLboolean swStencil = mesaVis->StencilBits > 0 && mesaVis->DepthBits != 24; + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) fprintf(stderr, "XMesaCreateWindowBuffer\n"); return gl_create_framebuffer(mesaVis, GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, + swStencil, mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 + GL_FALSE /* software alpha buffer/ */ ); } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h index 1ae30deec..e1aacb193 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h @@ -57,11 +57,13 @@ * - texture env GL_BLEND -- can be fixed * - 1D and 3D textures * - incomplete textures + * - GL_DEPTH_FUNC == GL_NEVER not in h/w */ #define MGA_FALLBACK_TEXTURE 0x1 #define MGA_FALLBACK_BUFFER 0x2 #define MGA_FALLBACK_LOGICOP 0x4 #define MGA_FALLBACK_STENCIL 0x8 +#define MGA_FALLBACK_DEPTH 0x10 /* For mgaCtx->new_state. @@ -191,6 +193,7 @@ struct mga_context_t { GLuint depth_clear_mask; GLuint stencil_clear_mask; GLuint hw_stencil; + GLboolean canDoStipple; /* Dma buffers */ @@ -220,7 +223,6 @@ struct mga_context_t { */ unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */ unsigned int dirtyAge; /* buffer age for synchronization */ - unsigned int lastSwap; /* throttling runaway apps */ GLuint *status; GLuint status_offset; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index dced4235b..6f055c5be 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -51,7 +51,7 @@ #include "X86/common_x86_asm.h" #endif -#define MGA_DATE "20010215" +#define MGA_DATE "20010306" diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index c803ac5b5..c31d23eca 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -28,7 +28,7 @@ static void mga_iload_dma_ioctl(mgaContextPtr mmesa, if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n", - buf->idx, dest, length); + buf->idx, (int) dest, length); ret = drmMGATextureLoad( mmesa->driFd, buf->idx, dest, length ); if ( ret < 0 ) { @@ -156,8 +156,9 @@ drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) -GLbitfield mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ) +static GLbitfield +mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; @@ -290,7 +291,6 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) int nbox; int ret; int i; - int tmp; GLuint last_frame, last_wrap; FLUSH_BATCH( mmesa ); @@ -300,6 +300,16 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) last_frame = mmesa->sarea->last_frame.head; last_wrap = mmesa->sarea->last_frame.wrap; + /* FIXME: Add a timeout to this loop... + */ + while ( 1 ) { + if ( last_wrap < mmesa->sarea->last_wrap || + ( last_wrap == mmesa->sarea->last_wrap && + last_frame <= *mmesa->status - mmesa->status_offset ) ) { + break; + } + } + /* Use the frontbuffer cliprects */ if (mmesa->dirty_cliprects & MGA_FRONT) @@ -329,32 +339,8 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) } } - if ( 0 ) { - fprintf( stderr, "waiting...\n" ); - } - - while ( 1 ) { - if ( last_wrap < mmesa->sarea->last_wrap || - ( last_wrap == mmesa->sarea->last_wrap && - last_frame <= *mmesa->status - mmesa->status_offset ) ) { - break; - } - if ( 0 ) { - fprintf( stderr, " head=0x%06x wrap=%d\n", - *mmesa->status - mmesa->status_offset, - mmesa->sarea->last_wrap ); - fprintf( stderr, " frame=0x%06x wrap=%d\n\n", - last_frame, last_wrap ); - } - } - - if ( 0 ) - fprintf( stderr, "waiting... done.\n" ); - UNLOCK_HARDWARE( mmesa ); - - mmesa->lastSwap = tmp; mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } @@ -408,8 +394,8 @@ static int intersect_rect( XF86DRIClipRectPtr out, if (b->y1 > out->y1) out->y1 = b->y1; if (b->x2 < out->x2) out->x2 = b->x2; if (b->y2 < out->y2) out->y2 = b->y2; - if (out->x1 >= out->x2) return 0; - if (out->y1 >= out->y2) return 0; + if (out->x1 > out->x2) return 0; + if (out->y1 > out->y2) return 0; return 1; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c index d970e49b4..72903c209 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c @@ -545,9 +545,9 @@ mgaDDDrawPixels( GLcontext *ctx, * negligble speedup when the buffers/images don't exactly * match: */ -#if 1 +#if 0 if (cpp == 2) { - if (!_mesa_convert_teximage( MESA_R5_G6_B5, + if (!_mesa_convert_teximage( MESA_FORMAT_RGB565, width, rows, address, bufferpitch, width, rows, @@ -558,7 +558,7 @@ mgaDDDrawPixels( GLcontext *ctx, return GL_FALSE; } } else { - if (!_mesa_convert_teximage( MESA_A8_R8_G8_B8, + if (!_mesa_convert_teximage( MESA_FORMAT_ARGB8888, width, rows, address, bufferpitch, width, rows, diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index b707bc406..83a78f2dc 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -25,7 +25,6 @@ dPriv->y * pitch); \ GLuint p = MGA_CONTEXT( ctx )->MonoColor; \ (void) read_buf; (void) buf; (void) p - #define LOCAL_DEPTH_VARS \ @@ -59,8 +58,10 @@ #define HW_LOCK() \ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ + FLUSH_BATCH(mmesa); \ LOCK_HARDWARE_QUIESCENT(mmesa); + #define HW_CLIPLOOP() \ do { \ int _nc = mmesa->numClipRects; \ @@ -97,9 +98,9 @@ #define READ_RGBA( rgba, _x, _y ) \ do { \ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ + rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \ + rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \ + rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \ rgba[3] = 255; \ } while(0) @@ -127,7 +128,7 @@ do { \ rgba[0] = (p >> 16) & 0xff; \ rgba[1] = (p >> 8) & 0xff; \ rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = (p >> 24) & 0xff; \ + rgba[3] = 0xff; \ } while (0) #define TAG(x) mga##x##_8888 @@ -168,13 +169,13 @@ do { \ #define WRITE_DEPTH( _x, _y, d ) { \ GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ tmp &= 0xff; \ - tmp |= (d) & 0xffffff00; \ + tmp |= (d) << 8; \ *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ } -#define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff; - +#define READ_DEPTH( d, _x, _y ) { \ + d = (*(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff) >> 8; \ +} #define TAG(x) mga##x##_24_8 #include "depthtmp.h" diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index eb45233e0..54cc4de29 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -190,7 +190,9 @@ static void mgaUpdateZMode(const GLcontext *ctx) if (ctx->Depth.Test) { switch(ctx->Depth.Func) { case GL_NEVER: - zmode = DC_zmode_nozcmp; break; + /* can't do this in h/w, we'll use a s/w fallback */ + zmode = DC_zmode_nozcmp; + break; case GL_ALWAYS: zmode = DC_zmode_nozcmp; break; case GL_LESS: @@ -208,15 +210,17 @@ static void mgaUpdateZMode(const GLcontext *ctx) default: break; } - } else { + + if (ctx->Depth.Mask) + zmode |= DC_atype_zi; + else + zmode |= DC_atype_i; + } + else { zmode |= DC_zmode_nozcmp; + zmode |= DC_atype_i; /* don't write to zbuffer */ } - if (ctx->Depth.Mask) - zmode |= DC_atype_zi; - else - zmode |= DC_atype_i; - #if defined(ACCEL_ROP) mmesa->setup.dwgctl &= DC_bop_MASK; if (ctx->Color.ColorLogicOpEnabled) @@ -287,6 +291,10 @@ static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) { FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; + if (func == GL_NEVER && ctx->Depth.Test) + MGA_CONTEXT(ctx)->Fallback |= MGA_FALLBACK_DEPTH; + else + MGA_CONTEXT(ctx)->Fallback &= ~MGA_FALLBACK_DEPTH; } static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag) @@ -439,7 +447,10 @@ static void mgaUpdateAlphaMode(GLcontext *ctx) a |= AC_src_zero; break; case GL_SRC_ALPHA_SATURATE: - a |= AC_src_src_alpha_sat; + if (ctx->Visual->AlphaBits > 0) + a |= AC_src_src_alpha_sat; + else + a |= AC_src_zero; break; default: /* never happens */ break; @@ -499,10 +510,10 @@ void mgaUpdateClipping(const GLcontext *ctx) if (mmesa->driDrawable) { int x1 = mmesa->driDrawable->x + ctx->Scissor.X; - int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y+ - ctx->Scissor.Height); - int x2 = mmesa->driDrawable->x + ctx->Scissor.X+ctx->Scissor.Width; - int y2 = mmesa->driDrawable->y + mmesa->driDrawable->h - ctx->Scissor.Y; + int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h + - (ctx->Scissor.Y + ctx->Scissor.Height); + int x2 = x1 + ctx->Scissor.Width - 1; + int y2 = y1 + ctx->Scissor.Height - 1; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; @@ -636,7 +647,7 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, mmesa->dirty |= MGA_UPLOAD_CONTEXT; } - return 1; + return 0; /* Kind of a hack */ } /* ============================================================= @@ -644,9 +655,12 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, * * The mga supports a subset of possible 4x4 stipples natively, GL * wants 32x32. Fortunately stipple is usually a repeating pattern. + * + * Note: the fully opaque pattern (0xffff) has been disabled in order + * to work around a conformance issue. */ static int mgaStipples[16] = { - 0xffff, + 0xffff1, /* See above note */ 0xa5a5, 0x5a5a, 0xa0a0, @@ -674,7 +688,12 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) GLuint stipple; FLUSH_BATCH(mmesa); - ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + + /* Turn off flags. We'll turn them on below if this stipple pattern + * works in h/w. + */ + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + mmesa->canDoStipple = GL_FALSE; if (active) { mmesa->dirty |= MGA_UPLOAD_CONTEXT; @@ -690,7 +709,6 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) for (j = 0 ; j < 4; j++) for (i = 0 ; i < 4 ; i++) if (*m++ != p[j]) { - ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; return; } @@ -706,13 +724,15 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) } if (i == 16) { - ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; return; } + mmesa->canDoStipple = GL_TRUE; + if (active) { mmesa->setup.dwgctl &= ~(0xf<<20); mmesa->setup.dwgctl |= mmesa->poly_stipple; + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; } } @@ -778,6 +798,16 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) mmesa->sarea->dirty |= mmesa->dirty; mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); + + /* This is a bit of a hack but seems to be the best place to ensure + * that separate specular is disabled when not needed. + */ + if (mmesa->glCtx->Texture.ReallyEnabled == 0 || + !mmesa->glCtx->Light.Enabled || + mmesa->glCtx->Light.Model.ColorControl == GL_SINGLE_COLOR) { + sarea->TexState[0].texctl2 &= ~TMC_specen_enable; + sarea->TexState[1].texctl2 &= ~TMC_specen_enable; + } } @@ -808,6 +838,10 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_DEPTH_TEST: FLUSH_BATCH( mmesa ); mmesa->new_state |= MGA_NEW_DEPTH; + if (ctx->Depth.Func == GL_NEVER && ctx->Depth.Test) + mmesa->Fallback |= MGA_FALLBACK_DEPTH; + else + mmesa->Fallback &= ~MGA_FALLBACK_DEPTH; break; case GL_SCISSOR_TEST: FLUSH_BATCH( mmesa ); @@ -829,14 +863,20 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) mmesa->new_state |= (MGA_NEW_TEXTURE|MGA_NEW_ALPHA); break; case GL_POLYGON_STIPPLE: - if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && - ctx->PB->primitive == GL_POLYGON) - { - FLUSH_BATCH(mmesa); - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - mmesa->setup.dwgctl &= ~(0xf<<20); - if (state) + FLUSH_BATCH(mmesa); + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mmesa->setup.dwgctl &= ~(0xf<<20); + if (state) { + if (mmesa->canDoStipple && ctx->PB->primitive == GL_POLYGON) { mmesa->setup.dwgctl |= mmesa->poly_stipple; + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + } + else { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + } + } + else { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; } break; case GL_COLOR_LOGIC_OP: @@ -948,11 +988,6 @@ void mgaDDUpdateHwState( GLcontext *ctx ) } - - - - - void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); @@ -960,20 +995,24 @@ void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) FLUSH_BATCH( mmesa ); mgaUpdateCull(ctx); - if (ctx->Polygon.StippleFlag && (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE)) - { + if (ctx->Polygon.StippleFlag) { mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->setup.dwgctl &= ~(0xf<<20); - if (ctx->PB->primitive == GL_POLYGON) + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + if (ctx->PB->primitive == GL_POLYGON && mmesa->canDoStipple) { mmesa->setup.dwgctl |= mmesa->poly_stipple; + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + } + } + else { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; } } #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ NEW_TEXTURE_MATRIX|\ - NEW_USER_CLIP|NEW_CLIENT_STATE|\ - NEW_TEXTURE_ENABLE)) + NEW_USER_CLIP|NEW_CLIENT_STATE)) void mgaDDUpdateState( GLcontext *ctx ) { @@ -999,6 +1038,9 @@ void mgaDDUpdateState( GLcontext *ctx ) ctx->Driver.TriangleFunc=mmesa->TriangleFunc; ctx->Driver.QuadFunc=mmesa->QuadFunc; } + else { + ctx->IndirectTriangles |= mmesa->IndirectTriangles; + } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 03f1e39f4..35945224a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -37,9 +37,11 @@ #include "mgaregs.h" #include "mgaioctl.h" +#include "context.h" #include "enums.h" #include "simple_list.h" #include "mem.h" +#include "texutil.h" #define TEX_0 1 #define TEX_1 2 @@ -144,11 +146,166 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) } +static GLint mgaChooseTexFormat( mgaContextPtr mmesa, + struct gl_texture_image *texImage, + GLenum format, GLenum type ) +{ + const GLboolean do32bpt = mmesa->default32BitTextures; + const struct gl_texture_format *texFormat; + GLint ret; + + if ( 0 ) + fprintf( stderr, "internal=%s format=%s type=%s\n", + texImage->IntFormat == 3 ? "GL_RGB (3)" : + texImage->IntFormat == 4 ? "GL_RGBA (4)" : + gl_lookup_enum_by_nr( texImage->IntFormat ), + gl_lookup_enum_by_nr( format ), + gl_lookup_enum_by_nr( type ) ); + +#define SET_FORMAT( r, gl ) \ + do { \ + ret = (r); \ + texFormat = &(gl); \ + } while (0) + +#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \ + do { \ + if ( do32bpt ) { \ + ret = (r32); \ + texFormat = &(gl32); \ + } else { \ + ret = (r16); \ + texFormat = &(gl16); \ + } \ + } while (0) + + switch ( texImage->IntFormat ) { + /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has + * got to be better than sticking them way down the end of this + * huge list. + */ + case GL_RGBA: + case 4: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 ); + break; + } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); + break; + } + } + SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, + TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + + case GL_RGB: + case 3: + if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { + SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); + break; + } + SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, + TMC_tformat_tw16, _mesa_texformat_rgb565 ); + break; + + /* GH: Okay, keep checking as normal. Still test for GL_RGB, + * GL_RGBA formats first. + */ + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, + TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + + case GL_RGBA4: + case GL_RGBA2: + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + + case GL_RGB5_A1: + SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); + break; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, + TMC_tformat_tw16, _mesa_texformat_rgb565 ); + break; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); + break; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + /* FIXME: This will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + /* FIXME: This will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); + break; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + /* FIXME: This will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + /* FIXME: This will report incorrect component sizes... */ + SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); + break; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 ); + break; + + default: + fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d", + texImage->IntFormat ); + return -1; + } + texImage->TexFormat = texFormat; + return ret; +} /* @@ -160,60 +317,27 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj) { - const struct gl_texture_image *image = tObj->Image[ 0 ]; + const GLint baseLevel = tObj->BaseLevel; + struct gl_texture_image *image = tObj->Image[baseLevel]; mgaTextureObjectPtr t; int i, ofs; int LastLevel; int s, s2; - int textureFormat; - + int tformat; if (!image) return; - tObj->DriverData = t = CALLOC( sizeof( *t ) ); if (!t) { fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); return; } - switch( image->Format ) { - case GL_RGB: - case GL_LUMINANCE: - if ( image->IntFormat != GL_RGB5 && ( image->IntFormat == GL_RGB8 || - mmesa->default32BitTextures ) ) { - t->texelBytes = 4; - textureFormat = TMC_tformat_tw32; - } else { - t->texelBytes = 2; - textureFormat = TMC_tformat_tw16; - } - break; - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_RGBA: - if ( image->IntFormat != GL_RGBA4 && ( image->IntFormat == GL_RGBA8 || - mmesa->default32BitTextures ) ) { - t->texelBytes = 4; - textureFormat = TMC_tformat_tw32; - } else { - t->texelBytes = 2; - textureFormat = TMC_tformat_tw12; - } - break; - case GL_COLOR_INDEX: - textureFormat = TMC_tformat_tw8; - t->texelBytes = 1; - break; - default: - fprintf(stderr, "mgaCreateTexObj: bad image->Format %x/%s\n", - image->Format, - gl_lookup_enum_by_nr(image->Format)); - FREE( t ); - tObj->DriverData = 0; - return; - } + /* FIXME: Use the real DD interface... + */ + tformat = mgaChooseTexFormat( mmesa, image, image->Format, + GL_UNSIGNED_BYTE ); + t->texelBytes = image->TexFormat->TexelBytes; /* We are going to upload all levels that are present, even if * later levels wouldn't be used by the current filtering mode. This @@ -236,7 +360,6 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, MAX2( tObj->Image[i]->Height, 8 ) * t->texelBytes) + 31) & ~31; } - t->totalSize = ofs; t->lastLevel = LastLevel; t->tObj = tObj; @@ -249,9 +372,7 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, /* setup hardware register values */ - t->setup.texctl = (TMC_takey_1 | - TMC_tamask_0 | - textureFormat ); + t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat; if (image->WidthLog2 >= 3) t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT); @@ -331,6 +452,7 @@ static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); GLuint source = mmesa->tmu_source[unit]; struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; + GLenum format; if ( tObj != ctx->Texture.Unit[source].CurrentD[2] || !tObj || @@ -338,95 +460,183 @@ static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D ) return; + format = tObj->Image[tObj->BaseLevel]->Format; switch (ctx->Texture.Unit[source].EnvMode) { case GL_REPLACE: - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); + if (format == GL_RGB || format == GL_LUMINANCE) { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else if (format == GL_ALPHA) { + *reg = (TD0_color_sel_arg2 | + TD0_color_arg2_diffuse | + TD0_alpha_sel_arg1 ); + } + else { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_sel_arg1 ); + } break; case GL_MODULATE: - if (unit == 0) + if (unit == 0) { *reg = ( TD0_color_arg2_diffuse | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul); - else + } + else { *reg = ( TD0_color_arg2_prevstage | TD0_color_alpha_prevstage | TD0_color_sel_mul | TD0_alpha_arg2_prevstage | TD0_alpha_sel_mul); + } break; case GL_DECAL: - if (tObj->Image[0]->Format == GL_RGB) - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); - else if (unit == 0) - *reg = (TD0_color_arg2_diffuse | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg2 ); - else - *reg = (TD0_color_arg2_prevstage | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2 ); - + if (format == GL_RGB) { + if (unit == 0) { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ); + } + } + else if ( format == GL_RGBA ) { +#if 0 + if (unit == 0) { + /* this doesn't work */ + *reg = (TD0_color_arg2_diffuse | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_blend_enable | + TD0_color_arg1add_mulout | + TD0_color_arg2add_mulout | + TD0_color_add_add | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else { + *reg = (TD0_color_arg2_prevstage | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ); + } +#else + /* s/w fallback, pretty sure we can't do in h/w */ + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; +#endif + } + else { + if (unit == 0) { + *reg = ( TD0_color_arg2_diffuse | + TD0_color_sel_arg2 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2); + } + else { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_sel_arg2 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } + } break; case GL_ADD: - if (unit == 0) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_add); - else - *reg = ( TD0_color_arg2_prevstage | - TD0_color_alpha_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_add); + if (unit == 0) { + if (format == GL_INTENSITY) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_add_enable | + TD0_alpha_sel_add); + else if (format == GL_ALPHA) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul); + else + *reg = ( TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul); + } + else { + if (format == GL_INTENSITY) { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_add_enable | + TD0_alpha_sel_add); + } + else if (format == GL_ALPHA) { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_sel_mul | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul); + } + else { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul); + } + } break; case GL_BLEND: - if (mmesa->blend_flags) - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - - /* Do singletexture GL_BLEND with 'all ones' env-color - * by using both texture units. Multitexture gl_blend - * is a fallback. - */ - if (unit == 0) { - /* Part 1: R1 = Rf ( 1 - Rt ) - * A1 = Af At - */ + if (format == GL_ALPHA) { *reg = ( TD0_color_arg2_diffuse | - TD0_color_arg1_inv_enable | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg1); - } else { - /* Part 2: R2 = R1 + Rt - * A2 = A1 - */ - *reg = ( TD0_color_arg2_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2); + TD0_alpha_sel_mul); + } + else { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + + /* Do singletexture GL_BLEND with 'all ones' env-color + * by using both texture units. Multitexture gl_blend + * is a fallback. + */ + if (unit == 0) { + /* Part 1: R1 = Rf ( 1 - Rt ) + * A1 = Af At + */ + *reg = ( TD0_color_arg2_diffuse | + TD0_color_arg1_inv_enable | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg1); + } else { + /* Part 2: R2 = R1 + Rt + * A2 = A1 + */ + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } } break; default: @@ -459,6 +669,11 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) return; } + if (tObj->Image[tObj->BaseLevel]->Border > 0) { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } + /* if (!tObj) tObj = ctx->Texture.Unit[0].Current; */ /* if (!tObj) return; */ @@ -597,6 +812,9 @@ static void mgaDDTexImage( GLcontext *ctx, GLenum target, { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaTextureObjectPtr t; + GLint tformat; + /* hack: cast-away const */ + struct gl_texture_image *img = (struct gl_texture_image *) image; /* just free the mga texture if it exists, it will be recreated at mgaUpdateTextureState time. */ @@ -608,6 +826,9 @@ static void mgaDDTexImage( GLcontext *ctx, GLenum target, mmesa->new_state |= MGA_NEW_TEXTURE; } + tformat = mgaChooseTexFormat( mmesa, img, img->Format, + GL_UNSIGNED_BYTE ); + if (0) fprintf(stderr, "mgaDDTexImage tObj %p, level %d, image %p\n", tObj, level, image); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index cd051bf26..4caa1bfa4 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -38,25 +38,6 @@ #include "mgavb.h" -static void mga_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) -{ -} - -static void mga_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void mga_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void mga_null_points( GLcontext *ctx, GLuint first, GLuint last ) -{ -} - - #define MGA_COLOR(to, from) { \ (to)[0] = (from)[2]; \ (to)[1] = (from)[1]; \ @@ -64,6 +45,12 @@ static void mga_null_points( GLcontext *ctx, GLuint first, GLuint last ) (to)[3] = (from)[3]; \ } +#define MGA_COLOR3(to, from) { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ +} + static triangle_func tri_tab[0x10]; @@ -106,9 +93,6 @@ static points_func points_tab[0x10]; void mgaDDTrifuncInit() { - int i; - - init(); init_flat(); init_offset(); @@ -117,14 +101,6 @@ void mgaDDTrifuncInit() init_twoside_flat(); init_twoside_offset(); init_twoside_offset_flat(); - - for (i = 0 ; i < 0x20 ; i++) - if (i & MGA_NODRAW_BIT) { - quad_tab[i] = mga_null_quad; - tri_tab[i] = mga_null_triangle; - line_tab[i] = mga_null_line; - points_tab[i] = mga_null_points; - } } @@ -134,7 +110,7 @@ void mgaDDTrifuncInit() #define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED) #define ANY_FALLBACK (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE) -#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_Z_NEVER) +#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET) /* Setup the Point, Line, Triangle and Quad functions based on the current rendering state. Wherever possible, use the hardware to @@ -147,6 +123,9 @@ void mgaDDChooseRenderState(GLcontext *ctx) if (mmesa->Fallback) { mmesa->renderindex = MGA_FALLBACK_BIT; + if (flags & DD_TRI_LIGHT_TWOSIDE) { + mmesa->IndirectTriangles = DD_TRI_LIGHT_TWOSIDE; + } return; } @@ -154,7 +133,6 @@ void mgaDDChooseRenderState(GLcontext *ctx) if (flags & DD_FLATSHADE) index |= MGA_FLAT_BIT; if (flags & DD_TRI_LIGHT_TWOSIDE) index |= MGA_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= MGA_OFFSET_BIT; - if (flags & DD_Z_NEVER) index |= MGA_NODRAW_BIT; } mmesa->PointsFunc = points_tab[index]; @@ -194,6 +172,9 @@ void mgaDDChooseRenderState(GLcontext *ctx) mmesa->QuadFunc = 0; mmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE); + if (flags & DD_TRI_LIGHT_TWOSIDE) { + mmesa->IndirectTriangles |= DD_TRI_LIGHT_TWOSIDE; + } } } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index f50c83974..9880bbdf1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -38,8 +38,7 @@ extern void mgaDDTrifuncInit( void ); #define MGA_FLAT_BIT 0x1 #define MGA_OFFSET_BIT 0x2 #define MGA_TWOSIDE_BIT 0x4 -#define MGA_NODRAW_BIT 0x8 -#define MGA_FALLBACK_BIT 0x10 +#define MGA_FALLBACK_BIT 0x8 static __inline void mga_draw_triangle( mgaContextPtr mmesa, mgaVertex *v0, @@ -90,40 +89,42 @@ static __inline void mga_draw_point( mgaContextPtr mmesa, { GLuint vertsize = mmesa->vertsize; GLuint *wv = mgaAllocVertexDwords( mmesa, 6*vertsize); - int j; + GLuint j; + const GLfloat x = tmp->v.x + 0.125; + const GLfloat y = tmp->v.y - 0.125; - *(float *)&wv[0] = tmp->v.x - sz; - *(float *)&wv[1] = tmp->v.y - sz; + *(float *)&wv[0] = x - sz; + *(float *)&wv[1] = y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x + sz; - *(float *)&wv[1] = tmp->v.y - sz; + *(float *)&wv[0] = x + sz; + *(float *)&wv[1] = y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x + sz; - *(float *)&wv[1] = tmp->v.y + sz; + *(float *)&wv[0] = x + sz; + *(float *)&wv[1] = y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x + sz; - *(float *)&wv[1] = tmp->v.y + sz; + *(float *)&wv[0] = x + sz; + *(float *)&wv[1] = y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x - sz; - *(float *)&wv[1] = tmp->v.y + sz; + *(float *)&wv[0] = x - sz; + *(float *)&wv[1] = y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp->v.x - sz; - *(float *)&wv[1] = tmp->v.y - sz; + *(float *)&wv[0] = x - sz; + *(float *)&wv[1] = y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; } @@ -134,55 +135,79 @@ static __inline void mga_draw_line( mgaContextPtr mmesa, const mgaVertex *tmp1, float width ) { - GLuint vertsize = mmesa->vertsize; + const GLuint vertsize = mmesa->vertsize; GLuint *wv = mgaAllocVertexDwords( mmesa, 6 * vertsize ); - float dx, dy, ix, iy; - int j; + GLuint j; + GLfloat x0 = tmp0->v.x; + GLfloat y0 = tmp0->v.y; + GLfloat x1 = tmp1->v.x; + GLfloat y1 = tmp1->v.y; + GLfloat dx, dy, ix, iy; + GLfloat hw; + + hw = 0.5F * width; + if (hw > 0.1F && hw < 0.5F) { + hw = 0.5F; + } + /* adjust vertices depending on line direction */ dx = tmp0->v.x - tmp1->v.x; dy = tmp0->v.y - tmp1->v.y; - - ix = width * .5; iy = 0; - - if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width - 0.5 also */ - if (dx * dx > dy * dy) { - iy = ix; ix = 0; + /* X-major line */ + ix = 0.0F; + iy = hw; + if (x1 < x0) { + x0 += 0.5F; + x1 += 0.5F; + } + y0 -= 0.5F; + y1 -= 0.5F; + } + else { + /* Y-major line */ + ix = hw; + iy = 0.0F; + if (y1 > y0) { + y0 -= 0.5F; + y1 -= 0.5F; + } + x0 += 0.5F; + x1 += 0.5F; } - - *(float *)&wv[0] = tmp0->v.x - ix; - *(float *)&wv[1] = tmp0->v.y - iy; + + *(float *)&wv[0] = x0 - ix; + *(float *)&wv[1] = y0 - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp1->v.x + ix; - *(float *)&wv[1] = tmp1->v.y + iy; + *(float *)&wv[0] = x1 + ix; + *(float *)&wv[1] = y1 + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp0->v.x + ix; - *(float *)&wv[1] = tmp0->v.y + iy; + *(float *)&wv[0] = x0 + ix; + *(float *)&wv[1] = y0 + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp0->v.x - ix; - *(float *)&wv[1] = tmp0->v.y - iy; + *(float *)&wv[0] = x0 - ix; + *(float *)&wv[1] = y0 - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp1->v.x - ix; - *(float *)&wv[1] = tmp1->v.y - iy; + *(float *)&wv[0] = x1 - ix; + *(float *)&wv[1] = y1 - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; wv += vertsize; - *(float *)&wv[0] = tmp1->v.x + ix; - *(float *)&wv[1] = tmp1->v.y + iy; + *(float *)&wv[0] = x1 + ix; + *(float *)&wv[1] = y1 + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; wv += vertsize; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h index f578871ce..a041d887d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h @@ -16,6 +16,7 @@ static __inline void TAG(triangle)(GLcontext *ctx, #if (IND & (MGA_TWOSIDE_BIT | MGA_FLAT_BIT)) GLuint c[3]; + GLuint s[3]; #endif v[0] = &mgaverts[e0]; @@ -26,6 +27,9 @@ static __inline void TAG(triangle)(GLcontext *ctx, c[0] = v[0]->ui[4]; c[1] = v[1]->ui[4]; c[2] = v[2]->ui[4]; + s[0] = v[0]->ui[5]; + s[1] = v[1]->ui[5]; + s[2] = v[2]->ui[5]; #endif @@ -41,13 +45,19 @@ static __inline void TAG(triangle)(GLcontext *ctx, { GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + GLubyte (*vbspec)[4] = VB->Spec[facing]; if (IND & MGA_FLAT_BIT) { MGA_COLOR((char *)&v[0]->ui[4], vbcolor[pv]); v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + MGA_COLOR3((char *)&v[0]->ui[5], vbspec[pv]); + v[2]->ui[5] = v[1]->ui[5] = v[0]->ui[5]; } else { MGA_COLOR((char *)&v[0]->ui[4], vbcolor[e0]); MGA_COLOR((char *)&v[1]->ui[4], vbcolor[e1]); MGA_COLOR((char *)&v[2]->ui[4], vbcolor[e2]); + MGA_COLOR3((char *)&v[0]->ui[5], vbspec[e0]); + MGA_COLOR3((char *)&v[1]->ui[5], vbspec[e1]); + MGA_COLOR3((char *)&v[2]->ui[5], vbspec[e2]); } } #endif @@ -79,9 +89,13 @@ static __inline void TAG(triangle)(GLcontext *ctx, #elif (IND & MGA_FLAT_BIT) { GLuint color = mgaverts[pv].ui[4]; + GLuint spec = mgaverts[pv].ui[5]; v[0]->ui[4] = color; v[1]->ui[4] = color; v[2]->ui[4] = color; + v[0]->ui[5] = spec; + v[1]->ui[5] = spec; + v[2]->ui[5] = spec; } #endif @@ -97,6 +111,9 @@ static __inline void TAG(triangle)(GLcontext *ctx, v[0]->ui[4] = c[0]; v[1]->ui[4] = c[1]; v[2]->ui[4] = c[2]; + v[0]->ui[5] = s[0]; + v[1]->ui[5] = s[1]; + v[2]->ui[5] = s[2]; #endif } @@ -120,25 +137,34 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) float width = ctx->Line.Width; GLfloat z0, z1; GLuint c0, c1; + GLuint s0, s1; mgaVertex *vert0 = &mgaVB[v0]; mgaVertex *vert1 = &mgaVB[v1]; - if (IND & MGA_TWOSIDE_BIT) { GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + GLubyte (*vbspec)[4] = ctx->VB->Specular; if (IND & MGA_FLAT_BIT) { MGA_COLOR((char *)&vert0->v.color,vbcolor[pv]); *(int *)&vert1->v.color = *(int *)&vert0->v.color; + MGA_COLOR3((char *)&vert0->v.specular, vbspec[pv]); + *(int *)&vert1->v.specular = *(int *)&vert0->v.specular; } else { MGA_COLOR((char *)&vert0->v.color,vbcolor[v0]); MGA_COLOR((char *)&vert1->v.color,vbcolor[v1]); + MGA_COLOR3((char *)&vert0->v.specular, vbspec[v0]); + MGA_COLOR3((char *)&vert1->v.specular, vbspec[v1]); } } else if (IND & MGA_FLAT_BIT) { c0 = *(GLuint *) &(vert0->v.color); c1 = *(GLuint *) &(vert1->v.color); *(int *)&vert0->v.color = *(int *)&vert1->v.color = *(int *)&mgaVB[pv].v.color; + s0 = *(GLuint *) &(vert0->v.specular); + s1 = *(GLuint *) &(vert1->v.specular); + *(int *)&vert0->v.specular = + *(int *)&vert1->v.specular = *(int *)&mgaVB[pv].v.specular; } if (IND & MGA_OFFSET_BIT) { @@ -159,6 +185,8 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) if ((IND & MGA_FLAT_BIT) && !(IND & MGA_TWOSIDE_BIT)) { *(GLuint *) &(vert0->v.color) = c0; *(GLuint *) &(vert1->v.color) = c1; + *(GLuint *) &(vert0->v.specular) = s0; + *(GLuint *) &(vert1->v.specular) = s1; } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index ae6316fc8..1dfc89d2b 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -35,34 +35,34 @@ #include <stdio.h> #include <stdlib.h> -#define TEX0 { \ +#define TEX0 { \ v->v.tu0 = tc0[i][0]; \ v->v.tv0 = tc0[i][1]; \ } -#define TEX1 { \ +#define TEX1 { \ v->v.tu1 = tc1[i][0]; \ v->v.tv1 = tc1[i][1]; \ } -#define SPC { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ +#define SPC { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ v->v.specular.red = spec[0]; \ - v->v.specular.green = spec[1]; \ + v->v.specular.green = spec[1]; \ v->v.specular.blue = spec[2]; \ } -#define FOG { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->v.specular.alpha = spec[3]; \ +#define FOG { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.alpha = spec[3]; \ } #define COL { \ GLubyte *col = &(VB->Color[0]->data[i][0]); \ - v->v.color.blue = col[2]; \ - v->v.color.green = col[1]; \ - v->v.color.red = col[0]; \ - v->v.color.alpha = col[3]; \ + v->v.color.blue = col[2]; \ + v->v.color.green = col[1]; \ + v->v.color.red = col[0]; \ + v->v.color.alpha = col[3]; \ } /* The v code we have doesn't seem to support projective texturing @@ -70,14 +70,13 @@ * second set of texcoords). This may be a problem for the g400. */ #define TEX0_4 \ - if (VB->TexCoordPtr[0]->size == 4) \ - { \ + if (VB->TexCoordPtr[0]->size == 4) { \ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ v = &(MGA_DRIVER_DATA(VB)->verts[start]); \ mmesa->setupdone &= ~MGA_WIN_BIT; \ - for (i=start; i < end; i++, v++) { \ - float oow = 1.0 / tc[i][3]; \ - v->v.rhw *= tc[i][3]; \ + for (i = start; i < end; i++, v++) { \ + GLfloat oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ v->v.tu0 *= oow; \ v->v.tv0 *= oow; \ } \ @@ -138,7 +137,7 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ spec; \ fog; \ } \ - col; \ + col; \ } \ tex0_4; \ } diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile index d862565d0..2dc0b3083 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/Imakefile +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile @@ -59,6 +59,8 @@ MESA_INCLUDES = -I. -I.. -I../../include \ radeon_span.c \ radeon_state.c \ radeon_tex.c \ + radeon_texmem.c \ + radeon_texstate.c \ radeon_tris.c \ radeon_vb.c \ radeon_xmesa.c @@ -74,6 +76,8 @@ MESA_INCLUDES = -I. -I.. -I../../include \ radeon_span.o \ radeon_state.o \ radeon_tex.o \ + radeon_texmem.o \ + radeon_texstate.o \ radeon_tris.o \ radeon_vb.o \ radeon_xmesa.o @@ -152,6 +156,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ ../../stages.c \ ../../state.c \ ../../stencil.c \ + ../../texformat.c \ ../../teximage.c \ ../../texobj.c \ ../../texstate.c \ @@ -225,6 +230,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ ../../stages.o \ ../../state.o \ ../../stencil.o \ + ../../texformat.o \ ../../teximage.o \ ../../texobj.o \ ../../texstate.o \ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c index 9b2c5b2f1..172e0f62a 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -163,16 +163,8 @@ GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, ctx->Const.MaxTextureSize = (1 << 10); } - /* FIXME: Support all available texture units... */ ctx->Const.MaxTextureUnits = 2; -#if ENABLE_PERF_BOXES - if (getenv("LIBGL_PERFORMANCE_BOXES")) - rmesa->boxes = 1; - else - rmesa->boxes = 0; -#endif - ctx->DriverCtx = (void *)rmesa; radeonDDInitExtensions( ctx ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c index b86506a8d..4ef0ebd30 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c @@ -46,7 +46,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "X86/common_x86_asm.h" #endif -#define RADEON_DATE "20010105" +#define RADEON_DATE "20010305" /* Return the width and height of the current color buffer. @@ -100,6 +100,11 @@ static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name ) strncat( buffer, " x86", 4 ); } #endif +#ifdef USE_MMX_ASM + if ( cpu_has_mmx ) { + strncat( buffer, "/MMX", 4 ); + } +#endif #ifdef USE_3DNOW_ASM if ( cpu_has_3dnow ) { strncat( buffer, "/3DNow!", 7 ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c index a02794e49..c2cd6a203 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -321,6 +321,7 @@ void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ) { +#if 0 GLint ret; ret = drmRadeonTextureBlit( rmesa->driFd, buffer->idx, @@ -332,6 +333,7 @@ void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer, fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); exit( 1 ); } +#endif } @@ -616,12 +618,6 @@ static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask, } #endif -#if 0 - if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeonEmitHwStateLocked( rmesa ); - } -#endif - for ( i = 0 ; i < rmesa->numClipRects ; ) { GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, rmesa->numClipRects ); XF86DRIClipRectPtr box = rmesa->pClipRects; diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c index d82013338..d80004dd6 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -511,7 +511,8 @@ static void radeonDDLightModelfv( GLcontext *ctx, GLenum pname, FLUSH_BATCH( rmesa ); - if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled && ctx->Texture.ReallyEnabled) { p |= RADEON_SPECULAR_ENABLE; } else { p &= ~RADEON_SPECULAR_ENABLE; @@ -805,6 +806,22 @@ static void radeonDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) } break; + case GL_LIGHTING: + { + GLuint p = rmesa->setup.pp_cntl; + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled && ctx->Texture.ReallyEnabled) { + p |= RADEON_SPECULAR_ENABLE; + } else { + p &= ~RADEON_SPECULAR_ENABLE; + } + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + break; + } + case GL_SCISSOR_TEST: FLUSH_BATCH( rmesa ); rmesa->scissor = state; @@ -919,29 +936,29 @@ void radeonEmitHwStateLocked( radeonContextPtr rmesa ) if ( (rmesa->dirty & RADEON_UPLOAD_TEX0) && t0 ) { radeon_texture_regs_t *tex = &sarea->TexState[0]; - tex->pp_txfilter = t0->setup.pp_txfilter | rmesa->lod_bias[0] << 8; - tex->pp_txformat = t0->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ0; - tex->pp_txoffset = t0->setup.pp_txoffset; + tex->pp_txfilter = t0->pp_txfilter | rmesa->lod_bias[0] << 8; + tex->pp_txformat = t0->pp_txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0; + tex->pp_txoffset = t0->pp_txoffset; tex->pp_txcblend = rmesa->color_combine[0]; tex->pp_txablend = rmesa->alpha_combine[0]; tex->pp_tfactor = rmesa->env_color[0]; - tex->pp_border_color = t0->setup.pp_border_color; + tex->pp_border_color = t0->pp_border_color; } if ( (rmesa->dirty & RADEON_UPLOAD_TEX1) && t1 ) { radeon_texture_regs_t *tex = &sarea->TexState[1]; - tex->pp_txfilter = t1->setup.pp_txfilter | rmesa->lod_bias[1] << 8; - tex->pp_txformat = t1->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ1; - tex->pp_txoffset = t1->setup.pp_txoffset; + tex->pp_txfilter = t1->pp_txfilter | rmesa->lod_bias[1] << 8; + tex->pp_txformat = t1->pp_txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1; + tex->pp_txoffset = t1->pp_txoffset; tex->pp_txcblend = rmesa->color_combine[1]; tex->pp_txablend = rmesa->alpha_combine[1]; tex->pp_tfactor = rmesa->env_color[1]; - tex->pp_border_color = t1->setup.pp_border_color; + tex->pp_border_color = t1->pp_border_color; } if ( rmesa->dirty & RADEON_UPLOAD_TEX2 ) { diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c index dd9c4557b..a77a7f154 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -44,1963 +44,701 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "simple_list.h" #include "enums.h" #include "mem.h" +#include "texutil.h" static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) { - t->setup.pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK); + t->pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK); switch ( swrap ) { case GL_REPEAT: - t->setup.pp_txfilter |= RADEON_CLAMP_S_WRAP; + t->pp_txfilter |= RADEON_CLAMP_S_WRAP; break; case GL_CLAMP: - t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; + t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; break; case GL_CLAMP_TO_EDGE: - t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; + t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; break; } switch ( twrap ) { case GL_REPEAT: - t->setup.pp_txfilter |= RADEON_CLAMP_T_WRAP; + t->pp_txfilter |= RADEON_CLAMP_T_WRAP; break; case GL_CLAMP: - t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; + t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; break; case GL_CLAMP_TO_EDGE: - t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; + t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; break; } } static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) { - t->setup.pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK); + t->pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK); switch ( minf ) { case GL_NEAREST: - t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST; + t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST; break; case GL_LINEAR: - t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR; + t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR; break; case GL_NEAREST_MIPMAP_NEAREST: - t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST; + t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST; break; case GL_LINEAR_MIPMAP_NEAREST: - t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST; + t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST; break; case GL_NEAREST_MIPMAP_LINEAR: - t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR; + t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR; break; case GL_LINEAR_MIPMAP_LINEAR: - t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR; + t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR; break; } switch ( magf ) { case GL_NEAREST: - t->setup.pp_txfilter |= RADEON_MAG_FILTER_NEAREST; + t->pp_txfilter |= RADEON_MAG_FILTER_NEAREST; break; case GL_LINEAR: - t->setup.pp_txfilter |= RADEON_MAG_FILTER_LINEAR; + t->pp_txfilter |= RADEON_MAG_FILTER_LINEAR; break; } } static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) { - t->setup.pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); + t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); } - -/* Allocate and initialize hardware state associated with texture `t'. - */ -static radeonTexObjPtr radeonCreateTexObj( radeonContextPtr rmesa, - struct gl_texture_object *tObj ) +static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *tObj ) { radeonTexObjPtr t; - struct gl_texture_image *image; - GLint log2Width, log2Height, log2Size, log2MinSize; - GLint totalSize; - GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; - GLint x, y, width, height; - GLint i; - GLuint txformat, txalpha; - - image = tObj->Image[0]; - if ( !image ) - return NULL; - - t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); - if ( !t ) - return NULL; - - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) - fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj ); - - switch ( image->Format ) { - case GL_RGBA: - if ( image->IntFormat != GL_RGBA4 && - ( image->IntFormat == GL_RGBA8 || - rmesa->radeonScreen->cpp == 4 ) ) { - t->texelBytes = 4; - txformat = RADEON_TXF_32BPP_ARGB8888; - } else { - t->texelBytes = 2; - txformat = RADEON_TXF_16BPP_ARGB4444; - } - txalpha = RADEON_TXF_ALPHA_IN_MAP; - break; - - case GL_RGB: - if ( image->IntFormat != GL_RGB5 && - ( image->IntFormat == GL_RGB8 || - rmesa->radeonScreen->cpp == 4 ) ) { - t->texelBytes = 4; - txformat = RADEON_TXF_32BPP_ARGB8888; - } else { - t->texelBytes = 2; - txformat = RADEON_TXF_16BPP_RGB565; - } - txalpha = 0; - break; - - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - t->texelBytes = 2; - txformat = RADEON_TXF_16BPP_AI88; - txalpha = RADEON_TXF_ALPHA_IN_MAP; - break; - - case GL_LUMINANCE: - t->texelBytes = 2; - txformat = RADEON_TXF_16BPP_AI88; - txalpha = 0; - break; - - case GL_INTENSITY: - t->texelBytes = 1; - txformat = RADEON_TXF_8BPP_I; - txalpha = 0; - break; - - case GL_COLOR_INDEX: - default: - fprintf( stderr, "%s: bad image->Format\n", __FUNCTION__ ); - FREE( t ); - return NULL; - } - - /* Calculate dimensions in log domain. - */ - for ( i = 1, log2Height = 0 ; i < image->Height ; i *= 2 ) { - log2Height++; - } - for ( i = 1, log2Width = 0 ; i < image->Width ; i *= 2 ) { - log2Width++; - } - if ( image->Width > image->Height ) { - log2Size = log2Width; - } else { - log2Size = log2Height; - } - - t->dirty_images = 0; - - /* The Radeon has a 64-byte minimum pitch for all blits. We - * calculate the equivalent number of texels to simplify the - * calculation of the texture image area. - */ - switch ( t->texelBytes ) { - case 1: - texelsPerDword = 4; - blitPitch = 64; - break; - case 2: - texelsPerDword = 2; - blitPitch = 32; - break; - case 4: - texelsPerDword = 1; - blitPitch = 16; - break; - } - - /* Select the larger of the two widths for our global texture image - * coordinate space. As the Radeon has very strict offset rules, we - * can't upload mipmaps directly and have to reference their location - * from the aligned start of the whole image. - */ - blitWidth = MAX2( image->Width, blitPitch ); - - /* Calculate mipmap offsets and dimensions. - */ - totalSize = 0; - x = 0; - y = 0; - - for ( i = 0 ; i <= log2Size ; i++ ) { - GLuint size; - image = tObj->Image[i]; - if ( !image ) - break; - - width = image->Width; - height = image->Height; - - /* Texture images have a minimum pitch of 32 bytes (half of the - * 64-byte minimum pitch for blits). For images that have a - * width smaller than this, we must pad each texture image - * scanline out to this amount. - */ - if ( width < blitPitch / 2 ) { - width = blitPitch / 2; - } - - size = width * height * t->texelBytes; - totalSize += size; - - t->dirty_images |= (1 << i); - - while ( width < blitWidth && height > 1 ) { - width *= 2; - height /= 2; - } - - t->image[i].x = x; - t->image[i].y = y; - - t->image[i].width = width; - t->image[i].height = height; - - t->image[i].dwords = size / sizeof(CARD32); - - /* While blits must have a pitch of at least 64 bytes, mipmaps - * must be aligned on a 32-byte boundary (just like each texture - * image scanline). - */ - if ( width >= blitWidth ) { - y += height; - } else { - x += width; - if ( x >= blitWidth ) { - x = 0; - y++; - } - } + t = CALLOC_STRUCT( radeon_tex_obj ); - if ( 0 ) - fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d) %d dwords\n", - i, blitWidth, image->Width, image->Height, - t->image[i].width, t->image[i].height, - t->image[i].x, t->image[i].y, - t->image[i].dwords ); + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, t ); } - log2MinSize = log2Size - i + 1; - - /* Align the total size of texture memory block. + /* Initialize non-image-dependent parts of the state: */ - totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; - - t->totalSize = totalSize; - - t->bound = 0; - t->heap = 0; t->tObj = tObj; + t->dirty_images = ~0; + t->pp_txfilter = RADEON_BORDER_MODE_OGL; + t->pp_txformat = (RADEON_TXFORMAT_ENDIAN_NO_SWAP | + RADEON_TXFORMAT_PERSPECTIVE_ENABLE); - t->memBlock = NULL; - t->bufAddr = 0; - - /* Hardware state: - */ - t->setup.pp_txfilter = ((log2Size << RADEON_MAX_MIP_LEVEL_SHIFT) | - RADEON_BORDER_MODE_OGL); - - t->setup.pp_txformat = (txformat | txalpha | - (log2Width << RADEON_TXF_WIDTH_SHIFT) | - (log2Height << RADEON_TXF_HEIGHT_SHIFT) | - RADEON_TXF_ENDIAN_NO_SWAP | - RADEON_TXF_PERSPECTIVE_ENABLE); - - t->setup.pp_txoffset = 0x00000000; - t->setup.pp_txcblend = 0x00000000; - t->setup.pp_txablend = 0x00000000; - t->setup.pp_tfactor = 0x00000000; - t->setup.pp_border_color = 0x00000000; + make_empty_list( t ); radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); radeonSetTexBorderColor( t, tObj->BorderColor ); - tObj->DriverData = t; - - make_empty_list( t ); - return t; } -/* Destroy hardware state associated with texture `t'. - */ -void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) -{ -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - rmesa->c_textureSwaps++; -#endif - if ( !t ) return; - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) - t->tObj->DriverData = NULL; - if ( t->bound ) - rmesa->CurrentTexObj[t->bound-1] = NULL; - - remove_from_list( t ); - FREE( t ); -} - -/* Keep track of swapped out texture objects. - */ -static void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) -{ -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - rmesa->c_textureSwaps++; -#endif - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - t->dirty_images = ~0; - move_to_tail( &rmesa->SwappedOut, t ); -} - -/* Print out debugging information about texture LRU. - */ -void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ) -{ - radeonTexObjPtr t; - int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]); - - fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - - foreach ( t, &rmesa->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 radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ) -{ - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int i, j; - - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); - - for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) { - fprintf( stderr, "list[%d] age %d next %d prev %d\n", - j, list[j].age, list[j].next, list[j].prev ); - j = list[j].next; - if ( j == RADEON_NR_TEX_REGIONS ) break; - } - - if ( j != RADEON_NR_TEX_REGIONS ) { - fprintf( stderr, "Loop detected in global LRU\n" ); - for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) { - fprintf( stderr, "list[%d] age %d next %d prev %d\n", - i, list[i].age, list[i].next, list[i].prev ); - } - } - - fprintf( stderr, "\n" ); -} - -/* Reset the global texture LRU. - */ -static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap ) -{ - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; - int i; - - /* - * (Re)initialize the global circular LRU list. The last element in - * the array (RADEON_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. - */ - for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - } - - i--; - list[0].prev = RADEON_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = RADEON_NR_TEX_REGIONS; - list[RADEON_NR_TEX_REGIONS].prev = i; - list[RADEON_NR_TEX_REGIONS].next = 0; - rmesa->sarea->texAge[heap] = 0; -} - -/* Update the local and glock texture LRUs. - */ -static void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t ) -{ - int heap = t->heap; - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = rmesa->radeonScreen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> sz; - int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; - int i; - - rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; - - if ( !t->memBlock ) { - fprintf( stderr, "no memblock\n\n" ); - return; - } - - /* Update our local LRU */ - move_to_head( &rmesa->TexObjList[heap], t ); - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - list[i].in_use = 1; - list[i].age = rmesa->lastTexAge[heap]; - - /* remove_from_list(i) */ - list[(CARD32)list[i].next].prev = list[i].prev; - list[(CARD32)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) */ - list[i].prev = RADEON_NR_TEX_REGIONS; - list[i].next = list[RADEON_NR_TEX_REGIONS].next; - list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; - list[RADEON_NR_TEX_REGIONS].next = i; - } - - if ( 0 ) { - radeonPrintGlobalLRU( rmesa, t->heap ); - radeonPrintLocalLRU( rmesa, 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). - */ -static void radeonTexturesGone( radeonContextPtr rmesa, int heap, - int offset, int size, int in_use ) -{ - radeonTexObjPtr t, tmp; - - foreach_s ( t, tmp, &rmesa->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 ) { - radeonSwapOutTexObj( rmesa, t ); - } else { - radeonDestroyTexObj( rmesa, t ); - } - } - - if ( in_use ) { - t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); - if ( !t ) return; - t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); - if ( !t->memBlock ) { - fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset ); - mmDumpMemInfo( rmesa->texHeap[heap] ); - return; - } - insert_at_head( &rmesa->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 radeonAgeTextures( radeonContextPtr rmesa, int heap ) +static GLint radeonChooseTexFormat( radeonContextPtr rmesa, + struct gl_texture_image *texImage, + GLenum format, GLenum type ) { - RADEONSAREAPrivPtr sarea = rmesa->sarea; - - if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { - int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; - int nr = 0; - int idx; - - for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; - idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; - idx = sarea->texList[heap][idx].prev, nr++ ) - { - /* 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 > rmesa->radeonScreen->texSize[heap] ) { - nr = RADEON_NR_TEX_REGIONS; - break; - } - - if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { - radeonTexturesGone( rmesa, heap, idx * sz, sz, - sarea->texList[heap][idx].in_use ); - } - } - - if ( nr == RADEON_NR_TEX_REGIONS ) { - radeonTexturesGone( rmesa, heap, 0, - rmesa->radeonScreen->texSize[heap], 0 ); - radeonResetGlobalLRU( rmesa, heap ); - } - - rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | - RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES); - rmesa->lastTexAge[heap] = sarea->texAge[heap]; - } -} + const GLboolean do32bpt = ( rmesa->radeonScreen->cpp == 4 ); + const struct gl_texture_format *texFormat; + GLint ret; + if ( 0 ) + fprintf( stderr, "internal=%s format=%s type=%s\n", + texImage->IntFormat == 3 ? "GL_RGB (3)" : + texImage->IntFormat == 4 ? "GL_RGBA (4)" : + gl_lookup_enum_by_nr( texImage->IntFormat ), + gl_lookup_enum_by_nr( format ), + gl_lookup_enum_by_nr( type ) ); -/* ================================================================ - * Texture image conversions - */ - -/* Convert a block of Mesa-formatted texture to an 8bpp hardware format. - */ -static void radeonConvertTexture8bpp( CARD32 *dst, - struct gl_texture_image *image, - int x, int y, int width, int height, - int pitch ) -{ - CARD8 *src; - int i, j; - - if ( width < 4 ) { - width = 4; - } - -#define ALIGN_DST \ +#define SET_FORMAT( r, gl ) \ do { \ - if ( width < 32 ) { \ - dst += ((32 - width) / 4); \ - } \ + ret = (r); \ + texFormat = &(gl); \ } while (0) - switch ( image->Format ) { - case GL_INTENSITY: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width >> 2 ; j ; j-- ) { - *dst++ = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); - src += 4; - } - ALIGN_DST; - } - break; - - case GL_COLOR_INDEX: - default: - fprintf( stderr, "%s: unsupported format 0x%x\n", - __FUNCTION__, image->Format ); - break; - } -} -#undef ALIGN_DST - -/* Convert a block of Mesa-formatted texture to a 16bpp hardware format. - */ -static void radeonConvertTexture16bpp( CARD32 *dst, - struct gl_texture_image *image, - int x, int y, int width, int height, - int pitch ) -{ - CARD8 *src; - int i, j; - - if ( width < 2 ) { - width = 2; - } - -#define ALIGN_DST \ +#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \ do { \ - if ( width < 16 ) { \ - dst += ((16 - width) / 2); \ + if ( do32bpt ) { \ + ret = (r32); \ + texFormat = &(gl32); \ + } else { \ + ret = (r16); \ + texFormat = &(gl16); \ } \ } while (0) - switch ( image->Format ) { + switch ( texImage->IntFormat ) { + /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has + * got to be better than sticking them way down the end of this + * huge list. + */ case GL_RGBA: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((RADEONPACKCOLOR4444( src[0], src[1], src[2], src[3] )) | - (RADEONPACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16)); - src += 8; + case 4: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + SET_FORMAT( RADEON_TXFORMAT_ARGB8888, _mesa_texformat_argb8888 ); + break; + } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + SET_FORMAT( RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 ); + break; + } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + SET_FORMAT( RADEON_TXFORMAT_ARGB1555, _mesa_texformat_argb1555 ); + break; } - ALIGN_DST; } + SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888, + RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 ); break; case GL_RGB: - { - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((RADEONPACKCOLOR565( src[0], src[1], src[2] )) | - (RADEONPACKCOLOR565( src[3], src[4], src[5] ) << 16)); - src += 6; - } - ALIGN_DST; + case 3: + if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { + SET_FORMAT( RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 ); + break; } - } + SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888, + RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 ); break; - case GL_ALPHA: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((RADEONPACKCOLOR88( 0x00, src[0] )) | - (RADEONPACKCOLOR88( 0x00, src[1] ) << 16)); - src += 2; - } - ALIGN_DST; - } + /* GH: Okay, keep checking as normal. Still test for GL_RGB, + * GL_RGBA formats first. + */ + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888, + RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 ); break; - case GL_LUMINANCE: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((RADEONPACKCOLOR88( src[0], 0xff )) | - (RADEONPACKCOLOR88( src[1], 0xff ) << 16)); - src += 2; - } - ALIGN_DST; - } + case GL_RGBA4: + case GL_RGBA2: + SET_FORMAT( RADEON_TXFORMAT_ARGB4444, _mesa_texformat_argb4444 ); break; - case GL_LUMINANCE_ALPHA: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((RADEONPACKCOLOR88( src[0], src[1] )) | - (RADEONPACKCOLOR88( src[2], src[3] ) << 16)); - src += 4; - } - ALIGN_DST; - } + case GL_RGB5_A1: + SET_FORMAT( RADEON_TXFORMAT_ARGB1555, _mesa_texformat_argb1555 ); break; - default: - fprintf( stderr, "%s: unsupported format 0x%x\n", - __FUNCTION__, image->Format ); + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + SET_FORMAT_32BPT( RADEON_TXFORMAT_RGBA8888, _mesa_texformat_rgba8888, + RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 ); break; - } -} -#undef ALIGN_DST -/* Convert a block of Mesa-formatted texture to a 32bpp hardware format. - */ -static void radeonConvertTexture32bpp( CARD32 *dst, - struct gl_texture_image *image, - int x, int y, int width, int height, - int pitch ) -{ - CARD8 *src; - int i, j; + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + SET_FORMAT( RADEON_TXFORMAT_RGB565, _mesa_texformat_rgb565 ); + break; -#define ALIGN_DST \ - do { \ - if ( width < 8 ) { \ - dst += (8 - width); \ - } \ - } while (0) + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + SET_FORMAT( RADEON_TXFORMAT_AI88, _mesa_texformat_al88 ); + break; - switch ( image->Format ) { - case GL_RGBA: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; - for ( j = width ; j ; j-- ) { - *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], src[3] ); - src += 4; - } - ALIGN_DST; - } + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + SET_FORMAT( RADEON_TXFORMAT_AI88, _mesa_texformat_al88 ); break; - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width ; j ; j-- ) { - *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], 0xff ); - src += 3; - } - ALIGN_DST; - } + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + SET_FORMAT( RADEON_TXFORMAT_AI88, _mesa_texformat_al88 ); break; - default: - fprintf( stderr, "%s: unsupported format 0x%x\n", - __FUNCTION__, image->Format ); + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + SET_FORMAT( RADEON_TXFORMAT_I8, _mesa_texformat_i8 ); break; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + default: + fprintf( stderr, "bad texture format in radeonChooseTexFormat() %d", + texImage->IntFormat ); + return -1; } + + texImage->TexFormat = texFormat; + + return ret; } -/* Upload the texture image associated with texture `t' at level `level' - * at the address relative to `start'. + +/* ================================================================ + * Texture image callbacks */ -static void radeonUploadSubImage( radeonContextPtr rmesa, - radeonTexObjPtr t, GLint level, - GLint x, GLint y, GLint width, GLint height ) -{ - struct gl_texture_image *image; - GLint texelsPerDword = 0; - GLint imageX, imageY, imageWidth, imageHeight; - GLint blitX, blitY, blitWidth, blitHeight; - GLint imageRows, blitRows; - GLint remaining ; - GLint format, dwords; - CARD32 pitch, offset; - drmBufPtr buffer; - CARD32 *dst; - - /* Ensure we have a valid texture to upload */ - if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) ) - return; - image = t->tObj->Image[level]; - if ( !image ) - return; +static GLboolean +radeonDDTexImage1D( GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; + GLuint unit = ctx->Texture.CurrentUnit; + GLuint texSize; + GLint txformat; + GLubyte *data; - switch ( t->texelBytes ) { - case 1: - texelsPerDword = 4; - break; - case 2: - texelsPerDword = 2; - break; - case 4: - texelsPerDword = 1; - break; - } + if ( target != GL_TEXTURE_1D ) + return GL_FALSE; - format = t->setup.pp_txformat & RADEON_TXF_FORMAT_MASK; - - imageX = 0; - imageY = 0; - imageWidth = image->Width; - imageHeight = image->Height; - - blitX = t->image[level].x; - blitY = t->image[level].y; - blitWidth = t->image[level].width; - blitHeight = t->image[level].height; - - dwords = t->image[level].dwords; - offset = t->bufAddr; - pitch = (t->image[0].width * t->texelBytes) / 64; - -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - rmesa->c_textureBytes += (dwords << 2); -#endif - - if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { - fprintf( stderr, " upload image: %d,%d at %d,%d\n", - imageWidth, imageHeight, imageX, imageY ); - fprintf( stderr, " upload blit: %d,%d at %d,%d\n", - blitWidth, blitHeight, blitX, blitY ); - fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d " - "level: %d format: %x\n", - (GLuint)offset, (GLuint)pitch, dwords, level, format ); + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, texObj, level ); } - /* Subdivide the texture if required */ - if ( dwords <= RADEON_BUFFER_MAX_DWORDS / 2 ) { - imageRows = imageHeight; - blitRows = blitHeight; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSwapOutTexObj( rmesa, t ); } else { - imageRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword)/(2 * imageWidth); - blitRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * blitWidth); + t = radeonAllocTexObj( texObj ); + texObj->DriverData = t; } - for ( remaining = imageHeight ; - remaining > 0 ; - remaining -= imageRows, imageY += imageRows, blitY += blitRows ) - { - if ( remaining >= imageRows ) { - imageHeight = imageRows; - blitHeight = blitRows; - } else { - imageHeight = remaining; - blitHeight = blitRows; - } - dwords = blitWidth * blitHeight / texelsPerDword; + txformat = radeonChooseTexFormat( rmesa, texImage, format, type ); + if ( txformat < 0 ) + return GL_FALSE; - if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { - fprintf( stderr, " blitting: %d,%d at %d,%d\n", - imageWidth, imageHeight, imageX, imageY ); - fprintf( stderr, " %d,%d at %d,%d - %d dwords\n", - blitWidth, blitHeight, blitX, blitY, dwords ); - } + texFormat = texImage->TexFormat; + texSize = texImage->Width * texFormat->TexelBytes; - /* Grab the indirect buffer for the texture blit */ - buffer = radeonGetBufferLocked( rmesa ); + /* We really shouldn't have to keep the texture image, it should be + * hung from the main texImage structure. + */ + if ( t->image[level].data ) { + FREE( t->image[level].data ); + t->image[level].data = NULL; + } - dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET); + data = (GLubyte *) MALLOC( texSize ); + if ( !data ) + return GL_FALSE; - /* Actually do the texture conversion */ - switch ( t->texelBytes ) { - case 1: - radeonConvertTexture8bpp( dst, image, - imageX, imageY, imageWidth, imageHeight, - imageWidth ); - break; - case 2: - radeonConvertTexture16bpp( dst, image, - imageX, imageY, imageWidth, imageHeight, - imageWidth ); - break; - case 4: - radeonConvertTexture32bpp( dst, image, - imageX, imageY, imageWidth, imageHeight, - imageWidth ); - break; - } - - radeonFireBlitLocked( rmesa, buffer, - offset, pitch, format, - blitX, blitY, blitWidth, blitHeight ); + if ( !_mesa_convert_texsubimage1d( texFormat->IntFormat, + 0, texImage->Width, + format, type, packing, + pixels, data ) ) { + /*fprintf( stderr, " *** convert failed!\n" );*/ + FREE( data ); + return GL_FALSE; } - rmesa->new_state |= RADEON_NEW_CONTEXT; - rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; -} + t->image[level].data = data; + t->dirty_images |= (1 << level); -/* Upload the texture images associated with texture `t'. This might - * require removing our own and/or other client's texture objects to - * make room for these images. - */ -/* NOTE: This function is only called while holding the hardware lock */ -int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) -{ - int i; - int heap; + /* Format-specific hardware state: + */ + t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | + RADEON_TXFORMAT_ALPHA_IN_MAP); + t->pp_txformat |= txformat; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %p )\n", - __FUNCTION__, rmesa->glCtx, t ); + if ( txformat == RADEON_TXFORMAT_RGBA8888 || + txformat == RADEON_TXFORMAT_ARGB4444 || + txformat == RADEON_TXFORMAT_ARGB1555 || + txformat == RADEON_TXFORMAT_AI88 ) { + t->pp_txformat |= RADEON_TXFORMAT_ALPHA_IN_MAP; } - if ( !t ) - return 0; - - /* Choose the heap appropriately */ - heap = t->heap = RADEON_CARD_HEAP; -#if 0 - if ( !rmesa->radeonScreen->IsPCI && - t->totalSize > rmesa->radeonScreen->texSize[heap] ) { - heap = t->heap = RADEON_AGP_HEAP; + /* If we don't have a texture bound, bind this one. + */ + if ( !rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; } -#endif - - /* Do we need to eject LRU texture objects? */ - if ( !t->memBlock ) { - /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ - t->memBlock = mmAllocMem( rmesa->texHeap[heap], - t->totalSize, 12, 0 ); - -#if 0 - /* Try AGP before kicking anything out of local mem */ - if ( !t->memBlock && heap == RADEON_CARD_HEAP ) { - t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP], - t->totalSize, 12, 0 ); - - if ( t->memBlock ) - heap = t->heap = RADEON_AGP_HEAP; - } -#endif - - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - if ( rmesa->TexObjList[heap].prev->bound ) { - fprintf( stderr, - "radeonUploadTexImages: ran into bound texture\n" ); - return -1; - } - if ( rmesa->TexObjList[heap].prev == - &rmesa->TexObjList[heap] ) { - if ( rmesa->radeonScreen->IsPCI ) { - fprintf( stderr, "radeonUploadTexImages: upload texture " - "failure on local texture heaps, sz=%d\n", - t->totalSize ); - return -1; -#if 0 - } else if ( heap == RADEON_CARD_HEAP ) { - heap = t->heap = RADEON_AGP_HEAP; - continue; -#endif - } else { - fprintf( stderr, "radeonUploadTexImages: upload texture " - "failure on both local and AGP texture heaps, " - "sz=%d\n", - t->totalSize ); - return -1; - } - } - - radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev ); - t->memBlock = mmAllocMem( rmesa->texHeap[heap], - t->totalSize, 12, 0 ); - } - - /* Set the base offset of the texture image */ - t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs; + rmesa->new_state |= RADEON_NEW_TEXTURE; - t->setup.pp_txoffset = t->bufAddr; -#if 0 - /* Fix AGP texture offsets */ - if ( heap == RADEON_AGP_HEAP ) { - t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET + - rmesa->radeonScreen->agpTexOffset; - } -#endif + *retainInternalCopy = GL_FALSE; + return GL_TRUE; +} - /* Force loading the new state into the hardware */ - switch ( t->bound ) { - case 1: - rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0; - break; +static GLboolean +radeonDDTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; + GLuint unit = ctx->Texture.CurrentUnit; + GLuint texSize; + GLint txformat; + GLubyte *data; - case 2: - rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1; - break; + if ( target != GL_TEXTURE_2D ) + return GL_FALSE; - default: - return -1; - } + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, texObj, level ); } - /* Let the world know we've used this memory recently */ - radeonUpdateTexLRU( rmesa, t ); + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSwapOutTexObj( rmesa, t ); + } else { + t = radeonAllocTexObj( texObj ); + texObj->DriverData = t; + } - /* Upload any images that are new */ - if ( t->dirty_images ) { - int num_levels = ((t->setup.pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >> - RADEON_MAX_MIP_LEVEL_SHIFT); + txformat = radeonChooseTexFormat( rmesa, texImage, format, type ); + if ( txformat < 0 ) + return GL_FALSE; - for ( i = 0 ; i <= num_levels ; i++ ) { - if ( t->dirty_images & (1 << i) ) { - radeonUploadSubImage( rmesa, t, i, 0, 0, - t->image[i].width, t->image[i].height ); - } - } + texFormat = texImage->TexFormat; + texSize = texImage->Width * texImage->Height * texFormat->TexelBytes; - rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + /* We really shouldn't have to keep the texture image, it should be + * hung from the main texImage structure. + */ + if ( t->image[level].data ) { + FREE( t->image[level].data ); + t->image[level].data = NULL; } - t->dirty_images = 0; - return 0; -} - + data = (GLubyte *) MALLOC( texSize ); + if ( !data ) + return GL_FALSE; -/* ================================================================ - * Texture combine functions - */ + if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat, + 0, 0, texImage->Width, texImage->Height, + texImage->Width, format, type, packing, + pixels, data ) ) { + if ( 0 ) + fprintf( stderr, " *** convert failed! %s/%s-> %s\n", + gl_lookup_enum_by_nr( format ), + gl_lookup_enum_by_nr( type ), + gl_lookup_enum_by_nr( texImage->IntFormat ) ); + FREE( data ); + return GL_FALSE; + } -#define RADEON_DISABLE 0 -#define RADEON_REPLACE 1 -#define RADEON_MODULATE 2 -#define RADEON_DECAL 3 -#define RADEON_BLEND 4 -#define RADEON_ADD 5 -#define RADEON_MAX_COMBFUNC 6 + t->image[level].data = data; + t->dirty_images |= (1 << level); -static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] = -{ - /* Unit 0: - */ - { - /* Disable combiner stage - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_CURRENT_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00802800 - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T0_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800142 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T0_COLOR | - RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x008c2d42 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T0_COLOR | - RADEON_COLOR_ARG_C_T0_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x008c2902 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_TFACTOR_COLOR | - RADEON_COLOR_ARG_C_T0_COLOR | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_ADD = 0x00812802 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T0_COLOR | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - }, - - /* Unit 1: - */ - { - /* Disable combiner stage - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_CURRENT_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00803000 - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T1_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800182 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T1_COLOR | - RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x008c3582 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T1_COLOR | - RADEON_COLOR_ARG_C_T1_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x008c3102 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_TFACTOR_COLOR | - RADEON_COLOR_ARG_C_T1_COLOR | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_ADD = 0x00813002 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T1_COLOR | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - }, - - /* Unit 2: + /* Format-specific hardware state: */ - { - /* Disable combiner stage - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_CURRENT_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00803800 - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T2_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x008001c2 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T2_COLOR | - RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x008c3dc2 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T2_COLOR | - RADEON_COLOR_ARG_C_T2_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x008c3902 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_TFACTOR_COLOR | - RADEON_COLOR_ARG_C_T2_COLOR | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_ADD = 0x00813802 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T2_COLOR | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), + t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | + RADEON_TXFORMAT_ALPHA_IN_MAP); + t->pp_txformat |= txformat; + + if ( txformat == RADEON_TXFORMAT_RGBA8888 || + txformat == RADEON_TXFORMAT_ARGB4444 || + txformat == RADEON_TXFORMAT_ARGB1555 || + txformat == RADEON_TXFORMAT_AI88 ) { + t->pp_txformat |= RADEON_TXFORMAT_ALPHA_IN_MAP; } -}; -static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] = -{ - /* Unit 0: - */ - { - /* Disable combiner stage - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00800500 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T0_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800051 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_T0_ALPHA | - RADEON_ALPHA_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x00800100 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x00800051 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | - RADEON_ALPHA_ARG_C_T0_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_ADD = 0x00800051 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T0_ALPHA | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - }, - - /* Unit 1: + /* If we don't have a texture bound, bind this one. */ - { - /* Disable combiner stage - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00800600 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T1_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800061 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_T1_ALPHA | - RADEON_ALPHA_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x00800100 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x00800061 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | - RADEON_ALPHA_ARG_C_T1_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_ADD = 0x00800061 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T1_ALPHA | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - }, - - /* Unit 2: - */ - { - /* Disable combiner stage - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00800700 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T2_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800071 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_T2_ALPHA | - RADEON_ALPHA_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x00800100 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x00800071 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | - RADEON_ALPHA_ARG_C_T2_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_ADD = 0x00800021 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T2_ALPHA | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), + if ( !rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; } -}; + rmesa->new_state |= RADEON_NEW_TEXTURE; -/* GL_EXT_texture_env_combine support - */ + *retainInternalCopy = GL_FALSE; + return GL_TRUE; +} -/* The color tables have combine functions for GL_SRC_COLOR, - * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. +/* GH: This is undoubtedly broken... */ -static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] = -{ - { - RADEON_COLOR_ARG_A_T0_COLOR, - RADEON_COLOR_ARG_A_T1_COLOR, - RADEON_COLOR_ARG_A_T2_COLOR - }, - { - RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A - }, - { - RADEON_COLOR_ARG_A_T0_ALPHA, - RADEON_COLOR_ARG_A_T1_ALPHA, - RADEON_COLOR_ARG_A_T2_ALPHA - }, - { - RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A - }, -}; - -static GLuint radeon_tfactor_color[] = -{ - RADEON_COLOR_ARG_A_TFACTOR_COLOR, - RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_TFACTOR_ALPHA, - RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A -}; - -static GLuint radeon_primary_color[] = -{ - RADEON_COLOR_ARG_A_DIFFUSE_COLOR, - RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_DIFFUSE_ALPHA, - RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A -}; - -static GLuint radeon_previous_color[] = +static GLboolean +radeonDDTexImage3D( GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy ) { - RADEON_COLOR_ARG_A_CURRENT_COLOR, - RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A, - RADEON_COLOR_ARG_A_CURRENT_ALPHA, - RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A -}; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; + GLuint unit = ctx->Texture.CurrentUnit; + GLuint texSize; + GLint txformat; + GLubyte *data; -/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. - */ -static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] = -{ - { - RADEON_ALPHA_ARG_A_T0_ALPHA, - RADEON_ALPHA_ARG_A_T1_ALPHA, - RADEON_ALPHA_ARG_A_T2_ALPHA - }, - { - RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, - RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, - RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A - }, -}; - -static GLuint radeon_tfactor_alpha[] = -{ - RADEON_ALPHA_ARG_A_TFACTOR_ALPHA, - RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A -}; + if ( target != GL_TEXTURE_3D ) + return GL_FALSE; -static GLuint radeon_primary_alpha[] = -{ - RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA, - RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A -}; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSwapOutTexObj( rmesa, t ); + } else { + t = radeonAllocTexObj( texObj ); + texObj->DriverData = t; + } -static GLuint radeon_previous_alpha[] = -{ - RADEON_ALPHA_ARG_A_CURRENT_ALPHA, - RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A -}; + txformat = radeonChooseTexFormat( rmesa, texImage, format, type ); + if ( txformat < 0 ) + return GL_FALSE; + texFormat = texImage->TexFormat; + texSize = (texImage->Width * texImage->Height * + texImage->Depth * texFormat->TexelBytes); -/* Extract the arg from slot A, shift it into the correct argument slot - * and set the corresponding complement bit. - */ -#define RADEON_COLOR_ARG( n, arg ) \ -do { \ - color_combine |= \ - ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ - << RADEON_COLOR_ARG_##arg##_SHIFT); \ - color_combine |= \ - ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ - << RADEON_COMP_ARG_##arg##_SHIFT); \ -} while (0) - -#define RADEON_ALPHA_ARG( n, arg ) \ -do { \ - alpha_combine |= \ - ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ - << RADEON_ALPHA_ARG_##arg##_SHIFT); \ - alpha_combine |= \ - ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ - << RADEON_COMP_ARG_##arg##_SHIFT); \ -} while (0) + /* We really shouldn't have to keep the texture image, it should be + * hung from the main texImage structure. + */ + if ( t->image[level].data ) { + FREE( t->image[level].data ); + t->image[level].data = NULL; + } + data = (GLubyte *) MALLOC( texSize ); + if ( !data ) + return GL_FALSE; -/* ================================================================ - * Texture unit state management - */ + if ( !_mesa_convert_texsubimage3d( texFormat->IntFormat, + 0, 0, 0, texImage->Width, + texImage->Height, texImage->Depth, + texImage->Width, texImage->Height, + format, type, packing, + pixels, data ) ) { + FREE( data ); + return GL_FALSE; + } -static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int source = rmesa->tmu_source[unit]; - struct gl_texture_object *tObj; - struct gl_texture_unit *texUnit; - GLuint enabled; - GLuint color_combine, alpha_combine; - GLuint color_arg[3], alpha_arg[3]; - GLuint i, numColorArgs = 0, numAlphaArgs = 0; - GLuint op; + t->image[level].data = data; + t->dirty_images |= (1 << level); - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %d )\n", - __FUNCTION__, ctx, unit ); + /* If we don't have a texture bound, bind this one. + */ + if ( !rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; } - enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; - if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) - return; + rmesa->new_state |= RADEON_NEW_TEXTURE; - /* Only update the hardware texture state if the texture is current, - * complete and enabled. - */ - texUnit = &ctx->Texture.Unit[source]; - tObj = texUnit->Current; - if ( !tObj || !tObj->Complete ) - return; + *retainInternalCopy = GL_FALSE; + return GL_TRUE; +} - if ( ( tObj != texUnit->CurrentD[2] ) && - ( tObj != texUnit->CurrentD[1] ) ) - return; - /* Set the texture environment state. Isn't this nice and clean? - * The Radeon will automagically set the texture alpha to 0xff when - * the texture format does not include an alpha component. This - * reduces the amount of special-casing we have to do, alpha-only - * textures being a notable exception. - */ - switch ( texUnit->EnvMode ) { - case GL_REPLACE: - switch ( tObj->Image[0]->Format ) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_REPLACE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; - break; - case GL_COLOR_INDEX: - default: - return; - } - break; +/* ================================================================ + * Texture subimage callbacks + */ - case GL_MODULATE: - switch ( tObj->Image[0]->Format ) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_MODULATE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_COLOR_INDEX: - default: - return; - } - break; +static GLboolean +radeonDDTexSubImage1D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; - case GL_DECAL: - switch ( tObj->Image[0]->Format ) { - case GL_RGBA: - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_DECAL]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_COLOR_INDEX: - default: - return; - } - break; + if ( target != GL_TEXTURE_1D ) + return GL_FALSE; - case GL_BLEND: - switch ( tObj->Image[0]->Format ) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_BLEND]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_BLEND]; - alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; - break; - case GL_COLOR_INDEX: - default: - return; - } - break; + /* FIXME: Can this ever be NULL??? + */ + ASSERT( t ); - case GL_ADD: - switch ( tObj->Image[0]->Format ) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_ADD]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_ADD]; - alpha_combine = radeon_alpha_combine[unit][RADEON_ADD]; - break; - case GL_COLOR_INDEX: - default: - return; - } - break; + if ( t->bound ) + FLUSH_BATCH( rmesa ); - case GL_COMBINE_EXT: - /* Step 0: - * Calculate how many arguments we need to process. - */ - switch ( texUnit->CombineModeRGB ) { - case GL_REPLACE: - numColorArgs = 1; - break; - case GL_MODULATE: - case GL_ADD: - case GL_ADD_SIGNED_EXT: - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGBA_EXT: - numColorArgs = 2; - break; - case GL_INTERPOLATE_EXT: - numColorArgs = 3; - break; - default: - return; - } + texFormat = texImage->TexFormat; - switch ( texUnit->CombineModeA ) { - case GL_REPLACE: - numAlphaArgs = 1; - break; - case GL_MODULATE: - case GL_ADD: - case GL_ADD_SIGNED_EXT: - numAlphaArgs = 2; - break; - case GL_INTERPOLATE_EXT: - numAlphaArgs = 3; - break; - default: - return; - } + if ( !_mesa_convert_texsubimage1d( texFormat->IntFormat, + xoffset, width, format, type, packing, + pixels, t->image[level].data ) ) { + /*fprintf( stderr, " *** convert failed!\n" );*/ + return GL_FALSE; + } - /* Step 1: - * Extract the color and alpha combine function arguments. - */ - for ( i = 0 ; i < numColorArgs ; i++ ) { - op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; - switch ( texUnit->CombineSourceRGB[i] ) { - case GL_TEXTURE: - color_arg[i] = radeon_texture_color[op][unit]; - break; - case GL_CONSTANT_EXT: - color_arg[i] = radeon_tfactor_color[op]; - break; - case GL_PRIMARY_COLOR_EXT: - color_arg[i] = radeon_primary_color[op]; - break; - case GL_PREVIOUS_EXT: - color_arg[i] = radeon_previous_color[op]; - break; - default: - return; - } - } + t->dirty_images |= (1 << level); + rmesa->new_state |= RADEON_NEW_TEXTURE; - for ( i = 0 ; i < numAlphaArgs ; i++ ) { - op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; - switch ( texUnit->CombineSourceA[i] ) { - case GL_TEXTURE: - alpha_arg[i] = radeon_texture_alpha[op][unit]; - break; - case GL_CONSTANT_EXT: - alpha_arg[i] = radeon_tfactor_alpha[op]; - break; - case GL_PRIMARY_COLOR_EXT: - alpha_arg[i] = radeon_primary_alpha[op]; - break; - case GL_PREVIOUS_EXT: - alpha_arg[i] = radeon_previous_alpha[op]; - break; - default: - return; - } - } + return GL_TRUE; +} - /* Step 2: - * Build up the color and alpha combine functions. - */ - switch ( texUnit->CombineModeRGB ) { - case GL_REPLACE: - color_combine = (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, C ); - break; - case GL_MODULATE: - color_combine = (RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, B ); - break; - case GL_ADD: - color_combine = (RADEON_COLOR_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - break; - case GL_ADD_SIGNED_EXT: - color_combine = (RADEON_COLOR_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADDSIGNED | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - break; - case GL_INTERPOLATE_EXT: - color_combine = (RADEON_BLEND_CTL_BLEND | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, B ); - RADEON_COLOR_ARG( 1, A ); - RADEON_COLOR_ARG( 2, C ); - break; - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGBA_EXT: - color_combine = (RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_DOT3 | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, B ); - break; - default: - return; - } +static GLboolean +radeonDDTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; - switch ( texUnit->CombineModeA ) { - case GL_REPLACE: - alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, C ); - break; - case GL_MODULATE: - alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, B ); - break; - case GL_ADD: - alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - break; - case GL_ADD_SIGNED_EXT: - alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADDSIGNED | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - break; - case GL_INTERPOLATE_EXT: - alpha_combine = (RADEON_BLEND_CTL_BLEND | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, B ); - RADEON_ALPHA_ARG( 1, A ); - RADEON_ALPHA_ARG( 2, C ); - break; - default: - return; - } + if ( target != GL_TEXTURE_2D ) + return GL_FALSE; - if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) { - alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; - } + /* FIXME: Can this ever be NULL??? + */ + ASSERT( t ); - /* Step 3: - * Apply the scale factor. The EXT extension has a somewhat - * unnecessary restriction that the scale must be 4x. The ARB - * extension will likely drop this and we can just apply the - * scale factors regardless. - */ - if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT && - texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) { - color_combine |= (texUnit->CombineScaleShiftRGB << 21); - alpha_combine |= (texUnit->CombineScaleShiftA << 21); - } else { - color_combine |= RADEON_SCALE_4X; - alpha_combine |= RADEON_SCALE_4X; - } + if ( t->bound ) + FLUSH_BATCH( rmesa ); - /* All done! - */ - break; + texFormat = texImage->TexFormat; - default: - return; + if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat, + xoffset, yoffset, width, height, + texImage->Width, format, type, packing, + pixels, t->image[level].data ) ) { + /*fprintf( stderr, " *** convert failed!\n" );*/ + return GL_FALSE; } - rmesa->color_combine[source] = color_combine; - rmesa->alpha_combine[source] = alpha_combine; + t->dirty_images |= (1 << level); + rmesa->new_state |= RADEON_NEW_TEXTURE; + + return GL_TRUE; } -static void radeonUpdateTextureObject( GLcontext *ctx, int unit ) +/* GH: This is undoubtedly broken... + */ +static GLboolean +radeonDDTexSubImage3D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLint depth, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int source = rmesa->tmu_source[unit]; - struct gl_texture_object *tObj; - radeonTexObjPtr t; - GLuint enabled; + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + const struct gl_texture_format *texFormat; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %d )\n", - __FUNCTION__, ctx, unit ); - } - - enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; - if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { - if ( enabled ) - rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; - return; - } + if ( target != GL_TEXTURE_3D ) + return GL_FALSE; - /* Only update the hardware texture state if the texture is current, - * complete and enabled. + /* FIXME: Can this ever be NULL??? */ - tObj = ctx->Texture.Unit[source].Current; - if ( !tObj || !tObj->Complete ) - return; - - if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && - ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) - return; + ASSERT( t ); - if ( !tObj->DriverData ) { - /* If this is the first time the texture has been used, then create - * a new texture object for it. - */ - radeonCreateTexObj( rmesa, tObj ); - - if ( !tObj->DriverData ) { - /* Can't create a texture object... */ - fprintf( stderr, "%s: texture object creation failed!\n", - __FUNCTION__ ); - rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; - return; - } - } - - /* We definately have a valid texture now */ - t = tObj->DriverData; - - /* Force the texture unit state to be loaded into the hardware */ - rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit); + if ( t->bound ) + FLUSH_BATCH( rmesa ); - /* Force any texture images to be loaded into the hardware */ - if ( t->dirty_images ) - rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit); + texFormat = texImage->TexFormat; - /* Bind to the given texture unit */ - rmesa->CurrentTexObj[unit] = t; - t->bound = unit + 1; + if ( !_mesa_convert_texsubimage3d( texFormat->IntFormat, + xoffset, yoffset, zoffset, + width, height, depth, + texImage->Width, texImage->Height, + format, type, packing, + pixels, t->image[level].data ) ) { + /*fprintf( stderr, " *** convert failed!\n" );*/ + return GL_FALSE; + } - if ( t->memBlock ) - radeonUpdateTexLRU( rmesa, t ); + t->dirty_images |= (1 << level); + rmesa->new_state |= RADEON_NEW_TEXTURE; - switch ( unit ) { - case 0: - rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE | - RADEON_TEX_BLEND_0_ENABLE); - break; - case 1: - rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE | - RADEON_TEX_BLEND_1_ENABLE); - break; - } + return GL_TRUE; } -void radeonUpdateTextureState( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p ) en=0x%x\n", - __FUNCTION__, ctx, ctx->Texture.ReallyEnabled ); - } - - /* Clear any texturing fallbacks */ - rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE; +/* ================================================================ + * DEPRECATED... + */ - /* Unbind any currently bound textures */ - if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0; - if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0; - rmesa->CurrentTexObj[0] = NULL; - rmesa->CurrentTexObj[1] = NULL; +static GLvoid *radeonDDGetTexImage( GLcontext *ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum *formatOut, GLenum *typeOut, + GLboolean *freeImageOut ) +{ + const struct gl_texture_image *texImage = texObj->Image[level]; + const struct gl_texture_format *texFormat = texImage->TexFormat; + radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + GLubyte *data; - if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) ) - rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + if ( !t || !t->image[level].data ) + return NULL; - /* Disable all texturing until it is known to be good */ - rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK | - RADEON_TEX_BLEND_ENABLE_MASK); + data = (GLubyte *) MALLOC( texImage->Width * texImage->Height * 4 ); + if ( !data ) + return NULL; - radeonUpdateTextureObject( ctx, 0 ); - radeonUpdateTextureEnv( ctx, 0 ); + if ( 0 ) + fprintf( stderr, " in=%d out=%s\n", + texFormat->IntFormat, + gl_lookup_enum_by_nr( texImage->Format ) ); - if ( rmesa->multitex ) { - radeonUpdateTextureObject( ctx, 1 ); - radeonUpdateTextureEnv( ctx, 1 ); + switch ( target ) { + case GL_TEXTURE_1D: + _mesa_unconvert_teximage1d( texFormat->IntFormat, texImage->Format, + texImage->Width, + t->image[level].data, data ); + break; + case GL_TEXTURE_2D: + _mesa_unconvert_teximage2d( texFormat->IntFormat, texImage->Format, + texImage->Width, texImage->Height, + t->image[level].data, data ); + break; + default: + return NULL; } - rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + *formatOut = texImage->Format; + *typeOut = GL_UNSIGNED_BYTE; + *freeImageOut = GL_TRUE; + + return data; } /* ================================================================ - * DD interface texturing functions - * - * FIXME: Many of these are deprecated -- we should move to the new - * single-copy texture interface. + * Texture state callbacks */ + #define SCALED_FLOAT_TO_BYTE( x, scale ) \ ((((GLint)((256.0F / scale) * (x))) - 1) / 2) @@ -2067,79 +805,6 @@ static void radeonDDTexEnv( GLcontext *ctx, GLenum target, } } -static void radeonDDTexImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint internalFormat, - const struct gl_texture_image *image ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t; - - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) - fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level ); - - if ( ( target != GL_TEXTURE_2D ) && - ( target != GL_TEXTURE_1D ) ) - return; - - if ( level >= RADEON_MAX_TEXTURE_LEVELS ) - return; - - t = (radeonTexObjPtr)tObj->DriverData; - if ( t ) { - if ( t->bound ) FLUSH_BATCH( rmesa ); - - /* Destroy the old texture, and upload a new one. The actual - * uploading of the texture image occurs in the UploadSubImage - * function. - */ - radeonDestroyTexObj( rmesa, t ); - rmesa->new_state |= RADEON_NEW_TEXTURE; - } -} - -static void radeonDDTexSubImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLint internalFormat, - const struct gl_texture_image *image ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t; - - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, level %d ) size: %d,%d of %d,%d\n", - __FUNCTION__, tObj, level, width, height, - image->Width, image->Height ); - } - - if ( ( target != GL_TEXTURE_2D ) && - ( target != GL_TEXTURE_1D ) ) - return; - - if ( level >= RADEON_MAX_TEXTURE_LEVELS ) - return; - - t = (radeonTexObjPtr)tObj->DriverData; - if ( t ) { - if ( t->bound ) FLUSH_BATCH( rmesa ); - -#if 0 - /* FIXME: Only upload textures if we already have space in the heap. - */ - LOCK_HARDWARE( rmesa ); - radeonUploadSubImage( rmesa, t, level, - xoffset, yoffset, width, height ); - UNLOCK_HARDWARE( rmesa ); -#else - radeonDestroyTexObj( rmesa, t ); -#endif - /* Update the context state */ - rmesa->new_state |= RADEON_NEW_TEXTURE; - } -} - static void radeonDDTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) @@ -2156,7 +821,7 @@ static void radeonDDTexParameter( GLcontext *ctx, GLenum target, * created with current state before it is used, so we don't have * to do anything now. */ - if ( !t || !t->bound ) + if ( !t ) return; if ( ( target != GL_TEXTURE_2D ) && @@ -2192,34 +857,51 @@ static void radeonDDBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLint unit = ctx->Texture.CurrentUnit; + radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; + GLuint unit = ctx->Texture.CurrentUnit; if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p ) unit=%d\n", - __FUNCTION__, tObj, ctx->Texture.CurrentUnit ); + __FUNCTION__, tObj, unit ); } FLUSH_BATCH( rmesa ); + if ( !t ) { + t = radeonAllocTexObj( tObj ); + tObj->DriverData = t; + } + + /* Unbind a currently bound texture. + */ if ( rmesa->CurrentTexObj[unit] ) { - rmesa->CurrentTexObj[unit]->bound = 0; + rmesa->CurrentTexObj[unit]->bound &= ~(unit + 1); rmesa->CurrentTexObj[unit] = NULL; } + /* Bind to the given texture unit. + */ + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; + rmesa->new_state |= RADEON_NEW_TEXTURE; } static void radeonDDDeleteTexture( GLcontext *ctx, - struct gl_texture_object *tObj ) + struct gl_texture_object *tObj ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, __FUNCTION__ "( %p )\n", tObj ); + } + if ( t ) { if ( t->bound ) { FLUSH_BATCH( rmesa ); - - rmesa->CurrentTexObj[t->bound-1] = 0; + if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; + if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; rmesa->new_state |= RADEON_NEW_TEXTURE; } @@ -2240,14 +922,19 @@ static GLboolean radeonDDIsTextureResident( GLcontext *ctx, void radeonDDInitTextureFuncs( GLcontext *ctx ) { + ctx->Driver.TexImage1D = radeonDDTexImage1D; + ctx->Driver.TexImage2D = radeonDDTexImage2D; + ctx->Driver.TexImage3D = NULL /*radeonDDTexImage3D*/; + ctx->Driver.TexSubImage1D = radeonDDTexSubImage1D; + ctx->Driver.TexSubImage2D = radeonDDTexSubImage2D; + ctx->Driver.TexSubImage3D = NULL /*radeonDDTexSubImage3D*/; + ctx->Driver.GetTexImage = radeonDDGetTexImage; ctx->Driver.TexEnv = radeonDDTexEnv; - ctx->Driver.TexImage = radeonDDTexImage; - ctx->Driver.TexSubImage = radeonDDTexSubImage; ctx->Driver.TexParameter = radeonDDTexParameter; ctx->Driver.BindTexture = radeonDDBindTexture; ctx->Driver.DeleteTexture = radeonDDDeleteTexture; - ctx->Driver.UpdateTexturePalette = NULL; - ctx->Driver.ActiveTexture = NULL; ctx->Driver.IsTextureResident = radeonDDIsTextureResident; ctx->Driver.PrioritizeTexture = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.UpdateTexturePalette = NULL; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h index 6bf967761..967048dd1 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h @@ -45,9 +45,11 @@ extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ); extern void radeonAgeTextures( radeonContextPtr rmesa, int heap ); extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); +extern void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ); extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ); +extern void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t ); extern void radeonDDInitTextureFuncs( GLcontext *ctx ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c new file mode 100644 index 000000000..13f6d4b59 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c @@ -0,0 +1,508 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "simple_list.h" +#include "enums.h" +#include "mem.h" + + +/* Destroy hardware state associated with texture `t'. + */ +void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureSwaps++; +#endif + if ( !t ) return; + + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + if ( t->tObj ) + t->tObj->DriverData = NULL; + + if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; + if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; + + remove_from_list( t ); + FREE( t ); +} + +/* Keep track of swapped out texture objects. + */ +void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureSwaps++; +#endif + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + t->dirty_images = ~0; + move_to_tail( &rmesa->SwappedOut, t ); +} + +/* Print out debugging information about texture LRU. + */ +void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ) +{ + radeonTexObjPtr t; + int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]); + + fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); + + foreach ( t, &rmesa->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 radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int i, j; + + fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); + + for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + j, list[j].age, list[j].next, list[j].prev ); + j = list[j].next; + if ( j == RADEON_NR_TEX_REGIONS ) break; + } + + if ( j != RADEON_NR_TEX_REGIONS ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + i, list[i].age, list[i].next, list[i].prev ); + } + } + + fprintf( stderr, "\n" ); +} + +/* Reset the global texture LRU. + */ +static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; + int i; + + /* + * (Re)initialize the global circular LRU list. The last element in + * the array (RADEON_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. + */ + for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = RADEON_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = RADEON_NR_TEX_REGIONS; + list[RADEON_NR_TEX_REGIONS].prev = i; + list[RADEON_NR_TEX_REGIONS].next = 0; + rmesa->sarea->texAge[heap] = 0; +} + +/* Update the local and glock texture LRUs. + */ +void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t ) +{ + int heap = t->heap; + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = rmesa->radeonScreen->logTexGranularity[heap]; + int start = t->memBlock->ofs >> sz; + int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; + int i; + + rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; + + if ( !t->memBlock ) { + fprintf( stderr, "no memblock\n\n" ); + return; + } + + /* Update our local LRU */ + move_to_head( &rmesa->TexObjList[heap], t ); + + /* Update the global LRU */ + for ( i = start ; i <= end ; i++ ) { + list[i].in_use = 1; + list[i].age = rmesa->lastTexAge[heap]; + + /* remove_from_list(i) */ + list[(CARD32)list[i].next].prev = list[i].prev; + list[(CARD32)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) */ + list[i].prev = RADEON_NR_TEX_REGIONS; + list[i].next = list[RADEON_NR_TEX_REGIONS].next; + list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; + list[RADEON_NR_TEX_REGIONS].next = i; + } + + if ( 0 ) { + radeonPrintGlobalLRU( rmesa, t->heap ); + radeonPrintLocalLRU( rmesa, 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). + */ +static void radeonTexturesGone( radeonContextPtr rmesa, int heap, + int offset, int size, int in_use ) +{ + radeonTexObjPtr t, tmp; + + foreach_s ( t, tmp, &rmesa->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 ) { + radeonSwapOutTexObj( rmesa, t ); + } else { + radeonDestroyTexObj( rmesa, t ); + } + } + + if ( in_use ) { + t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); + if ( !t ) return; + + t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); + if ( !t->memBlock ) { + fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", + (int)size, (int)offset ); + mmDumpMemInfo( rmesa->texHeap[heap] ); + return; + } + insert_at_head( &rmesa->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 radeonAgeTextures( radeonContextPtr rmesa, int heap ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + + if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { + int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; + int nr = 0; + int idx; + + for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; + idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++ ) + { + /* 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 > rmesa->radeonScreen->texSize[heap] ) { + nr = RADEON_NR_TEX_REGIONS; + break; + } + + if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { + radeonTexturesGone( rmesa, heap, idx * sz, sz, + sarea->texList[heap][idx].in_use ); + } + } + + if ( nr == RADEON_NR_TEX_REGIONS ) { + radeonTexturesGone( rmesa, heap, 0, + rmesa->radeonScreen->texSize[heap], 0 ); + radeonResetGlobalLRU( rmesa, heap ); + } + + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES); + rmesa->lastTexAge[heap] = sarea->texAge[heap]; + } +} + + +/* ================================================================ + * Texture image uploads + */ + +/* Upload the texture image associated with texture `t' at level `level' + * at the address relative to `start'. + */ +static void radeonUploadSubImage( radeonContextPtr rmesa, + radeonTexObjPtr t, GLint level, + GLint x, GLint y, GLint width, GLint height ) +{ + struct gl_texture_image *texImage; + const struct gl_texture_format *texFormat; + GLint texelsPerDword = 0; + GLint imageX, imageY, imageWidth, imageHeight; + GLint blitX, blitY, blitWidth, blitHeight; + GLint imageRows, blitRows; + GLint remaining; + GLint format, dwords; + CARD32 pitch, offset; + drmBufPtr buffer; + CARD32 *dst; + GLint ret; + + /* Ensure we have a valid texture to upload */ + texImage = t->tObj->Image[level]; + if ( !texImage ) + return; + + texFormat = texImage->TexFormat; + + switch ( texFormat->TexelBytes ) { + case 1: + texelsPerDword = 4; + break; + case 2: + texelsPerDword = 2; + break; + case 4: + texelsPerDword = 1; + break; + } + + format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK; + + imageX = 0; + imageY = 0; + imageWidth = texImage->Width; + imageHeight = texImage->Height; + + blitX = t->image[level].x; + blitY = t->image[level].y; + blitWidth = t->image[level].width; + blitHeight = t->image[level].height; + + /* dwords = t->image[level].dwords; */ + offset = t->bufAddr; + pitch = (t->image[0].width * texFormat->TexelBytes) / 64; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, " upload image: %d,%d at %d,%d\n", + imageWidth, imageHeight, imageX, imageY ); + fprintf( stderr, " upload blit: %d,%d at %d,%d\n", + blitWidth, blitHeight, blitX, blitY ); + fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x " + "level: %d format: %x\n", + (GLuint)offset, (GLuint)pitch, level, format ); + } + + ret = drmRadeonLoadTexture( rmesa->driFd, offset, pitch, format, + imageWidth, imageHeight, &t->image[level] ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); + exit( 1 ); + } + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; +} + +/* Upload the texture images associated with texture `t'. This might + * require removing our own and/or other client's texture objects to + * make room for these images. + */ +int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ + int i; + int heap; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %p )\n", + __FUNCTION__, rmesa->glCtx, t->tObj ); + } + + if ( !t ) + return 0; + + /* Choose the heap appropriately */ + heap = t->heap = RADEON_CARD_HEAP; +#if 0 + if ( !rmesa->radeonScreen->IsPCI && + t->totalSize > rmesa->radeonScreen->texSize[heap] ) { + heap = t->heap = RADEON_AGP_HEAP; + } +#endif + + /* Do we need to eject LRU texture objects? */ + if ( !t->memBlock ) { + /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ + t->memBlock = mmAllocMem( rmesa->texHeap[heap], + t->totalSize, 12, 0 ); + +#if 0 + /* Try AGP before kicking anything out of local mem */ + if ( !t->memBlock && heap == RADEON_CARD_HEAP ) { + t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP], + t->totalSize, 12, 0 ); + + if ( t->memBlock ) + heap = t->heap = RADEON_AGP_HEAP; + } +#endif + + /* Kick out textures until the requested texture fits */ + while ( !t->memBlock ) { + if ( rmesa->TexObjList[heap].prev->bound ) { + fprintf( stderr, + "radeonUploadTexImages: ran into bound texture\n" ); + return -1; + } + if ( rmesa->TexObjList[heap].prev == + &rmesa->TexObjList[heap] ) { + if ( rmesa->radeonScreen->IsPCI ) { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on local texture heaps, sz=%d\n", + t->totalSize ); + return -1; +#if 0 + } else if ( heap == RADEON_CARD_HEAP ) { + heap = t->heap = RADEON_AGP_HEAP; + continue; +#endif + } else { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize ); + return -1; + } + } + + radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev ); + + t->memBlock = mmAllocMem( rmesa->texHeap[heap], + t->totalSize, 12, 0 ); + } + + /* Set the base offset of the texture image */ + t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs; + + t->pp_txoffset = t->bufAddr; +#if 0 + /* Fix AGP texture offsets */ + if ( heap == RADEON_AGP_HEAP ) { + t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET + + rmesa->radeonScreen->agpTexOffset; + } +#endif + + /* Force loading the new state into the hardware */ + switch ( t->bound ) { + case 1: + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0; + break; + + case 2: + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1; + break; + + default: + return -1; + } + } + + /* Let the world know we've used this memory recently */ + radeonUpdateTexLRU( rmesa, t ); + + /* Upload any images that are new */ + if ( t->dirty_images ) { + int levels = ((t->pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >> + RADEON_MAX_MIP_LEVEL_SHIFT); + + for ( i = 0 ; i <= levels ; i++ ) { + if ( t->dirty_images & (1 << i) ) { + radeonUploadSubImage( rmesa, t, i, 0, 0, + t->image[i].width, t->image[i].height ); + } + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + + t->dirty_images = 0; + return 0; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h index b63d5c6a7..7cec84e9a 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h @@ -40,17 +40,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_sarea.h" #include "mm.h" -/* Handle the Radeon's tightly packed mipmaps and strict offset, - * pitch rules for blits by assigning each mipmap a set of - * coordinates that can be used for a hostdata blit. - */ -typedef struct { - GLuint x; /* Blit coordinates */ - GLuint y; - GLuint width; /* Blit dimensions */ - GLuint height; - GLuint dwords; /* Size of image level */ -} radeonTexImage; +#define TEX_0 1 +#define TEX_1 2 typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; @@ -72,16 +63,15 @@ struct radeon_tex_obj { GLint bound; /* Texture unit currently bound to */ GLint heap; /* Texture heap currently stored in */ - radeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; /* Image data for all - mipmap levels */ + drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; GLint totalSize; /* Total size of the texture including all mipmap levels */ - GLint texelBytes; /* Number of bytes per texel */ - - GLboolean hasAlpha; - radeon_texture_regs_t setup; /* Setup regs for texture */ + GLuint pp_txfilter; /* Hardware register values */ + GLuint pp_txformat; + GLuint pp_txoffset; + GLuint pp_border_color; }; #endif /* __RADEON_TEXOBJ_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c new file mode 100644 index 000000000..2a076717e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c @@ -0,0 +1,1103 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "simple_list.h" +#include "enums.h" +#include "mem.h" + +static void radeonSetTexImages( radeonContextPtr rmesa, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + struct gl_texture_image *texImage = tObj->Image[0]; + const struct gl_texture_format *texFormat = texImage->TexFormat; + GLint log2Width, log2Height, log2Size; + GLint totalSize; + GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; + GLint x, y, width, height; + GLint i; + + /* Calculate dimensions in log domain. + */ + for ( i = 1, log2Height = 0 ; i < texImage->Height ; i *= 2 ) { + log2Height++; + } + for ( i = 1, log2Width = 0 ; i < texImage->Width ; i *= 2 ) { + log2Width++; + } + log2Size = MAX2( log2Width, log2Height ); + + /* The Radeon has a 64-byte minimum pitch for all blits. We + * calculate the equivalent number of texels to simplify the + * calculation of the texture image area. + */ + switch ( texFormat->TexelBytes ) { + case 4: + texelsPerDword = 1; + blitPitch = 16; + break; + case 2: + texelsPerDword = 2; + blitPitch = 32; + break; + case 1: + texelsPerDword = 4; + blitPitch = 64; + break; + } + + /* Select the larger of the two widths for our global texture image + * coordinate space. As the Radeon has very strict offset rules, we + * can't upload mipmaps directly and have to reference their location + * from the aligned start of the whole image. + */ + blitWidth = MAX2( texImage->Width, blitPitch ); + + /* Calculate mipmap offsets and dimensions. + */ + totalSize = 0; + x = 0; + y = 0; + + for ( i = 0 ; i <= log2Size ; i++ ) { + GLuint size; + + texImage = tObj->Image[i]; + if ( !texImage ) + break; + + width = texImage->Width; + height = texImage->Height; + + /* Texture images have a minimum pitch of 32 bytes (half of the + * 64-byte minimum pitch for blits). For images that have a + * width smaller than this, we must pad each texture image + * scanline out to this amount. + */ + if ( width < blitPitch / 2 ) { + width = blitPitch / 2; + } + + size = width * height * texFormat->TexelBytes; + totalSize += size; + ASSERT( (totalSize & 31) == 0 ); + + while ( width < blitWidth && height > 1 ) { + width *= 2; + height /= 2; + } + + t->image[i].x = x; + t->image[i].y = y; + + t->image[i].width = width; + t->image[i].height = height; + + /* While blits must have a pitch of at least 64 bytes, mipmaps + * must be aligned on a 32-byte boundary (just like each texture + * image scanline). + */ + if ( width >= blitWidth ) { + y += height; + } else { + x += width; + if ( x >= blitWidth ) { + x = 0; + y++; + } + } + + if ( 0 ) { + fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d)\n", + i, blitWidth, texImage->Width, texImage->Height, + t->image[i].width, t->image[i].height, + t->image[i].x, t->image[i].y ); + } + } + + /* Align the total size of texture memory block. + */ + t->totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + /* Hardware state: + */ + t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; + t->pp_txfilter |= i << RADEON_MAX_MIP_LEVEL_SHIFT; + + t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | + RADEON_TXFORMAT_HEIGHT_MASK); + t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | + (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); +} + + +/* ================================================================ + * Texture combine functions + */ + +#define RADEON_DISABLE 0 +#define RADEON_REPLACE 1 +#define RADEON_MODULATE 2 +#define RADEON_DECAL 3 +#define RADEON_BLEND 4 +#define RADEON_ADD 5 +#define RADEON_MAX_COMBFUNC 6 + +static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00802800 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800142 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T0_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c2d42 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T0_COLOR | + RADEON_COLOR_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c2902 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00812802 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00803000 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800182 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T1_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c3582 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T1_COLOR | + RADEON_COLOR_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c3102 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00813002 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00803800 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x008001c2 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T2_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c3dc2 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T2_COLOR | + RADEON_COLOR_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c3902 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00813802 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + } +}; + +static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800500 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T0_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800600 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T1_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800700 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800071 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T2_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800071 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800021 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + } +}; + + +/* GL_EXT_texture_env_combine support + */ + +/* The color tables have combine functions for GL_SRC_COLOR, + * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] = +{ + { + RADEON_COLOR_ARG_A_T0_COLOR, + RADEON_COLOR_ARG_A_T1_COLOR, + RADEON_COLOR_ARG_A_T2_COLOR + }, + { + RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A + }, + { + RADEON_COLOR_ARG_A_T0_ALPHA, + RADEON_COLOR_ARG_A_T1_ALPHA, + RADEON_COLOR_ARG_A_T2_ALPHA + }, + { + RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A + }, +}; + +static GLuint radeon_tfactor_color[] = +{ + RADEON_COLOR_ARG_A_TFACTOR_COLOR, + RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_TFACTOR_ALPHA, + RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_primary_color[] = +{ + RADEON_COLOR_ARG_A_DIFFUSE_COLOR, + RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_DIFFUSE_ALPHA, + RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_previous_color[] = +{ + RADEON_COLOR_ARG_A_CURRENT_COLOR, + RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_CURRENT_ALPHA, + RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A +}; + +/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] = +{ + { + RADEON_ALPHA_ARG_A_T0_ALPHA, + RADEON_ALPHA_ARG_A_T1_ALPHA, + RADEON_ALPHA_ARG_A_T2_ALPHA + }, + { + RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, + RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, + RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A + }, +}; + +static GLuint radeon_tfactor_alpha[] = +{ + RADEON_ALPHA_ARG_A_TFACTOR_ALPHA, + RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_primary_alpha[] = +{ + RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA, + RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_previous_alpha[] = +{ + RADEON_ALPHA_ARG_A_CURRENT_ALPHA, + RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A +}; + + +/* Extract the arg from slot A, shift it into the correct argument slot + * and set the corresponding complement bit. + */ +#define RADEON_COLOR_ARG( n, arg ) \ +do { \ + color_combine |= \ + ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ + << RADEON_COLOR_ARG_##arg##_SHIFT); \ + color_combine |= \ + ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ +} while (0) + +#define RADEON_ALPHA_ARG( n, arg ) \ +do { \ + alpha_combine |= \ + ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ + << RADEON_ALPHA_ARG_##arg##_SHIFT); \ + alpha_combine |= \ + ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ +} while (0) + + +/* ================================================================ + * Texture unit state management + */ + +static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; + struct gl_texture_object *tObj; + struct gl_texture_unit *texUnit; + GLuint enabled; + GLuint color_combine, alpha_combine; + GLuint color_arg[3], alpha_arg[3]; + GLuint i, numColorArgs = 0, numAlphaArgs = 0; + GLuint op; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) + return; + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + texUnit = &ctx->Texture.Unit[source]; + tObj = texUnit->Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != texUnit->CurrentD[2] ) && + ( tObj != texUnit->CurrentD[1] ) ) + return; + + /* Set the texture environment state. Isn't this nice and clean? + * The Radeon will automagically set the texture alpha to 0xff when + * the texture format does not include an alpha component. This + * reduces the amount of special-casing we have to do, alpha-only + * textures being a notable exception. + */ + switch ( texUnit->EnvMode ) { + case GL_REPLACE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_REPLACE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_MODULATE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + color_combine = radeon_color_combine[unit][RADEON_DECAL]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_ADD]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_COMBINE_EXT: + /* Step 0: + * Calculate how many arguments we need to process. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + numColorArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + numColorArgs = 2; + break; + case GL_INTERPOLATE_EXT: + numColorArgs = 3; + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + numAlphaArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + numAlphaArgs = 2; + break; + case GL_INTERPOLATE_EXT: + numAlphaArgs = 3; + break; + default: + return; + } + + /* Step 1: + * Extract the color and alpha combine function arguments. + */ + for ( i = 0 ; i < numColorArgs ; i++ ) { + op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; + switch ( texUnit->CombineSourceRGB[i] ) { + case GL_TEXTURE: + color_arg[i] = radeon_texture_color[op][unit]; + break; + case GL_CONSTANT_EXT: + color_arg[i] = radeon_tfactor_color[op]; + break; + case GL_PRIMARY_COLOR_EXT: + color_arg[i] = radeon_primary_color[op]; + break; + case GL_PREVIOUS_EXT: + color_arg[i] = radeon_previous_color[op]; + break; + default: + return; + } + } + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; + switch ( texUnit->CombineSourceA[i] ) { + case GL_TEXTURE: + alpha_arg[i] = radeon_texture_alpha[op][unit]; + break; + case GL_CONSTANT_EXT: + alpha_arg[i] = radeon_tfactor_alpha[op]; + break; + case GL_PRIMARY_COLOR_EXT: + alpha_arg[i] = radeon_primary_alpha[op]; + break; + case GL_PREVIOUS_EXT: + alpha_arg[i] = radeon_previous_alpha[op]; + break; + default: + return; + } + } + + /* Step 2: + * Build up the color and alpha combine functions. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + color_combine = (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, C ); + break; + case GL_MODULATE: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + case GL_ADD: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_ADD_SIGNED_EXT: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_INTERPOLATE_EXT: + color_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, B ); + RADEON_COLOR_ARG( 1, A ); + RADEON_COLOR_ARG( 2, C ); + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_DOT3 | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, C ); + break; + case GL_MODULATE: + alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, B ); + break; + case GL_ADD: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_ADD_SIGNED_EXT: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_INTERPOLATE_EXT: + alpha_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, B ); + RADEON_ALPHA_ARG( 1, A ); + RADEON_ALPHA_ARG( 2, C ); + break; + default: + return; + } + + if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) { + alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; + } + + /* Step 3: + * Apply the scale factor. The EXT extension has a somewhat + * unnecessary restriction that the scale must be 4x. The ARB + * extension will likely drop this and we can just apply the + * scale factors regardless. + */ + if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT && + texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) { + color_combine |= (texUnit->CombineScaleShiftRGB << 21); + alpha_combine |= (texUnit->CombineScaleShiftA << 21); + } else { + color_combine |= RADEON_SCALE_4X; + alpha_combine |= RADEON_SCALE_4X; + } + + /* All done! + */ + break; + + default: + return; + } + + rmesa->color_combine[source] = color_combine; + rmesa->alpha_combine[source] = alpha_combine; +} + +static void radeonUpdateTextureObject( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; + struct gl_texture_object *tObj; + radeonTexObjPtr t; + GLuint enabled; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { + if ( enabled ) + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + tObj = ctx->Texture.Unit[source].Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && + ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) + return; + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + /* Force the texture unit state to be loaded into the hardware */ + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit); + + /* Force any texture images to be loaded into the hardware */ + if ( t->dirty_images ) { + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, " t->dirty_images = 0x%x\n", t->dirty_images ); + } + radeonSetTexImages( rmesa, tObj ); + rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit); + } + + if ( t->memBlock ) + radeonUpdateTexLRU( rmesa, t ); + + switch ( unit ) { + case 0: + rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE | + RADEON_TEX_BLEND_0_ENABLE); + break; + case 1: + rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE | + RADEON_TEX_BLEND_1_ENABLE); + break; + } +} + +void radeonUpdateTextureState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) en=0x%x\n", + __FUNCTION__, ctx, ctx->Texture.ReallyEnabled ); + } + + /* Clear any texturing fallbacks */ + rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE; + + /* Disable all texturing until it is known to be good */ + rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK | + RADEON_TEX_BLEND_ENABLE_MASK); + + radeonUpdateTextureObject( ctx, 0 ); + radeonUpdateTextureEnv( ctx, 0 ); + + if ( rmesa->multitex ) { + radeonUpdateTextureObject( ctx, 1 ); + radeonUpdateTextureEnv( ctx, 1 ); + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c index 71ed6910b..e4b6394ee 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c @@ -55,6 +55,13 @@ do { \ *(GLuint *)(to) = *(GLuint *)(from); \ } while (0) +#define RADEON_COLOR3( to, from ) \ +do { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ +} while (0) + static void radeon_null_quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv ) @@ -162,6 +169,10 @@ void radeonDDChooseRenderState( GLcontext *ctx ) if ( rmesa->Fallback ) { rmesa->RenderIndex = RADEON_FALLBACK_BIT; + /* fixes vorder.c failure: */ + if (flags & DD_TRI_LIGHT_TWOSIDE) { + rmesa->IndirectTriangles = DD_TRI_LIGHT_TWOSIDE; + } return; } @@ -200,6 +211,11 @@ void radeonDDChooseRenderState( GLcontext *ctx ) rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE); } + + /* fixes vorder.c failure: */ + if (flags & DD_TRI_LIGHT_TWOSIDE) { + rmesa->IndirectTriangles |= DD_TRI_LIGHT_TWOSIDE; + } } if ( 0 ) { diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h index ed5006ea2..a53512a30 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h @@ -247,7 +247,8 @@ static void TAG(line)( GLcontext *ctx, GLfloat z[2]; #endif #if (IND & RADEON_TWOSIDE_BIT) - int c[2]; + GLuint c[2]; + GLuint s[2]; #endif v[0] = &verts[e0]; @@ -256,17 +257,24 @@ static void TAG(line)( GLcontext *ctx, #if (IND & RADEON_TWOSIDE_BIT) c[0] = v[0]->ui[4]; c[1] = v[1]->ui[4]; + s[0] = v[0]->ui[5]; + s[1] = v[1]->ui[5]; #endif #if (IND & RADEON_TWOSIDE_BIT) { GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + GLubyte (*vbspec)[4] = ctx->VB->Specular; if ( IND & RADEON_FLAT_BIT ) { RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[1]->ui[4] = v[0]->ui[4]; + RADEON_COLOR3( (char *)&v[0]->ui[5], vbspec[pv] ); + v[1]->ui[5] = v[0]->ui[5]; } else { RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR3( (char *)&v[0]->ui[5], vbspec[e0] ); + RADEON_COLOR3( (char *)&v[1]->ui[5], vbspec[e1] ); } } #endif @@ -289,6 +297,8 @@ static void TAG(line)( GLcontext *ctx, #if (IND & RADEON_TWOSIDE_BIT) v[0]->ui[4] = c[0]; v[1]->ui[4] = c[1]; + v[0]->ui[5] = s[0]; + v[1]->ui[5] = s[1]; #endif } @@ -309,7 +319,10 @@ static void TAG(points)( GLcontext *ctx, if ( IND & RADEON_TWOSIDE_BIT ) { GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + GLubyte (*vbspec)[4] = VB->Specular; RADEON_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); + if (vbspec) + RADEON_COLOR3( (char *)&tmp0.v.specular, vbspec[i] ); } if ( IND & RADEON_OFFSET_BIT ) { GLfloat offset = ctx->PointZoffset * rmesa->depth_scale; diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index ebb353844..9f45df60d 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -150,6 +150,7 @@ MESA_INCLUDES = -I. -I.. -I../../include ../../stages.c \ ../../state.c \ ../../stencil.c \ + ../../texformat.c \ ../../teximage.c \ ../../texobj.c \ ../../texstate.c \ @@ -223,6 +224,7 @@ MESA_INCLUDES = -I. -I.. -I../../include ../../stages.o \ ../../state.o \ ../../stencil.o \ + ../../texformat.o \ ../../teximage.o \ ../../texobj.o \ ../../texstate.o \ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c index 4cb7efaba..293c42fd7 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c @@ -43,9 +43,22 @@ #include "tdfx_render.h" #include "tdfx_pipeline.h" #include "tdfx_span.h" +#include "tdfx_tex.h" #include "tdfx_texman.h" #include "extensions.h" +#ifndef TDFX_DEBUG +int TDFX_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_API */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_VERBOSE_LRU */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VERBOSE_IOCTL */ +/* | DEBUG_VERBOSE_2D */ +/* | DEBUG_VERBOSE_TEXTURE */ + ); +#endif #if 0 @@ -75,15 +88,13 @@ static void tdfxDDInitExtensions( GLcontext *ctx ) gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); gl_extensions_enable( ctx, "GL_HP_occlusion_test" ); - if ( !fxMesa->haveTwoTMUs ) { + if ( fxMesa->numTMUs == 1 ) { gl_extensions_disable( ctx, "GL_EXT_texture_env_add" ); gl_extensions_disable( ctx, "GL_ARB_multitexture" ); } if ( TDFX_IS_NAPALM( fxMesa ) ) { - gl_extensions_enable( ctx, "GL_ARB_texture_compression" ); gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" ); - gl_extensions_enable( ctx, "GL_3DFX_texture_compression_FXT1" ); } if (fxMesa->haveHwStencil) { @@ -178,16 +189,10 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, fxMesa->Glide.Initialized = GL_FALSE; fxMesa->Glide.Board = 0; - - if (getenv("FX_EMULATE_SINGLE_TMU")) { - fxMesa->haveTwoTMUs = GL_FALSE; - } - else { - if ( TDFX_IS_BANSHEE( fxMesa ) ) { - fxMesa->haveTwoTMUs = GL_FALSE; - } else { - fxMesa->haveTwoTMUs = GL_TRUE; - } + if ( getenv( "FX_EMULATE_SINGLE_TMU" ) || TDFX_IS_BANSHEE( fxMesa ) ) { + fxMesa->numTMUs = 1; + } else { + fxMesa->numTMUs = 2; } fxMesa->stats.swapBuffer = 0; @@ -218,6 +223,7 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, tdfxDDInitStateFuncs( ctx ); tdfxDDInitRenderFuncs( ctx ); tdfxDDInitSpanFuncs( ctx ); + tdfxDDInitTextureFuncs( ctx ); ctx->Driver.TriangleCaps = (DD_TRI_CULL | DD_TRI_LIGHT_TWOSIDE | @@ -448,19 +454,21 @@ void tdfxDestroyContext( tdfxContextPtr fxMesa ) } if ( fxMesa ) { - if (fxMesa->glCtx->Shared->RefCount == 1) { + GLcontext *ctx = fxMesa->glCtx; + struct gl_texture_object *tObj; + + if ( ctx->Shared->RefCount == 1 ) { /* This share group is about to go away, free our private * texture object data. */ - struct gl_texture_object *tObj; - tObj = fxMesa->glCtx->Shared->TexObjectList; - while (tObj) { - tdfxTMFreeTexture(fxMesa, tObj); - tObj = tObj->Next; + LOCK_HARDWARE( fxMesa ); + for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) { + tdfxTMFreeTextureLocked( fxMesa, tObj ); } + UNLOCK_HARDWARE( fxMesa ); } - tdfxTMClose(fxMesa); /* free texture memory */ + tdfxTMClose( fxMesa ); /* free texture memory */ XFree( fxMesa ); } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h index d630184bd..a73347435 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h @@ -280,9 +280,7 @@ typedef struct { volatile int fifoOwner; volatile int ctxOwner; volatile int texOwner; -} -TDFXSAREAPriv; - +} TDFXSAREAPriv; typedef struct { GLuint swapBuffer; @@ -292,73 +290,72 @@ typedef struct { GLuint texSwaps; } tdfxStats; - - /* * Memory range from startAddr to endAddr-1 */ typedef struct mem_range { struct mem_range *next; FxU32 startAddr, endAddr; -} -tdfxMemRange; +} tdfxMemRange; +typedef struct { + GLvoid *data; + GLsizei width, height; + FxU32 size; +} tdfxTexRawData; typedef struct { - GLsizei width, height; /* image size */ - GLint texelSize; /* How many bytes to a texel */ - GrTextureFormat_t glideFormat; /* Glide image format */ - void *data; /* Glide-formated texture image */ - FxU32 dataSize; /* image size in bytes */ -} -tdfxMipMapLevel; + tdfxTexRawData original; /* Mesa-formatted texture image */ + tdfxTexRawData rescaled; /* Only needed if aspect ratio > 8:1 */ + + GLvoid *data; /* Final version of texture image */ + FxU32 size; /* image size in bytes */ + + GrTextureFormat_t glideFormat; /* Glide image format */ + GLint wScale, hScale; /* Broken hardware... */ +} tdfxTexImage, *tdfxTexImagePtr; #define TDFX_NUM_TMU 2 -typedef struct tdfxTexInfo_t -{ +typedef struct { GLboolean isInTM; GLboolean reloadImages; /* if true, resend images to Glide */ GLuint lastTimeUsed; FxU32 whichTMU; GrTexInfo info; - GrAspectRatio_t aspectRatio; - tdfxMipMapLevel mipmapLevel[MAX_TEXTURE_LEVELS]; - tdfxMemRange *tm[TDFX_NUM_TMU]; + tdfxTexImage image[MAX_TEXTURE_LEVELS]; + tdfxMemRange *range[TDFX_NUM_TMU]; GLint minLevel, maxLevel; + GrMipMapMode_t mmMode; + GrAspectRatio_t aspectRatio; + FxBool LODblend; GrTextureFilterMode_t minFilt; GrTextureFilterMode_t magFilt; GrTextureClampMode_t sClamp; GrTextureClampMode_t tClamp; - FxBool LODblend; - GrMipMapMode_t mmMode; - GLfloat sScale, tScale; /* texcoord scale factor */ + GLfloat sScale, tScale; /* texcoord scale factor */ GuTexPalette palette; -} -tdfxTexInfo; +} tdfxTexObj, *tdfxTexObjPtr; +#define TDFX_TEXTURE_DATA(tObj) ((tdfxTexObjPtr)((tObj)->DriverData)) -#define TDFX_TEXTURE_DATA(mesaObj) ((tdfxTexInfo *)((mesaObj)->DriverData)) - - -/* - * This is state which may be shared by several tdfx contexts. +/* This is state which may be shared by several tdfx contexts. * It hangs off of Mesa's gl_shared_state object (ctx->Shared->DriverData). */ -struct tdfxSharedState { +typedef struct tdfx_shared_state { GLboolean umaTexMemory; - GLuint totalTexMem[TDFX_NUM_TMU]; /* constant */ - GLuint freeTexMem[TDFX_NUM_TMU]; /* changes as we go */ - tdfxMemRange *tmPool; - tdfxMemRange *tmFree[TDFX_NUM_TMU]; -}; + GLuint totalTexMem[TDFX_NUM_TMU]; /* constant */ + GLuint freeTexMem[TDFX_NUM_TMU]; /* changes as we go */ + tdfxMemRange *rangePool; + tdfxMemRange *freeRanges[TDFX_NUM_TMU]; +} tdfxSharedState, *tdfxSharedStatePtr; @@ -516,6 +513,11 @@ struct tdfx_depth { FxBool Mask; /* Write enable flag */ }; +#ifndef GR_STIPPLE_PATTERN +#error "You MUST upgrade your Glide3 libraries and headers." +#error "Get the latest from http://dri.sourceforge.net/resources.html" +#endif + struct tdfx_stipple { GrStippleMode_t Mode; /* Stipple enable/disable */ FxU32 Pattern; /* 8x4 Stipple Pattern */ @@ -630,6 +632,7 @@ struct tdfx_context { GLuint tmu_source[TDFX_NUM_TMU]; GLuint tex_dest[MAX_TEXTURE_UNITS]; + GLuint numTMUs; GLuint SetupIndex; GLuint SetupDone; @@ -641,10 +644,6 @@ struct tdfx_context { GLfloat sScale0, tScale0; GLfloat sScale1, tScale1; -#if 0 - GLuint last_tri_caps; - GLuint stw_hint_state; /* for grHints */ -#endif GLuint using_fast_path, passes, multipass; GLuint texBindNumber; GLint tmuSrc; @@ -652,13 +651,6 @@ struct tdfx_context { int screen_width; int screen_height; -#if 0 - void *state; /* Glide state buffer */ - - GLint textureAlign; - GLboolean verbose; -#endif - GLboolean haveTwoTMUs; /* True if we have 2 tmu's */ GLboolean haveHwStencil; GLint maxPendingSwapBuffers; @@ -768,6 +760,7 @@ extern int TDFX_DEBUG; #define DEBUG_VERBOSE_DRI 0x10 #define DEBUG_VERBOSE_IOCTL 0x20 #define DEBUG_VERBOSE_2D 0x40 +#define DEBUG_VERBOSE_TEXTURE 0x80 #endif /* GLX_DIRECT_RENDERING */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c index ec5b25871..3f76fb88d 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c @@ -43,9 +43,11 @@ #include "enums.h" #include "pb.h" +#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM) +#include "X86/common_x86_asm.h" +#endif - -#define TDFX_DATE "20010104" +#define TDFX_DATE "20010305" /* These are used in calls to FX_grColorMaskv() */ @@ -63,10 +65,12 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name ) tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; switch ( name ) { - case GL_RENDERER: - { - static char buffer[100]; - char hardware[100]; + case GL_VENDOR: + return "VA Linux Systems, Inc."; + + case GL_RENDERER: { + static char buffer[128]; + char hardware[128]; strcpy( hardware, FX_grGetString( fxMesa, GR_HARDWARE ) ); @@ -83,19 +87,41 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name ) strcpy( hardware, "Voodoo5" ); } else { - /* unexpected result: replace spaces with hyphens */ + /* Unexpected result: replace spaces with hyphens */ int i; for ( i = 0 ; hardware[i] ; i++ ) { if ( hardware[i] == ' ' || hardware[i] == '\t' ) hardware[i] = '-'; } } - /* now make the GL_RENDERER string */ + /* Now make the GL_RENDERER string */ sprintf( buffer, "Mesa DRI %s " TDFX_DATE, hardware ); + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( gl_x86_cpu_features ) { + strncat( buffer, " x86", 4 ); + } +#endif +#ifdef USE_MMX_ASM + if ( cpu_has_mmx ) { + strncat( buffer, "/MMX", 4 ); + } +#endif +#ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + strncat( buffer, "/3DNow!", 7 ); + } +#endif +#ifdef USE_KATMAI_ASM + if ( cpu_has_xmm ) { + strncat( buffer, "/SSE", 4 ); + } +#endif return buffer; } - case GL_VENDOR: - return "VA Linux Systems, Inc."; + default: return NULL; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c index 97931a351..da60bee16 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c @@ -594,16 +594,13 @@ static void uploadTextureImages( tdfxContextPtr fxMesa ) { GLcontext *ctx = fxMesa->glCtx; int unit; - for (unit = 0; unit < TDFX_NUM_TMU; unit++) { - if (ctx->Texture.Unit[unit].ReallyEnabled == TEXTURE0_2D) { + for ( unit = 0 ; unit < TDFX_NUM_TMU ; unit++ ) { + if ( ctx->Texture.Unit[unit].ReallyEnabled == TEXTURE0_2D ) { struct gl_texture_object *tObj = ctx->Texture.Unit[unit].CurrentD[2]; - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - if (ti && ti->reloadImages) { - /* - printf("download texture image on unit %d\n", unit); - */ - tdfxTMDownloadTexture(fxMesa, tObj); - ti->reloadImages = GL_FALSE; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + if ( t && t->reloadImages ) { + tdfxTMDownloadTextureLocked( fxMesa, tObj ); + t->reloadImages = GL_FALSE; } } } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c index eb9a6a98b..d630fbd8c 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c @@ -45,7 +45,6 @@ #include "tdfx_vb.h" #include "tdfx_tex.h" #include "tdfx_texman.h" -#include "tdfx_texstate.h" #include "tdfx_tris.h" #include "tdfx_render.h" @@ -1535,15 +1534,6 @@ void tdfxDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.Scissor = tdfxDDScissor; ctx->Driver.ShadeModel = tdfxDDShadeModel; - ctx->Driver.BindTexture = tdfxDDBindTexture; - ctx->Driver.DeleteTexture = tdfxDDDeleteTexture; - ctx->Driver.TexEnv = tdfxDDTexEnv; - ctx->Driver.TexParameter = tdfxDDTexParameter; - ctx->Driver.TexImage2D = tdfxDDTexImage2D; - ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D; - ctx->Driver.GetTexImage = tdfxDDGetTexImage; - ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette; - if ( fxMesa->haveHwStencil ) { ctx->Driver.StencilFunc = tdfxDDStencilFunc; ctx->Driver.StencilMask = tdfxDDStencilMask; diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c index c572e22a8..e0f2d2eb0 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c @@ -35,39 +35,37 @@ * */ -#include "image.h" -#include "texutil.h" #include "tdfx_context.h" #include "tdfx_tex.h" #include "tdfx_texman.h" +#include "enums.h" +#include "image.h" +#include "texutil.h" + +#define TX_DITHER_NONE 0x00000000 -static int -logbase2(int n) +static int logbase2( int n ) { - GLint i = 1; - GLint log2 = 0; - - if (n < 0) { - return -1; - } - - while (n > i) { - i *= 2; - log2++; - } - if (i != n) { - return -1; - } - else { - return log2; - } + GLint i = 1; + GLint log2 = 0; + + if ( n < 0 ) + return -1; + + while ( n > i ) { + i *= 2; + log2++; + } + if ( i != n ) { + return -1; + } else { + return log2; + } } - -/* - * Compute various texture image parameters. +/* Compute various texture image parameters. * Input: w, h - source texture width and height * Output: lodlevel - Glide lod level token for the larger texture dimension * aspectratio - Glide aspect ratio token @@ -84,1520 +82,977 @@ logbase2(int n) * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1) * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0) */ -static void -tdfxTexGetInfo(const GLcontext *ctx, int w, int h, - GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio, - float *sscale, float *tscale, - int *wscale, int *hscale) +static void tdfxTexGetInfo( const GLcontext *ctx, int w, int h, + GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio, + float *sscale, float *tscale, + int *wscale, int *hscale ) { - int logw, logh, ar, lod, ws, hs; - float s, t; - - ASSERT(w >= 1); - ASSERT(h >= 1); - - logw = logbase2(w); - logh = logbase2(h); - ar = logw - logh; /* aspect ratio = difference in log dimensions */ - - /* Hardware only allows a maximum aspect ratio of 8x1, so handle - |ar| > 3 by scaling the image and using an 8x1 aspect ratio */ - if (ar >= 0) { - ASSERT(width >= height); - lod = logw; - s = 256.0; - ws = 1; - if (ar <= GR_ASPECT_LOG2_8x1) { - t = 256 >> ar; - hs = 1; - } - else { - /* have to stretch image height */ - t = 32.0; - hs = 1 << (ar - 3); - } - } - else { - ASSERT(width < height); - lod = logh; - t = 256.0; - hs = 1; - if (ar >= GR_ASPECT_LOG2_1x8) { - s = 256 >> -ar; - ws = 1; - } - else { - /* have to stretch image width */ - s = 32.0; - ws = 1 << (-ar - 3); - } - } - - if (ar < GR_ASPECT_LOG2_1x8) - ar = GR_ASPECT_LOG2_1x8; - else if (ar > GR_ASPECT_LOG2_8x1) - ar = GR_ASPECT_LOG2_8x1; - - if (lodlevel) - *lodlevel = (GrLOD_t) lod; - if (aspectratio) - *aspectratio = (GrAspectRatio_t) ar; - if (sscale) - *sscale = s; - if (tscale) - *tscale = t; - if (wscale) - *wscale = ws; - if (hscale) - *hscale = hs; + int logw, logh, ar, lod, ws, hs; + float s, t; + + ASSERT( w >= 1 ); + ASSERT( h >= 1 ); + + logw = logbase2( w ); + logh = logbase2( h ); + ar = logw - logh; /* aspect ratio = difference in log dimensions */ + + /* Hardware only allows a maximum aspect ratio of 8x1, so handle + * |ar| > 3 by scaling the image and using an 8x1 aspect ratio. + */ + if ( ar >= 0 ) { + ASSERT( width >= height ); + lod = logw; + s = 256.0; + ws = 1; + if ( ar <= GR_ASPECT_LOG2_8x1 ) { + t = 256 >> ar; + hs = 1; + } else { + /* have to stretch image height */ + t = 32.0; + hs = 1 << (ar - 3); + } + } else { + ASSERT( width < height ); + lod = logh; + t = 256.0; + hs = 1; + if ( ar >= GR_ASPECT_LOG2_1x8 ) { + s = 256 >> -ar; + ws = 1; + } else { + /* have to stretch image width */ + s = 32.0; + ws = 1 << (-ar - 3); + } + } + + if ( ar < GR_ASPECT_LOG2_1x8 ) { + ar = GR_ASPECT_LOG2_1x8; + } else if ( ar > GR_ASPECT_LOG2_8x1 ) { + ar = GR_ASPECT_LOG2_8x1; + } + + if ( lodlevel ) + *lodlevel = (GrLOD_t)lod; + if ( aspectratio ) + *aspectratio = (GrAspectRatio_t)ar; + if ( sscale ) + *sscale = s; + if ( tscale ) + *tscale = t; + if ( wscale ) + *wscale = ws; + if ( hscale ) + *hscale = hs; } -/* - * We need to call this when a texture object's minification filter +/* We need to call this when a texture object's minification filter * or texture image sizes change. */ -static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj) +static void tdfxRevalidateTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) { - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - GLint minl, maxl; - - if (!ti) - return; - - minl = maxl = tObj->BaseLevel; - - if (tObj->Image[minl]) { - maxl = MIN2(tObj->MaxLevel, tObj->Image[minl]->MaxLog2); - - /* compute largeLodLog2, aspect ratio and texcoord scale factors */ - tdfxTexGetInfo(ctx, tObj->Image[minl]->Width, tObj->Image[minl]->Height, - &ti->info.largeLodLog2, - &ti->info.aspectRatioLog2, - &(ti->sScale), &(ti->tScale), NULL, NULL); - } - - if (tObj->Image[maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) { - /* mipmapping: need to compute smallLodLog2 */ - tdfxTexGetInfo(ctx, tObj->Image[maxl]->Width, - tObj->Image[maxl]->Height, - &ti->info.smallLodLog2, NULL, - NULL, NULL, NULL, NULL); - } - else { - /* not mipmapping: smallLodLog2 = largeLodLog2 */ - ti->info.smallLodLog2 = ti->info.largeLodLog2; - } - - ti->minLevel = minl; - ti->maxLevel = maxl; - ti->info.data = NULL; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + GLint minl, maxl; + + if ( !t ) + return; + + minl = maxl = tObj->BaseLevel; + + if ( tObj->Image[minl] ) { + maxl = MIN2( tObj->MaxLevel, tObj->Image[minl]->MaxLog2 ); + + /* Compute largeLodLog2, aspect ratio and texcoord scale factors. + */ + tdfxTexGetInfo( ctx, + tObj->Image[minl]->Width, tObj->Image[minl]->Height, + &t->info.largeLodLog2, &t->info.aspectRatioLog2, + &t->sScale, &t->tScale, NULL, NULL ); + } + + if ( tObj->Image[maxl] && + tObj->MinFilter != GL_NEAREST && + tObj->MinFilter != GL_LINEAR ) { + /* Mipmapping: need to compute smallLodLog2 */ + tdfxTexGetInfo( ctx, + tObj->Image[maxl]->Width, tObj->Image[maxl]->Height, + &t->info.smallLodLog2, + NULL, NULL, NULL, NULL, NULL ); + } else { + /* Not mipmapping: smallLodLog2 = largeLodLog2 */ + t->info.smallLodLog2 = t->info.largeLodLog2; + } + + t->minLevel = minl; + t->maxLevel = maxl; + t->info.data = NULL; } -static tdfxTexInfo * -fxAllocTexObjData(tdfxContextPtr fxMesa) +static tdfxTexObjPtr tdfxAllocTexObj( tdfxContextPtr fxMesa ) { - tdfxTexInfo *ti; - int i; + tdfxTexObjPtr t; + int i; - if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) { - gl_problem(NULL, "tdfx driver: out of memory"); - return NULL; - } + t = CALLOC( sizeof(tdfxTexObj) ); + if ( !t ) { + gl_problem( NULL, "tdfx driver: out of memory" ); + return NULL; + } - ti->isInTM = GL_FALSE; + t->isInTM = GL_FALSE; - ti->whichTMU = TDFX_TMU_NONE; + t->whichTMU = TDFX_TMU_NONE; - ti->tm[TDFX_TMU0] = NULL; - ti->tm[TDFX_TMU1] = NULL; + t->range[TDFX_TMU0] = NULL; + t->range[TDFX_TMU1] = NULL; - ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - ti->magFilt = GR_TEXTUREFILTER_BILINEAR; + t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + t->magFilt = GR_TEXTUREFILTER_BILINEAR; - ti->sClamp = GR_TEXTURECLAMP_WRAP; - ti->tClamp = GR_TEXTURECLAMP_WRAP; + t->sClamp = GR_TEXTURECLAMP_WRAP; + t->tClamp = GR_TEXTURECLAMP_WRAP; - ti->mmMode = GR_MIPMAP_NEAREST; - ti->LODblend = FXFALSE; + t->mmMode = GR_MIPMAP_NEAREST; + t->LODblend = FXFALSE; - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { - ti->mipmapLevel[i].data = NULL; - } + for ( i = 0 ; i < MAX_TEXTURE_LEVELS ; i++ ) { + t->image[i].original.data = NULL; + t->image[i].rescaled.data = NULL; + } - return ti; + return t; } -/* - * Called via glBindTexture. +/* Given an OpenGL internal texture format, return the corresponding + * Glide internal texture format and MesaIntTexFormat. + * If allow32bpp is true, we'll return 32-bit texel formats when + * appropriate. */ - -void -tdfxDDBindTexture(GLcontext * ctx, GLenum target, - struct gl_texture_object *tObj) +static GrTextureFormat_t +tdfxTexGetFormat( tdfxContextPtr fxMesa, struct gl_texture_image *texImage, + GLenum format, GLenum type ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexInfo *ti; + const GLboolean allow32bpp = TDFX_IS_NAPALM(fxMesa); + const GLboolean is32bpp = ( fxMesa->fxScreen->cpp == 4 ); + const struct gl_texture_format *texFormat; + GrTextureFormat_t ret; + + if ( 0 ) + fprintf( stderr, "internal=%s format=%s type=%s\n", + texImage->IntFormat == 3 ? "GL_RGB (3)" : + texImage->IntFormat == 4 ? "GL_RGBA (4)" : + gl_lookup_enum_by_nr( texImage->IntFormat ), + gl_lookup_enum_by_nr( format ), + gl_lookup_enum_by_nr( type ) ); + +#define SET_FORMAT( gr, gl ) \ + do { \ + ret = (gr); \ + texFormat = &(gl); \ + } while (0) + +#define SET_FORMAT_32BPP( gr32, gl32, gr16, gl16 ) \ + do { \ + if ( allow32bpp ) { \ + ret = (gr32); \ + texFormat = &(gl32); \ + } else { \ + ret = (gr16); \ + texFormat = &(gl16); \ + } \ + } while (0) + + switch ( texImage->IntFormat ) { + /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has + * got to be better than sticking them way down the end of this + * huge list. + */ + case GL_RGBA: + case 4: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && allow32bpp ) { + SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888 ); + break; + } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); + break; + } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + SET_FORMAT( GR_TEXFMT_ARGB_1555, _mesa_texformat_argb1555 ); + break; + } + } + if ( allow32bpp && is32bpp ) { + SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_rgba8888 ); + } else { + SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); + } + break; + + case GL_RGB: + case 3: + if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { + SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); + break; + } + if ( allow32bpp && is32bpp ) { + SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_rgba8888 ); + } else { + SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); + } + break; + + /* GH: Okay, keep checking as normal. Still test for GL_RGB, + * GL_RGBA formats first. + */ + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + SET_FORMAT_32BPP( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888, + GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); + break; + + case GL_RGBA4: + case GL_RGBA2: + SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); + break; + + case GL_RGB5_A1: + SET_FORMAT( GR_TEXFMT_ARGB_1555, _mesa_texformat_argb1555 ); + break; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + SET_FORMAT_32BPP( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888, + GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); + break; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); + break; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + SET_FORMAT( GR_TEXFMT_ALPHA_8, _mesa_texformat_a8 ); + break; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + SET_FORMAT( GR_TEXFMT_INTENSITY_8, _mesa_texformat_l8 ); + break; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + SET_FORMAT( GR_TEXFMT_ALPHA_INTENSITY_88, _mesa_texformat_al88 ); + break; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + SET_FORMAT( GR_TEXFMT_ALPHA_8, _mesa_texformat_i8 ); + break; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + SET_FORMAT( GR_TEXFMT_P_8, _mesa_texformat_ci8 ); + break; + + default: + fprintf( stderr, "bad texture format in fxTexGetFormat() %d", + texImage->IntFormat ); + return -1; + } + + texImage->TexFormat = texFormat; + + return ret; +} - if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name, - tObj->DriverData); - } - if (target != GL_TEXTURE_2D) - return; +static GLboolean +tdfxDDTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + const struct gl_texture_format *texFormat; + GrTextureFormat_t glideFormat; + tdfxTexObjPtr t; + tdfxTexImagePtr image; + GLint dstWidth, dstHeight, wScale, hScale; + GLint size; + void *data; + + if ( 0 ) { + printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", + texObj->Name, texImage->IntFormat, format, type, + texImage->Width, texImage->Height); + } + + if ( target != GL_TEXTURE_2D || texImage->Border > 0 ) + return GL_FALSE; + + if ( !texObj->DriverData ) + texObj->DriverData = tdfxAllocTexObj( fxMesa ); + + t = TDFX_TEXTURE_DATA(texObj); + image = &t->image[level]; + + /* Determine the appropriate GL internal texel format, Mesa internal + * texel format, and texelSize (bytes) given the user's internal + * texture format hint. + */ + glideFormat = tdfxTexGetFormat( fxMesa, texImage, format, type ); - if (!tObj->DriverData) { - tObj->DriverData = fxAllocTexObjData(fxMesa); - } + /* Get the destination internal format. + */ + texFormat = texImage->TexFormat; - ti = TDFX_TEXTURE_DATA(tObj); - ti->lastTimeUsed = fxMesa->texBindNumber++; + /* Determine width and height scale factors for texture. Remember, + * Glide is limited to 8:1 aspect ratios. + */ + tdfxTexGetInfo( ctx, + texImage->Width, texImage->Height, + NULL, NULL, NULL, NULL, + &wScale, &hScale ); + dstWidth = texImage->Width * wScale; + dstHeight = texImage->Height * hScale; + + /* Allocate new storage for texture image, if needed. This + * conditional wants to set uncompressedImage to point to the + * uncompressed image, and mml->data to the texture data. If the + * image is uncompressed, these are identical. If the image is not + * compressed, these are different. + */ + if ( !image->original.data || image->glideFormat != glideFormat || + image->original.width != texImage->Width || + image->original.height != texImage->Height ) + { + if ( image->original.data ) { + FREE( image->original.data ); + image->original.data = NULL; + } + if ( image->rescaled.data ) { + FREE( image->rescaled.data ); + image->rescaled.data = NULL; + } + + size = texImage->Width * texImage->Height * texFormat->TexelBytes; + image->original.data = (void *) MALLOC( size ); + if ( !image->original.data ) + return GL_FALSE; + + image->original.width = texImage->Width; + image->original.height = texImage->Height; + image->original.size = size; + + image->glideFormat = glideFormat; + image->wScale = wScale; + image->hScale = hScale; + + t->info.format = glideFormat; + tdfxTMMoveOutTM( fxMesa, texObj ); + } + + /* Store the texture image into the 'original' space. + */ + if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat, + 0, 0, texImage->Width, + texImage->Height, texImage->Width, + format, type, packing, pixels, + image->original.data ) ) { + return GL_FALSE; + } + + data = image->original.data; + size = image->original.size; + + /* GH: Sigh... + */ + if ( wScale > 1 || hScale > 1 ) { + if ( image->rescaled.data ) { + FREE( image->rescaled.data ); + image->rescaled.data = NULL; + } - fxMesa->new_state |= TDFX_NEW_TEXTURE; -} + size = dstWidth * dstHeight * texFormat->TexelBytes; + image->rescaled.data = (void *) MALLOC( size ); + if ( !image->rescaled.data ) + return GL_FALSE; + image->rescaled.width = dstWidth; + image->rescaled.height = dstHeight; + image->rescaled.size = size; -/* - * Called via glTexEnv. - */ -void -tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, - const GLfloat * param) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - if (param) - fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname, - (GLint) (*param)); - else - fprintf(stderr, "fxmesa: texenv(%x)\n", pname); - } + _mesa_rescale_teximage2d( texFormat, + texImage->Width, texImage->Height, + dstWidth, dstHeight, + image->original.data, image->rescaled.data ); - fxMesa->new_state |= TDFX_NEW_TEXTURE; -} + data = image->rescaled.data; + } + image->data = data; + image->size = size; -/* - * Called via glTexParameter. - */ -void -tdfxDDTexParameter(GLcontext * ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat * params) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLenum param = (GLenum) (GLint) params[0]; - tdfxTexInfo *ti; - - if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name, - tObj->DriverData, pname, param); - } - - if (target != GL_TEXTURE_2D) - return; - - if (!tObj->DriverData) - tObj->DriverData = fxAllocTexObjData(fxMesa); - - ti = TDFX_TEXTURE_DATA(tObj); - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - switch (param) { - case GL_NEAREST: - ti->mmMode = GR_MIPMAP_DISABLE; - ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - ti->LODblend = FXFALSE; - break; - case GL_LINEAR: - ti->mmMode = GR_MIPMAP_DISABLE; - ti->minFilt = GR_TEXTUREFILTER_BILINEAR; - ti->LODblend = FXFALSE; - break; - case GL_NEAREST_MIPMAP_LINEAR: - if (TDFX_IS_NAPALM(fxMesa)) { - if (fxMesa->haveTwoTMUs) { - ti->mmMode = GR_MIPMAP_NEAREST; - ti->LODblend = FXTRUE; - } - else { - ti->mmMode = GR_MIPMAP_NEAREST_DITHER; - ti->LODblend = FXFALSE; - } - ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - break; - } - /* XXX Voodoo3/Banshee mipmap blending seems to produce - * incorrectly filtered colors for the smallest mipmap levels. - * To work-around we fall-through here and use a different filter. - */ - case GL_NEAREST_MIPMAP_NEAREST: - ti->mmMode = GR_MIPMAP_NEAREST; - ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - ti->LODblend = FXFALSE; - break; - case GL_LINEAR_MIPMAP_LINEAR: - if (TDFX_IS_NAPALM(fxMesa)) { - if (fxMesa->haveTwoTMUs) { - ti->mmMode = GR_MIPMAP_NEAREST; - ti->LODblend = FXTRUE; - } - else { - ti->mmMode = GR_MIPMAP_NEAREST_DITHER; - ti->LODblend = FXFALSE; - } - ti->minFilt = GR_TEXTUREFILTER_BILINEAR; - break; - } - /* XXX Voodoo3/Banshee mipmap blending seems to produce - * incorrectly filtered colors for the smallest mipmap levels. - * To work-around we fall-through here and use a different filter. - */ - case GL_LINEAR_MIPMAP_NEAREST: - ti->mmMode = GR_MIPMAP_NEAREST; - ti->minFilt = GR_TEXTUREFILTER_BILINEAR; - ti->LODblend = FXFALSE; - break; - default: - break; - } - RevalidateTexture(ctx, tObj); - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; - - case GL_TEXTURE_MAG_FILTER: - switch (param) { - case GL_NEAREST: - ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - break; - case GL_LINEAR: - ti->magFilt = GR_TEXTUREFILTER_BILINEAR; - break; - default: - break; - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; - - case GL_TEXTURE_WRAP_S: - switch (param) { - case GL_CLAMP: - ti->sClamp = GR_TEXTURECLAMP_CLAMP; - break; - case GL_REPEAT: - ti->sClamp = GR_TEXTURECLAMP_WRAP; - break; - default: - break; - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; - - case GL_TEXTURE_WRAP_T: - switch (param) { - case GL_CLAMP: - ti->tClamp = GR_TEXTURECLAMP_CLAMP; - break; - case GL_REPEAT: - ti->tClamp = GR_TEXTURECLAMP_WRAP; - break; - default: - break; - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; - - case GL_TEXTURE_BORDER_COLOR: - /* TO DO */ - break; - case GL_TEXTURE_MIN_LOD: - /* TO DO */ - break; - case GL_TEXTURE_MAX_LOD: - /* TO DO */ - break; - case GL_TEXTURE_BASE_LEVEL: - RevalidateTexture(ctx, tObj); - break; - case GL_TEXTURE_MAX_LEVEL: - RevalidateTexture(ctx, tObj); - break; - - default: - break; - } -} + tdfxRevalidateTexture( ctx, texObj ); + t->reloadImages = GL_TRUE; + fxMesa->new_state |= TDFX_NEW_TEXTURE; -/* - * Called via glDeleteTextures to delete a texture object. - * Here, we delete the Glide data associated with the texture. - */ -void -tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTMFreeTexture(fxMesa, tObj); - fxMesa->new_state |= TDFX_NEW_TEXTURE; + *retainInternalCopy = GL_FALSE; + return GL_TRUE; } -/* - * Return true if texture is resident, false otherwise. - */ -GLboolean -tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj) +static GLboolean +tdfxDDTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) { - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - return (GLboolean) (ti && ti->isInTM); -} + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); + tdfxTexImagePtr image; + if ( target != GL_TEXTURE_2D ) + return GL_FALSE; + if ( !t ) + return GL_FALSE; -/* - * Convert a gl_color_table texture palette to Glide's format. - */ -static void -convertPalette(FxU32 data[256], const struct gl_color_table *table) -{ - const GLubyte *tableUB = (const GLubyte *) table->Table; - GLint width = table->Size; - FxU32 r, g, b, a; - GLint i; - - ASSERT(table->TableType == GL_UNSIGNED_BYTE); - - switch (table->Format) { - case GL_INTENSITY: - for (i = 0; i < width; i++) { - r = tableUB[i]; - g = tableUB[i]; - b = tableUB[i]; - a = tableUB[i]; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - case GL_LUMINANCE: - for (i = 0; i < width; i++) { - r = tableUB[i]; - g = tableUB[i]; - b = tableUB[i]; - a = 255; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - case GL_ALPHA: - for (i = 0; i < width; i++) { - r = g = b = 255; - a = tableUB[i]; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - case GL_LUMINANCE_ALPHA: - for (i = 0; i < width; i++) { - r = g = b = tableUB[i * 2 + 0]; - a = tableUB[i * 2 + 1]; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - case GL_RGB: - for (i = 0; i < width; i++) { - r = tableUB[i * 3 + 0]; - g = tableUB[i * 3 + 1]; - b = tableUB[i * 3 + 2]; - a = 255; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - case GL_RGBA: - for (i = 0; i < width; i++) { - r = tableUB[i * 4 + 0]; - g = tableUB[i * 4 + 1]; - b = tableUB[i * 4 + 2]; - a = tableUB[i * 4 + 3]; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - } -} + if ( 0 ) { + fprintf( stderr, "TexSubImage id=%d lvl=%d int=0x%x format=0x%x type=0x%x x=%d y=%d w=%d h=%d fullW=%d fullH=%d\n", + texObj->Name, level, texImage->IntFormat, format, type, + xoffset, yoffset, width, height, + texImage->Width, texImage->Height ); + } + image = &t->image[level]; + /* Must have an existing texture image! + */ + assert( image->original.data ); -void -tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - - if (tObj) { - /* per-texture palette */ - tdfxTexInfo *ti; - if (!tObj->DriverData) - tObj->DriverData = fxAllocTexObjData(fxMesa); - ti = TDFX_TEXTURE_DATA(tObj); - convertPalette(ti->palette.data, &tObj->Palette); - /*tdfxTexInvalidate(ctx, tObj);*/ - } - else { - /* global texture palette */ - convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */ + if ( !_mesa_convert_texsubimage2d( texImage->TexFormat->IntFormat, + xoffset, yoffset, width, height, + texImage->Width, + format, type, packing, + pixels, image->original.data ) ) { + return GL_FALSE; + } + + /* Rescale the original image again if we have to. + */ + if ( image->wScale > 1 || image->hScale > 1 ) { + assert( image->rescaled.data ); + _mesa_rescale_teximage2d( texImage->TexFormat, + image->original.width, image->original.height, + image->rescaled.width, image->rescaled.height, + image->original.data, image->rescaled.data ); + } + + t->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ + fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */ + + return GL_TRUE; } -/* - * Given an OpenGL internal texture format, return the corresponding - * Glide internal texture format and MesaIntTexFormat. - * If allow32bpp is true, we'll return 32-bit texel formats when - * appropriate. - */ -static void -tdfxTexGetFormat(GLenum intFormatHint, GLboolean allow32bpp, - GrTextureFormat_t *glideFormat, - MesaIntTexFormat *mesaFormat, - GLint *texelSize) -{ - switch (intFormatHint) { - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - if (glideFormat) - *glideFormat = GR_TEXFMT_INTENSITY_8; - if (mesaFormat) - *mesaFormat = MESA_L8; - if (texelSize) - *texelSize = 1; - break; - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - if (glideFormat) - *glideFormat = GR_TEXFMT_ALPHA_INTENSITY_88; - if (mesaFormat) - *mesaFormat = MESA_A8_L8; - if (texelSize) - *texelSize = 2; - break; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - if (glideFormat) - *glideFormat = GR_TEXFMT_ALPHA_8; - if (mesaFormat) - *mesaFormat = MESA_I8; - if (texelSize) - *texelSize = 1; - break; - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - if (glideFormat) - *glideFormat = GR_TEXFMT_ALPHA_8; - if (mesaFormat) - *mesaFormat = MESA_A8; - if (texelSize) - *texelSize = 1; - break; - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - if (glideFormat) - *glideFormat = GR_TEXFMT_RGB_565; - if (mesaFormat) - *mesaFormat = MESA_R5_G6_B5; - if (texelSize) - *texelSize = 2; - break; - case 3: - case GL_RGB: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - if (allow32bpp) { - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_8888; - if (mesaFormat) - *mesaFormat = MESA_FF_R8_G8_B8; - if (texelSize) - *texelSize = 4; - } - else { - if (glideFormat) - *glideFormat = GR_TEXFMT_RGB_565; - if (mesaFormat) - *mesaFormat = MESA_R5_G6_B5; - if (texelSize) - *texelSize = 2; - } - break; - case GL_RGBA2: - case GL_RGBA4: - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_4444; - if (mesaFormat) - *mesaFormat = MESA_A4_R4_G4_B4; - if (texelSize) - *texelSize = 2; - break; - case 4: - case GL_RGBA: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - if (allow32bpp) { - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_8888; - if (mesaFormat) - *mesaFormat = MESA_A8_R8_G8_B8; - if (texelSize) - *texelSize = 4; - } - else { - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_4444; - if (mesaFormat) - *mesaFormat = MESA_A4_R4_G4_B4; - if (texelSize) - *texelSize = 2; - } - break; - case GL_RGB5_A1: - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_1555; - if (mesaFormat) - *mesaFormat = MESA_A1_R5_G5_B5; - if (texelSize) - *texelSize = 2; - break; - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - if (glideFormat) - *glideFormat = GR_TEXFMT_P_8; - if (mesaFormat) - *mesaFormat = MESA_C8; - if (texelSize) - *texelSize = 1; - break; - case GL_COMPRESSED_RGB_FXT1_3DFX: - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; - if (mesaFormat) - *mesaFormat = MESA_A8_R8_G8_B8; - if (texelSize) - *texelSize = 4; - break; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - if (glideFormat) - *glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; - if (mesaFormat) - *mesaFormat = MESA_A8_R8_G8_B8; - if (texelSize) - *texelSize = 4; - break; - default: - fprintf(stderr, "bad texture format in fxTexGetFormat() %d", intFormatHint); - break; - } -} +/* ================================================================ + * + */ -/**********************************************************************/ -/**** NEW TEXTURE IMAGE FUNCTIONS ****/ -/**********************************************************************/ +static void tdfxDDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); -static FxBool TexusFatalError = FXFALSE; -static FxBool TexusError = FXFALSE; + if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { + if ( param ) { + fprintf( stderr, __FUNCTION__"( %x, %x )\n", pname, (GLint)(*param) ); + } else { + fprintf( stderr, __FUNCTION__"( %x )\n", pname ); + } + } -#define TX_DITHER_NONE 0x00000000 + fxMesa->new_state |= TDFX_NEW_TEXTURE; +} -static void -fxTexusError(const char *string, FxBool fatal) +static void tdfxDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) { - gl_problem(NULL, string); - /* - * Just propagate the fatal value up. - */ - TexusError = FXTRUE; - TexusFatalError = fatal; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLenum param = (GLenum) (GLint) params[0]; + tdfxTexObjPtr t; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, __FUNCTION__ "( %d, %p, %x, %x )\n", + tObj->Name, tObj->DriverData, pname, param ); + } + + if ( target != GL_TEXTURE_2D ) + return; + + if ( !tObj->DriverData ) + tObj->DriverData = tdfxAllocTexObj( fxMesa ); + + t = TDFX_TEXTURE_DATA(tObj); + + switch ( pname ) { + case GL_TEXTURE_MIN_FILTER: + switch ( param ) { + case GL_NEAREST: + t->mmMode = GR_MIPMAP_DISABLE; + t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + t->LODblend = FXFALSE; + break; + + case GL_LINEAR: + t->mmMode = GR_MIPMAP_DISABLE; + t->minFilt = GR_TEXTUREFILTER_BILINEAR; + t->LODblend = FXFALSE; + break; + + case GL_NEAREST_MIPMAP_LINEAR: + if ( TDFX_IS_NAPALM(fxMesa) ) { + if ( fxMesa->numTMUs > 1 ) { + t->mmMode = GR_MIPMAP_NEAREST; + t->LODblend = FXTRUE; + } else { + t->mmMode = GR_MIPMAP_NEAREST_DITHER; + t->LODblend = FXFALSE; + } + t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + } + /* XXX Voodoo3/Banshee mipmap blending seems to produce + * incorrectly filtered colors for the smallest mipmap levels. + * To work-around we fall-through here and use a different filter. + */ + case GL_NEAREST_MIPMAP_NEAREST: + t->mmMode = GR_MIPMAP_NEAREST; + t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + t->LODblend = FXFALSE; + break; + + case GL_LINEAR_MIPMAP_LINEAR: + if ( TDFX_IS_NAPALM(fxMesa) ) { + if ( fxMesa->numTMUs > 1 ) { + t->mmMode = GR_MIPMAP_NEAREST; + t->LODblend = FXTRUE; + } else { + t->mmMode = GR_MIPMAP_NEAREST_DITHER; + t->LODblend = FXFALSE; + } + t->minFilt = GR_TEXTUREFILTER_BILINEAR; + break; + } + /* XXX Voodoo3/Banshee mipmap blending seems to produce + * incorrectly filtered colors for the smallest mipmap levels. + * To work-around we fall-through here and use a different filter. + */ + case GL_LINEAR_MIPMAP_NEAREST: + t->mmMode = GR_MIPMAP_NEAREST; + t->minFilt = GR_TEXTUREFILTER_BILINEAR; + t->LODblend = FXFALSE; + break; + default: + break; + } + tdfxRevalidateTexture( ctx, tObj ); + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_MAG_FILTER: + switch ( param ) { + case GL_NEAREST: + t->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + case GL_LINEAR: + t->magFilt = GR_TEXTUREFILTER_BILINEAR; + break; + default: + break; + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_WRAP_S: + switch ( param ) { + case GL_CLAMP: + t->sClamp = GR_TEXTURECLAMP_CLAMP; + break; + case GL_REPEAT: + t->sClamp = GR_TEXTURECLAMP_WRAP; + break; + default: + break; + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_WRAP_T: + switch ( param ) { + case GL_CLAMP: + t->tClamp = GR_TEXTURECLAMP_CLAMP; + break; + case GL_REPEAT: + t->tClamp = GR_TEXTURECLAMP_WRAP; + break; + default: + break; + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_BASE_LEVEL: + tdfxRevalidateTexture( ctx, tObj ); + break; + + case GL_TEXTURE_MAX_LEVEL: + tdfxRevalidateTexture( ctx, tObj ); + break; + + case GL_TEXTURE_BORDER_COLOR: + /* TO DO */ + break; + case GL_TEXTURE_MIN_LOD: + /* TO DO */ + break; + case GL_TEXTURE_MAX_LOD: + /* TO DO */ + break; + + default: + break; + } } -GLboolean -tdfxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib * packing, - struct gl_texture_object * texObj, - struct gl_texture_image * texImage, - GLboolean * retainInternalCopy) +static void tdfxDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa); - GrTextureFormat_t gldformat; - tdfxTexInfo *ti; - tdfxMipMapLevel *mml; - GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride; - MesaIntTexFormat intFormat; - GLboolean isCompressedFormat; - GLint texsize; - void *uncompressedImage; - - /* - printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", - texObj->Name, texImage->IntFormat, format, type, - texImage->Width, texImage->Height); - */ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexObjPtr t; - isCompressedFormat = texImage->IsCompressed; - if (target != GL_TEXTURE_2D || texImage->Border > 0) - return GL_FALSE; - - if (!texObj->DriverData) - texObj->DriverData = fxAllocTexObjData(fxMesa); - - ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[level]; - - /* Determine the appropriate GL internal texel format, Mesa internal - * texel format, and texelSize (bytes) given the user's internal - * texture format hint. - */ - tdfxTexGetFormat(texImage->IntFormat, allow32bpt, - &gldformat, &intFormat, &texelSize); - - /* Determine width and height scale factors for texture. - * Remember, Glide is limited to 8:1 aspect ratios. - */ - tdfxTexGetInfo(ctx, - texImage->Width, texImage->Height, - NULL, /* lod level */ - NULL, /* aspect ratio */ - NULL, NULL, /* sscale, tscale */ - &wScale, &hScale); - dstWidth = texImage->Width * wScale; - dstHeight = texImage->Height * hScale; - if (isCompressedFormat) { - texsize = tdfxDDCompressedImageSize(ctx, - texImage->IntFormat, - 2, - texImage->Width, - texImage->Height, - 1); - } - else { - texsize = dstWidth * dstHeight * texelSize; - } - - /* - * If the image is not compressed, this doesn't - * matter, but it might as well have a sensible - * value, and it might save a failure later on. - */ - texImage->CompressedSize = texsize; - /* housekeeping */ - _mesa_set_teximage_component_sizes(intFormat, texImage); - - /* - * allocate new storage for texture image, if needed. - * This conditional wants to set uncompressedImage to - * point to the uncompressed image, and mml->data to - * the texture data. If the image is uncompressed, - * these are identical. If the image is not compressed, - * these are different. - */ - if (!mml->data || mml->glideFormat != gldformat || - mml->width != dstWidth || mml->height != dstHeight || - texsize != mml->dataSize ) { - if (mml->data) { - FREE(mml->data); - } - uncompressedImage - = (void *)MALLOC(dstWidth * dstHeight * texelSize); - if (!uncompressedImage) { - return GL_FALSE; - } - if (isCompressedFormat) { - mml->data = MALLOC(texsize); - if (!mml->data) { - FREE(uncompressedImage); - return GL_FALSE; - } - } else { - mml->data = uncompressedImage; - } - mml->texelSize = texelSize; - mml->glideFormat = gldformat; - mml->width = dstWidth; - mml->height = dstHeight; - mml->dataSize = texsize; - ti->info.format = gldformat; - tdfxTMMoveOutTM(fxMesa, texObj); - /*tdfxTexInvalidate(ctx, texObj);*/ - } - else { - /* - * Here we don't have to allocate anything, but we - * do have to point uncompressedImage to the uncompressed - * data. - */ - if (isCompressedFormat) { - uncompressedImage - = (void *)MALLOC(dstWidth * dstHeight * texelSize); - if (!uncompressedImage) { - return GL_FALSE; - } - } else { - uncompressedImage = mml->data; - } - } - - dstStride = dstWidth * texelSize; - - /* store the texture image into uncompressedImage */ - if (!_mesa_convert_teximage(intFormat, - dstWidth, dstHeight, - uncompressedImage, - dstStride, - texImage->Width, texImage->Height, - format, type, pixels, packing)) { - /*printf("convert failed\n");*/ - return GL_FALSE; /* not necessarily an error */ - } - - /* - * Now compress it if necessary. - */ - if (isCompressedFormat) { - TxErrorCallbackFnc_t oldErrorCallback; - (*txErrorSetCallbackProc)(fxTexusError, &oldErrorCallback); - (*txImgQuantizeProc)((char *)mml->data, - (char *)uncompressedImage, - texImage->Width, - texImage->Height, - gldformat, - TX_DITHER_NONE); - (*txErrorSetCallbackProc)(oldErrorCallback, NULL); - if (uncompressedImage != mml->data) { - /* - * We do not need this any more, errors or no. - */ - FREE(uncompressedImage); - } - TexusError = FXFALSE; - if (TexusFatalError) { - FREE(mml->data); - mml->data = NULL; - TexusFatalError = FXFALSE; - return GL_FALSE; - } - } - - - RevalidateTexture(ctx, texObj); - - ti->reloadImages = GL_TRUE; - fxMesa->new_state |= TDFX_NEW_TEXTURE; - - *retainInternalCopy = GL_FALSE; - return GL_TRUE; -} + if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, __FUNCTION__ "( %d, %p )\n", + tObj->Name, tObj->DriverData ); + } + if ( target != GL_TEXTURE_2D ) + return; -GLboolean -tdfxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib * packing, - struct gl_texture_object * texObj, - struct gl_texture_image * texImage) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexInfo *ti; - GLint wscale, hscale, dstStride = 0; - tdfxMipMapLevel *mml; - GLboolean result; - void *uncompressedImage = (void *)0; - FxU32 uncompressedSize; - TxErrorCallbackFnc_t oldErrorCallback; - - if (target != GL_TEXTURE_2D) - return GL_FALSE; - - if (!texObj->DriverData) - return GL_FALSE; - - /* - printf("TexSubImage id=%d lvl=%d int=0x%x format=0x%x type=0x%x x=%d y=%d w=%d h=%d fullW=%d fullH=%d\n", - texObj->Name, level, - texImage->IntFormat, format, type, xoffset, yoffset, width, height, - texImage->Width, texImage->Height); - */ + if ( !tObj->DriverData ) + tObj->DriverData = tdfxAllocTexObj( fxMesa ); - ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[level]; - - tdfxTexGetInfo(ctx, texImage->Width, texImage->Height, NULL, NULL, - NULL, NULL, &wscale, &hscale); - - /* - * Must have an existing texture image! - */ - assert(mml->data); - - switch (mml->glideFormat) { - case GR_TEXFMT_INTENSITY_8: - dstStride = mml->width; - result = _mesa_convert_texsubimage(MESA_I8, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - case GR_TEXFMT_ALPHA_8: - dstStride = mml->width; - result = _mesa_convert_texsubimage(MESA_A8, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - case GR_TEXFMT_P_8: - dstStride = mml->width; - result = _mesa_convert_texsubimage(MESA_C8, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - case GR_TEXFMT_ALPHA_INTENSITY_88: - dstStride = mml->width * 2; - result = _mesa_convert_texsubimage(MESA_A8_L8, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - case GR_TEXFMT_RGB_565: - dstStride = mml->width * 2; - result = _mesa_convert_texsubimage(MESA_R5_G6_B5, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - case GR_TEXFMT_ARGB_4444: - dstStride = mml->width * 2; - result = _mesa_convert_texsubimage(MESA_A4_R4_G4_B4, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - case GR_TEXFMT_ARGB_CMP_FXT1: - /* - * There are some special legality constraints for compressed - * textures. - */ - if ((xoffset != texImage->Border) - || (yoffset != texImage->Border)) { - gl_error( ctx, - GL_INVALID_OPERATION, - "glTexSubImage2D(offset)" ); - return GL_FALSE; - } - if ((width != texImage->Width) - || (height != texImage->Height)) { - gl_error( ctx, - GL_INVALID_VALUE, - "glTexSubImage2D(image size)" ); - return GL_FALSE; - } - /* - * The width and height have to be multiples of - * 8 and 4 respectively. - */ - width = (mml->width + 0x7) &~ 0x7; - height = (mml->height + 0x3) &~ 0x3; - /* - * A texel is 8888 for this format. - */ - uncompressedSize = mml->width * mml->height * 4; - uncompressedImage = (void *)MALLOC(uncompressedSize); - /* - * Convert the data. - */ - dstStride = mml->width * 4; - result = _mesa_convert_texsubimage(MESA_A8_R8_G8_B8, xoffset, yoffset, - mml->width, mml->height, uncompressedImage, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - if (!result) { - FREE(uncompressedImage); - printf("TexSubImage convert failed\n"); - return GL_FALSE; - } - /* - * Now that we have converted the data, then compress it. - */ - (*txErrorSetCallbackProc)(fxTexusError, &oldErrorCallback); - (*txImgQuantizeProc)((char *)mml->data, - (char *)uncompressedImage, - mml->width, - mml->height, - mml->glideFormat, - TX_DITHER_NONE); - (*txErrorSetCallbackProc)(oldErrorCallback, NULL); - result = TexusFatalError; - TexusFatalError = TexusError = FXFALSE; - /* - * We don't need this any more. - */ - FREE(uncompressedImage); - break; - case GR_TEXFMT_ARGB_8888: - { - MesaIntTexFormat intFormat; - if (texImage->Format == GL_RGB) { - /* An RGB image padded out to 4 bytes/texel */ - intFormat = MESA_FF_R8_G8_B8; - } - else { - intFormat = MESA_A8_R8_G8_B8; - } - dstStride = mml->width * 4; - result = _mesa_convert_texsubimage(intFormat, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - } - break; - case GR_TEXFMT_ARGB_1555: - dstStride = mml->width * 2; - result = _mesa_convert_texsubimage(MESA_A1_R5_G5_B5, xoffset, yoffset, - mml->width, mml->height, mml->data, - dstStride, width, height, - texImage->Width, texImage->Height, - format, type, pixels, packing); - break; - default: - gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format"); - result = GL_FALSE; - } - - if (!result) { - return GL_FALSE; - } - - ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ - fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */ - - return GL_TRUE; + t = TDFX_TEXTURE_DATA(tObj); + t->lastTimeUsed = fxMesa->texBindNumber++; + + fxMesa->new_state |= TDFX_NEW_TEXTURE; } +static void tdfxDDDeleteTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); -/**********************************************************************/ -/**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/ -/**********************************************************************/ + LOCK_HARDWARE( fxMesa ); + tdfxTMFreeTextureLocked( fxMesa, tObj ); + UNLOCK_HARDWARE( fxMesa ); -GLboolean -tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, - GLint level, GLsizei imageSize, - const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - GLboolean *retainInternalCopy) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa); - GrTextureFormat_t gldformat; - tdfxTexInfo *ti; - tdfxMipMapLevel *mml; - GLint dstWidth, dstHeight, wScale, hScale, texelSize; - MesaIntTexFormat intFormat; - GLboolean isCompressedFormat; - GLsizei texsize; - - if (target != GL_TEXTURE_2D || texImage->Border > 0) - return GL_FALSE; - - if (!texObj->DriverData) - texObj->DriverData = fxAllocTexObjData(fxMesa); - - ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[level]; - - isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat); - if (!isCompressedFormat) { - gl_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)" ); - return GL_FALSE; - } - /* Determine the apporpriate GL internal texel format, Mesa internal - * texel format, and texelSize (bytes) given the user's internal - * texture format hint. - */ - tdfxTexGetFormat(texImage->IntFormat, allow32bpt, - &gldformat, &intFormat, &texelSize); - - /* Determine width and height scale factors for texture. - * Remember, Glide is limited to 8:1 aspect ratios. - */ - tdfxTexGetInfo(ctx, - texImage->Width, texImage->Height, - NULL, /* lod level */ - NULL, /* aspect ratio */ - NULL, NULL, /* sscale, tscale */ - &wScale, &hScale); - dstWidth = texImage->Width * wScale; - dstHeight = texImage->Height * hScale; - /* housekeeping */ - _mesa_set_teximage_component_sizes(intFormat, texImage); - - texsize = tdfxDDCompressedImageSize(ctx, - texImage->IntFormat, - 2, - texImage->Width, - texImage->Height, - 1); - if (texsize != imageSize) { - gl_error(ctx, - GL_INVALID_VALUE, - "glCompressedTexImage2D(texsize)"); - return GL_FALSE; - } - - /* allocate new storage for texture image, if needed */ - if (!mml->data || mml->glideFormat != gldformat || - mml->width != dstWidth || mml->height != dstHeight || - texsize != mml->dataSize) { - if (mml->data) { - FREE(mml->data); - } - mml->data = MALLOC(texsize); - if (!mml->data) { - return GL_FALSE; - } - mml->texelSize = texelSize; - mml->glideFormat = gldformat; - mml->width = dstWidth; - mml->height = dstHeight; - tdfxTMMoveOutTM(fxMesa, texObj); - /*tdfxTexInvalidate(ctx, texObj);*/ - } - - /* save the texture data */ - MEMCPY(mml->data, data, imageSize); - - RevalidateTexture(ctx, texObj); - - ti->reloadImages = GL_TRUE; - fxMesa->new_state |= TDFX_NEW_TEXTURE; - - *retainInternalCopy = GL_FALSE; - return GL_TRUE; + fxMesa->new_state |= TDFX_NEW_TEXTURE; } -GLboolean -tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLint height, GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) +static GLboolean tdfxDDIsTextureResident( GLcontext *ctx, + struct gl_texture_object *tObj ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexInfo *ti; - tdfxMipMapLevel *mml; - - /* - * We punt if we are not replacing the entire image. This - * is allowed by the spec. - */ - if ((xoffset != 0) && (yoffset != 0) - && (width != texImage->Width) - && (height != texImage->Height)) { - return GL_FALSE; - } - - ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[level]; - if (imageSize != mml->dataSize) { - return GL_FALSE; - } - MEMCPY(data, mml->data, imageSize); - - ti->reloadImages = GL_TRUE; - fxMesa->new_state |= TDFX_NEW_TEXTURE; - - return GL_TRUE; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + + return ( t && t->isInTM ); } -#if 0 +/* Convert a gl_color_table texture palette to Glide's format. + */ static void -PrintTexture(int w, int h, int c, const GLubyte * data) +tdfxConvertPalette( FxU32 data[256], const struct gl_color_table *table ) { - int i, j; - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - if (c == 2) - printf("%02x %02x ", data[0], data[1]); - else if (c == 3) - printf("%02x %02x %02x ", data[0], data[1], data[2]); - data += c; - } - printf("\n"); - } + const GLubyte *tableUB = (const GLubyte *) table->Table; + GLint width = table->Size; + FxU32 r, g, b, a; + GLint i; + + ASSERT( table->TableType == GL_UNSIGNED_BYTE ); + + switch ( table->Format ) { + case GL_RGBA: + for ( i = 0 ; i < width ; i++ ) { + r = tableUB[i * 4 + 0]; + g = tableUB[i * 4 + 1]; + b = tableUB[i * 4 + 2]; + a = tableUB[i * 4 + 3]; + data[i] = PACK_COLOR_8888( a, r, g, b ); + } + break; + case GL_RGB: + for ( i = 0 ; i < width ; i++ ) { + r = tableUB[i * 3 + 0]; + g = tableUB[i * 3 + 1]; + b = tableUB[i * 3 + 2]; + a = 255; + data[i] = PACK_COLOR_8888( a, r, g, b ); + } + break; + case GL_LUMINANCE: + for ( i = 0 ; i < width ; i++ ) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = 255; + data[i] = PACK_COLOR_8888( a, r, g, b ); + } + break; + case GL_ALPHA: + for ( i = 0 ; i < width ; i++ ) { + r = g = b = 255; + a = tableUB[i]; + data[i] = PACK_COLOR_8888( a, r, g, b ); + } + break; + case GL_LUMINANCE_ALPHA: + for ( i = 0 ; i < width ; i++ ) { + r = g = b = tableUB[i * 2 + 0]; + a = tableUB[i * 2 + 1]; + data[i] = PACK_COLOR_8888( a, r, g, b ); + } + break; + case GL_INTENSITY: + for ( i = 0 ; i < width ; i++ ) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = tableUB[i]; + data[i] = PACK_COLOR_8888( a, r, g, b ); + } + break; + } } -#endif - -GLboolean -tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target, - GLint level, GLint internalFormat, - GLenum format, GLenum type, - GLint width, GLint height, - GLint depth, GLint border) +static void +tdfxDDTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - - switch (target) { - case GL_PROXY_TEXTURE_1D: - return GL_TRUE; /* software rendering */ - case GL_PROXY_TEXTURE_2D: - { - struct gl_texture_object *tObj; - tdfxTexInfo *ti; - int memNeeded; - - tObj = ctx->Texture.Proxy2D; - if (!tObj->DriverData) - tObj->DriverData = fxAllocTexObjData(fxMesa); - ti = TDFX_TEXTURE_DATA(tObj); - - /* assign the parameters to test against */ - tObj->Image[level]->Width = width; - tObj->Image[level]->Height = height; - tObj->Image[level]->Border = border; - tObj->Image[level]->IntFormat = internalFormat; - if (level == 0) { - /* don't use mipmap levels > 0 */ - tObj->MinFilter = tObj->MagFilter = GL_NEAREST; - } - else { - /* test with all mipmap levels */ - tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR; - tObj->MagFilter = GL_NEAREST; - } - RevalidateTexture(ctx, tObj); - - /* - printf("small lodlog2 0x%x\n", ti->info.smallLodLog2); - printf("large lodlog2 0x%x\n", ti->info.largeLodLog2); - printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2); - printf("glide format 0x%x\n", ti->info.format); - printf("data %p\n", ti->info.data); - printf("lodblend %d\n", (int) ti->LODblend); - */ - - /* determine where texture will reside */ - if (ti->LODblend && !shared->umaTexMemory) { - /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ - memNeeded = FX_grTexTextureMemRequired_NoLock( - GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); - } - else { - /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ - memNeeded = FX_grTexTextureMemRequired_NoLock( - GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); - } - /* - printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]); - */ - if (memNeeded > shared->totalTexMem[0]) - return GL_FALSE; - else - return GL_TRUE; - } - case GL_PROXY_TEXTURE_3D: - return GL_TRUE; /* software rendering */ - default: - return GL_TRUE; /* never happens, silence compiler */ - } + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexObjPtr t; + + if ( tObj ) { + /* Per-texture palette */ + if ( !tObj->DriverData ) + tObj->DriverData = tdfxAllocTexObj(fxMesa); + + t = TDFX_TEXTURE_DATA(tObj); + tdfxConvertPalette( t->palette.data, &tObj->Palette ); + /*tdfxTexInvalidate( ctx, tObj );*/ + } else { + /* Global texture palette */ + tdfxConvertPalette( fxMesa->glbPalette.data, &ctx->Texture.Palette ); + } + + fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */ } -/* - * Return a texture image to Mesa. This is either to satisfy - * a glGetTexImage() call or to prepare for software texturing. - */ -GLvoid * -tdfxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level, - const struct gl_texture_object *texObj, - GLenum * formatOut, GLenum * typeOut, - GLboolean * freeImageOut) -{ - tdfxTexInfo *ti; - tdfxMipMapLevel *mml; - - if (target != GL_TEXTURE_2D) - return NULL; - - if (!texObj->DriverData) - return NULL; - - ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[level]; - if (mml->data) { - MesaIntTexFormat mesaFormat; - GLenum glFormat; - struct gl_texture_image *texImage = texObj->Image[level]; - GLint srcStride; - void *uncompressedImage = NULL; - - GLubyte *data = - (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4); - if (!data) - return NULL; - - uncompressedImage = (void *)mml->data; - switch (mml->glideFormat) { - case GR_TEXFMT_INTENSITY_8: - mesaFormat = MESA_I8; - glFormat = GL_INTENSITY; - srcStride = mml->width; - break; - case GR_TEXFMT_ALPHA_INTENSITY_88: - mesaFormat = MESA_A8_L8; - glFormat = GL_LUMINANCE_ALPHA; - srcStride = mml->width; - break; - case GR_TEXFMT_ALPHA_8: - if (texImage->Format == GL_INTENSITY) { - mesaFormat = MESA_I8; - glFormat = GL_INTENSITY; - } - else { - mesaFormat = MESA_A8; - glFormat = GL_ALPHA; - } - srcStride = mml->width; - break; - case GR_TEXFMT_RGB_565: - mesaFormat = MESA_R5_G6_B5; - glFormat = GL_RGB; - srcStride = mml->width * 2; - break; - case GR_TEXFMT_ARGB_8888: - mesaFormat = MESA_A8_R8_G8_B8; - glFormat = GL_RGBA; - srcStride = mml->width * 4; - break; - case GR_TEXFMT_ARGB_4444: - mesaFormat = MESA_A4_R4_G4_B4; - glFormat = GL_RGBA; - srcStride = mml->width * 2; - break; - case GR_TEXFMT_ARGB_1555: - mesaFormat = MESA_A1_R5_G5_B5; - glFormat = GL_RGBA; - srcStride = mml->width * 2; - break; - case GR_TEXFMT_P_8: - mesaFormat = MESA_C8; - glFormat = GL_COLOR_INDEX; - srcStride = mml->width; - break; - case GR_TEXFMT_ARGB_CMP_FXT1: - mesaFormat = MESA_A8_R8_G8_B8; - glFormat = GL_RGBA; - srcStride = mml->width * 4; - /* - * Allocate data for the uncompressed image, - * decompress the image. The data will be deallocated - * after it is converted to the mesa format. - */ - uncompressedImage = MALLOC(mml->width * mml->height * 4); - if (!uncompressedImage) { - gl_problem(NULL, "can't get memory in tdfxDDGetTexImage"); - return NULL; - } - (*txImgDequantizeFXT1Proc)((FxU32 *)uncompressedImage, - (FxU32 *)mml->data, - mml->width, - mml->height); - break; - default: - gl_problem(NULL, "Bad glideFormat in tdfxDDGetTexImage"); - return NULL; - } - _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, - uncompressedImage, srcStride, texImage->Width, - texImage->Height, glFormat, data); - if (uncompressedImage != mml->data) { - FREE(uncompressedImage); - } - *formatOut = glFormat; - *typeOut = GL_UNSIGNED_BYTE; - *freeImageOut = GL_TRUE; - return data; - } - else { - return NULL; - } -} -/* - * This is called from _mesa_GetCompressedTexImage. We just - * copy out the compressed data. - */ -void -tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, - GLint lod, void *image, - const struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - tdfxTexInfo *ti; - tdfxMipMapLevel *mml; - if (target != GL_TEXTURE_2D) - return; +/**********************************************************************/ +/**** NEW TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ - if (!texObj->DriverData) - return; - ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[lod]; - if (mml->data) { - MEMCPY(image, mml->data, mml->dataSize); - } -} -/* - * Calculate a specific texture format given a generic - * texture format. - */ -GLint -tdfxDDSpecificCompressedTexFormat(GLcontext *ctx, - GLint internalFormat, - GLint numDimensions) +#if 0 +static void +PrintTexture(int w, int h, int c, const GLubyte * data) { - if (numDimensions != 2) { - return internalFormat; - } - /* - * If we don't have pointers to the functions, then - * we drop back to uncompressed format. The logic - * in Mesa proper handles this for us. - * - * This is just to ease the transition to a Glide with - * the texus2 library. - */ - if (!txImgQuantizeProc || !txImgDequantizeFXT1Proc) { - return internalFormat; - } - switch (internalFormat) { - case GL_COMPRESSED_RGB_ARB: - return GL_COMPRESSED_RGB_FXT1_3DFX; - case GL_COMPRESSED_RGBA_ARB: - return GL_COMPRESSED_RGBA_FXT1_3DFX; - } - return internalFormat; + int i, j; + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + if (c == 2) + printf("%02x %02x ", data[0], data[1]); + else if (c == 3) + printf("%02x %02x %02x ", data[0], data[1], data[2]); + data += c; + } + printf("\n"); + } } +#endif -/* - * Calculate a specific texture format given a generic - * texture format. - */ -GLint -tdfxDDBaseCompressedTexFormat(GLcontext *ctx, - GLint internalFormat) + +static GLboolean +tdfxDDTestProxyTexImage( GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLint width, GLint height, + GLint depth, GLint border ) { - switch (internalFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - return GL_RGB; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return GL_RGBA; - } - return -1; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + + switch (target) { + case GL_PROXY_TEXTURE_1D: + return GL_TRUE; /* software rendering */ + case GL_PROXY_TEXTURE_2D: + { + struct gl_texture_object *tObj; + tdfxTexObjPtr t; + int memNeeded; + + tObj = ctx->Texture.Proxy2D; + if (!tObj->DriverData) + tObj->DriverData = tdfxAllocTexObj(fxMesa); + t = TDFX_TEXTURE_DATA(tObj); + + /* assign the parameters to test against */ + tObj->Image[level]->Width = width; + tObj->Image[level]->Height = height; + tObj->Image[level]->Border = border; + tObj->Image[level]->IntFormat = internalFormat; + if (level == 0) { + /* don't use mipmap levels > 0 */ + tObj->MinFilter = tObj->MagFilter = GL_NEAREST; + } + else { + /* test with all mipmap levels */ + tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR; + tObj->MagFilter = GL_NEAREST; + } + tdfxRevalidateTexture(ctx, tObj); + + /* + printf("small lodlog2 0x%x\n", t->info.smallLodLog2); + printf("large lodlog2 0x%x\n", t->info.largeLodLog2); + printf("aspect ratio 0x%x\n", t->info.aspectRatioLog2); + printf("glide format 0x%x\n", t->info.format); + printf("data %p\n", t->info.data); + printf("lodblend %d\n", (int) t->LODblend); + */ + + /* determine where texture will reside */ + if (t->LODblend && !tss->umaTexMemory) { + /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ + memNeeded = FX_grTexTextureMemRequired_NoLock( + GR_MIPMAPLEVELMASK_BOTH, &(t->info)); + } + else { + /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ + memNeeded = FX_grTexTextureMemRequired_NoLock( + GR_MIPMAPLEVELMASK_BOTH, &(t->info)); + } + /* + printf("Proxy test %d > %d\n", memNeeded, tss->totalTexMem[0]); + */ + if (memNeeded > tss->totalTexMem[0]) + return GL_FALSE; + else + return GL_TRUE; + } + case GL_PROXY_TEXTURE_3D: + return GL_TRUE; /* software rendering */ + default: + return GL_TRUE; /* never happens, silence compiler */ + } } -/* - * Tell us if an image is compressed. The real work is done - * in a macro, but we need to have a function to create a - * function pointer. + +/* Return a texture image to Mesa. This is either to satisfy + * a glGetTexImage() call or to prepare for software texturing. */ -GLboolean -tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat) +static GLvoid * +tdfxDDGetTexImage( GLcontext *ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum *formatOut, GLenum *typeOut, + GLboolean *freeImageOut ) { - return tdfxDDIsCompressedFormatMacro(internalFormat); + const struct gl_texture_image *texImage = texObj->Image[level]; + const struct gl_texture_format *texFormat = texImage->TexFormat; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); + tdfxTexImagePtr image; + GLubyte *data; + + if ( target != GL_TEXTURE_2D ) + return NULL; + if ( !t ) + return NULL; + + image = &t->image[level]; + if ( !image->original.data ) + return NULL; + + data = (GLubyte *) MALLOC( texImage->Width * texImage->Height * 4 ); + if ( !data ) + return NULL; + + _mesa_unconvert_teximage2d( texFormat->IntFormat, texImage->Format, + texImage->Width, texImage->Height, + image->original.data, data ); + + *formatOut = texImage->Format; + *typeOut = GL_UNSIGNED_BYTE; + *freeImageOut = GL_TRUE; + + return data; } -/* - * Calculate the image size of a compressed texture. - * - * The current compressed format, the FXT1 family, all - * map 8x32 texel blocks into 128 bits. - * - * We return 0 if we can't calculate the size. - * - * Glide would report this out to us, but we don't have - * exactly the right parameters. - */ -GLsizei -tdfxDDCompressedImageSize(GLcontext *ctx, - GLenum intFormat, - GLuint numDimensions, - GLuint width, - GLuint height, - GLuint depth) +void tdfxDDInitTextureFuncs( GLcontext *ctx ) { - if (numDimensions != 2) { - return 0; - } - switch (intFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - /* - * Round height and width to multiples of 4 and 8, - * divide the resulting product by 32 to get the number - * of blocks, and multiply by 32 = 128/8 to get the. - * number of bytes required. That is to say, just - * return the product. Remember that we are returning - * bytes, not texels, so we have shrunk the texture - * by a factor of the texel size. - */ - width = (width + 0x7) &~ 0x7; - height = (height + 0x3) &~ 0x3; - return width * height; - } - return 0; + ctx->Driver.TexImage2D = tdfxDDTexImage2D; + ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D; + ctx->Driver.GetTexImage = tdfxDDGetTexImage; + ctx->Driver.TexEnv = tdfxDDTexEnv; + ctx->Driver.TexParameter = tdfxDDTexParameter; + ctx->Driver.BindTexture = tdfxDDBindTexture; + ctx->Driver.DeleteTexture = tdfxDDDeleteTexture; + ctx->Driver.IsTextureResident = tdfxDDIsTextureResident; + ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h index 95ef3b018..1132f3f35 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h @@ -35,123 +35,12 @@ * */ -#ifndef _TDFX_TEX_H_ -#define _TDFX_TEX_H_ +#ifndef __TDFX_TEX_H__ +#define __TDFX_TEX_H__ +extern void tdfxUpdateTextureState( GLcontext *ctx ); +extern void tdfxUpdateTextureBinding( GLcontext *ctx ); -#include "texutil.h" - - -#define tdfxDDIsCompressedFormatMacro(internalFormat) \ - (((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) || \ - ((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX)) -#define tdfxDDIsCompressedGlideFormatMacro(internalFormat) \ - ((internalFormat) == GR_TEXFMT_ARGB_CMP_FXT1) - - - -extern void -tdfxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj); - -extern void -tdfxDDBindTexture(GLcontext * ctx, GLenum target, - struct gl_texture_object *tObj); - -extern void -tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj); - -extern GLboolean -tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj); - -extern void -tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj); - -#if 000 /* DEAD? */ -extern void -fxDDTexUseGlobalPalette(GLcontext * ctx, GLboolean state); -#endif - -extern void -tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, - const GLfloat * param); - -extern void -tdfxDDTexParameter(GLcontext * ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat * params); - -extern GLboolean -tdfxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib * packing, - struct gl_texture_object * texObj, - struct gl_texture_image * texImage, - GLboolean * retainInternalCopy); - -extern GLboolean -tdfxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib * packing, - struct gl_texture_object * texObj, - struct gl_texture_image * texImage); - -extern GLboolean -tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, - GLint level, GLsizei imageSize, - const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - GLboolean *retainInternalCopy); - -extern GLboolean -tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLint height, GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ); - -extern GLboolean -tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target, - GLint level, GLint internalFormat, - GLenum format, GLenum type, - GLint width, GLint height, - GLint depth, GLint border); - -extern GLvoid * -tdfxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level, - const struct gl_texture_object *texObj, - GLenum * formatOut, GLenum * typeOut, - GLboolean * freeImageOut); - -extern void -tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, - GLint lod, void *image, - const struct gl_texture_object *texObj, - struct gl_texture_image *texImage ); - -extern GLint -tdfxDDSpecificCompressedTexFormat(GLcontext *ctx, - GLint internalFormat, - GLint numDimensions); - -extern GLint -tdfxDDBaseCompressedTexFormat(GLcontext *ctx, - GLint internalFormat); - -extern GLboolean -tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat); - -extern GLsizei -tdfxDDCompressedImageSize(GLcontext *ctx, - GLenum intFormat, - GLuint numDimensions, - GLuint width, - GLuint height, - GLuint depth); - +extern void tdfxDDInitTextureFuncs( GLcontext *ctx ); #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c index 97fe9d4c6..8ca93f91a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c @@ -39,930 +39,882 @@ #include "tdfx_tex.h" #include "tdfx_texman.h" +#define BAD_ADDRESS ((FxU32) -1) -#define BAD_ADDRESS ((FxU32) -1) - - -#if 0 /* DEBUG use */ -/* - * Verify the consistancy of the texture memory manager. +/* Verify the consistancy of the texture memory manager. * This involves: * Traversing all texture objects and computing total memory used. * Traverse the free block list and computing total memory free. * Compare the total free and total used amounts to the total memory size. * Make various assertions about the results. */ -static void -VerifyFreeList(tdfxContextPtr fxMesa, FxU32 tmu) +static void tdfxTMVerifyFreeList( tdfxContextPtr fxMesa, FxU32 unit ) { - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *block; - int prevStart = -1, prevEnd = -1; - int totalFree = 0; - int numObj = 0, numRes = 0; - int totalUsed = 0; - - for (block = shared->tmFree[tmu]; block; block = block->next) { - assert( block->endAddr > 0 ); - assert( block->startAddr <= shared->totalTexMem[tmu] ); - assert( block->endAddr <= shared->totalTexMem[tmu] ); - assert( (int) block->startAddr > prevStart ); - assert( (int) block->startAddr >= prevEnd ); - prevStart = (int) block->startAddr; - prevEnd = (int) block->endAddr; - totalFree += (block->endAddr - block->startAddr); - } - assert(totalFree == shared->freeTexMem[tmu]); - - { - struct gl_texture_object *obj; - for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(obj); - numObj++; - if (ti) { - if (ti->isInTM) { - numRes++; - assert(ti->tm[0]); - if (ti->tm[tmu]) - totalUsed += (ti->tm[tmu]->endAddr - ti->tm[tmu]->startAddr); - } - else { - assert(!ti->tm[0]); - } - } - } - } - - printf("totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n", - shared->freeTexMem[tmu], totalUsed, shared->totalTexMem[tmu], - numObj, numRes); - - assert(totalUsed + totalFree == shared->totalTexMem[tmu]); -} + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + struct gl_texture_object *texObj; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + tdfxMemRange *block; + int prevStart = -1, prevEnd = -1; + int totalFree = 0; + int numObj = 0, numRes = 0; + int totalUsed = 0; + + for ( block = tss->freeRanges[unit] ; block ; block = block->next ) { + assert( block->endAddr > 0 ); + assert( block->startAddr <= tss->totalTexMem[unit] ); + assert( block->endAddr <= tss->totalTexMem[unit] ); + assert( (int) block->startAddr > prevStart ); + assert( (int) block->startAddr >= prevEnd ); + prevStart = (int) block->startAddr; + prevEnd = (int) block->endAddr; + totalFree += (block->endAddr - block->startAddr); + } + assert( totalFree == tss->freeTexMem[unit] ); + + for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) { + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); + numObj++; + if ( t ) { + if ( t->isInTM ) { + numRes++; + assert( t->range[0] ); + if ( t->range[unit] ) + totalUsed += (t->range[unit]->endAddr - t->range[unit]->startAddr); + } else { + assert(!t->range[0]); + } + } + } + fprintf( stderr, + "totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n", + tss->freeTexMem[unit], totalUsed, tss->totalTexMem[unit], + numObj, numRes ); + + assert( totalUsed + totalFree == tss->totalTexMem[unit] ); +} -static void -dump_texmem(tdfxContextPtr fxMesa) +static void tdfxTMDumpTexMem( tdfxContextPtr fxMesa ) { - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj; - tdfxMemRange *r; - FxU32 prev; - - printf("DUMP Objects:\n"); - for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { - tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); - - if (info && info->isInTM) { - printf("Obj %8p: %4d info = %p\n", obj, obj->Name, info); - - printf(" isInTM=%d whichTMU=%d lastTimeUsed=%d\n", - info->isInTM, info->whichTMU, info->lastTimeUsed); - printf(" tm[0] = %p", info->tm[0]); - assert(info->tm[0]); - if (info->tm[0]) { - printf(" tm startAddr = %d endAddr = %d", - info->tm[0]->startAddr, - info->tm[0]->endAddr); - } - printf("\n"); - printf(" tm[1] = %p", info->tm[1]); - if (info->tm[1]) { - printf(" tm startAddr = %d endAddr = %d", - info->tm[1]->startAddr, - info->tm[1]->endAddr); - } - printf("\n"); - } - } - - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - - printf("Free memory unit 0: %d bytes\n", shared->freeTexMem[0]); - prev = 0; - for (r = shared->tmFree[0]; r; r = r->next) { - printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); - prev = r->endAddr; - } - - printf("Free memory unit 1: %d bytes\n", shared->freeTexMem[1]); - prev = 0; - for (r = shared->tmFree[1]; r; r = r->next) { - printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); - prev = r->endAddr; - } + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + struct gl_texture_object *texObj; + tdfxMemRange *r; + FxU32 prev; + + printf( "DUMP Objects:\n" ); + for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) { + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); + + if ( t && t->isInTM ) { + printf( "Obj %8p: %4d info = %p\n", texObj, texObj->Name, t ); + + printf( " isInTM=%d whichTMU=%ld lastTimeUsed=%d\n", + t->isInTM, t->whichTMU, t->lastTimeUsed ); + printf( " tm[0] = %p", t->range[0] ); + assert( t->range[0] ); + if ( t->range[0] ) { + printf( " tm startAddr = %ld endAddr = %ld", + t->range[0]->startAddr, + t->range[0]->endAddr ); + } + printf( "\n" ); + printf( " tm[1] = %p", t->range[1] ); + if ( t->range[1] ) { + printf( " tm startAddr = %ld endAddr = %ld", + t->range[1]->startAddr, + t->range[1]->endAddr ); + } + printf( "\n" ); + } + } -} -#endif + tdfxTMVerifyFreeList( fxMesa, 0 ); + tdfxTMVerifyFreeList( fxMesa, 1 ); + + printf( "Free memory unit 0: %d bytes\n", tss->freeTexMem[0] ); + prev = 0; + for ( r = tss->freeRanges[0] ; r ; r = r->next ) { + printf( "%8p: start %8ld end %8ld size %8ld gap %8ld\n", + r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, + r->startAddr - prev ); + prev = r->endAddr; + } + printf( "Free memory unit 1: %d bytes\n", tss->freeTexMem[1] ); + prev = 0; + for ( r = tss->freeRanges[1] ; r ; r = r->next ) { + printf( "%8p: start %8ld end %8ld size %8ld gap %8ld\n", + r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, + r->startAddr - prev ); + prev = r->endAddr; + } +} #ifdef TEXSANITY -static void -fubar(void) +static void fubar( void ) { + /* GH: What am I meant to do??? */ } -/* - * Sanity Check +/* Sanity Check */ -static void -sanity(tdfxContextPtr fxMesa) +static void sanity( tdfxContextPtr fxMesa ) { - tdfxMemRange *tmp, *prev, *pos; - - prev = 0; - tmp = fxMesa->tmFree[0]; - while (tmp) { - if (!tmp->startAddr && !tmp->endAddr) { - fprintf(stderr, "Textures fubar\n"); - fubar(); - } - if (tmp->startAddr >= tmp->endAddr) { - fprintf(stderr, "Node fubar\n"); - fubar(); - } - if (prev && (prev->startAddr >= tmp->startAddr || - prev->endAddr > tmp->startAddr)) { - fprintf(stderr, "Sorting fubar\n"); - fubar(); - } - prev = tmp; - tmp = tmp->next; - } - prev = 0; - tmp = fxMesa->tmFree[1]; - while (tmp) { - if (!tmp->startAddr && !tmp->endAddr) { - fprintf(stderr, "Textures fubar\n"); - fubar(); - } - if (tmp->startAddr >= tmp->endAddr) { - fprintf(stderr, "Node fubar\n"); - fubar(); - } - if (prev && (prev->startAddr >= tmp->startAddr || - prev->endAddr > tmp->startAddr)) { - fprintf(stderr, "Sorting fubar\n"); - fubar(); - } - prev = tmp; - tmp = tmp->next; - } + tdfxMemRange *tmp, *prev, *pos; + + prev = 0; + tmp = fxMesa->freeRanges[0]; + while ( tmp ) { + if ( !tmp->startAddr && !tmp->endAddr ) { + fprintf( stderr, "Textures fubar\n" ); + fubar(); + } + if ( tmp->startAddr >= tmp->endAddr ) { + fprintf( stderr, "Node fubar\n" ); + fubar(); + } + if ( prev && ( prev->startAddr >= tmp->startAddr || + prev->endAddr > tmp->startAddr ) ) { + fprintf( stderr, "Sorting fubar\n" ); + fubar(); + } + prev = tmp; + tmp = tmp->next; + } + + prev = 0; + tmp = fxMesa->freeRanges[1]; + while ( tmp ) { + if ( !tmp->startAddr && !tmp->endAddr ) { + fprintf( stderr, "Textures fubar\n" ); + fubar(); + } + if ( tmp->startAddr >= tmp->endAddr ) { + fprintf( stderr, "Node fubar\n" ); + fubar(); + } + if ( prev && ( prev->startAddr >= tmp->startAddr || + prev->endAddr > tmp->startAddr ) ) { + fprintf( stderr, "Sorting fubar\n" ); + fubar(); + } + prev = tmp; + tmp = tmp->next; + } } #endif - - - -/* - * Allocate and initialize a new MemRange struct. - * Try to allocate it from the pool of free MemRange nodes rather than malloc. +/* Allocate and initialize a new MemRange struct. Try to allocate it + * from the pool of free MemRange nodes rather than malloc. */ static tdfxMemRange * -NewRangeNode(tdfxContextPtr fxMesa, FxU32 start, FxU32 end) +tdfxTMNewRangeNode( tdfxContextPtr fxMesa, FxU32 start, FxU32 end ) { - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *result; - - _glthread_LOCK_MUTEX(mesaShared->Mutex); - if (shared && shared->tmPool) { - result = shared->tmPool; - shared->tmPool = shared->tmPool->next; - } - else { - result = MALLOC(sizeof(tdfxMemRange)); - - } - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - - if (!result) { - /*fprintf(stderr, "fxDriver: out of memory!\n");*/ - return NULL; - } - - result->startAddr = start; - result->endAddr = end; - result->next = NULL; - - return result; + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + tdfxMemRange *range; + + _glthread_LOCK_MUTEX( ss->Mutex ); + if ( tss && tss->rangePool ) { + range = tss->rangePool; + tss->rangePool = tss->rangePool->next; + } else { + range = MALLOC( sizeof(tdfxMemRange) ); + } + _glthread_UNLOCK_MUTEX( ss->Mutex ); + + if ( !range ) { + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, __FUNCTION__ ": out of memory!\n" ); + return NULL; + } + + range->startAddr = start; + range->endAddr = end; + range->next = NULL; + + return range; } -/* - * Initialize texture memory. - * We take care of one or both TMU's here. +/* Initialize texture memory. We take care of one or both TMU's here. */ -void -tdfxTMInit(tdfxContextPtr fxMesa) +void tdfxTMInit( tdfxContextPtr fxMesa ) { - if (!fxMesa->glCtx->Shared->DriverData) { - const char *extensions; - struct tdfxSharedState *shared = CALLOC_STRUCT(tdfxSharedState); - if (!shared) - return; - - extensions = FX_grGetString(fxMesa, GR_EXTENSION); - if (strstr(extensions, "TEXUMA")) { - FxU32 start, end; - shared->umaTexMemory = GL_TRUE; - FX_grEnable(fxMesa, GR_TEXTURE_UMA_EXT); - start = FX_grTexMinAddress(fxMesa, 0); - end = FX_grTexMaxAddress(fxMesa, 0); - shared->totalTexMem[0] = end - start; - shared->totalTexMem[1] = 0; - shared->freeTexMem[0] = end - start; - shared->freeTexMem[1] = 0; - shared->tmFree[0] = NewRangeNode(fxMesa, start, end); - shared->tmFree[1] = NULL; - /*printf("UMA tex memory: %d\n", (int) (end - start));*/ - } - else { - const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; - int tmu; - shared->umaTexMemory = GL_FALSE; - for (tmu = 0; tmu < numTMUs; tmu++) { - FxU32 start = FX_grTexMinAddress(fxMesa, tmu); - FxU32 end = FX_grTexMaxAddress(fxMesa, tmu); - shared->totalTexMem[tmu] = end - start; - shared->freeTexMem[tmu] = end - start; - shared->tmFree[tmu] = NewRangeNode(fxMesa, start, end); - /*printf("Split tex memory: %d\n", (int) (end - start));*/ - } - } - - shared->tmPool = NULL; - fxMesa->glCtx->Shared->DriverData = shared; - /*printf("Texture memory init UMA: %d\n", shared->umaTexMemory);*/ - } + GLcontext *ctx = fxMesa->glCtx; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, __FUNCTION__ "\n" ); + + if ( !ctx->Shared->DriverData ) { + const char *extensions; + tdfxSharedStatePtr tss = CALLOC_STRUCT( tdfx_shared_state ); + + if ( !tss ) + return; + + LOCK_HARDWARE( fxMesa ); + + extensions = grGetString( GR_EXTENSION ); + + if ( strstr( extensions, " TEXUMA " ) ) { + FxU32 start, end; + + tss->umaTexMemory = GL_TRUE; + + grEnable( GR_TEXTURE_UMA_EXT ); + + start = grTexMinAddress( 0 ); + end = grTexMaxAddress( 0 ); + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, " UMA tex memory: %d\n", (int)(end - start) ); + + tss->totalTexMem[0] = end - start; + tss->totalTexMem[1] = 0; + tss->freeTexMem[0] = end - start; + tss->freeTexMem[1] = 0; + tss->freeRanges[0] = tdfxTMNewRangeNode( fxMesa, start, end ); + tss->freeRanges[1] = NULL; + } else { + int unit; + + tss->umaTexMemory = GL_FALSE; + + for ( unit = 0 ; unit < fxMesa->numTMUs ; unit++ ) { + FxU32 start, end; + + start = grTexMinAddress( unit ); + end = grTexMaxAddress( unit ); + + tss->totalTexMem[unit] = end - start; + tss->freeTexMem[unit] = end - start; + tss->freeRanges[unit] = tdfxTMNewRangeNode( fxMesa, start, end ); + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, " Split tex memory: %d\n", + (int)(end - start) ); + } + } + + UNLOCK_HARDWARE( fxMesa ); + + tss->rangePool = NULL; + ctx->Shared->DriverData = tss; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, " init UMA: %d\n", tss->umaTexMemory ); + } } -/* - * Clean-up texture memory before destroying context. +/* Clean-up texture memory before destroying context. */ -void -tdfxTMClose(tdfxContextPtr fxMesa) +void tdfxTMClose( tdfxContextPtr fxMesa ) { - if (fxMesa->glCtx->Shared->RefCount == 1) { - /* refcount will soon go to zero, free our 3dfx stuff */ - struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData; - - const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; - int tmu; - tdfxMemRange *tmp, *next; - - /* Deallocate the pool of free tdfxMemRange nodes */ - tmp = shared->tmPool; - while (tmp) { - next = tmp->next; - FREE(tmp); - tmp = next; - } - - /* Delete the texture memory block tdfxMemRange nodes */ - for (tmu = 0; tmu < numTMUs; tmu++) { - tmp = shared->tmFree[tmu]; - while (tmp) { - next = tmp->next; - FREE(tmp); - tmp = next; - } - } - - FREE(shared); - fxMesa->glCtx->Shared->DriverData = NULL; - } -} + GLcontext *ctx = fxMesa->glCtx; + if ( ctx->Shared->RefCount == 1 ) { + /* RefCount will soon go to zero, free our 3dfx stuff */ + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ctx->Shared->DriverData; + int unit; + tdfxMemRange *tmp, *next; + + /* Deallocate the pool of free tdfxMemRange nodes */ + tmp = tss->rangePool; + while ( tmp ) { + next = tmp->next; + FREE( tmp ); + tmp = next; + } + /* Delete the texture memory block tdfxMemRange nodes */ + for ( unit = 0 ; unit < fxMesa->numTMUs ; unit++ ) { + tmp = tss->freeRanges[unit]; + while ( tmp ) { + next = tmp->next; + FREE( tmp ); + tmp = next; + } + } -/* - * Delete a tdfxMemRange struct. - * We keep a linked list of free/available tdfxMemRange structs to - * avoid extra malloc/free calls. - */ -#if 0 -static void -DeleteRangeNode_NoLock(struct TdfxSharedState *shared, tdfxMemRange *range) -{ - /* insert at head of list */ - range->next = shared->tmPool; - shared->tmPool = range; + FREE( tss ); + ctx->Shared->DriverData = NULL; + } } -#endif -#define DELETE_RANGE_NODE(shared, range) \ - (range)->next = (shared)->tmPool; \ - (shared)->tmPool = (range) +/* Delete a tdfxMemRange struct. + * We keep a linked list of free/available tdfxMemRange structs to + * avoid extra malloc/free calls. + */ +#define DELETE_RANGE_NODE( tss, range ) \ +do { \ + (range)->next = (tss)->rangePool; \ + (tss)->rangePool = (range); \ +} while (0) -/* - * When we've run out of texture memory we have to throw out an +/* When we've run out of texture memory we have to throw out an * existing texture to make room for the new one. This function * determins the texture to throw out. */ static struct gl_texture_object * -FindOldestObject(tdfxContextPtr fxMesa, FxU32 tmu) +tdfxTMFindOldestObject( tdfxContextPtr fxMesa, FxU32 unit ) { - const GLuint bindnumber = fxMesa->texBindNumber; - struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj; - GLfloat lowestPriority; - GLuint oldestAge; - - oldestObj = NULL; - oldestAge = 0; - - lowestPriority = 1.0F; - lowestPriorityObj = NULL; - - for (obj = fxMesa->glCtx->Shared->TexObjectList; obj; obj = obj->Next) { - tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); - - if (info && info->isInTM && - ((info->whichTMU == tmu) || (info->whichTMU == TDFX_TMU_BOTH) || - (info->whichTMU == TDFX_TMU_SPLIT))) { - GLuint age, lasttime; - - assert(info->tm[0]); - lasttime = info->lastTimeUsed; - - if (lasttime > bindnumber) - age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */ - else - age = bindnumber - lasttime; - - if (age >= oldestAge) { - oldestAge = age; - oldestObj = obj; - } - - /* examine priority */ - if (obj->Priority < lowestPriority) { - lowestPriority = obj->Priority; - lowestPriorityObj = obj; - } - } - } - - if (lowestPriority < 1.0) { - ASSERT(lowestPriorityObj); - /* - printf("discard %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); - */ - return lowestPriorityObj; - } - else { - /* - printf("discard %d age=%d\n", oldestObj->Name, oldestAge); - */ - return oldestObj; - } -} + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + const GLuint bindNumber = fxMesa->texBindNumber; + struct gl_texture_object *oldestObj, *texObj, *lowestPriorityObj; + GLfloat lowestPriority; + GLuint oldestAge; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, __FUNCTION__ "\n" ); + + oldestObj = NULL; + oldestAge = 0; + + lowestPriority = 1.0F; + lowestPriorityObj = NULL; + + for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) { + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); + + if ( t && t->isInTM && + ( ( t->whichTMU == unit ) || + ( t->whichTMU == TDFX_TMU_BOTH ) || + ( t->whichTMU == TDFX_TMU_SPLIT ) ) ) { + GLuint age, lastTime; + + assert( t->range[0] ); + lastTime = t->lastTimeUsed; + + if ( lastTime > bindNumber ) { + /* TODO: check wrap around */ + age = bindNumber + (UINT_MAX - lastTime + 1); + } else { + age = bindNumber - lastTime; + } + if ( age >= oldestAge ) { + oldestAge = age; + oldestObj = texObj; + } + /* examine priority */ + if ( texObj->Priority < lowestPriority ) { + lowestPriority = texObj->Priority; + lowestPriorityObj = texObj; + } + } + } -#if 0 -static void -FlushTexMemory(tdfxContextPtr fxMesa) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - struct gl_texture_object *obj; - - for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { - if (obj->RefCount < 2) { - /* don't flush currently bound textures */ - tdfxTMMoveOutTM_NoLock(fxMesa, obj); - } - } + if ( lowestPriority < 1.0 ) { + ASSERT( lowestPriorityObj ); + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, "discard %d pri=%f\n", + lowestPriorityObj->Name, lowestPriority ); + return lowestPriorityObj; + } else { + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf( stderr, "discard %d age=%d\n", + oldestObj->Name, oldestAge ); + return oldestObj; + } } -#endif -/* - * Find the address (offset?) at which we can store a new texture. - * <tmu> is the texture unit. +/* Find the address (offset?) at which we can store a new texture. + * <unit> is the texture unit. * <size> is the texture size in bytes. */ -static FxU32 -FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size) +static FxU32 tdfxTMFindStartAddr( tdfxContextPtr fxMesa, + FxU32 unit, FxU32 size ) { - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *prev, *block; - FxU32 result; -#if 0 - int discardedCount = 0; -#define MAX_DISCARDS 10 -#endif + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + struct gl_texture_object *texObj; + tdfxMemRange *prev, *block; + FxU32 result; + + if ( tss->umaTexMemory ) { + assert( unit == TDFX_TMU0 ); + } - if (shared->umaTexMemory) { - assert(tmu == TDFX_TMU0); - } - - _glthread_LOCK_MUTEX(mesaShared->Mutex); - while (1) { - prev = NULL; - block = shared->tmFree[tmu]; - while (block) { - if (block->endAddr - block->startAddr >= size) { - /* The texture will fit here */ - result = block->startAddr; - block->startAddr += size; - if (block->startAddr == block->endAddr) { - /* Remove this node since it's empty */ - if (prev) { - prev->next = block->next; - } - else { - shared->tmFree[tmu] = block->next; - } - DELETE_RANGE_NODE(shared, block); - } - shared->freeTexMem[tmu] -= size; - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return result; - } - prev = block; - block = block->next; - } - /* We failed to find a block large enough to accomodate <size> bytes. - * Find the oldest texObject and free it. - */ -#if 0 - discardedCount++; - if (discardedCount > MAX_DISCARDS + 1) { - gl_problem(NULL, "tdfx driver: extreme texmem fragmentation"); - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return BAD_ADDRESS; - } - else if (discardedCount > MAX_DISCARDS) { - /* texture memory is probably really fragmented, flush it */ - FlushTexMemory(fxMesa); - } - else -#endif - { - struct gl_texture_object *obj = FindOldestObject(fxMesa, tmu); - if (obj) { - tdfxTMMoveOutTM_NoLock(fxMesa, obj); - fxMesa->stats.texSwaps++; - } - else { - gl_problem(NULL, "tdfx driver: extreme texmem fragmentation"); - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return BAD_ADDRESS; - } - } - } - - /* never get here, but play it safe */ - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return BAD_ADDRESS; + _glthread_LOCK_MUTEX( ss->Mutex ); + while ( 1 ) { + prev = NULL; + block = tss->freeRanges[unit]; + + while ( block ) { + if ( block->endAddr - block->startAddr >= size ) { + /* The texture will fit here */ + result = block->startAddr; + block->startAddr += size; + if ( block->startAddr == block->endAddr ) { + /* Remove this node since it's empty */ + if ( prev ) { + prev->next = block->next; + } else { + tss->freeRanges[unit] = block->next; + } + DELETE_RANGE_NODE( tss, block ); + } + tss->freeTexMem[unit] -= size; + _glthread_UNLOCK_MUTEX( ss->Mutex ); + return result; + } + prev = block; + block = block->next; + } + + /* We failed to find a block large enough to accomodate <size> bytes. + * Find the oldest texObject and free it. + */ + texObj = tdfxTMFindOldestObject( fxMesa, unit ); + if ( texObj ) { + tdfxTMMoveOutTMLocked( fxMesa, texObj ); + fxMesa->stats.texSwaps++; + } else { + gl_problem( NULL, "tdfx driver: extreme texmem fragmentation" ); + _glthread_UNLOCK_MUTEX( ss->Mutex ); + return BAD_ADDRESS; + } + } + + /* never get here, but play it safe */ + _glthread_UNLOCK_MUTEX( ss->Mutex ); + return BAD_ADDRESS; } -/* - * Remove the given tdfxMemRange node from hardware texture memory. +/* Remove the given tdfxMemRange node from hardware texture memory. */ -static void -RemoveRange_NoLock(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) +static void tdfxTMRemoveRangeLocked( tdfxContextPtr fxMesa, + FxU32 unit, tdfxMemRange *range ) { - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *block, *prev; - - if (shared->umaTexMemory) { - assert(tmu == TDFX_TMU0); - } - - if (!range) - return; - - if (range->startAddr == range->endAddr) { - DELETE_RANGE_NODE(shared, range); - return; - } - shared->freeTexMem[tmu] += range->endAddr - range->startAddr; - - /* find position in linked list to insert this tdfxMemRange node */ - prev = NULL; - block = shared->tmFree[tmu]; - while (block) { - assert(range->startAddr != block->startAddr); - if (range->startAddr > block->startAddr) { - prev = block; - block = block->next; - } - else { - break; - } - } - - /* Insert the free block, combine with adjacent blocks when possible */ - range->next = block; - if (block) { - if (range->endAddr == block->startAddr) { - /* Combine */ - block->startAddr = range->startAddr; - DELETE_RANGE_NODE(shared, range); - range = block; - } - } - if (prev) { - if (prev->endAddr == range->startAddr) { - /* Combine */ - prev->endAddr = range->endAddr; - prev->next = range->next; - DELETE_RANGE_NODE(shared, range); - } - else { - prev->next = range; - } - } - else { - shared->tmFree[tmu] = range; - } -} + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + tdfxMemRange *block, *prev; + if ( tss->umaTexMemory ) { + assert( unit == TDFX_TMU0 ); + } -#if 0 /* NOT USED */ -static void -RemoveRange(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - _glthread_LOCK_MUTEX(mesaShared->Mutex); - RemoveRange_NoLock(fxMesa, tmu, range); - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); + if ( !range ) + return; + + if ( range->startAddr == range->endAddr ) { + DELETE_RANGE_NODE( tss, range ); + return; + } + tss->freeTexMem[unit] += range->endAddr - range->startAddr; + + /* find position in linked list to insert this tdfxMemRange node */ + prev = NULL; + block = tss->freeRanges[unit]; + while ( block ) { + assert( range->startAddr != block->startAddr ); + if ( range->startAddr > block->startAddr ) { + prev = block; + block = block->next; + } else { + break; + } + } + + /* Insert the free block, combine with adjacent blocks when possible */ + range->next = block; + if ( block ) { + if ( range->endAddr == block->startAddr ) { + /* Combine */ + block->startAddr = range->startAddr; + DELETE_RANGE_NODE( tss, range ); + range = block; + } + } + if ( prev ) { + if ( prev->endAddr == range->startAddr ) { + /* Combine */ + prev->endAddr = range->endAddr; + prev->next = range->next; + DELETE_RANGE_NODE( tss, range ); + } else { + prev->next = range; + } + } else { + tss->freeRanges[unit] = range; + } } -#endif -/* - * Allocate space for a texture image. +/* Allocate space for a texture image. * <tmu> is the texture unit * <texmemsize> is the number of bytes to allocate */ static tdfxMemRange * -AllocTexMem(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 texmemsize) +tdfxTMAllocTexMem( tdfxContextPtr fxMesa, FxU32 unit, FxU32 size ) { - FxU32 startAddr; - startAddr = FindStartAddr(fxMesa, tmu, texmemsize); - if (startAddr == BAD_ADDRESS) { - printf("AllocTexMem returned NULL! tmu=%d texmemsize=%d\n", - tmu, texmemsize); - return NULL; - } - else { - tdfxMemRange *range; - range = NewRangeNode(fxMesa, startAddr, startAddr + texmemsize); - return range; - } + tdfxMemRange *range = NULL; + FxU32 start; + + start = tdfxTMFindStartAddr( fxMesa, unit, size ); + + if ( start != BAD_ADDRESS ) { + range = tdfxTMNewRangeNode( fxMesa, start, start + size ); + } else { + fprintf( stderr, + "tdfxTMAllocTexMem returned NULL! unit=%ld size=%ld\n", + unit, size ); + } + return range; } -/* - * Download (copy) the given texture data (all mipmap levels) into the - * Voodoo's texture memory. - * The texture memory must have already been allocated. +/* Download (copy) the given texture data (all mipmap levels) into the + * Voodoo's texture memory. The texture memory must have already been + * allocated. */ -void -tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) +void tdfxTMDownloadTextureLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ) { - tdfxTexInfo *ti; - GLint l; - FxU32 targetTMU; - - assert(tObj); - ti = TDFX_TEXTURE_DATA(tObj); - assert(ti); - targetTMU = ti->whichTMU; - - switch (targetTMU) { - case TDFX_TMU0: - case TDFX_TMU1: - if (ti->tm[targetTMU]) { - for (l = ti->minLevel; l <= ti->maxLevel - && ti->mipmapLevel[l].data; l++) { - GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; - FX_grTexDownloadMipMapLevel_NoLock(targetTMU, - ti->tm[targetTMU]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[l].data); - } - } - break; - case TDFX_TMU_SPLIT: - if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { - for (l = ti->minLevel; l <= ti->maxLevel - && ti->mipmapLevel[l].data; l++) { - GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, - ti->tm[TDFX_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_ODD, - ti->mipmapLevel[l].data); - - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, - ti->tm[TDFX_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_EVEN, - ti->mipmapLevel[l].data); - } - } - break; - case TDFX_TMU_BOTH: - if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { - for (l = ti->minLevel; l <= ti->maxLevel - && ti->mipmapLevel[l].data; l++) { - GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, - ti->tm[TDFX_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[l].data); - - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, - ti->tm[TDFX_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[l].data); - } - } - break; - default: - gl_problem(NULL, "error in tdfxTMDownloadTexture: bad tmu"); - return; - } + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + FxU32 targetTMU; + GLint l; + + assert( tObj ); + assert( t ); + + targetTMU = t->whichTMU; + + switch ( targetTMU ) { + case TDFX_TMU0: + case TDFX_TMU1: + if ( t->range[targetTMU] ) { + for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) { + GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel; + + grTexDownloadMipMapLevel( targetTMU, + t->range[targetTMU]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_BOTH, + t->image[l].data ); + } + } + break; + + case TDFX_TMU_SPLIT: + if ( t->range[TDFX_TMU0] && t->range[TDFX_TMU1] ) { + for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) { + GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel; + + grTexDownloadMipMapLevel( GR_TMU0, + t->range[TDFX_TMU0]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_ODD, + t->image[l].data ); + + grTexDownloadMipMapLevel( GR_TMU1, + t->range[TDFX_TMU1]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_EVEN, + t->image[l].data ); + } + } + break; + + case TDFX_TMU_BOTH: + if ( t->range[TDFX_TMU0] && t->range[TDFX_TMU1] ) { + for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) { + GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel; + + grTexDownloadMipMapLevel( GR_TMU0, + t->range[TDFX_TMU0]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_BOTH, + t->image[l].data ); + + grTexDownloadMipMapLevel( GR_TMU1, + t->range[TDFX_TMU1]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_BOTH, + t->image[l].data ); + } + } + break; + + default: + gl_problem( NULL, "error in tdfxTMDownloadTexture: bad unit" ); + return; + } } -void -tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj, - GLint level) +void tdfxTMReloadMipMapLevelLocked( GLcontext *ctx, + struct gl_texture_object *tObj, + GLint level ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - GrLOD_t glideLod; - FxU32 tmu; - - tmu = ti->whichTMU; - glideLod = ti->info.largeLodLog2 - level + tObj->BaseLevel; - ASSERT(ti->isInTM); - - switch (tmu) { - case TDFX_TMU0: - case TDFX_TMU1: - FX_grTexDownloadMipMapLevel(fxMesa, tmu, - ti->tm[tmu]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[level].data); - break; - case TDFX_TMU_SPLIT: - FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU0, - ti->tm[GR_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_ODD, - ti->mipmapLevel[level].data); - - FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU1, - ti->tm[GR_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_EVEN, - ti->mipmapLevel[level].data); - break; - case TDFX_TMU_BOTH: - FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU0, - ti->tm[GR_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[level].data); - - FX_grTexDownloadMipMapLevel(fxMesa, GR_TMU1, - ti->tm[GR_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[level].data); - break; - - default: - gl_problem(ctx, "error in tdfxTMReloadMipMapLevel(): wrong tmu"); - break; - } + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + GrLOD_t glideLod; + FxU32 unit; + + ASSERT( t->isInTM ); + + unit = t->whichTMU; + glideLod = t->info.largeLodLog2 - level + tObj->BaseLevel; + + switch ( unit ) { + case TDFX_TMU0: + case TDFX_TMU1: + grTexDownloadMipMapLevel( unit, + t->range[unit]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_BOTH, + t->image[level].data ); + break; + + case TDFX_TMU_SPLIT: + grTexDownloadMipMapLevel( GR_TMU0, + t->range[GR_TMU0]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_ODD, + t->image[level].data ); + + grTexDownloadMipMapLevel( GR_TMU1, + t->range[GR_TMU1]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_EVEN, + t->image[level].data ); + break; + + case TDFX_TMU_BOTH: + grTexDownloadMipMapLevel( GR_TMU0, + t->range[GR_TMU0]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_BOTH, + t->image[level].data ); + + grTexDownloadMipMapLevel( GR_TMU1, + t->range[GR_TMU1]->startAddr, + glideLod, + t->info.largeLodLog2, + t->info.aspectRatioLog2, + t->info.format, + GR_MIPMAPLEVELMASK_BOTH, + t->image[level].data ); + break; + + default: + gl_problem( ctx, "error in tdfxTMReloadMipMapLevel(): wrong unit" ); + break; + } } -/* - * Allocate space for the given texture in texture memory then +/* Allocate space for the given texture in texture memory then * download (copy) it into that space. */ -void -tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj, - FxU32 targetTMU ) +void tdfxTMMoveInTMLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj, FxU32 targetTMU ) { - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - FxU32 texmemsize; - - fxMesa->stats.reqTexUpload++; - - if (ti->isInTM) { - if (ti->whichTMU == targetTMU) - return; - if (targetTMU == TDFX_TMU_SPLIT || ti->whichTMU == TDFX_TMU_SPLIT) { - tdfxTMMoveOutTM_NoLock(fxMesa, tObj); - } - else { - if (ti->whichTMU == TDFX_TMU_BOTH) - return; - targetTMU = TDFX_TMU_BOTH; - } - } - - ti->whichTMU = targetTMU; - - switch (targetTMU) { - case TDFX_TMU0: - case TDFX_TMU1: - texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); - ti->tm[targetTMU] = AllocTexMem(fxMesa, targetTMU, texmemsize); - break; - case TDFX_TMU_SPLIT: - texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, - &(ti->info)); - ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); - if (ti->tm[TDFX_TMU0]) - fxMesa->stats.memTexUpload += texmemsize; - - texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN, - &(ti->info)); - ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); - break; - case TDFX_TMU_BOTH: - texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); - ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); - if (ti->tm[TDFX_TMU0]) - fxMesa->stats.memTexUpload += texmemsize; - - texmemsize = FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); - ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); - break; - default: - gl_problem(NULL, "error in tdfxTMMoveInTM() -> bad tmu (%d)"); - return; - } - - ti->reloadImages = GL_TRUE; - ti->isInTM = GL_TRUE; - - fxMesa->stats.texUpload++; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + FxU32 size; + + fxMesa->stats.reqTexUpload++; + + if ( t->isInTM ) { + if ( t->whichTMU == targetTMU ) + return; + + if ( targetTMU == TDFX_TMU_SPLIT || t->whichTMU == TDFX_TMU_SPLIT ) { + tdfxTMMoveOutTMLocked( fxMesa, tObj ); + } else { + if ( t->whichTMU == TDFX_TMU_BOTH ) + return; + targetTMU = TDFX_TMU_BOTH; + } + } + + t->whichTMU = targetTMU; + + switch ( targetTMU ) { + case TDFX_TMU0: + case TDFX_TMU1: + size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); + t->range[targetTMU] = tdfxTMAllocTexMem(fxMesa, targetTMU, size); + break; + + case TDFX_TMU_SPLIT: + size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_ODD, &t->info ); + t->range[TDFX_TMU0] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU0, size ); + if ( t->range[TDFX_TMU0] ) + fxMesa->stats.memTexUpload += size; + + size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_EVEN, &t->info ); + t->range[TDFX_TMU1] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU1, size ); + break; + + case TDFX_TMU_BOTH: + size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); + t->range[TDFX_TMU0] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU0, size ); + if ( t->range[TDFX_TMU0] ) + fxMesa->stats.memTexUpload += size; + + size = grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); + t->range[TDFX_TMU1] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU1, size ); + break; + + default: + gl_problem( NULL, "error in tdfxTMMoveInTM() -> bad unit (%d)" ); + return; + } + + t->reloadImages = GL_TRUE; + t->isInTM = GL_TRUE; + + fxMesa->stats.texUpload++; } -/* - * Move the given texture out of hardware texture memory. +/* Move the given texture out of hardware texture memory. * This deallocates the texture's memory space. */ -void -tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj ) +void tdfxTMMoveOutTMLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ) { - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - - if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "fxmesa: fxTMMoveOutTM(%p (%d))\n", tObj, tObj->Name); - } - - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ - - if (!ti || !ti->isInTM) - return; - - switch (ti->whichTMU) { - case TDFX_TMU0: - case TDFX_TMU1: - RemoveRange_NoLock(fxMesa, ti->whichTMU, ti->tm[ti->whichTMU]); - break; - case TDFX_TMU_SPLIT: - case TDFX_TMU_BOTH: - assert(!shared->umaTexMemory); - RemoveRange_NoLock(fxMesa, TDFX_TMU0, ti->tm[TDFX_TMU0]); - RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]); - break; - default: - gl_problem(NULL, "tdfx driver: bad tmu in tdfxTMMOveOutTM()"); - return; - } - - ti->isInTM = GL_FALSE; - ti->tm[0] = NULL; - ti->tm[1] = NULL; - ti->whichTMU = TDFX_TMU_NONE; - - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ + struct gl_shared_state *ss = fxMesa->glCtx->Shared; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { + fprintf( stderr, __FUNCTION__ "( %p (%d) )\n", tObj, tObj->Name ); + tdfxTMVerifyFreeList( fxMesa, 0 ); + tdfxTMVerifyFreeList( fxMesa, 1 ); + } + + if ( !t || !t->isInTM ) + return; + + switch ( t->whichTMU ) { + case TDFX_TMU0: + case TDFX_TMU1: + tdfxTMRemoveRangeLocked( fxMesa, t->whichTMU, t->range[t->whichTMU] ); + break; + + case TDFX_TMU_SPLIT: + case TDFX_TMU_BOTH: + assert( !tss->umaTexMemory ); + tdfxTMRemoveRangeLocked( fxMesa, TDFX_TMU0, t->range[TDFX_TMU0] ); + tdfxTMRemoveRangeLocked( fxMesa, TDFX_TMU1, t->range[TDFX_TMU1] ); + break; + + default: + gl_problem( NULL, "tdfx driver: bad unit in tdfxTMMOveOutTM()" ); + return; + } + + t->isInTM = GL_FALSE; + t->range[0] = NULL; + t->range[1] = NULL; + t->whichTMU = TDFX_TMU_NONE; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { + tdfxTMVerifyFreeList( fxMesa, 0 ); + tdfxTMVerifyFreeList( fxMesa, 1 ); + } } -/* - * Called via glDeleteTexture to delete a texture object. - */ -void -tdfxTMFreeTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) +void tdfxTMFreeTextureLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ) { - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - if (ti) { - int i; - tdfxTMMoveOutTM(fxMesa, tObj); - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { - if (ti->mipmapLevel[i].data) { - FREE(ti->mipmapLevel[i].data); - ti->mipmapLevel[i].data = NULL; - } - } - FREE(ti); - tObj->DriverData = NULL; - } - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ -} + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); + + if ( t ) { + int i; + tdfxTMMoveOutTMLocked( fxMesa, tObj ); + for ( i = 0 ; i < MAX_TEXTURE_LEVELS ; i++ ) { + if ( t->image[i].original.data ) { + FREE( t->image[i].original.data ); + t->image[i].original.data = NULL; + t->image[i].original.width = 0; + t->image[i].original.height = 0; + t->image[i].original.size = 0; + } + if ( t->image[i].rescaled.data ) { + FREE( t->image[i].rescaled.data ); + t->image[i].rescaled.data = NULL; + t->image[i].rescaled.width = 0; + t->image[i].rescaled.height = 0; + t->image[i].rescaled.size = 0; + } + } + FREE( t ); + tObj->DriverData = NULL; + } + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { + tdfxTMVerifyFreeList( fxMesa, 0 ); + tdfxTMVerifyFreeList( fxMesa, 1 ); + } +} -/* - * After a context switch this function will be called to restore +/* After a context switch this function will be called to restore * texture memory for the new context. */ -void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ) +void tdfxTMRestoreTexturesLocked( tdfxContextPtr fxMesa ) { GLcontext *ctx = fxMesa->glCtx; struct gl_texture_object *tObj; int i; for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) { - tdfxTexInfo *ti = TDFX_TEXTURE_DATA( tObj ); - if ( ti && ti->isInTM ) { + tdfxTexObjPtr t = TDFX_TEXTURE_DATA( tObj ); + if ( t && t->isInTM ) { for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) { if ( ctx->Texture.Unit[i].Current == tObj ) { - tdfxTMDownloadTexture( fxMesa, tObj ); + tdfxTMDownloadTextureLocked( fxMesa, tObj ); break; } } if ( i == MAX_TEXTURE_UNITS ) { - tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); + tdfxTMMoveOutTMLocked( fxMesa, tObj ); } } } - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ + + if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { + tdfxTMVerifyFreeList( fxMesa, 0 ); + tdfxTMVerifyFreeList( fxMesa, 1 ); + } } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h index 1965aaa84..6979367a0 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h @@ -38,47 +38,39 @@ #ifndef __TDFX_TEXMAN_H__ #define __TDFX_TEXMAN_H__ - #include "tdfx_lock.h" - extern void tdfxTMInit( tdfxContextPtr fxMesa ); - extern void tdfxTMClose( tdfxContextPtr fxMesa ); -extern void tdfxTMDownloadTexture(tdfxContextPtr fxMesa, - struct gl_texture_object *tObj); - -extern void tdfxTMReloadMipMapLevel( GLcontext *ctx, - struct gl_texture_object *tObj, - GLint level ); - -extern void tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj, - FxU32 targetTMU ); - -extern void tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ); - -extern void tdfxTMFreeTexture( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ); - -extern void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ); - - -#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \ - do { \ - LOCK_HARDWARE( fxMesa ); \ - tdfxTMMoveInTM_NoLock( fxMesa, tObj, targetTMU ); \ - UNLOCK_HARDWARE( fxMesa ); \ - } while (0) - -#define tdfxTMMoveOutTM( fxMesa, tObj ) \ - do { \ - LOCK_HARDWARE( fxMesa ); \ - tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); \ - UNLOCK_HARDWARE( fxMesa ); \ - } while (0) - +extern void tdfxTMDownloadTextureLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ); +extern void tdfxTMReloadMipMapLevelLocked( GLcontext *ctx, + struct gl_texture_object *tObj, + GLint level ); +extern void tdfxTMMoveInTMLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj, + FxU32 targetTMU ); +extern void tdfxTMMoveOutTMLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ); +extern void tdfxTMRestoreTexturesLocked( tdfxContextPtr fxMesa ); + +extern void tdfxTMFreeTextureLocked( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ); + + +#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \ +do { \ + LOCK_HARDWARE( fxMesa ); \ + tdfxTMMoveInTMLocked( fxMesa, tObj, targetTMU ); \ + UNLOCK_HARDWARE( fxMesa ); \ +} while (0) + +#define tdfxTMMoveOutTM( fxMesa, tObj ) \ +do { \ + LOCK_HARDWARE( fxMesa ); \ + tdfxTMMoveOutTMLocked( fxMesa, tObj ); \ + UNLOCK_HARDWARE( fxMesa ); \ +} while (0) #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c index 5493eea8a..368f051a3 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c @@ -38,7 +38,6 @@ #include "tdfx_state.h" #include "tdfx_tex.h" #include "tdfx_texman.h" -#include "tdfx_texstate.h" /* ============================================================= @@ -1270,105 +1269,105 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, static void setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) { - struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData; - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); const GLcontext *ctx = fxMesa->glCtx; + tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ctx->Shared->DriverData; + tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); /* Make sure we're not loaded incorrectly */ - if (ti->isInTM && !shared->umaTexMemory) { + if (t->isInTM && !tss->umaTexMemory) { /* if doing filtering between mipmap levels, alternate mipmap levels * must be in alternate TMUs. */ - if (ti->LODblend) { - if (ti->whichTMU != TDFX_TMU_SPLIT) - tdfxTMMoveOutTM_NoLock(fxMesa, tObj); + if (t->LODblend) { + if (t->whichTMU != TDFX_TMU_SPLIT) + tdfxTMMoveOutTMLocked(fxMesa, tObj); } else { - if (ti->whichTMU == TDFX_TMU_SPLIT) - tdfxTMMoveOutTM_NoLock(fxMesa, tObj); + if (t->whichTMU == TDFX_TMU_SPLIT) + tdfxTMMoveOutTMLocked(fxMesa, tObj); } } /* Make sure we're loaded correctly */ - if (!ti->isInTM) { + if (!t->isInTM) { /* Have to download the texture */ - if (shared->umaTexMemory) { - tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0); + if (tss->umaTexMemory) { + tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU0); } else { /* Voodoo3 (split texture memory) */ - if (ti->LODblend) { - tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU_SPLIT); + if (t->LODblend) { + tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU_SPLIT); } else { #if 0 /* XXX putting textures into the second memory bank when the * first bank is full is not working at this time. */ - if (fxMesa->haveTwoTMUs) { - GLint memReq = FX_grTexTextureMemRequired_NoLock( - GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); - if (shared->freeTexMem[TDFX_TMU0] > memReq) { - tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0); + if (fxMesa->numTMUs > 1) { + GLint memReq = + grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); + if (tss->freeTexMem[TDFX_TMU0] > memReq) { + tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU0); } else { - tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU1); + tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU1); } } else #endif { - tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0); + tdfxTMMoveInTMLocked( fxMesa, tObj, TDFX_TMU0 ); } } } } - if (ti->LODblend && ti->whichTMU == TDFX_TMU_SPLIT) { + if (t->LODblend && t->whichTMU == TDFX_TMU_SPLIT) { /* mipmap levels split between texture banks */ GLint u; - if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { + if (t->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(ti->palette); + fxMesa->TexPalette.Data = &(t->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } for (u = 0; u < 2; u++) { - fxMesa->TexParams[u].sClamp = ti->sClamp; - fxMesa->TexParams[u].tClamp = ti->tClamp; - fxMesa->TexParams[u].minFilt = ti->minFilt; - fxMesa->TexParams[u].magFilt = ti->magFilt; - fxMesa->TexParams[u].mmMode = ti->mmMode; - fxMesa->TexParams[u].LODblend = ti->LODblend; + fxMesa->TexParams[u].sClamp = t->sClamp; + fxMesa->TexParams[u].tClamp = t->tClamp; + fxMesa->TexParams[u].minFilt = t->minFilt; + fxMesa->TexParams[u].magFilt = t->magFilt; + fxMesa->TexParams[u].mmMode = t->mmMode; + fxMesa->TexParams[u].LODblend = t->LODblend; fxMesa->TexParams[u].LodBias = ctx->Texture.Unit[u].LodBias; } fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; - fxMesa->TexSource[0].StartAddress = ti->tm[TDFX_TMU0]->startAddr; + fxMesa->TexSource[0].StartAddress = t->range[TDFX_TMU0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_ODD; - fxMesa->TexSource[0].Info = &(ti->info); - fxMesa->TexSource[1].StartAddress = ti->tm[TDFX_TMU1]->startAddr; + fxMesa->TexSource[0].Info = &(t->info); + fxMesa->TexSource[1].StartAddress = t->range[TDFX_TMU1]->startAddr; fxMesa->TexSource[1].EvenOdd = GR_MIPMAPLEVELMASK_EVEN; - fxMesa->TexSource[1].Info = &(ti->info); + fxMesa->TexSource[1].Info = &(t->info); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; } else { FxU32 tmu; - if (ti->whichTMU == TDFX_TMU_BOTH) + if (t->whichTMU == TDFX_TMU_BOTH) tmu = TDFX_TMU0; else - tmu = ti->whichTMU; + tmu = t->whichTMU; - if (shared->umaTexMemory) { - assert(ti->whichTMU == TDFX_TMU0); + if (tss->umaTexMemory) { + assert(t->whichTMU == TDFX_TMU0); assert(tmu == TDFX_TMU0); } - if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { + if (t->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(ti->palette); + fxMesa->TexPalette.Data = &(t->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } @@ -1377,18 +1376,18 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) * texture memory, so perhaps it's not a good idea. */ - if (fxMesa->TexParams[tmu].sClamp != ti->sClamp || - fxMesa->TexParams[tmu].tClamp != ti->tClamp || - fxMesa->TexParams[tmu].minFilt != ti->minFilt || - fxMesa->TexParams[tmu].magFilt != ti->magFilt || - fxMesa->TexParams[tmu].mmMode != ti->mmMode || + if (fxMesa->TexParams[tmu].sClamp != t->sClamp || + fxMesa->TexParams[tmu].tClamp != t->tClamp || + fxMesa->TexParams[tmu].minFilt != t->minFilt || + fxMesa->TexParams[tmu].magFilt != t->magFilt || + fxMesa->TexParams[tmu].mmMode != t->mmMode || fxMesa->TexParams[tmu].LODblend != FXFALSE || fxMesa->TexParams[tmu].LodBias != ctx->Texture.Unit[tmu].LodBias) { - fxMesa->TexParams[tmu].sClamp = ti->sClamp; - fxMesa->TexParams[tmu].tClamp = ti->tClamp; - fxMesa->TexParams[tmu].minFilt = ti->minFilt; - fxMesa->TexParams[tmu].magFilt = ti->magFilt; - fxMesa->TexParams[tmu].mmMode = ti->mmMode; + fxMesa->TexParams[tmu].sClamp = t->sClamp; + fxMesa->TexParams[tmu].tClamp = t->tClamp; + fxMesa->TexParams[tmu].minFilt = t->minFilt; + fxMesa->TexParams[tmu].magFilt = t->magFilt; + fxMesa->TexParams[tmu].mmMode = t->mmMode; fxMesa->TexParams[tmu].LODblend = FXFALSE; fxMesa->TexParams[tmu].LodBias = ctx->Texture.Unit[tmu].LodBias; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; @@ -1397,16 +1396,16 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) /* Glide texture source info */ fxMesa->TexSource[0].Info = NULL; fxMesa->TexSource[1].Info = NULL; - if (ti->tm[tmu]) { - fxMesa->TexSource[tmu].StartAddress = ti->tm[tmu]->startAddr; + if (t->range[tmu]) { + fxMesa->TexSource[tmu].StartAddress = t->range[tmu]->startAddr; fxMesa->TexSource[tmu].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu].Info = &(ti->info); + fxMesa->TexSource[tmu].Info = &(t->info); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; } } - fxMesa->sScale0 = ti->sScale; - fxMesa->tScale0 = ti->tScale; + fxMesa->sScale0 = t->sScale; + fxMesa->tScale0 = t->tScale; } static void @@ -1420,12 +1419,12 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend) fxMesa->TexCombine[0].InvertRGB = FXFALSE; fxMesa->TexCombine[0].InvertAlpha = FXFALSE; - if (fxMesa->haveTwoTMUs) { - const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + if ( fxMesa->numTMUs > 1 ) { + const struct gl_shared_state *ss = fxMesa->glCtx->Shared; + const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; int tmu; - if (shared->umaTexMemory) + if (tss->umaTexMemory) tmu = GR_TMU0; else tmu = GR_TMU1; @@ -1447,7 +1446,7 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend) fxMesa->TexCombine[0].FactorAlpha = GR_COMBINE_FACTOR_NONE; fxMesa->TexCombine[0].InvertRGB = FXFALSE; fxMesa->TexCombine[0].InvertAlpha = FXFALSE; - if (fxMesa->haveTwoTMUs) { + if ( fxMesa->numTMUs > 1 ) { fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO; fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE; fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_ZERO; @@ -1511,7 +1510,7 @@ static void print_state(tdfxContextPtr fxMesa) static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexInfo *ti; + tdfxTexObjPtr t; struct gl_texture_object *tObj; int tmu; GLenum envMode, baseFormat; @@ -1530,17 +1529,17 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) setupSingleTMU(fxMesa, tObj); - ti = TDFX_TEXTURE_DATA(tObj); - if (ti->whichTMU == TDFX_TMU_BOTH) + t = TDFX_TEXTURE_DATA(tObj); + if (t->whichTMU == TDFX_TMU_BOTH) tmu = TDFX_TMU0; else - tmu = ti->whichTMU; + tmu = t->whichTMU; if (fxMesa->tmuSrc != tmu) { - selectSingleTMUSrc(fxMesa, tmu, ti->LODblend); + selectSingleTMUSrc(fxMesa, tmu, t->LODblend); } - if (ti->reloadImages) + if (t->reloadImages) fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_IMAGES; /* Some texture environments not supported */ @@ -1627,35 +1626,35 @@ setupDoubleTMU(tdfxContextPtr fxMesa, #define T0_IN_TMU1 0x10 #define T1_IN_TMU1 0x20 - const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + const struct gl_shared_state *ss = fxMesa->glCtx->Shared; + const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; const GLcontext *ctx = fxMesa->glCtx; - tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); - tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); + tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0); + tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1); GLuint tstate = 0; int tmu0 = 0, tmu1 = 1; - if (shared->umaTexMemory) { - if (!ti0->isInTM) { - tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0); - assert(ti0->isInTM); + if (tss->umaTexMemory) { + if (!t0->isInTM) { + tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0); + assert(t0->isInTM); } - if (!ti1->isInTM) { - tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU0); - assert(ti1->isInTM); + if (!t1->isInTM) { + tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU0); + assert(t1->isInTM); } } else { /* We shouldn't need to do this. There is something wrong with multitexturing when the TMUs are swapped. So, we're forcing them to always be loaded correctly. !!! */ - if (ti0->whichTMU == TDFX_TMU1) - tdfxTMMoveOutTM_NoLock(fxMesa, tObj0); - if (ti1->whichTMU == TDFX_TMU0) - tdfxTMMoveOutTM_NoLock(fxMesa, tObj1); + if (t0->whichTMU == TDFX_TMU1) + tdfxTMMoveOutTMLocked(fxMesa, tObj0); + if (t1->whichTMU == TDFX_TMU0) + tdfxTMMoveOutTMLocked(fxMesa, tObj1); - if (ti0->isInTM) { - switch (ti0->whichTMU) { + if (t0->isInTM) { + switch (t0->whichTMU) { case TDFX_TMU0: tstate |= T0_IN_TMU0; break; @@ -1673,8 +1672,8 @@ setupDoubleTMU(tdfxContextPtr fxMesa, else tstate |= T0_NOT_IN_TMU; - if (ti1->isInTM) { - switch (ti1->whichTMU) { + if (t1->isInTM) { + switch (t1->whichTMU) { case TDFX_TMU0: tstate |= T1_IN_TMU0; break; @@ -1697,7 +1696,7 @@ setupDoubleTMU(tdfxContextPtr fxMesa, if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) || ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) { if (tObj0 == tObj1) { - tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU_BOTH); + tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU_BOTH); } else { /* Find the minimal way to correct the situation */ @@ -1705,10 +1704,10 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* We have one in the standard order, setup the other */ if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */ - tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU1); + tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU1); } else { - tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0); + tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0); } /* tmu0 and tmu1 are setup */ } @@ -1716,36 +1715,36 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* we have one in the reverse order, setup the other */ if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */ - tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU1); + tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU1); } else { - tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU0); + tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU0); } tmu0 = 1; tmu1 = 0; } else { /* Nothing is loaded */ - tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0); - tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU1); + tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0); + tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU1); /* tmu0 and tmu1 are setup */ } } } } - ti0->lastTimeUsed = fxMesa->texBindNumber; - ti1->lastTimeUsed = fxMesa->texBindNumber; + t0->lastTimeUsed = fxMesa->texBindNumber; + t1->lastTimeUsed = fxMesa->texBindNumber; if (!ctx->Texture.SharedPalette) { - if (ti0->info.format == GR_TEXFMT_P_8) { + if (t0->info.format == GR_TEXFMT_P_8) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(ti0->palette); + fxMesa->TexPalette.Data = &(t0->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } - else if (ti1->info.format == GR_TEXFMT_P_8) { + else if (t1->info.format == GR_TEXFMT_P_8) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(ti1->palette); + fxMesa->TexPalette.Data = &(t1->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } else { @@ -1756,25 +1755,25 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* * Setup Unit 0 */ - assert(ti0->isInTM); - assert(ti0->tm[tmu0]); - fxMesa->TexSource[tmu0].StartAddress = ti0->tm[tmu0]->startAddr; + assert(t0->isInTM); + assert(t0->range[tmu0]); + fxMesa->TexSource[tmu0].StartAddress = t0->range[tmu0]->startAddr; fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu0].Info = &(ti0->info); + fxMesa->TexSource[tmu0].Info = &(t0->info); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; - if (fxMesa->TexParams[tmu0].sClamp != ti0->sClamp || - fxMesa->TexParams[tmu0].tClamp != ti0->tClamp || - fxMesa->TexParams[tmu0].minFilt != ti0->minFilt || - fxMesa->TexParams[tmu0].magFilt != ti0->magFilt || - fxMesa->TexParams[tmu0].mmMode != ti0->mmMode || + if (fxMesa->TexParams[tmu0].sClamp != t0->sClamp || + fxMesa->TexParams[tmu0].tClamp != t0->tClamp || + fxMesa->TexParams[tmu0].minFilt != t0->minFilt || + fxMesa->TexParams[tmu0].magFilt != t0->magFilt || + fxMesa->TexParams[tmu0].mmMode != t0->mmMode || fxMesa->TexParams[tmu0].LODblend != FXFALSE || fxMesa->TexParams[tmu0].LodBias != ctx->Texture.Unit[tmu0].LodBias) { - fxMesa->TexParams[tmu0].sClamp = ti0->sClamp; - fxMesa->TexParams[tmu0].tClamp = ti0->tClamp; - fxMesa->TexParams[tmu0].minFilt = ti0->minFilt; - fxMesa->TexParams[tmu0].magFilt = ti0->magFilt; - fxMesa->TexParams[tmu0].mmMode = ti0->mmMode; + fxMesa->TexParams[tmu0].sClamp = t0->sClamp; + fxMesa->TexParams[tmu0].tClamp = t0->tClamp; + fxMesa->TexParams[tmu0].minFilt = t0->minFilt; + fxMesa->TexParams[tmu0].magFilt = t0->magFilt; + fxMesa->TexParams[tmu0].mmMode = t0->mmMode; fxMesa->TexParams[tmu0].LODblend = FXFALSE; fxMesa->TexParams[tmu0].LodBias = ctx->Texture.Unit[tmu0].LodBias; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; @@ -1783,42 +1782,42 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* * Setup Unit 1 */ - if (shared->umaTexMemory) { - ASSERT(ti1->isInTM); - ASSERT(ti1->tm[0]); - fxMesa->TexSource[tmu1].StartAddress = ti1->tm[0]->startAddr; + if (tss->umaTexMemory) { + ASSERT(t1->isInTM); + ASSERT(t1->range[0]); + fxMesa->TexSource[tmu1].StartAddress = t1->range[0]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &(ti1->info); + fxMesa->TexSource[tmu1].Info = &(t1->info); } else { - ASSERT(ti1->isInTM); - ASSERT(ti1->tm[tmu1]); - fxMesa->TexSource[tmu1].StartAddress = ti1->tm[tmu1]->startAddr; + ASSERT(t1->isInTM); + ASSERT(t1->range[tmu1]); + fxMesa->TexSource[tmu1].StartAddress = t1->range[tmu1]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &(ti1->info); + fxMesa->TexSource[tmu1].Info = &(t1->info); } - if (fxMesa->TexParams[tmu1].sClamp != ti1->sClamp || - fxMesa->TexParams[tmu1].tClamp != ti1->tClamp || - fxMesa->TexParams[tmu1].minFilt != ti1->minFilt || - fxMesa->TexParams[tmu1].magFilt != ti1->magFilt || - fxMesa->TexParams[tmu1].mmMode != ti1->mmMode || + if (fxMesa->TexParams[tmu1].sClamp != t1->sClamp || + fxMesa->TexParams[tmu1].tClamp != t1->tClamp || + fxMesa->TexParams[tmu1].minFilt != t1->minFilt || + fxMesa->TexParams[tmu1].magFilt != t1->magFilt || + fxMesa->TexParams[tmu1].mmMode != t1->mmMode || fxMesa->TexParams[tmu1].LODblend != FXFALSE || fxMesa->TexParams[tmu1].LodBias != ctx->Texture.Unit[tmu1].LodBias) { - fxMesa->TexParams[tmu1].sClamp = ti1->sClamp; - fxMesa->TexParams[tmu1].tClamp = ti1->tClamp; - fxMesa->TexParams[tmu1].minFilt = ti1->minFilt; - fxMesa->TexParams[tmu1].magFilt = ti1->magFilt; - fxMesa->TexParams[tmu1].mmMode = ti1->mmMode; + fxMesa->TexParams[tmu1].sClamp = t1->sClamp; + fxMesa->TexParams[tmu1].tClamp = t1->tClamp; + fxMesa->TexParams[tmu1].minFilt = t1->minFilt; + fxMesa->TexParams[tmu1].magFilt = t1->magFilt; + fxMesa->TexParams[tmu1].mmMode = t1->mmMode; fxMesa->TexParams[tmu1].LODblend = FXFALSE; fxMesa->TexParams[tmu1].LodBias = ctx->Texture.Unit[tmu1].LodBias; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; } - fxMesa->sScale0 = ti0->sScale; - fxMesa->tScale0 = ti0->tScale; - fxMesa->sScale1 = ti1->sScale; - fxMesa->tScale1 = ti1->tScale; + fxMesa->sScale0 = t0->sScale; + fxMesa->tScale0 = t0->tScale; + fxMesa->sScale1 = t1->sScale; + fxMesa->tScale1 = t1->tScale; #undef T0_NOT_IN_TMU #undef T1_NOT_IN_TMU @@ -1833,8 +1832,8 @@ static void setupTextureDoubleTMU(GLcontext * ctx) tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2]; struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2]; - tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); - tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); + tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0); + tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1); struct gl_texture_image *baseImage0 = tObj0->Image[tObj0->BaseLevel]; struct gl_texture_image *baseImage1 = tObj1->Image[tObj1->BaseLevel]; const GLenum envMode0 = ctx->Texture.Unit[0].EnvMode; @@ -1847,7 +1846,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx) setupDoubleTMU(fxMesa, tObj0, tObj1); - if (ti0->reloadImages || ti1->reloadImages) + if (t0->reloadImages || t1->reloadImages) fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_IMAGES; fxMesa->tmuSrc = TDFX_TMU_BOTH; @@ -1893,7 +1892,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx) } else { int unit0, unit1; - if ((ti0->whichTMU == TDFX_TMU1) || (ti1->whichTMU == TDFX_TMU0)) + if ((t0->whichTMU == TDFX_TMU1) || (t1->whichTMU == TDFX_TMU0)) unit0 = 1; else unit0 = 0; @@ -1924,34 +1923,34 @@ static void setupTextureDoubleTMU(GLcontext * ctx) } -void -tdfxUpdateTextureState( GLcontext *ctx ) +void tdfxUpdateTextureState( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint tex2Denabled = ctx->Texture.ReallyEnabled; + GLuint enabled = ctx->Texture.ReallyEnabled; - if (!fxMesa->haveTwoTMUs) - tex2Denabled &= TEXTURE0_2D; + if ( fxMesa->numTMUs == 1 ) + enabled &= TEXTURE0_2D; - switch (tex2Denabled) { + switch ( enabled ) { case TEXTURE0_2D: LOCK_HARDWARE( fxMesa ); /* XXX remove locking eventually */ - setupTextureSingleTMU(ctx, 0); + setupTextureSingleTMU( ctx, 0 ); UNLOCK_HARDWARE( fxMesa ); break; case TEXTURE1_2D: LOCK_HARDWARE( fxMesa ); - setupTextureSingleTMU(ctx, 1); + setupTextureSingleTMU( ctx, 1 ); UNLOCK_HARDWARE( fxMesa ); break; - case (TEXTURE0_2D | TEXTURE1_2D): + case TEXTURE0_2D | TEXTURE1_2D: LOCK_HARDWARE( fxMesa ); - setupTextureDoubleTMU(ctx); + setupTextureDoubleTMU( ctx ); UNLOCK_HARDWARE( fxMesa ); break; + default: - /* disable hardware texturing */ - if (TDFX_IS_NAPALM(fxMesa)) { + /* Disable hardware texturing */ + if ( TDFX_IS_NAPALM( fxMesa ) ) { fxMesa->ColorCombineExt.SourceA = GR_CMBX_ITRGB; fxMesa->ColorCombineExt.ModeA = GR_FUNC_MODE_X; fxMesa->ColorCombineExt.SourceB = GR_CMBX_ZERO; @@ -1972,9 +1971,8 @@ tdfxUpdateTextureState( GLcontext *ctx ) fxMesa->AlphaCombineExt.InvertD = FXFALSE; fxMesa->AlphaCombineExt.Shift = 0; fxMesa->AlphaCombineExt.Invert = FXFALSE; - } - else { - /* Voodoo 3*/ + } else { + /* Voodoo 3 */ fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_LOCAL; fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_NONE; fxMesa->ColorCombine.Local = GR_COMBINE_LOCAL_ITERATED; @@ -1997,106 +1995,103 @@ tdfxUpdateTextureState( GLcontext *ctx ) } - -/* - * This is a special case of texture state update. +/* This is a special case of texture state update. * It's used when we've simply bound a new texture to a texture * unit and the new texture has the exact same attributes as the * previously bound texture. * This is very common in Quake3. */ -void -tdfxUpdateTextureBinding( GLcontext *ctx ) +void tdfxUpdateTextureBinding( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + const struct gl_shared_state *ss = fxMesa->glCtx->Shared; + const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2]; struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2]; - tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); - tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); - - const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0); + tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1); - if (ti0) { - fxMesa->sScale0 = ti0->sScale; - fxMesa->tScale0 = ti0->tScale; - if (ti0->info.format == GR_TEXFMT_P_8) { + if ( t0 ) { + fxMesa->sScale0 = t0->sScale; + fxMesa->tScale0 = t0->tScale; + if ( t0->info.format == GR_TEXFMT_P_8 ) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(ti0->palette); + fxMesa->TexPalette.Data = &t0->palette; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; - } - else if (ti1 && ti1->info.format == GR_TEXFMT_P_8) { + } else if ( t1 && t1->info.format == GR_TEXFMT_P_8 ) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(ti1->palette); + fxMesa->TexPalette.Data = &t1->palette; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } } - if (ti1) { - fxMesa->sScale1 = ti1->sScale; - fxMesa->tScale1 = ti1->tScale; + if ( t1 ) { + fxMesa->sScale1 = t1->sScale; + fxMesa->tScale1 = t1->tScale; } - if (ctx->Texture.ReallyEnabled == TEXTURE0_2D) { - if (shared->umaTexMemory) { - fxMesa->TexSource[0].StartAddress = ti0->tm[0]->startAddr; + switch ( ctx->Texture.ReallyEnabled ) { + case TEXTURE0_2D: + if ( tss->umaTexMemory ) { + fxMesa->TexSource[0].StartAddress = t0->range[0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[0].Info = &(ti0->info); - } - else { - if (ti0->LODblend && ti0->whichTMU == TDFX_TMU_SPLIT) { - fxMesa->TexSource[0].StartAddress = ti0->tm[TDFX_TMU0]->startAddr; + fxMesa->TexSource[0].Info = &(t0->info); + } else { + if ( t0->LODblend && t0->whichTMU == TDFX_TMU_SPLIT ) { + fxMesa->TexSource[0].StartAddress = t0->range[TDFX_TMU0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_ODD; - fxMesa->TexSource[0].Info = &(ti0->info); - fxMesa->TexSource[1].StartAddress = ti0->tm[TDFX_TMU1]->startAddr; + fxMesa->TexSource[0].Info = &t0->info; + fxMesa->TexSource[1].StartAddress = t0->range[TDFX_TMU1]->startAddr; fxMesa->TexSource[1].EvenOdd = GR_MIPMAPLEVELMASK_EVEN; - fxMesa->TexSource[1].Info = &(ti0->info); - } - else { - FxU32 tmu; - if (ti0->whichTMU == TDFX_TMU_BOTH) - tmu = TDFX_TMU0; - else - tmu = ti0->whichTMU; + fxMesa->TexSource[1].Info = &t0->info; + } else { + FxU32 unit; + if ( t0->whichTMU == TDFX_TMU_BOTH ) { + unit = TDFX_TMU0; + } else { + unit = t0->whichTMU; + } fxMesa->TexSource[0].Info = NULL; fxMesa->TexSource[1].Info = NULL; - if (ti0->tm[tmu]) { - fxMesa->TexSource[tmu].StartAddress = ti0->tm[tmu]->startAddr; - fxMesa->TexSource[tmu].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu].Info = &(ti0->info); + if ( t0->range[unit] ) { + fxMesa->TexSource[unit].StartAddress = t0->range[unit]->startAddr; + fxMesa->TexSource[unit].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; + fxMesa->TexSource[unit].Info = &t0->info; } } } - } - else if (ctx->Texture.ReallyEnabled == TEXTURE1_2D) { - if (shared->umaTexMemory) { - fxMesa->TexSource[0].StartAddress = ti1->tm[0]->startAddr; + break; + + case TEXTURE1_2D: + if ( tss->umaTexMemory ) { + fxMesa->TexSource[0].StartAddress = t1->range[0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[0].Info = &(ti1->info); + fxMesa->TexSource[0].Info = &t1->info; } - } - else if (ctx->Texture.ReallyEnabled == (TEXTURE0_2D | TEXTURE1_2D)) { - if (shared->umaTexMemory) { + break; + + case TEXTURE0_2D | TEXTURE1_2D: + if ( tss->umaTexMemory ) { const FxU32 tmu0 = 0, tmu1 = 1; - fxMesa->TexSource[tmu0].StartAddress = ti0->tm[0]->startAddr; + fxMesa->TexSource[tmu0].StartAddress = t0->range[0]->startAddr; fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu0].Info = &(ti0->info); + fxMesa->TexSource[tmu0].Info = &t0->info; - fxMesa->TexSource[tmu1].StartAddress = ti1->tm[0]->startAddr; + fxMesa->TexSource[tmu1].StartAddress = t1->range[0]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &(ti1->info); + fxMesa->TexSource[tmu1].Info = &t1->info; } else { const FxU32 tmu0 = 0, tmu1 = 1; - fxMesa->TexSource[tmu0].StartAddress = ti0->tm[tmu0]->startAddr; + fxMesa->TexSource[tmu0].StartAddress = t0->range[tmu0]->startAddr; fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu0].Info = &(ti0->info); + fxMesa->TexSource[tmu0].Info = &t0->info; - fxMesa->TexSource[tmu1].StartAddress = ti1->tm[tmu1]->startAddr; + fxMesa->TexSource[tmu1].StartAddress = t1->range[tmu1]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &(ti1->info); + fxMesa->TexSource[tmu1].Info = &t1->info; } + break; } - fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h deleted file mode 100644 index 0c0d4adcb..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- mode: c; c-basic-offset: 3 -*- - * - * Copyright 2000 VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* $XFree86$ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * - */ - -#ifndef __TDFX_TEXSTATE_H__ -#define __TDFX_TEXSTATE_H__ - -extern void tdfxUpdateTextureState( GLcontext *ctx ); -extern void tdfxUpdateTextureBinding( GLcontext *ctx ); - -#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h index 20e5530c5..0adb85b41 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h @@ -552,8 +552,6 @@ extern FxBool FX_grLfbLock(tdfxContextPtr fxMesa, UNLOCK_HARDWARE(fxMesa); \ } while (0) -#define FX_grTexDownloadMipMapLevel_NoLock grTexDownloadMipMapLevel - #define FX_grTexDownloadMipMapLevelPartial(fxMesa, t, sa, tlod, llod, ar, f, eo, d, s, e); \ do { \ LOCK_HARDWARE(fxMesa); \ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c index a0b4304e4..00935e2de 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c @@ -52,19 +52,6 @@ #include "tdfx_texman.h" -#ifndef TDFX_DEBUG -int TDFX_DEBUG = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_API */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_VERBOSE_LRU */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VERBOSE_IOCTL */ -/* | DEBUG_VERBOSE_2D */ - ); -#endif - - GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) { @@ -393,11 +380,12 @@ XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, GLboolean XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) { - fprintf(stderr,"***** XMesaOpenFullScreen *****\n"); + if ( 0 ) + fprintf( stderr, "***** XMesaOpenFullScreen *****\n" ); #if 0 /* When new glide3 calls exist */ - return((GLboolean)grDRISetupFullScreen(GL_TRUE)); + return (GLboolean)grDRISetupFullScreen( GL_TRUE ); #else - return GL_TRUE; + return GL_TRUE; #endif } @@ -405,11 +393,12 @@ XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) GLboolean XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) { - fprintf(stderr,"***** XMesaCloseFullScreen *****\n"); + if ( 0 ) + fprintf( stderr, "***** XMesaCloseFullScreen *****\n" ); #if 0 /* When new glide3 calls exist */ - return((GLboolean)grDRISetupFullScreen(GL_FALSE)); + return (GLboolean)grDRISetupFullScreen( GL_FALSE ); #else - return GL_TRUE; + return GL_TRUE; #endif } |