#include #include #include "main/glheader.h" #include "main/macros.h" #include "main/mtypes.h" #include "main/simple_list.h" #include "main/enums.h" #include "main/mm.h" #include "gammacontext.h" static void gammaSetTexImages( gammaContextPtr gmesa, struct gl_texture_object *tObj ) { GLuint height, width, pitch, i, log_pitch; gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData; const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; GLint firstLevel, lastLevel, numLevels; GLint log2Width, log2Height; /* fprintf(stderr, "%s\n", __FUNCTION__); */ t->texelBytes = 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[0][firstLevel]->WidthLog2; log2Height = tObj->Image[0][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[0][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[0][firstLevel + i]; t->image[i].offset = height * pitch; t->image[i].internalFormat = baseImage->Format; height += t->image[i].image->Height; t->TextureBaseAddr[i] = /* ??? */ (unsigned long)(t->image[i].offset + t->BufAddr) << 5; } t->Pitch = pitch; t->totalSize = height*pitch; t->max_level = i-1; gmesa->dirty |= GAMMA_UPLOAD_TEX0 /* | GAMMA_UPLOAD_TEX1*/; gammaUploadTexImages( gmesa, t ); } static void gammaUpdateTexEnv( GLcontext *ctx, GLuint unit ) { const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; const struct gl_texture_object *tObj = texUnit->_Current; const GLuint format = tObj->Image[0][tObj->BaseLevel]->Format; gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData; GLuint tc; /* fprintf(stderr, "%s\n", __FUNCTION__); */ tc = t->TextureColorMode & ~(TCM_BaseFormatMask | TCM_ApplicationMask); switch (format) { case GL_RGB: tc |= TCM_BaseFormat_RGB; break; case GL_LUMINANCE: tc |= TCM_BaseFormat_Lum; break; case GL_ALPHA: tc |= TCM_BaseFormat_Alpha; break; case GL_LUMINANCE_ALPHA: tc |= TCM_BaseFormat_LumAlpha; break; case GL_INTENSITY: tc |= TCM_BaseFormat_Intensity; break; case GL_RGBA: tc |= TCM_BaseFormat_RGBA; break; case GL_COLOR_INDEX: break; } switch (texUnit->EnvMode) { case GL_REPLACE: tc |= TCM_Replace; break; case GL_MODULATE: tc |= TCM_Modulate; break; case GL_ADD: /* do nothing ???*/ break; case GL_DECAL: tc |= TCM_Decal; break; case GL_BLEND: tc |= TCM_Blend; break; default: fprintf(stderr, "unknown tex env mode"); return; } t->TextureColorMode = tc; } static void gammaUpdateTexUnit( GLcontext *ctx, GLuint unit ) { gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; /* fprintf(stderr, "%s\n", __FUNCTION__); */ if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) { struct gl_texture_object *tObj = texUnit->_Current; gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData; /* Upload teximages (not pipelined) */ if (t->dirty_images) { gammaSetTexImages( gmesa, tObj ); if (!t->MemBlock) { FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_TRUE ); return; } } #if 0 if (tObj->Image[0][tObj->BaseLevel]->Border > 0) { FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_TRUE ); return; } #endif /* Update state if this is a different texture object to last * time. */ if (gmesa->CurrentTexObj[unit] != t) { gmesa->dirty |= GAMMA_UPLOAD_TEX0 /* << unit */; gmesa->CurrentTexObj[unit] = t; gammaUpdateTexLRU( gmesa, t ); /* done too often */ } /* Update texture environment if texture object image format or * texture environment state has changed. */ if (tObj->Image[0][tObj->BaseLevel]->Format != gmesa->TexEnvImageFmt[unit]) { gmesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->Format; gammaUpdateTexEnv( ctx, unit ); } } else if (texUnit->_ReallyEnabled) { FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_TRUE ); } else /*if (gmesa->CurrentTexObj[unit])*/ { gmesa->CurrentTexObj[unit] = 0; gmesa->TexEnvImageFmt[unit] = 0; gmesa->dirty &= ~(GAMMA_UPLOAD_TEX0<