updated texture image handling - STILL UNTESTED
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 6 Feb 2001 23:35:49 +0000 (23:35 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 6 Feb 2001 23:35:49 +0000 (23:35 +0000)
src/mesa/drivers/glide/fxddtex.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/glide/fxtexman.c

index bc89917..d8a3862 100644 (file)
@@ -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
index c8876f7..a5a81dd 100644 (file)
@@ -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);
index b98cced..9dc2d89 100644 (file)
@@ -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: