changes to accomodate texture compression
authorDaniel Borca <dborca@users.sourceforge.net>
Wed, 29 Oct 2003 14:40:43 +0000 (14:40 +0000)
committerDaniel Borca <dborca@users.sourceforge.net>
Wed, 29 Oct 2003 14:40:43 +0000 (14:40 +0000)
src/mesa/drivers/glide/fxapi.c
src/mesa/drivers/glide/fxdd.c
src/mesa/drivers/glide/fxddtex.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/glide/fxg.c
src/mesa/drivers/glide/fxg.h
src/mesa/drivers/glide/fxglidew.c
src/mesa/drivers/glide/fxglidew.h
src/mesa/drivers/glide/fxsetup.c
src/mesa/drivers/glide/fxtris.c

index 2ebb451b2dd8711ae07dd1569fc03f211b9b5cc6..b726240cba9789bdf436079c0c889a84fe29a322 100644 (file)
@@ -318,6 +318,7 @@ fxMesaCreateContext(GLuint win,
  }
 
  fxMesa->type = voodoo->type;
+ fxMesa->HavePalExt = voodoo->HavePalExt;
  fxMesa->HavePixExt = voodoo->HavePixExt;
  fxMesa->HaveTexFmt = voodoo->HaveTexFmt;
  fxMesa->HaveCmbExt = voodoo->HaveCmbExt;
index fec2ee9d72a5a2f697e1a483c88020b4302abf00..895271fcbacb54fb0b5fbfc2086fa9d3aa131000 100644 (file)
@@ -1427,6 +1427,13 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxDDInitExtensions(ctx);
 
+#if 0
+   /* [dBorca] Hack alert:
+    * do we want dither? It just looks bad...
+    */
+   grEnable(GR_ALLOW_MIPMAP_DITHER);
+   grTexNccTable(GR_NCCTABLE_NCC0); /* set this once... no multipass */
+#endif
    grGlideGetState((GrState *) fxMesa->state);
 
    return 1;
@@ -1474,15 +1481,36 @@ fxDDInitExtensions(GLcontext * ctx)
       _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" );
    }
 
-#if 0 /* not ready yet */
-      /* banshee/avenger should enable this for NCC */
-      _mesa_enable_extension( ctx, "GL_ARB_texture_compression" );
-#endif
-   if (0/*IS_NAPALM*/) {
-      /* tex_compress: not ready yet */
-      _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" );
-      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
-      /*_mesa_enable_extension( ctx, "GL_S3_s3tc" );*/
+   /* [dBorca] Hack alert:
+    * True texture compression can be done only on Napalm.
+    * We will advertise, however, generic texture compression
+    * on all Voodoo cards; the Mesa logic allows us to eventually
+    * fallback to uncompressed. This will fix those dumb applications
+    * which refuse to run w/o texture compression! We actually _can_
+    * do texture compression for pre-Napalm cores, through NCC. But
+    * NCC poses many issues:
+    * 1) NCC w/o DITHER_ERR has poor quality and NCC w/ DITHER_ERR is
+    *    damn slow!
+    * 2) NCC compression cannot be used with multitexturing, because
+    *    the decompression tables are not per TMU anymore (bear in mind
+    *    that earlier Voodoos could handle 2 NCC tables for each TMU --
+    *    just look for POINTCAST_PALETTE). As a last resort, we could
+    *    fake NCC multitexturing through multipass rendering, but...
+    *    ohwell, it's not worth the effort...
+    *    This stand true for multitexturing palletized textures.
+    * 3) since NCC is not an OpenGL standard (as opposed to FXT1), we
+    *    would need to plug deeper into the core... First, we would need to
+    *    bind NCC to GL_COMPRESSED_RGB[A]. Then, we would need to trick
+    *    Mesa into reporting our texture as compressed. Last, we would need
+    *    to stash the NCC decompression table into the mipmap data and adjust
+    *    CompressedSize accordingly!
+    */
+   _mesa_enable_extension(ctx, "GL_ARB_texture_compression");
+
+   if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+      _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1");
+      _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
+      /*_mesa_enable_extension(ctx, "GL_S3_s3tc");*/
    }
 
    if (fxMesa->HaveCmbExt) {
@@ -1697,11 +1725,13 @@ fxSetupDDPointers(GLcontext * ctx)
    ctx->Driver.TexSubImage2D = fxDDTexSubImage2D;
    ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
    ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
-   ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+   ctx->Driver.CompressedTexImage2D = fxDDCompressedTexImage2D;
    ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
    ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
-   ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+   ctx->Driver.CompressedTexSubImage2D = fxDDCompressedTexSubImage2D;
    ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+   ctx->Driver.IsCompressedFormat = fxDDIsCompressedFormat;
+   ctx->Driver.CompressedTextureSize = fxDDCompressedTextureSize;
    ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
    ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
    ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
index 8b64a8e2c6855438f87e6cddbd2eabebfb929a43..bfff09aea17c16f133259f0b137679cc88d71460 100644 (file)
@@ -367,8 +367,8 @@ fxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj)
 /*
  * Convert a gl_color_table texture palette to Glide's format.
  */
-static void
-convertPalette(FxU32 data[256], const struct gl_color_table *table)
+static GrTexTable_t
+convertPalette(const fxMesaContext fxMesa, FxU32 data[256], const struct gl_color_table *table)
 {
    const GLubyte *tableUB = (const GLubyte *) table->Table;
    GLint width = table->Size;
@@ -386,7 +386,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table)
         a = tableUB[i];
         data[i] = (a << 24) | (r << 16) | (g << 8) | b;
       }
-      break;
+      return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE;
    case GL_LUMINANCE:
       for (i = 0; i < width; i++) {
         r = tableUB[i];
@@ -395,21 +395,22 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table)
         a = 255;
         data[i] = (a << 24) | (r << 16) | (g << 8) | b;
       }
-      break;
+      return GR_TEXTABLE_PALETTE;
    case GL_ALPHA:
       for (i = 0; i < width; i++) {
         r = g = b = 255;
         a = tableUB[i];
         data[i] = (a << 24) | (r << 16) | (g << 8) | b;
       }
-      break;
+      return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE;
    case GL_LUMINANCE_ALPHA:
       for (i = 0; i < width; i++) {
         r = g = b = tableUB[i * 2 + 0];
         a = tableUB[i * 2 + 1];
         data[i] = (a << 24) | (r << 16) | (g << 8) | b;
       }
-      break;
+      return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE;
+   default:
    case GL_RGB:
       for (i = 0; i < width; i++) {
         r = tableUB[i * 3 + 0];
@@ -418,7 +419,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table)
         a = 255;
         data[i] = (a << 24) | (r << 16) | (g << 8) | b;
       }
-      break;
+      return GR_TEXTABLE_PALETTE;
    case GL_RGBA:
       for (i = 0; i < width; i++) {
         r = tableUB[i * 4 + 0];
@@ -427,7 +428,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table)
         a = tableUB[i * 4 + 3];
         data[i] = (a << 24) | (r << 16) | (g << 8) | b;
       }
-      break;
+      return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE;
    }
 }
 
@@ -447,7 +448,7 @@ fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj)
       if (!tObj->DriverData)
         tObj->DriverData = fxAllocTexObjData(fxMesa);
       ti = fxTMGetTexInfo(tObj);
-      convertPalette(ti->palette.data, &tObj->Palette);
+      ti->paltype = convertPalette(fxMesa, ti->palette.data, &tObj->Palette);
       fxTexInvalidate(ctx, tObj);
    }
    else {
@@ -455,7 +456,7 @@ fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj)
       if (TDFX_DEBUG & VERBOSE_DRIVER) {
         fprintf(stderr, "%s(global)\n", __FUNCTION__);
       }
-      convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
+      fxMesa->glbPalType = convertPalette(fxMesa, fxMesa->glbPalette.data, &ctx->Texture.Palette);
       fxMesa->new_state |= FX_NEW_TEXTURING;
    }
 }
@@ -473,7 +474,7 @@ fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state)
    if (state) {
       fxMesa->haveGlobalPaletteTexture = 1;
 
-      grTexDownloadTable(GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
+      grTexDownloadTable(fxMesa->glbPalType, &(fxMesa->glbPalette));
    }
    else {
       fxMesa->haveGlobalPaletteTexture = 0;
@@ -856,6 +857,127 @@ PrintTexture(int w, int h, int c, const GLubyte * data)
 }
 
 
+#define fxDDIsCompressedFormatMacro(internalFormat) (\
+          ((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) ||      \
+          ((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX) ||     \
+          ((internalFormat) == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) ||  \
+          ((internalFormat) == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || \
+          ((internalFormat) == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || \
+          ((internalFormat) == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT))
+
+/* [dBorca]
+ * we are handling differently the above formats from the generic
+ * GL_COMPRESSED_RGB[A]. For this, we will never call the function
+ * below! It is just a callback for core functions.
+ */
+
+GLboolean fxDDIsCompressedFormat ( GLcontext *ctx, GLenum internalFormat )
+{
+ if (fxDDIsCompressedFormatMacro(internalFormat)) {
+    return GL_TRUE;
+ }
+
+#if FX_TC_NCC || FX_TC_NAPALM
+ if ((internalFormat == GL_COMPRESSED_RGB) || (internalFormat == GL_COMPRESSED_RGBA)) {
+    return GL_TRUE;
+ }
+#endif
+
+ return GL_FALSE;
+}
+
+
+GLuint fxDDCompressedTextureSize (GLcontext *ctx,
+                                  GLsizei width, GLsizei height, GLsizei depth,
+                                  GLenum format)
+{
+ GLuint size;
+ int wScale, hScale;
+
+ ASSERT(depth == 1);
+
+ /* Determine width and height scale factors for texture.
+  * Remember, Glide is limited to 8:1 aspect ratios.
+  */
+ fxTexGetInfo(width, height,
+              NULL,       /* lod level          */
+              NULL,       /* aspect ratio       */
+              NULL, NULL, /* sscale, tscale     */
+              &wScale, &hScale);
+
+ width *= wScale;
+ height *= hScale;
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+    /* round up to multiple of 4 */
+    size = ((width + 7) / 8) * ((height + 3) / 4) * 16;
+    /* Textures smaller than 4x4 will effectively be made into 4x4 and
+     * take 8 bytes.
+     */
+    if (size < 16)
+       size = 16;
+    return size;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+    /* round up width, height to next multiple of 4 */
+    width = (width + 3) & ~3;
+    height = (height + 3) & ~3;
+    /* 8 bytes per 4x4 tile of RGB[A] texels */
+    size = (width * height * 8) / 16;
+    /* Textures smaller than 4x4 will effectively be made into 4x4 and
+     * take 8 bytes.
+     */
+    if (size < 8)
+       size = 8;
+    return size;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+    /* round up width, height to next multiple of 4 */
+    width = (width + 3) & ~3;
+    height = (height + 3) & ~3;
+    /* 16 bytes per 4x4 tile of RGBA texels */
+    size = width * height; /* simple! */
+    /* Textures smaller than 4x4 will effectively be made into 4x4 and
+     * take 16 bytes.
+     */
+    if (size < 16)
+       size = 16;
+    return size;
+ case GL_COMPRESSED_RGB:
+#if FX_TC_NAPALM
+    {
+     fxMesaContext fxMesa = FX_CONTEXT(ctx);
+     if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+        return fxDDCompressedTextureSize(ctx, width, height, 1, GL_COMPRESSED_RGB_FXT1_3DFX);
+     }
+    }
+#endif
+#if FX_TC_NCC
+    /* should really use `txBitsPerPixel' instead of 8; also add NCC table */
+    return (width * height * 8 >> 3) + 12 * 4;
+#endif
+ case GL_COMPRESSED_RGBA:
+#if FX_TC_NAPALM
+    {
+     fxMesaContext fxMesa = FX_CONTEXT(ctx);
+     if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+        return fxDDCompressedTextureSize(ctx, width, height, 1, GL_COMPRESSED_RGBA_FXT1_3DFX);
+     }
+    }
+#endif
+#if FX_TC_NCC
+    /* should really use `txBitsPerPixel' instead of 16; also add NCC table */
+    return (width * height * 16 >> 3) + 12 * 4;
+#endif
+ default:
+    _mesa_problem(ctx, "bad texformat in fxDDCompressedTextureSize");
+    return 0;
+ }
+}
+
+
 const struct gl_texture_format *
 fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
                          GLenum srcFormat, GLenum srcType )
@@ -871,7 +993,7 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
     *                 GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
     *    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     * 3) we get here with internalFormat==3 and return either
-    *    _mesa_texformat_argb565 or _mesa_texformat_argb8888
+    *    _mesa_texformat_rgb565 or _mesa_texformat_argb8888
     * 4) at some point, we encounter total rasterization fallback
     * 5) displaying a polygon with the above textures yield garbage on areas
     *    where pixel is larger than a texel, because our already set texel
@@ -966,7 +1088,6 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
                           : &_mesa_texformat_argb4444;
    case GL_RGB5_A1:
       return &_mesa_texformat_argb1555;
-#if 0
    /* GL_EXT_texture_compression_s3tc */
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
       return &_mesa_texformat_rgb_dxt1;
@@ -976,10 +1097,11 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
       return &_mesa_texformat_rgba_dxt3;
    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
       return &_mesa_texformat_rgba_dxt5;
-   /*case GL_COMPRESSED_RGB_FXT1_3DFX:
-     case GL_COMPRESSED_RGBA_FXT1_3DFX:
-      return blah;*/
-#endif
+   /* GL_3DFX_texture_compression_FXT1 */
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+      return &_mesa_texformat_rgb_fxt1;
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      return &_mesa_texformat_rgba_fxt1;
    default:
       _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat");
       return NULL;
@@ -1009,7 +1131,9 @@ fxGlideFormat(GLint mesaFormat)
       return GR_TEXFMT_ARGB_1555;
    case MESA_FORMAT_ARGB8888:
       return GR_TEXFMT_ARGB_8888;
-#if 0
+   case MESA_FORMAT_RGB_FXT1:
+   case MESA_FORMAT_RGBA_FXT1:
+     return GR_TEXFMT_ARGB_CMP_FXT1;
    case MESA_FORMAT_RGB_DXT1:
    case MESA_FORMAT_RGBA_DXT1:
      return GR_TEXFMT_ARGB_CMP_DXT1;
@@ -1017,11 +1141,6 @@ fxGlideFormat(GLint mesaFormat)
      return GR_TEXFMT_ARGB_CMP_DXT3;
    case MESA_FORMAT_RGBA_DXT5:
      return GR_TEXFMT_ARGB_CMP_DXT5;
-   /*case MESA_FORMAT_ARGB_CMP_FXT1:
-     return GR_TEXFMT_ARGB_CMP_FXT1;
-   case MESA_FORMAT_RGB_CMP_FXT1:
-     return GL_COMPRESSED_RGBA_FXT1_3DFX;*/
-#endif
    default:
       _mesa_problem(NULL, "Unexpected format in fxGlideFormat");
       return 0;
@@ -1051,13 +1170,13 @@ fxFetchFunction(GLint mesaFormat)
       return fetch_r5g5b5a1;
    case MESA_FORMAT_ARGB8888:
       return fetch_a8r8g8b8;
-#if 0
+   case MESA_FORMAT_RGB_FXT1:
+   case MESA_FORMAT_RGBA_FXT1:
    case MESA_FORMAT_RGB_DXT1:
    case MESA_FORMAT_RGBA_DXT1:
    case MESA_FORMAT_RGBA_DXT3:
    case MESA_FORMAT_RGBA_DXT5:
      return fetch_r4g4b4a4;
-#endif
    default:
       _mesa_problem(NULL, "Unexpected format in fxFetchFunction");
       return NULL;
@@ -1077,6 +1196,10 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
    tfxMipMapLevel *mml;
    GLint texelBytes;
 
+   GLvoid *_final_texImage_Data;
+   const struct gl_texture_format *_final_texImage_TexFormat;
+   GLboolean isCompressed = fxDDIsCompressedFormatMacro(internalFormat);
+
    if (TDFX_DEBUG & VERBOSE_TEXTURE) {
        fprintf(stderr, "fxDDTexImage2D: id=%d int 0x%x  format 0x%x  type 0x%x  %dx%d\n",
                        texObj->Name, texImage->IntFormat, format, type,
@@ -1121,6 +1244,55 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
    texelBytes = texImage->TexFormat->TexelBytes;
    /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
 
+   mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
+   /* dirty trick: will thrash CopyTex[Sub]Image */
+#if FX_TC_NCC || FX_TC_NAPALM
+   if (internalFormat == GL_COMPRESSED_RGB) {
+#if FX_TC_NCC
+      isCompressed = GL_TRUE;
+      mml->glideFormat = GR_TEXFMT_YIQ_422;
+#endif
+#if FX_TC_NAPALM
+      if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+         isCompressed = GL_TRUE;
+         mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1;
+      }
+#endif
+   } else if (internalFormat == GL_COMPRESSED_RGBA) {
+#if FX_TC_NCC
+      isCompressed = GL_TRUE;
+      mml->glideFormat = GR_TEXFMT_AYIQ_8422;
+#endif
+#if FX_TC_NAPALM
+      if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+         isCompressed = GL_TRUE;
+         mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1;
+      }
+#endif
+   }
+#endif
+
+   /* allocate mipmap buffer */
+   assert(!texImage->Data);
+   if (isCompressed) {
+      texImage->Data = MESA_PBUFFER_ALLOC(texImage->CompressedSize);
+      texelBytes = 4;
+      _final_texImage_TexFormat = &_mesa_texformat_argb8888;
+      _final_texImage_Data = MALLOC(mml->width * mml->height * 4);
+      if (!_final_texImage_Data) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+         return;
+      }
+   } else {
+      texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
+      _final_texImage_TexFormat = texImage->TexFormat;
+      _final_texImage_Data = texImage->Data;
+   }
+   if (!texImage->Data) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+      return;
+   }
+
    if (mml->wScale != 1 || mml->hScale != 1) {
       /* rescale image to overcome 1:8 aspect limitation */
       GLvoid *tempImage;
@@ -1131,51 +1303,57 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
       }
       /* unpack image, apply transfer ops and store in tempImage */
       _mesa_transfer_teximage(ctx, 2, texImage->Format,
-                              texImage->TexFormat,
+                              _final_texImage_TexFormat,
                               tempImage,
                               width, height, 1, 0, 0, 0,
                               width * texelBytes,
                               0, /* dstImageStride */
                               format, type, pixels, packing);
-      assert(!texImage->Data);
-      texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
-      if (!texImage->Data) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
-         FREE(tempImage);
-         return;
-      }
       _mesa_rescale_teximage2d(texelBytes,
                                mml->width * texelBytes, /* dst stride */
                                width, height,
                                mml->width, mml->height,
-                               tempImage /*src*/, texImage->Data /*dst*/ );
+                               tempImage /*src*/, _final_texImage_Data /*dst*/ );
       FREE(tempImage);
    }
    else {
       /* no rescaling needed */
-      assert(!texImage->Data);
-      texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
-      if (!texImage->Data) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
-         return;
-      }
       /* unpack image, apply transfer ops and store in texImage->Data */
       _mesa_transfer_teximage(ctx, 2, texImage->Format,
-                              texImage->TexFormat, texImage->Data,
+                              _final_texImage_TexFormat, _final_texImage_Data,
                               width, height, 1, 0, 0, 0,
                               texImage->Width * texelBytes,
                               0, /* dstImageStride */
                               format, type, pixels, packing);
    }
 
-   mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
+   /* now compress */
+   if (isCompressed) {
+#if FX_TC_NCC
+      if ((mml->glideFormat == GR_TEXFMT_AYIQ_8422) ||
+          (mml->glideFormat == GR_TEXFMT_YIQ_422)) {
+         TxMip txMip, pxMip;
+         txMip.width = mml->width;
+         txMip.height = mml->height;
+         txMip.depth = 1;
+         txMip.data[0] = _final_texImage_Data;
+         pxMip.data[0] = texImage->Data;
+         fxMesa->Glide.txMipQuantize(&pxMip, &txMip, mml->glideFormat, TX_DITHER_ERR, TX_COMPRESSION_STATISTICAL);
+         fxMesa->Glide.txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal);
+         MEMCPY((char *)texImage->Data + texImage->CompressedSize - 12 * 4, &(ti->palette), 12 * 4);
+      } else
+#endif
+      fxMesa->Glide.txImgQuantize(texImage->Data, _final_texImage_Data, mml->width, mml->height, mml->glideFormat, TX_DITHER_NONE);
+      FREE(_final_texImage_Data);
+   }
+
    ti->info.format = mml->glideFormat;
    texImage->FetchTexel = fxFetchFunction(texImage->TexFormat->MesaFormat);
 
    /* [dBorca]
     * Hack alert: unsure...
     */
-   if (!(fxMesa->new_state & FX_NEW_TEXTURING) && ti->validated && ti->isInTM) {
+   if (0 && ti->validated && ti->isInTM) {
       /*fprintf(stderr, "reloadmipmaplevels\n"); */
       fxTMReloadMipMapLevel(fxMesa, texObj, level);
    }
@@ -1200,6 +1378,10 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
    tfxMipMapLevel *mml;
    GLint texelBytes;
 
+   /* [dBorca] Hack alert:
+    * fix the goddamn texture compression here
+    */
+
    if (TDFX_DEBUG & VERBOSE_TEXTURE) {
        fprintf(stderr, "fxDDTexSubImage2D: id=%d\n", texObj->Name);
    }
@@ -1269,7 +1451,181 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
    /* [dBorca]
     * Hack alert: unsure...
     */
-   if (!(fxMesa->new_state & FX_NEW_TEXTURING) && ti->validated && ti->isInTM)
+   if (0 && ti->validated && ti->isInTM)
+      fxTMReloadMipMapLevel(fxMesa, texObj, level);
+   else
+      fxTexInvalidate(ctx, texObj);
+}
+
+
+void
+fxDDCompressedTexImage2D (GLcontext *ctx, GLenum target,
+                          GLint level, GLint internalFormat,
+                          GLsizei width, GLsizei height, GLint border,
+                          GLsizei imageSize, const GLvoid *data,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage)
+{
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   GrTextureFormat_t gldFormat;
+   tfxTexInfo *ti;
+   tfxMipMapLevel *mml;
+   GLint dstWidth, dstHeight, wScale, hScale;
+
+   if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+       fprintf(stderr, "fxDDCompressedTexImage2D: id=%d int 0x%x  %dx%d\n",
+                       texObj->Name, internalFormat,
+                       width, height);
+   }
+
+   if (!fxIsTexSupported(target, internalFormat, texImage)) {
+      _mesa_problem(NULL, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
+      return;
+   }
+
+#if FX_TC_NCC || FX_TC_NAPALM
+   if ((internalFormat != GL_COMPRESSED_RGB) && (internalFormat != GL_COMPRESSED_RGBA))
+#endif
+   if (!fxDDIsCompressedFormatMacro(internalFormat)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)");
+      return;
+   }
+
+   if (!texObj->DriverData) {
+      texObj->DriverData = fxAllocTexObjData(fxMesa);
+      if (!texObj->DriverData) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+         return;
+      }
+   }
+   ti = fxTMGetTexInfo(texObj);
+
+   if (!texImage->DriverData) {
+      texImage->DriverData = CALLOC(sizeof(tfxMipMapLevel));
+      if (!texImage->DriverData) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+         return;
+      }
+   }
+   mml = FX_MIPMAP_DATA(texImage);
+
+   /* Determine the appropriate Glide texel format,
+    * given the user's internal texture format hint.
+    */
+   gldFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
+#if FX_TC_NCC || FX_TC_NAPALM
+   if (internalFormat == GL_COMPRESSED_RGB) {
+#if FX_TC_NCC
+      gldFormat = GR_TEXFMT_YIQ_422;
+#endif
+#if FX_TC_NAPALM
+      if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+         gldFormat = GR_TEXFMT_ARGB_CMP_FXT1;
+      }
+#endif
+   } else if (internalFormat == GL_COMPRESSED_RGBA) {
+#if FX_TC_NCC
+      gldFormat = GR_TEXFMT_AYIQ_8422;
+#endif
+#if FX_TC_NAPALM
+      if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
+         gldFormat = GR_TEXFMT_ARGB_CMP_FXT1;
+      }
+#endif
+   }
+#endif
+
+   /* Determine width and height scale factors for texture.
+    * Remember, Glide is limited to 8:1 aspect ratios.
+    */
+   fxTexGetInfo(width, height,
+                NULL,       /* lod level          */
+                NULL,       /* aspect ratio       */
+                NULL, NULL, /* sscale, tscale     */
+                &wScale, &hScale);
+   dstWidth = width * wScale;
+   dstHeight = height * hScale;
+
+   /* allocate new storage for texture image, if needed */
+   if (!texImage->Data) {
+      texImage->Data = MESA_PBUFFER_ALLOC(imageSize);
+      if (!texImage->Data) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+         return;
+      }
+   }
+
+   /* save the texture data */
+   MEMCPY(texImage->Data, data, imageSize);
+#if FX_TC_NCC
+   if ((gldFormat == GR_TEXFMT_AYIQ_8422) ||
+       (gldFormat == GR_TEXFMT_YIQ_422)) {
+      MEMCPY(&(ti->palette), (char *)texImage->Data + imageSize - 12 * 4, 12 * 4);
+   }
+#endif
+
+   /* [dBorca] Hack alert:
+    * what about different size/texel? other anomalies? SW rescaling?
+    */
+   if (1 || mml->glideFormat != gldFormat ||
+      mml->width != dstWidth || mml->height != dstHeight ||
+      !ti->validated || !ti->isInTM || (fxMesa->new_state & FX_NEW_TEXTURING)) {
+      mml->glideFormat = gldFormat;
+      mml->width = dstWidth;
+      mml->height = dstHeight;
+      fxTexInvalidate(ctx, texObj);
+   } else {
+      fxTMReloadMipMapLevel(fxMesa, texObj, level);
+   }
+}
+
+
+void
+fxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
+                             GLint level, GLint xoffset,
+                             GLint yoffset, GLsizei width,
+                             GLint height, GLenum format,
+                             GLsizei imageSize, const GLvoid *data,
+                             struct gl_texture_object *texObj,
+                             struct gl_texture_image *texImage )
+{
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   tfxTexInfo *ti;
+   tfxMipMapLevel *mml;
+
+   if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+       fprintf(stderr, "fxDDCompressedTexSubImage2D: id=%d\n", texObj->Name);
+   }
+
+   ti = fxTMGetTexInfo(texObj);
+   assert(ti);
+   mml = FX_MIPMAP_DATA(texImage);
+   assert(mml);
+
+   /*
+    * We punt if we are not replacing the entire image.  This
+    * is allowed by the spec.
+    *
+    * [dBorca] Hack alert:
+    * ohwell, we should NOT! Look into _mesa_store_compressed_texsubimage2d
+    * on how to calculate the sub-image.
+    */
+   if ((xoffset != 0) && (yoffset != 0)
+       && (width != texImage->Width)
+       && (height != texImage->Height)) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(CHICKEN)");
+      return;
+   }
+
+   /* [dBorca] Hack alert:
+    * what about different size/texel? other anomalies? SW rescaling?
+    */
+   MEMCPY(texImage->Data, data, imageSize);
+
+   /* [dBorca]
+    * Hack alert: unsure...
+    */
+   if (0 && ti->validated && ti->isInTM)
       fxTMReloadMipMapLevel(fxMesa, texObj, level);
    else
       fxTexInvalidate(ctx, texObj);
index 996c1be2bb444b394786f0f494324fa0cb64cf55..46b53574a99cbffc238df1e153853144bc4bfb40 100644 (file)
@@ -286,6 +286,7 @@ typedef struct tfxTexInfo_t
 
    GLfloat sScale, tScale;
 
+   GrTexTable_t paltype;
    GuTexPalette palette;
 
    GLboolean fixedPalette;
@@ -426,6 +427,7 @@ typedef void (*fx_point_func) (fxMesaContext, GrVertex *);
 
 struct tfxMesaContext
 {
+   GrTexTable_t glbPalType;
    GuTexPalette glbPalette;
 
    GLcontext *glCtx;           /* the core Mesa context */
@@ -534,6 +536,7 @@ struct tfxMesaContext
     * from `glbHWConfig' when creating a new context...
     */
    GrSstType type;
+   FxBool HavePalExt;  /* PALETTE6666 */
    FxBool HavePixExt;  /* PIXEXT */
    FxBool HaveTexFmt;  /* TEXFMT */
    FxBool HaveCmbExt;  /* COMBINE */
@@ -577,6 +580,10 @@ extern void fxPrintTextureData(tfxTexInfo * ti);
 extern const struct gl_texture_format *
 fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
                          GLenum srcFormat, GLenum srcType );
+extern GLboolean fxDDIsCompressedFormat (GLcontext *ctx, GLenum internalFormat);
+extern GLuint fxDDCompressedTextureSize (GLcontext *ctx,
+                                         GLsizei width, GLsizei height, GLsizei depth,
+                                         GLenum format);
 extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
                           GLint internalFormat, GLint width, GLint height,
                           GLint border, GLenum format, GLenum type,
@@ -584,7 +591,6 @@ extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
                           const struct gl_pixelstore_attrib *packing,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage);
-
 extern void fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
                              GLint xoffset, GLint yoffset,
                              GLsizei width, GLsizei height,
@@ -593,6 +599,19 @@ extern void fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
                              const struct gl_pixelstore_attrib *packing,
                              struct gl_texture_object *texObj,
                              struct gl_texture_image *texImage);
+extern void fxDDCompressedTexImage2D(GLcontext *ctx, GLenum target,
+                                     GLint level, GLint internalFormat,
+                                     GLsizei width, GLsizei height, GLint border,
+                                     GLsizei imageSize, const GLvoid *data,
+                                     struct gl_texture_object *texObj,
+                                     struct gl_texture_image *texImage);
+extern void fxDDCompressedTexSubImage2D(GLcontext *ctx, GLenum target,
+                                        GLint level, GLint xoffset,
+                                        GLint yoffset, GLsizei width,
+                                        GLint height, GLenum format,
+                                        GLsizei imageSize, const GLvoid *data,
+                                        struct gl_texture_object *texObj,
+                                        struct gl_texture_image *texImage);
 extern void fxDDTexEnv(GLcontext *, GLenum, GLenum, const GLfloat *);
 extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *,
                         GLenum, const GLfloat *);
index bb162c5808ccd35f7ffbf2db49b488f0e17f8b14..1ead397fddb26c363ceb4ad2537b92fb2cc5be4f 100644 (file)
 #define DEBUG_TRAP_internal
 #include "fxg.h"
 
+/* texus.h */
+FX_ENTRY int FX_CALL txBitsPerPixel (GrTextureFormat_t format);
+FX_ENTRY void FX_CALL txImgQuantize (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither);
+FX_ENTRY void FX_CALL txMipQuantize (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp);
+FX_ENTRY void FX_CALL txPalToNcc (GuNccTable *ncc_table, const FxU32 *pal);
+FX_ENTRY void FX_CALL txErrorSetCallback (TxErrorCallbackFnc_t fnc, TxErrorCallbackFnc_t *old_fnc);
+/* texus.h */
+
 
 
 /****************************************************************************\
 * logging                                                                    *
 \****************************************************************************/
 #if DEBUG_TRAP
-#define TRAP_LOG trap_printf
+#define TRAP_LOG trp_printf
 #ifdef __GNUC__
 __attribute__ ((format(printf, 1, 2)))
 #endif /* __GNUC__ */
-int trap_printf (const char *format, ...)
+int trp_printf (const char *format, ...)
 {
  va_list arg;
  int n;
@@ -234,8 +242,10 @@ const char *TRP_BLEND (GrAlphaBlendFnc_t func)
         TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SRC_COLOR);
         /*TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_DST_COLOR); ==GR_BLEND_ONE_MINUS_SRC_COLOR*/
         TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_DST_ALPHA);
-        TRAP_CASE_STRING(GR_BLEND_RESERVED_8);
-        TRAP_CASE_STRING(GR_BLEND_RESERVED_9);
+        TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT);
+        /*TRAP_CASE_STRING(GR_BLEND_RESERVED_8); ==GR_BLEND_SAME_COLOR_EXT*/
+        TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT);
+        /*TRAP_CASE_STRING(GR_BLEND_RESERVED_9); ==GR_BLEND_ONE_MINUS_SAME_COLOR_EXT*/
         TRAP_CASE_STRING(GR_BLEND_RESERVED_A);
         TRAP_CASE_STRING(GR_BLEND_RESERVED_B);
         TRAP_CASE_STRING(GR_BLEND_RESERVED_C);
@@ -243,8 +253,6 @@ const char *TRP_BLEND (GrAlphaBlendFnc_t func)
         TRAP_CASE_STRING(GR_BLEND_RESERVED_E);
         TRAP_CASE_STRING(GR_BLEND_ALPHA_SATURATE);
         /*TRAP_CASE_STRING(GR_BLEND_PREFOG_COLOR); ==GR_BLEND_ALPHA_SATURATE*/
-        TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT);
-        TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT);
         TRAP_NODEFAULT;
  }
 }
@@ -785,6 +793,25 @@ const char *TRP_TMU (GrChipID_t tmu)
  }
 }
 
+const char *TRP_TXDITHER (FxU32 dither)
+{
+ switch (dither) {
+        TRAP_CASE_STRING(TX_DITHER_NONE);
+        TRAP_CASE_STRING(TX_DITHER_4x4);
+        TRAP_CASE_STRING(TX_DITHER_ERR);
+        TRAP_NODEFAULT;
+ }
+}
+
+const char *TRP_TXCOMPRESS (FxU32 compress)
+{
+ switch (compress) {
+        TRAP_CASE_STRING(TX_COMPRESSION_STATISTICAL);
+        TRAP_CASE_STRING(TX_COMPRESSION_HEURISTIC);
+        TRAP_NODEFAULT;
+ }
+}
+
 
 
 /****************************************************************************\
@@ -801,6 +828,11 @@ void (FX_CALL *real_grChromaRangeExt) (GrColor_t color, GrColor_t range, GrChrom
 void (FX_CALL *real_grTexChromaModeExt) (GrChipID_t tmu, GrChromakeyMode_t mode);
 void (FX_CALL *real_grTexChromaRangeExt) (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode);
 
+/* pointcast */
+void (FX_CALL *real_grTexDownloadTableExt) (GrChipID_t tmu, GrTexTable_t type, void *data);
+void (FX_CALL *real_grTexDownloadTablePartialExt) (GrChipID_t tmu, GrTexTable_t type, void *data, int start, int end);
+void (FX_CALL *real_grTexNCCTableExt) (GrChipID_t tmu, GrNCCTable_t table);
+
 /* tbext */
 void (FX_CALL *real_grTextureBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask);
 void (FX_CALL *real_grTextureAuxBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask);
@@ -1857,6 +1889,41 @@ void FX_CALL trap_grTexChromaRangeExt (GrChipID_t           tmu,
  assert(real_grTexChromaRangeExt);
  (*real_grTexChromaRangeExt)(tmu, min, max, mode);
 #undef FN_NAME
+}
+
+        /* pointcast */
+void FX_CALL trap_grTexDownloadTableExt (GrChipID_t   tmu,
+                                         GrTexTable_t type,
+                                         void         *data)
+{
+#define FN_NAME "grTexDownloadTableExt"
+ TRAP_LOG("%s(%s, %s, %p)\n", FN_NAME, TRP_TMU(tmu), TRP_TABLE(type), data);
+ assert(real_grTexDownloadTableExt);
+ (*real_grTexDownloadTableExt)(tmu, type, data);
+#undef FN_NAME
+}
+
+void FX_CALL trap_grTexDownloadTablePartialExt (GrChipID_t   tmu,
+                                                GrTexTable_t type,
+                                                void         *data,
+                                                int          start,
+                                                int          end)
+{
+#define FN_NAME "grTexDownloadTablePartialExt"
+ TRAP_LOG("%s(%s, %s, %p, %d, %d)\n", FN_NAME, TRP_TMU(tmu), TRP_TABLE(type), data, start, end);
+ assert(real_grTexDownloadTablePartialExt);
+ (*real_grTexDownloadTablePartialExt)(tmu, type, data, start, end);
+#undef FN_NAME
+}
+
+void FX_CALL trap_grTexNCCTableExt (GrChipID_t   tmu,
+                                    GrNCCTable_t table)
+{
+#define FN_NAME "grTexNCCTableExt"
+ TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_NCC(table));
+ assert(real_grTexNCCTableExt);
+ (*real_grTexNCCTableExt)(tmu, table);
+#undef FN_NAME
 }
 
         /* tbext */
@@ -2089,10 +2156,94 @@ void FX_CALL trap_grTBufferWriteMaskExt (FxU32 tmask)
  (*real_grTBufferWriteMaskExt)(tmask);
 #undef FN_NAME
 }
+
+/*
+** texus functions
+*/
+int FX_CALL trap_txBitsPerPixel (GrTextureFormat_t format)
+{
+#define FN_NAME "txBitsPerPixel"
+ int rv;
+ TRAP_LOG("%s(%s)\n", FN_NAME, TRP_TEXFMT(format));
+ rv = txBitsPerPixel(format);
+ TRAP_LOG(GOT "%d\n", rv);
+ return rv;
+#undef FN_NAME
+}
+
+void FX_CALL trap_txImgQuantize (char  *dst,
+                                 char  *src,
+                                 int   w,
+                                 int   h,
+                                 FxU32 format,
+                                 FxU32 dither)
+{
+#define FN_NAME "txImgQuantize"
+ TRAP_LOG("%s(%p, %p, %d, %d, %s, %s)\n", FN_NAME, dst, src, w, h, TRP_TEXFMT(format), TRP_TXDITHER(dither));
+ txImgQuantize(dst, src, w, h, format, dither);
+#undef FN_NAME
+}
+
+void FX_CALL trap_txMipQuantize (TxMip *pxMip,
+                                 TxMip *txMip,
+                                 int   fmt,
+                                 FxU32 d,
+                                 FxU32 comp)
+{
+#define FN_NAME "txMipQuantize"
+ TRAP_LOG("%s(%p, %p, %s, %s, %s)\n", FN_NAME, (void *)pxMip, (void *)txMip, TRP_TEXFMT(fmt), TRP_TXDITHER(d), TRP_TXCOMPRESS(comp));
+ txMipQuantize(pxMip, txMip, fmt, d, comp);
+#undef FN_NAME
+}
+
+void FX_CALL trap_txPalToNcc (GuNccTable *ncc_table,
+                              const FxU32 *pal)
+{
+#define FN_NAME "txPalToNcc"
+ TRAP_LOG("%s(%p, %p)\n", FN_NAME, (void *)ncc_table, (void *)pal);
+ txPalToNcc(ncc_table, pal);
+#undef FN_NAME
+}
+
+void FX_CALL trap_txErrorSetCallback (TxErrorCallbackFnc_t fnc,
+                                      TxErrorCallbackFnc_t *old_fnc)
+{
+#define FN_NAME "txErrorSetCallback"
+ TRAP_LOG("%s(%p, %p)\n", FN_NAME, (void *)fnc, (void *)old_fnc);
+ txErrorSetCallback(fnc, old_fnc);
+#undef FN_NAME
+}
 #endif
 
 
 
+/****************************************************************************\
+* housekeeping (fake pointers)
+\****************************************************************************/
+void FX_CALL fake_grTexDownloadTableExt (GrChipID_t   tmu,
+                                         GrTexTable_t type,
+                                         void         *data)
+{
+ grTexDownloadTable(type, data);
+}
+
+void FX_CALL fake_grTexDownloadTablePartialExt (GrChipID_t   tmu,
+                                                GrTexTable_t type,
+                                                void         *data,
+                                                int          start,
+                                                int          end)
+{
+ grTexDownloadTablePartial(type, data, start, end);
+}
+
+void FX_CALL fake_grTexNCCTableExt (GrChipID_t   tmu,
+                                    GrNCCTable_t table)
+{
+ grTexNCCTable(table);
+}
+
+
+
 /****************************************************************************\
 * interface
 \****************************************************************************/
@@ -2100,8 +2251,10 @@ void tdfx_hook_glide (struct tdfx_glide *Glide)
 {
 #if DEBUG_TRAP
 #define GET_EXT_ADDR(name)  *(GrProc *)&real_##name = grGetProcAddress(#name), Glide->name = trap_##name
+#define GET_TXS_ADDR(name)  Glide->name = trap_##name
 #else  /* DEBUG_TRAP */
 #define GET_EXT_ADDR(name)  *(GrProc *)&Glide->name = grGetProcAddress(#name)
+#define GET_TXS_ADDR(name)  Glide->name = name
 #endif /* DEBUG_TRAP */
 
  /*
@@ -2113,6 +2266,10 @@ void tdfx_hook_glide (struct tdfx_glide *Glide)
  GET_EXT_ADDR(grChromaRangeExt);
  GET_EXT_ADDR(grTexChromaModeExt);
  GET_EXT_ADDR(grTexChromaRangeExt);
+ /* pointcast */
+ GET_EXT_ADDR(grTexDownloadTableExt);
+ GET_EXT_ADDR(grTexDownloadTablePartialExt);
+ GET_EXT_ADDR(grTexNCCTableExt);
  /* tbext */
  GET_EXT_ADDR(grTextureBufferExt);
  GET_EXT_ADDR(grTextureAuxBufferExt);
@@ -2133,8 +2290,29 @@ void tdfx_hook_glide (struct tdfx_glide *Glide)
  GET_EXT_ADDR(grAlphaBlendFunctionExt);
  GET_EXT_ADDR(grTBufferWriteMaskExt);
 
+ /*
+ ** texus
+ */
+ GET_TXS_ADDR(txBitsPerPixel);
+ GET_TXS_ADDR(txImgQuantize);
+ GET_TXS_ADDR(txMipQuantize);
+ GET_TXS_ADDR(txPalToNcc);
+ GET_TXS_ADDR(txErrorSetCallback);
+
+ /* housekeeping: make sure the pointcast always point to something valid */
+ if (grGetProcAddress("grTexDownloadTableExt") == NULL) {
+#if DEBUG_TRAP
+    real_grTexDownloadTableExt = fake_grTexDownloadTableExt;
+    real_grTexDownloadTablePartialExt = fake_grTexDownloadTablePartialExt;
+    real_grTexNCCTableExt = fake_grTexNCCTableExt;
+#else
+    Glide->grTexDownloadTableExt = fake_grTexDownloadTableExt;
+    Glide->grTexDownloadTablePartialExt = fake_grTexDownloadTablePartialExt;
+    Glide->grTexNCCTableExt = fake_grTexNCCTableExt;
+#endif
+ }
+
 #undef GET_EXT_ADDR
 }
 
-
 #endif /* FX */
index 234e52aee8cd241380fea3719ebd5beb2b4c0521..cae63cb69f21b0fca7cd22c4c3b66fce78d2d7f1 100644 (file)
@@ -307,6 +307,30 @@ void FX_CALL trap_guFogGenerateLinear (GrFog_t *fogtable, float nearZ, float far
 #endif /* DEBUG_TRAP_internal */
 #endif /* DEBUG_TRAP */
 
+
+
+/* <texus.h> */
+#define TX_MAX_LEVEL 16
+typedef struct _TxMip {
+        int format;
+        int width;
+        int height;
+        int depth;
+        int size;
+        void *data[TX_MAX_LEVEL];
+        FxU32 pal[256];
+} TxMip;
+typedef void (*TxErrorCallbackFnc_t) (const char *string, FxBool fatal);
+#define TX_DITHER_NONE                                  0x00000000
+#define TX_DITHER_4x4                                   0x00000001
+#define TX_DITHER_ERR                                   0x00000002
+
+#define TX_COMPRESSION_STATISTICAL                      0x00000000
+#define TX_COMPRESSION_HEURISTIC                        0x00000010
+/* <texus.h> */
+
+
+
 struct tdfx_glide {
    /*
    ** glide extensions
@@ -318,6 +342,11 @@ struct tdfx_glide {
    void (FX_CALL *grTexChromaModeExt) (GrChipID_t tmu, GrChromakeyMode_t mode);
    void (FX_CALL *grTexChromaRangeExt) (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode);
 
+   /* pointcast */
+   void (FX_CALL *grTexDownloadTableExt) (GrChipID_t tmu, GrTexTable_t type, void *data);
+   void (FX_CALL *grTexDownloadTablePartialExt) (GrChipID_t tmu, GrTexTable_t type, void *data, int start, int end);
+   void (FX_CALL *grTexNCCTableExt) (GrChipID_t tmu, GrNCCTable_t table);
+
    /* tbext */
    void (FX_CALL *grTextureBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask);
    void (FX_CALL *grTextureAuxBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask);
@@ -342,9 +371,11 @@ struct tdfx_glide {
    /*
    ** Texus2 functions
    */
-   void (*txImgQuantize) (void *xxx_unknown_arguments);
-   void (*txImgDequantizeFXT1) (void *txMip, void *pxMip);
-   void (*txErrorSetCallback) (void *fnc);
+   int (FX_CALL *txBitsPerPixel) (GrTextureFormat_t format);
+   void (FX_CALL *txImgQuantize) (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither);
+   void (FX_CALL *txMipQuantize) (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp);
+   void (FX_CALL *txPalToNcc) (GuNccTable *ncc_table, const FxU32 *pal);
+   void (FX_CALL *txErrorSetCallback) (TxErrorCallbackFnc_t fnc, TxErrorCallbackFnc_t *old_fnc);
 };
 
 void tdfx_hook_glide (struct tdfx_glide *Glide);
index 0e6ff6a53033432b6ae591d58fd9394bcc617956..ff4454d9a8fae64fec75f8a182d6f04ba5bbc90b 100644 (file)
@@ -224,6 +224,7 @@ FX_grSstQueryHardware(GrHwConfiguration * config)
       }
 
       extension = grGetString(GR_EXTENSION);
+      config->SSTs[i].HavePalExt = (strstr(extension, " PALETTE6666 ") != NULL);
       config->SSTs[i].HavePixExt = (strstr(extension, " PIXEXT ") != NULL);
       config->SSTs[i].HaveTexFmt = (strstr(extension, " TEXFMT ") != NULL);
       config->SSTs[i].HaveCmbExt = (strstr(extension, " COMBINE ") != NULL);
index 7f7bd692ee06bc0a332be51717d17b4c997b3cb3..31a8fa3b02eece2421ce74da40af4dd487c470bc 100644 (file)
@@ -72,6 +72,7 @@ typedef struct {
                int numChips;   /* Number of Voodoo chips */
                GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */
                /* Glide3 extensions */
+               FxBool HavePalExt;      /* PALETTE6666 */
                FxBool HavePixExt;      /* PIXEXT */
                FxBool HaveTexFmt;      /* TEXFMT */
                FxBool HaveCmbExt;      /* COMBINE */
index 40fd4a5f9cf5ddb1053f64e6e8b5bf8bf1d27f76..6e929257dbfb2d7210fe2df3f5fcd54efb756cfd 100644 (file)
@@ -327,13 +327,23 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
    }
 
    if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) {
+      /* broadcast */
       if ((ti->info.format == GR_TEXFMT_P_8)
          && (!fxMesa->haveGlobalPaletteTexture)) {
         if (TDFX_DEBUG & VERBOSE_DRIVER) {
            fprintf(stderr, "%s: uploading texture palette\n", __FUNCTION__);
         }
-        grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti->palette));
+        grTexDownloadTable(ti->paltype, &(ti->palette));
       }
+#if FX_TC_NCC
+      if ((ti->info.format == GR_TEXFMT_AYIQ_8422) ||
+          (ti->info.format == GR_TEXFMT_YIQ_422)) {
+        if (TDFX_DEBUG & VERBOSE_DRIVER) {
+           fprintf(stderr, "%s: uploading NCC table\n", __FUNCTION__);
+        }
+        grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette));
+      }
+#endif
 
       grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp);
       grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp);
@@ -353,13 +363,23 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
       else
         tmu = ti->whichTMU;
 
+      /* pointcast */
       if ((ti->info.format == GR_TEXFMT_P_8)
          && (!fxMesa->haveGlobalPaletteTexture)) {
         if (TDFX_DEBUG & VERBOSE_DRIVER) {
            fprintf(stderr, "%s: uploading texture palette\n", __FUNCTION__);
         }
-        grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti->palette));
+        fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette));
+      }
+#if FX_TC_NCC
+      if ((ti->info.format == GR_TEXFMT_AYIQ_8422) ||
+          (ti->info.format == GR_TEXFMT_YIQ_422)) {
+        if (TDFX_DEBUG & VERBOSE_DRIVER) {
+           fprintf(stderr, "%s: uploading NCC table\n", __FUNCTION__);
+        }
+        fxMesa->Glide.grTexDownloadTableExt(tmu, GR_TEXTABLE_NCC0, &(ti->palette));
       }
+#endif
 
       /* KW: The alternative is to do the download to the other tmu.  If
        * we get to this point, I think it means we are thrashing the
@@ -784,17 +804,40 @@ fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
    }
 
    if (!fxMesa->haveGlobalPaletteTexture) {
-      /* [dBorca]
-       * all TMUs share the same table.
-       * The next test shouldn't be TMU specific...
-       */
+      /* pointcast */
       if (ti0->info.format == GR_TEXFMT_P_8) {
         if (TDFX_DEBUG & VERBOSE_DRIVER) {
-           fprintf(stderr, "%s: uploading texture palette TMU0\n", __FUNCTION__);
+           fprintf(stderr, "%s: uploading texture palette for TMU0\n", __FUNCTION__);
+        }
+        fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette));
+      }
+#if 1
+      else /* does anyone guess why is this here? :D */
+#endif
+      if (ti1->info.format == GR_TEXFMT_P_8) {
+        if (TDFX_DEBUG & VERBOSE_DRIVER) {
+           fprintf(stderr, "%s: uploading texture palette for TMU1\n", __FUNCTION__);
         }
-        grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti0->palette));
+        fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, ti1->paltype, &(ti1->palette));
+      }
+   }
+#if FX_TC_NCC
+   /* pointcast */
+   if ((ti0->info.format == GR_TEXFMT_AYIQ_8422) ||
+       (ti0->info.format == GR_TEXFMT_YIQ_422)) {
+      if (TDFX_DEBUG & VERBOSE_DRIVER) {
+         fprintf(stderr, "%s: uploading NCC0 table for TMU0\n", __FUNCTION__);
       }
+      fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, GR_TEXTABLE_NCC0, &(ti0->palette));
    }
+   if ((ti1->info.format == GR_TEXFMT_AYIQ_8422) ||
+       (ti1->info.format == GR_TEXFMT_YIQ_422)) {
+      if (TDFX_DEBUG & VERBOSE_DRIVER) {
+         fprintf(stderr, "%s: uploading NCC0 table for TMU1\n", __FUNCTION__);
+      }
+      fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, GR_TEXTABLE_NCC0, &(ti1->palette));
+   }
+#endif
 
    grTexSource(tmu0, ti0->tm[tmu0]->startAddr,
                         GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
index d60b8740270e87d39d5f3c0141c21e8f1de7bfdb..08ecc6dd81b95dce146a879c260e66c2d916dc3a 100644 (file)
@@ -530,6 +530,7 @@ static void init_rast_tab( void )
 /* Accelerate vertex buffer rendering when renderindex == 0 and
  * there is no clipping.
  */
+#define INIT(x) fxRenderPrimitive( ctx, x )
 
 static void fx_render_vb_points( GLcontext *ctx,
                                 GLuint start,
@@ -545,7 +546,7 @@ static void fx_render_vb_points( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_points\n");
    }
 
-   fxRenderPrimitive(ctx, GL_POINTS);
+   INIT(GL_POINTS);
 
    /* Adjust point coords */
    for (i = start; i < count; i++) {
@@ -576,7 +577,7 @@ static void fx_render_vb_line_strip( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_line_strip\n");
    }
 
-   fxRenderPrimitive(ctx, GL_LINE_STRIP);
+   INIT(GL_LINE_STRIP);
 
    /* adjust line coords */
    for (i = start; i < count; i++) {
@@ -609,7 +610,7 @@ static void fx_render_vb_line_loop( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_line_loop\n");
    }
 
-   fxRenderPrimitive(ctx, GL_LINE_LOOP);
+   INIT(GL_LINE_LOOP);
 
    if (!(flags & PRIM_BEGIN)) {
       j++;
@@ -649,7 +650,7 @@ static void fx_render_vb_lines( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_lines\n");
    }
 
-   fxRenderPrimitive(ctx, GL_LINES);
+   INIT(GL_LINES);
 
    /* adjust line coords */
    for (i = start; i < count; i++) {
@@ -680,7 +681,7 @@ static void fx_render_vb_triangles( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_triangles\n");
    }
 
-   fxRenderPrimitive(ctx, GL_TRIANGLES);
+   INIT(GL_TRIANGLES);
 
 #if 0
    /* [dBorca]
@@ -716,7 +717,7 @@ static void fx_render_vb_tri_strip( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_tri_strip\n");
    }
 
-   fxRenderPrimitive(ctx, GL_TRIANGLE_STRIP);
+   INIT(GL_TRIANGLE_STRIP);
 
    if (flags & PRIM_PARITY) 
       mode = GR_TRIANGLE_STRIP_CONTINUE;
@@ -741,7 +742,7 @@ static void fx_render_vb_tri_fan( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_tri_fan\n");
    }
 
-   fxRenderPrimitive(ctx, GL_TRIANGLE_FAN);
+   INIT(GL_TRIANGLE_FAN);
 
    grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start,
                                 fxVB + start, sizeof(GrVertex) );
@@ -761,7 +762,7 @@ static void fx_render_vb_quads( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_quads\n");
    }
 
-   fxRenderPrimitive(ctx, GL_QUADS);
+   INIT(GL_QUADS);
 
    for (i = start ; i < count-3 ; i += 4 ) {
 #define VERT(x) (fxVB + (x))
@@ -784,7 +785,7 @@ static void fx_render_vb_quad_strip( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_quad_strip\n");
    }
 
-   fxRenderPrimitive(ctx, GL_QUAD_STRIP);
+   INIT(GL_QUAD_STRIP);
 
    count -= (count-start)&1;
 
@@ -805,7 +806,7 @@ static void fx_render_vb_poly( GLcontext *ctx,
       fprintf(stderr, "fx_render_vb_poly\n");
    }
 
-   fxRenderPrimitive(ctx, GL_POLYGON);
+   INIT(GL_POLYGON);
 
    grDrawVertexArrayContiguous( GR_POLYGON, count-start,
                                 fxVB + start, sizeof(GrVertex));
@@ -836,6 +837,7 @@ static void (*fx_render_tab_verts[GL_POLYGON+2])(GLcontext *,
    fx_render_vb_poly,
    fx_render_vb_noop,
 };
+#undef INIT(x)
 
 
 /**********************************************************************/