summaryrefslogtreecommitdiff
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2001-02-06 23:35:49 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2001-02-06 23:35:49 +0000
commit78ad878b661d72ce1246b8c66ce97b7f67bed4e7 (patch)
treec63359b6b529df80b2640d0f27407dfba00ad277 /src/mesa/drivers
parentf378ab825c0c74aab263e7dec30194eead22c288 (diff)
updated texture image handling - STILL UNTESTED
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/glide/fxddtex.c712
-rw-r--r--src/mesa/drivers/glide/fxdrv.h16
-rw-r--r--src/mesa/drivers/glide/fxtexman.c72
3 files changed, 480 insertions, 320 deletions
diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c
index bc89917050..d8a386230e 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;i<MAX_TEXTURE_LEVELS;i++) {
- ti->mipmapLevel[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 c8876f7433..a5a81dd597 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 b98ccedd3f..9dc2d890ad 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; i<MAX_TEXTURE_LEVELS; i++) {
- if (ti->mipmapLevel[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: