diff options
Diffstat (limited to 'src/mesa/drivers/dri/s3v/s3v_texstate.c')
-rw-r--r-- | src/mesa/drivers/dri/s3v/s3v_texstate.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/s3v/s3v_texstate.c b/src/mesa/drivers/dri/s3v/s3v_texstate.c new file mode 100644 index 0000000000..7141e39182 --- /dev/null +++ b/src/mesa/drivers/dri/s3v/s3v_texstate.c @@ -0,0 +1,303 @@ +/* + * Author: Max Lingua <sunmax@libero.it> + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" + +#include "mm.h" +#include "s3v_context.h" +#include "s3v_tex.h" + + +static void s3vSetTexImages( s3vContextPtr vmesa, + struct gl_texture_object *tObj ) +{ + GLuint height, width, pitch, i, /*textureFormat,*/ log_pitch; + s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData; + const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; + GLint firstLevel, lastLevel, numLevels; + GLint log2Width, log2Height; +#if TEX_DEBUG_ON + static unsigned int times=0; + DEBUG_TEX(("*** s3vSetTexImages: #%i ***\n", ++times)); +#endif + + t->texelBytes = 2; /* FIXME: always 2 ? */ + + /* Compute which mipmap levels we really want to send to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + * Yes, this looks overly complicated, but it's all needed. + */ + if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) { + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + + /* save these values */ + t->firstLevel = firstLevel; + t->lastLevel = lastLevel; + + numLevels = lastLevel - firstLevel + 1; + + log2Width = tObj->Image[firstLevel]->WidthLog2; + log2Height = tObj->Image[firstLevel]->HeightLog2; + + + /* Figure out the amount of memory required to hold all the mipmap + * levels. Choose the smallest pitch to accomodate the largest + * mipmap: + */ + width = tObj->Image[firstLevel]->Width * t->texelBytes; + for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 ) + log_pitch++; + + /* All images must be loaded at this pitch. Count the number of + * lines required: + */ + for ( height = i = 0 ; i < numLevels ; i++ ) { + t->image[i].image = tObj->Image[firstLevel + i]; + t->image[i].offset = height * pitch; + t->image[i].internalFormat = baseImage->Format; + height += t->image[i].image->Height; + t->TextureBaseAddr[i] = (t->BufAddr + t->image[i].offset + + _TEXALIGN) & (CARD32)(~_TEXALIGN); + } + + t->Pitch = pitch; + t->WidthLog2 = log2Width; + t->totalSize = height*pitch; + t->max_level = i-1; + vmesa->dirty |= S3V_UPLOAD_TEX0 /* | S3V_UPLOAD_TEX1*/; + vmesa->restore_primitive = -1; + DEBUG(("<><>pitch = TexStride = %i\n", pitch)); + DEBUG(("log2Width = %i\n", log2Width)); + + s3vUploadTexImages( vmesa, t ); +} + +static void s3vUpdateTexEnv( GLcontext *ctx, GLuint unit ) +{ + s3vContextPtr vmesa = S3V_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + const struct gl_texture_object *tObj = texUnit->_Current; + const GLuint format = tObj->Image[tObj->BaseLevel]->Format; +/* + s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData; + GLuint tc; +*/ + GLuint alpha = 0; + CARD32 cmd = vmesa->CMD; +#if TEX_DEBUG_ON + static unsigned int times=0; + DEBUG_TEX(("*** s3vUpdateTexEnv: %i ***\n", ++times)); +#endif + + cmd &= ~TEX_COL_MASK; + cmd &= ~TEX_BLEND_MAKS; +/* cmd &= ~ALPHA_BLEND_MASK; */ + + DEBUG(("format = ")); + + switch (format) { + case GL_RGB: + DEBUG_TEX(("GL_RGB\n")); + cmd |= TEX_COL_ARGB1555; + break; + case GL_LUMINANCE: + DEBUG_TEX(("GL_LUMINANCE\n")); + cmd |= TEX_COL_ARGB4444; + alpha = 1; /* FIXME: check */ + break; + case GL_ALPHA: + DEBUG_TEX(("GL_ALPHA\n")); + cmd |= TEX_COL_ARGB4444; + alpha = 1; + break; + case GL_LUMINANCE_ALPHA: + DEBUG_TEX(("GL_LUMINANCE_ALPHA\n")); + cmd |= TEX_COL_ARGB4444; + alpha = 1; + break; + case GL_INTENSITY: + DEBUG_TEX(("GL_INTENSITY\n")); + cmd |= TEX_COL_ARGB4444; + alpha = 1; + break; + case GL_RGBA: + DEBUG_TEX(("GL_RGBA\n")); + cmd |= TEX_COL_ARGB4444; + alpha = 1; + break; + case GL_COLOR_INDEX: + DEBUG_TEX(("GL_COLOR_INDEX\n")); + cmd |= TEX_COL_PAL; + break; + } + + DEBUG_TEX(("EnvMode = ")); + + switch (texUnit->EnvMode) { + case GL_REPLACE: + DEBUG_TEX(("GL_REPLACE\n")); + cmd |= TEX_REFLECT; /* FIXME */ + vmesa->_tri[1] = DO_TEX_UNLIT_TRI; /* FIXME: white tri hack */ + vmesa->_alpha_tex = ALPHA_TEX /* * alpha */; + break; + case GL_MODULATE: + DEBUG_TEX(("GL_MODULATE\n")); + cmd |= TEX_MODULATE; + vmesa->_tri[1] = DO_TEX_LIT_TRI; +#if 0 + if (alpha) + vmesa->_alpha_tex = ALPHA_TEX /* * alpha */; + else + vmesa->_alpha_tex = ALPHA_SRC /* * alpha */; +#else + vmesa->_alpha_tex = ALPHA_TEX ; +#endif + break; + case GL_ADD: + DEBUG_TEX(("DEBUG_TEX\n")); + /* do nothing ???*/ + break; + case GL_DECAL: + DEBUG_TEX(("GL_DECAL\n")); + cmd |= TEX_DECAL; + vmesa->_tri[1] = DO_TEX_LIT_TRI; + vmesa->_alpha_tex = ALPHA_OFF; + break; + case GL_BLEND: + DEBUG_TEX(("GL_BLEND\n")); + cmd |= TEX_DECAL; + vmesa->_tri[1] = DO_TEX_LIT_TRI; + vmesa->_alpha_tex = ALPHA_OFF; /* FIXME: sure? */ + break; + default: + fprintf(stderr, "unknown tex env mode"); + return; + } + + DEBUG_TEX(("\n\n vmesa->CMD was 0x%x\n", vmesa->CMD)); + DEBUG_TEX(( " vmesa->CMD is 0x%x\n\n", cmd )); + + vmesa->_alpha[1] = vmesa->_alpha_tex; + vmesa->CMD = cmd; /* | MIPMAP_LEVEL(8); */ + vmesa->restore_primitive = -1; +} + +static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit ) +{ + s3vContextPtr vmesa = S3V_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + CARD32 cmd = vmesa->CMD; +#if TEX_DEBUG_ON + static unsigned int times=0; + DEBUG_TEX(("*** s3vUpdateTexUnit: %i ***\n", ++times)); + DEBUG_TEX(("and vmesa->CMD was 0x%x\n", vmesa->CMD)); +#endif + + if (texUnit->_ReallyEnabled == TEXTURE0_2D) + { + struct gl_texture_object *tObj = texUnit->_Current; + s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData; + + /* Upload teximages (not pipelined) + */ + if (t->dirty_images) { +#if _TEXFLUSH + DMAFLUSH(); +#endif + s3vSetTexImages( vmesa, tObj ); + if (!t->MemBlock) { +#if _TEXFALLBACK + FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE ); +#endif + return; + } + } + + /* Update state if this is a different texture object to last + * time. + */ +#if 1 + if (vmesa->CurrentTexObj[unit] != t) { + vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */; + vmesa->CurrentTexObj[unit] = t; + s3vUpdateTexLRU( vmesa, t ); /* done too often */ + } +#endif + + /* Update texture environment if texture object image format or + * texture environment state has changed. + */ + if (tObj->Image[tObj->BaseLevel]->Format != vmesa->TexEnvImageFmt[unit]) { + vmesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format; + s3vUpdateTexEnv( ctx, unit ); + } +#if 1 + cmd = vmesa->CMD & ~MIP_MASK; + vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */; + vmesa->CurrentTexObj[unit] = t; + vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel]; + vmesa->TexStride = t->Pitch; + cmd |= MIPMAP_LEVEL(t->WidthLog2); + + DEBUG_TEX(("\n\n>> vmesa->CMD was 0x%x\n", vmesa->CMD)); + DEBUG_TEX(( ">> vmesa->CMD is 0x%x\n\n", cmd )); + DEBUG_TEX(("t->WidthLog2 = %i\n", t->WidthLog2)); + DEBUG_TEX(("MIPMAP_LEVEL(t->WidthLog2) = 0x%x\n", MIPMAP_LEVEL(t->WidthLog2))); + + vmesa->CMD = cmd; + vmesa->restore_primitive = -1; +#endif + } + else if (texUnit->_ReallyEnabled) { /* _ReallyEnabled but != TEXTURE0_2D */ +#if _TEXFALLBACK + FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE ); +#endif + } + else /*if (vmesa->CurrentTexObj[unit])*/ { /* !_ReallyEnabled */ + vmesa->CurrentTexObj[unit] = 0; + vmesa->TexEnvImageFmt[unit] = 0; + vmesa->dirty &= ~(S3V_UPLOAD_TEX0<<unit); + } +} + + +void s3vUpdateTextureState( GLcontext *ctx ) +{ + s3vContextPtr vmesa = S3V_CONTEXT(ctx); +#if TEX_DEBUG_ON + static unsigned int times=0; + DEBUG_TEX(("*** s3vUpdateTextureState: #%i ***\n", ++times)); +#endif + + if (!ctx->Texture._ReallyEnabled) { + DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n")); + return; + } + +#if _TEXFALLBACK + FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_FALSE ); +#endif + s3vUpdateTexUnit( ctx, 0 ); +#if 0 + s3vUpdateTexUnit( ctx, 1 ); +#endif +} |