summaryrefslogtreecommitdiff
path: root/xc/lib/GL
diff options
context:
space:
mode:
authorkem <kem>2001-03-07 21:47:11 +0000
committerkem <kem>2001-03-07 21:47:11 +0000
commitbbfdc489c17ab69c7071acd8f94ce0c9b2a15abb (patch)
tree052a9299a68f44afdc002196de62837b617d0ee4 /xc/lib/GL
parent38baaad074b69a17801ab41e8edb1c033f270650 (diff)
- Merge from trunk into branchsarea-1-0-0-20010307
Diffstat (limited to 'xc/lib/GL')
-rw-r--r--xc/lib/GL/mesa/src/Imakefile9
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ioctl.c9
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.c14
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.c63
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.c300
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.h46
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.c18
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/Imakefile2
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c9
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgacontext.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadd.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.c46
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgapixel.c6
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaspan.c19
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.c110
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.c437
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.c45
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.h101
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatritmp.h30
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.c35
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/Imakefile6
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_context.c8
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c7
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c8
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_state.c35
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c2347
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c508
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h24
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c1103
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c16
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h15
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/Imakefile2
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c48
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h85
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c46
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c15
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c10
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c2339
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h121
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c1564
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h66
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c423
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c27
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
}