From 78ad878b661d72ce1246b8c66ce97b7f67bed4e7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 6 Feb 2001 23:35:49 +0000 Subject: [PATCH] updated texture image handling - STILL UNTESTED --- src/mesa/drivers/glide/fxddtex.c | 712 ++++++++++++++++++------------ src/mesa/drivers/glide/fxdrv.h | 16 +- src/mesa/drivers/glide/fxtexman.c | 72 ++- 3 files changed, 480 insertions(+), 320 deletions(-) diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c index bc899170503..d8a386230e1 100644 --- a/src/mesa/drivers/glide/fxddtex.c +++ b/src/mesa/drivers/glide/fxddtex.c @@ -1,9 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 3.3 + * Version: 3.5 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2001 Brian Paul 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"), @@ -50,6 +50,8 @@ #include "fxdrv.h" #include "image.h" +#include "teximage.h" +#include "texstore.h" #include "texutil.h" @@ -104,7 +106,6 @@ static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj) static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa) { tfxTexInfo *ti; - int i; if(!(ti=CALLOC(sizeof(tfxTexInfo)))) { fprintf(stderr,"fx Driver: out of memory !\n"); @@ -129,10 +130,6 @@ static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa) ti->mmMode=GR_MIPMAP_NEAREST; ti->LODblend=FXFALSE; - for(i=0;imipmapLevel[i].data=NULL; - } - return ti; } @@ -819,6 +816,164 @@ static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat, /**** NEW TEXTURE IMAGE FUNCTIONS ****/ /**********************************************************************/ +/* Texel-fetch functions for software texturing and glGetTexImage(). + * We should have been able to use some "standard" fetch functions (which + * may get defined in texutil.c) but we have to account for scaled texture + * images on tdfx hardware (the 8:1 aspect ratio limit). + * Hence, we need special functions here. + */ + +static void +fetch_intensity8(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = *texel; + rgba[GCOMP] = *texel; + rgba[BCOMP] = *texel; + rgba[ACOMP] = *texel; +} + + +static void +fetch_luminance8(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = *texel; + rgba[GCOMP] = *texel; + rgba[BCOMP] = *texel; + rgba[ACOMP] = 255; + +} + + +static void +fetch_alpha8(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + i = i * mml->width / texImage->Width; + j = j * mml->height / texImage->Height; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = 255; + rgba[GCOMP] = 255; + rgba[BCOMP] = 255; + rgba[ACOMP] = *texel; +} + + +static void +fetch_index8(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + /* XXX todo */ +} + + +static void +fetch_luminance8_alpha8(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2; + rgba[RCOMP] = texel[0]; + rgba[GCOMP] = texel[0]; + rgba[BCOMP] = texel[0]; + rgba[ACOMP] = texel[1]; +} + +static void +fetch_r5g6b5(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31; + rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63; + rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31; + rgba[ACOMP] = 255; +} + + +static void +fetch_r4g4b4a4(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15; + rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15; + rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15; + rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15; +} + + +static void +fetch_r5g5b5a1(GLcontext *ctx, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan rgba[4]) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31; + rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31; + rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31; + rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255; +} + static void PrintTexture(int w, int h, int c, const GLubyte *data) { @@ -844,145 +999,184 @@ fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GrTextureFormat_t gldformat; + tfxTexInfo *ti = fxTMGetTexInfo(texObj); + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + MesaIntTexFormat mesaFormat; + GLint texelSize; + GLboolean success; + + if (!fxIsTexSupported(target, internalFormat, texImage)) { + gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n"); + return; + } - if (!texObj->DriverData) - texObj->DriverData = fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) + texObj->DriverData = fxAllocTexObjData(fxMesa); - if (fxIsTexSupported(target, internalFormat, texImage)) { - GrTextureFormat_t gldformat; - tfxTexInfo *ti = fxTMGetTexInfo(texObj); - tfxMipMapLevel *mml = &ti->mipmapLevel[level]; - GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride; - MesaIntTexFormat intFormat; + if (!mml) { + texImage->DriverData = MALLOC(sizeof(tfxMipMapLevel)); + mml = FX_MIPMAP_DATA(texImage); + } - fxTexGetFormat(internalFormat, &gldformat, NULL); + fxTexGetFormat(internalFormat, &gldformat, NULL); - fxTexGetInfo(width, height, NULL,NULL,NULL,NULL, - NULL,NULL, &wScale, &hScale); + fxTexGetInfo(width, height, NULL, NULL, NULL, NULL, + NULL, NULL, &mml->wScale, &mml->hScale); - dstWidth = texImage->Width * wScale; - dstHeight = texImage->Height * hScale; - - switch (texImage->IntFormat) { - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - texelSize = 1; - intFormat = MESA_I8; - break; - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - texelSize = 1; - intFormat = MESA_L8; - break; - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - texelSize = 1; - intFormat = MESA_A8; - 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: - texelSize = 1; - intFormat = MESA_C8; - 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: - texelSize = 2; - intFormat = MESA_A8_L8; - break; - case 3: - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - texelSize = 2; - intFormat = MESA_R5_G6_B5; - break; - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - texelSize = 2; - intFormat = MESA_A4_R4_G4_B4; - break; - case GL_RGB5_A1: - texelSize = 2; - intFormat = MESA_A1_R5_G5_B5; - break; - default: - gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format"); - return; - } - - _mesa_set_teximage_component_sizes(intFormat, texImage); - - /*printf("teximage:\n");*/ - /* allocate new storage for texture image, if needed */ - if (!mml->data || mml->glideFormat != gldformat || - mml->width != dstWidth || mml->height != dstHeight) { - if (mml->data) - FREE(mml->data); - mml->data = MALLOC(dstWidth * dstHeight * texelSize); - if (!mml->data) - return; - mml->glideFormat = gldformat; - mml->width = dstWidth; - mml->height = dstHeight; - fxTexInvalidate(ctx, texObj); - } + mml->width = texImage->Width * mml->wScale; + mml->height = texImage->Height * mml->hScale; + + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + texImage->FetchTexel = fetch_intensity8; + texelSize = 1; + mesaFormat = MESA_I8; + break; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + texImage->FetchTexel = fetch_luminance8; + texelSize = 1; + mesaFormat = MESA_L8; + break; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + texImage->FetchTexel = fetch_alpha8; + texelSize = 1; + mesaFormat = MESA_A8; + 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: + texImage->FetchTexel = fetch_index8; + texelSize = 1; + mesaFormat = MESA_C8; + 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: + texImage->FetchTexel = fetch_luminance8_alpha8; + texelSize = 2; + mesaFormat = MESA_A8_L8; + break; + case 3: + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + texImage->FetchTexel = fetch_r5g6b5; + texelSize = 2; + mesaFormat = MESA_R5_G6_B5; + break; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + texImage->FetchTexel = fetch_r4g4b4a4; + texelSize = 2; + mesaFormat = MESA_A4_R4_G4_B4; + break; + case GL_RGB5_A1: + texImage->FetchTexel = fetch_r5g5b5a1; + texelSize = 2; + mesaFormat = MESA_A1_R5_G5_B5; + break; + default: + gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format"); + return; + } - dstStride = dstWidth * texelSize; + _mesa_set_teximage_component_sizes(mesaFormat, texImage); - /* store the texture image */ - if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data, - dstStride, - width, height, - format, type, pixels, packing)) { + /* allocate new storage for texture image, if needed */ + texImage->Data = MALLOC(mml->width * mml->height * texelSize); + if (!texImage->Data) return; - } + mml->glideFormat = gldformat; + fxTexInvalidate(ctx, texObj); + + /* store the texture image */ + if (ctx->_ImageTransferState) { + success = GL_FALSE; + } + else { + success = _mesa_convert_teximage(mesaFormat, mml->width, mml->height, + texImage->Data, mml->width * texelSize, + width, height, + format, type, pixels, packing); + } + + if (!success) { + /* First attempt at texture conversion failed. We may need to + * do fancy pixel transfer ops or convert from an obscure texture + * format. + */ + GLenum simpleFormat = _mesa_base_tex_format(ctx, internalFormat); + GLint comps = _mesa_components_in_format(simpleFormat); + GLubyte *tempImage; + + tempImage = MALLOC(width * height * comps * sizeof(GLubyte)); + + /* Apply pixel transfer ops and convert image format to something + * simple (format = simpleFormat, type = CHAN_TYPE). + */ + _mesa_transfer_teximage(ctx, 2, /* dimensions */ + simpleFormat, /* dest format */ + tempImage, /* dest addr */ + width, height, 1, /* src size */ + 0, 0, 0, /* dst offsets */ + width * comps, /* dstRowStride */ + 0, /* dstImageStride */ + format, type, pixels, packing /* src info */); + + /* this conversion better work! */ + success = _mesa_convert_teximage(mesaFormat, mml->width, mml->height, + texImage->Data, mml->width * texelSize, + width, height, + simpleFormat, CHAN_TYPE, tempImage, + &_mesa_native_packing); + assert(success); + FREE(tempImage); + } - if (ti->validated && ti->isInTM) { + if (ti->validated && ti->isInTM) { /*printf("reloadmipmaplevels\n");*/ fxTMReloadMipMapLevel(fxMesa, texObj, level); - } - else { + } + else { /*printf("invalidate2\n");*/ fxTexInvalidate(ctx,texObj); - } - } - else { - gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n"); - } + } } @@ -995,180 +1189,116 @@ fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; - tfxTexInfo *ti; - GLint wscale, hscale, dstStride; - tfxMipMapLevel *mml; - GLboolean result; - - if (!texObj->DriverData) { - gl_problem(ctx, "problem in fxDDTexSubImage2D"); - return; - } - - ti = fxTMGetTexInfo(texObj); - mml = &ti->mipmapLevel[level]; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + tfxTexInfo *ti; + GLint texelSize; + tfxMipMapLevel *mml; + GLboolean success; + MesaIntTexFormat mesaFormat; + + if (!texObj->DriverData) { + gl_problem(ctx, "problem in fxDDTexSubImage2D"); + return; + } - fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL, - NULL,NULL, &wscale, &hscale); + ti = fxTMGetTexInfo(texObj); + assert(ti); + mml = FX_MIPMAP_DATA(texImage); + assert(mml); - assert(mml->data); /* must have an existing texture image! */ + assert(texImage->Data); /* must have an existing texture image! */ - 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); + switch (mml->glideFormat) { + case GR_TEXFMT_INTENSITY_8: + texelSize = 1; + mesaFormat = MESA_I8; 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); + case GR_TEXFMT_ALPHA_8: + texelSize = 1; + mesaFormat = MESA_A8; 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); + case GR_TEXFMT_P_8: + texelSize = 1; + mesaFormat = MESA_C8; 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); + case GR_TEXFMT_ALPHA_INTENSITY_88: + texelSize = 2; + mesaFormat = MESA_A8_L8; 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); + case GR_TEXFMT_RGB_565: + texelSize = 2; + mesaFormat = MESA_R5_G6_B5; 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); + case GR_TEXFMT_ARGB_4444: + texelSize = 2; + mesaFormat = MESA_A4_R4_G4_B4; 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); + case GR_TEXFMT_ARGB_1555: + texelSize = 2; + mesaFormat = MESA_A1_R5_G5_B5; break; - default: + default: gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format"); - result = GL_FALSE; - } - - if (!result) { - return; - } - - if (ti->validated && ti->isInTM) - fxTMReloadMipMapLevel(fxMesa, texObj, level); - else - fxTexInvalidate(ctx, texObj); + return; + } -} + if (ctx->_ImageTransferState) { + success = GL_FALSE; + } + else { + success = _mesa_convert_texsubimage(mesaFormat, xoffset, yoffset, + mml->width, mml->height, + texImage->Data, + mml->width * texelSize, + width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + } + if (!success) { + /* Incoming image might need scale/bias or is in an uncommon format + * that _mesa_convert_texsubimage() can't deal with. Convert it to + * a simpler format now. + */ + + GLenum simpleFormat = _mesa_base_tex_format(ctx, texImage->IntFormat); + GLint comps = _mesa_components_in_format(simpleFormat); + GLubyte *tempImage; + GLboolean success; + + tempImage = MALLOC(width * height * comps * sizeof(GLubyte)); + + /* Apply pixel transfer ops and convert image format to something + * simple (format = simpleFormat, type = CHAN_TYPE). + */ + _mesa_transfer_teximage(ctx, 2, /* dimensions */ + simpleFormat, /* dest format */ + tempImage, /* dest addr */ + width, height, 1, /* src size */ + 0, 0, 0, /* dst offsets */ + width * comps, /* dstRowStride */ + 0, /* dstImageStride */ + format, type, pixels, packing /* src info */); + + /* this conversion better work! */ + success = _mesa_convert_texsubimage(mesaFormat, xoffset, yoffset, + mml->width, mml->height, + texImage->Data, + mml->width * texelSize, /* dstRowStride */ + width * mml->wScale, + height * mml->hScale, + width, height, + simpleFormat, CHAN_TYPE, tempImage, + &_mesa_native_packing); + assert(success); + FREE(tempImage); + } -#if 000 -GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level, - const struct gl_texture_object *texObj, - GLenum *formatOut, GLenum *typeOut, - GLboolean *freeImageOut ) -{ - tfxTexInfo *ti; - tfxMipMapLevel *mml; - - if (target != GL_TEXTURE_2D) - return NULL; - - if (!texObj->DriverData) - return NULL; - - ti = fxTMGetTexInfo(texObj); - mml = &ti->mipmapLevel[level]; - if (mml->data) { - MesaIntTexFormat mesaFormat; - GLenum glFormat; - struct gl_texture_image *texImage = texObj->Image[level]; - GLint srcStride; - - GLubyte *data = (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4); - if (!data) - return NULL; - - 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: - 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_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; - default: - gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage"); - return NULL; - } - _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, mml->data, - srcStride, texImage->Width, texImage->Height, - glFormat, data); - *formatOut = glFormat; - *typeOut = GL_UNSIGNED_BYTE; - *freeImageOut = GL_TRUE; - return data; - } - else { - return NULL; - } + if (ti->validated && ti->isInTM) + fxTMReloadMipMapLevel(fxMesa, texObj, level); + else + fxTexInvalidate(ctx, texObj); } -#endif - #else diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index c8876f7433d..a5a81dd5972 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -211,10 +211,14 @@ typedef struct MemRange_t { typedef struct { GLsizei width, height; /* image size */ + GLint wScale, hScale; /* image scale factor */ GrTextureFormat_t glideFormat; /* Glide image format */ - unsigned short *data; /* Glide-formated texture image */ } tfxMipMapLevel; +/* + * TDFX-specific texture object data. This hangs off of the + * struct gl_texture_object DriverData pointer. + */ typedef struct tfxTexInfo_t { struct tfxTexInfo *next; struct gl_texture_object *tObj; @@ -223,8 +227,6 @@ typedef struct tfxTexInfo_t { FxU32 whichTMU; GLboolean isInTM; - tfxMipMapLevel mipmapLevel[MAX_TEXTURE_LEVELS]; - MemRange *tm[FX_NUM_TMU]; GLint minLevel, maxLevel; @@ -300,7 +302,12 @@ typedef struct { #define FX_CONTEXT(ctx) ((fxMesaContext)((ctx)->DriverCtx)) -#define FX_TEXTURE_DATA(t) fxTMGetTexInfo((t)->_Current) + +#define FX_TEXTURE_DATA(texUnit) fxTMGetTexInfo((texUnit)->_Current) + +#define fxTMGetTexInfo(o) ((tfxTexInfo*)((o)->DriverData)) + +#define FX_MIPMAP_DATA(img) ((tfxMipMapLevel *) (img)->DriverData) #define BEGIN_BOARD_LOCK() #define END_BOARD_LOCK() @@ -570,7 +577,6 @@ extern void fxDDDepthFunc(GLcontext *, GLenum); extern void fxDDInitExtensions( GLcontext *ctx ); -#define fxTMGetTexInfo(o) ((tfxTexInfo*)((o)->DriverData)) extern void fxTMInit(fxMesaContext ctx); extern void fxTMClose(fxMesaContext ctx); extern void fxTMRestoreTextures_NoLock(fxMesaContext ctx); diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index b98ccedd3f9..9dc2d890ad8 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -349,7 +349,8 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G for (i=FX_largeLodValue(ti->info), l=ti->minLevel; i<=FX_smallLodValue(ti->info); - i++,l++) + i++,l++) { + struct gl_texture_image *texImage = tObj->Image[l]; FX_grTexDownloadMipMapLevel_NoLock(where, ti->tm[where]->startAddr, FX_valueToLod(i), @@ -357,7 +358,8 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[l].data); + texImage->Data); + } break; case FX_TMU_SPLIT: texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, @@ -373,6 +375,8 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G for (i=FX_largeLodValue(ti->info),l=ti->minLevel; i<=FX_smallLodValue(ti->info); i++,l++) { + struct gl_texture_image *texImage = tObj->Image[l]; + FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, ti->tm[FX_TMU0]->startAddr, FX_valueToLod(i), @@ -380,7 +384,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_ODD, - ti->mipmapLevel[l].data); + texImage->Data); FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, ti->tm[FX_TMU1]->startAddr, @@ -389,7 +393,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_EVEN, - ti->mipmapLevel[l].data); + texImage->Data); } break; case FX_TMU_BOTH: @@ -406,6 +410,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G for (i=FX_largeLodValue(ti->info),l=ti->minLevel; i<=FX_smallLodValue(ti->info); i++,l++) { + struct gl_texture_image *texImage = tObj->Image[l]; FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, ti->tm[FX_TMU0]->startAddr, FX_valueToLod(i), @@ -413,7 +418,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[l].data); + texImage->Data); FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, ti->tm[FX_TMU1]->startAddr, @@ -422,7 +427,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[l].data); + texImage->Data); } break; default: @@ -436,17 +441,27 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G ti->isInTM=GL_TRUE; } -void fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) { + +void +fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) +{ BEGIN_BOARD_LOCK(); fxTMMoveInTM_NoLock(fxMesa, tObj, where); END_BOARD_LOCK(); } -void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint level) + +void +fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint level) { - tfxTexInfo *ti=fxTMGetTexInfo(tObj); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); GrLOD_t lodlevel; GLint tmu; + struct gl_texture_image *texImage = tObj->Image[level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + assert(mml); if (!ti->validated) { fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n"); @@ -454,10 +469,10 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, exit(-1); } - tmu=(int)ti->whichTMU; + tmu = (int)ti->whichTMU; fxTMMoveInTM(fxMesa, tObj, tmu); - fxTexGetInfo(ti->mipmapLevel[0].width,ti->mipmapLevel[0].height, + fxTexGetInfo(mml->width, mml->height, &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); #ifdef FX_GLIDE3 @@ -475,7 +490,7 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[level].data); + texImage->Data); break; case FX_TMU_SPLIT: FX_grTexDownloadMipMapLevel(GR_TMU0, @@ -485,7 +500,7 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_ODD, - ti->mipmapLevel[level].data); + texImage->Data); FX_grTexDownloadMipMapLevel(GR_TMU1, ti->tm[GR_TMU1]->startAddr, @@ -494,7 +509,7 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_EVEN, - ti->mipmapLevel[level].data); + texImage->Data); break; case FX_TMU_BOTH: FX_grTexDownloadMipMapLevel(GR_TMU0, @@ -504,7 +519,7 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[level].data); + texImage->Data); FX_grTexDownloadMipMapLevel(GR_TMU1, ti->tm[GR_TMU1]->startAddr, @@ -513,7 +528,7 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->mipmapLevel[level].data); + texImage->Data); break; default: @@ -531,8 +546,12 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, GrLOD_t lodlevel; unsigned short *data; GLint tmu; + struct gl_texture_image *texImage = tObj->Image[level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); - if(!ti->validated) { + assert(mml); + + if (!ti->validated) { fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n"); fxCloseHardware(); exit(-1); @@ -541,15 +560,15 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, tmu=(int)ti->whichTMU; fxTMMoveInTM(fxMesa, tObj, tmu); - fxTexGetInfo(ti->mipmapLevel[0].width, ti->mipmapLevel[0].height, + fxTexGetInfo(mml->width, mml->height, &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if((ti->info.format==GR_TEXFMT_INTENSITY_8) || (ti->info.format==GR_TEXFMT_P_8) || (ti->info.format==GR_TEXFMT_ALPHA_8)) - data=ti->mipmapLevel[level].data+((yoffset*ti->mipmapLevel[level].width)>>1); + data = (GLushort *) texImage->Data + ((yoffset * mml->width) >> 1); else - data=ti->mipmapLevel[level].data+yoffset*ti->mipmapLevel[level].width; + data = (GLushort *) texImage->Data + yoffset * mml->width; switch(tmu) { case FX_TMU0: @@ -651,10 +670,15 @@ void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) fxTMMoveOutTM(fxMesa, tObj); for (i=0; imipmapLevel[i].data) { - FREE(ti->mipmapLevel[i].data); - ti->mipmapLevel[i].data = NULL; - } + struct gl_texture_image *texImage = tObj->Image[i]; + if (texImage->Data) { + FREE(texImage->Data); + texImage->Data = NULL; + } + if (texImage->DriverData) { + FREE(texImage->DriverData); + texImage->DriverData = NULL; + } } switch (ti->whichTMU) { case FX_TMU0: -- 2.30.2