summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/FX/fxddtex.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/extras/Mesa/src/FX/fxddtex.c')
-rw-r--r--xc/extras/Mesa/src/FX/fxddtex.c1197
1 files changed, 1197 insertions, 0 deletions
diff --git a/xc/extras/Mesa/src/FX/fxddtex.c b/xc/extras/Mesa/src/FX/fxddtex.c
new file mode 100644
index 000000000..dd2bf4456
--- /dev/null
+++ b/xc/extras/Mesa/src/FX/fxddtex.c
@@ -0,0 +1,1197 @@
+/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.3
+ *
+ * Copyright (C) 1999-2000 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"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
+ * terms stated above.
+ *
+ * Thank you for your contribution, David!
+ *
+ * Please make note of the above copyright/license statement. If you
+ * contributed code or bug fixes to this code under the previous (GNU
+ * Library) license and object to the new license, your code will be
+ * removed at your request. Please see the Mesa docs/COPYRIGHT file
+ * for more information.
+ *
+ * Additional Mesa/3Dfx driver developers:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ * Keith Whitwell <keith@precisioninsight.com>
+ *
+ * See fxapi.h for more revision/author details.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+#include "image.h"
+#include "texutil.h"
+
+
+void fxPrintTextureData(tfxTexInfo *ti)
+{
+ fprintf(stderr, "Texture Data:\n");
+ if (ti->tObj) {
+ fprintf(stderr, "\tName: %d\n", ti->tObj->Name);
+ fprintf(stderr, "\tBaseLevel: %d\n", ti->tObj->BaseLevel);
+ fprintf(stderr, "\tSize: %d x %d\n",
+ ti->tObj->Image[ti->tObj->BaseLevel]->Width,
+ ti->tObj->Image[ti->tObj->BaseLevel]->Height);
+ } else
+ fprintf(stderr, "\tName: UNNAMED\n");
+ fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed);
+ fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU);
+ fprintf(stderr, "\t%s\n", (ti->isInTM)?"In TMU":"Not in TMU");
+ if (ti->tm[0])
+ fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr,
+ (unsigned) ti->tm[0]->endAddr);
+ if (ti->tm[1])
+ fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr,
+ (unsigned) ti->tm[1]->endAddr);
+ fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel);
+ fprintf(stderr, "\tFilters: min %d min %d\n",
+ (int) ti->minFilt, (int) ti->maxFilt);
+ fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp, (int) ti->tClamp);
+ fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale);
+ fprintf(stderr, "\tInt Scales: s %d t %d\n",
+ ti->int_sScale/0x800000, ti->int_tScale/0x800000);
+ fprintf(stderr, "\t%s\n", (ti->fixedPalette)?"Fixed palette":"Non fixed palette");
+ fprintf(stderr, "\t%s\n", (ti->validated)?"Validated":"Not validated");
+}
+
+
+/************************************************************************/
+/*************************** Texture Mapping ****************************/
+/************************************************************************/
+
+static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ tfxTexInfo *ti;
+
+ ti=fxTMGetTexInfo(tObj);
+ if (ti->isInTM) fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */
+
+ ti->validated=GL_FALSE;
+ fxMesa->new_state|=FX_NEW_TEXTURING;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa)
+{
+ tfxTexInfo *ti;
+ int i;
+
+ if(!(ti=CALLOC(sizeof(tfxTexInfo)))) {
+ fprintf(stderr,"fx Driver: out of memory !\n");
+ fxCloseHardware();
+ exit(-1);
+ }
+
+ ti->validated=GL_FALSE;
+ ti->isInTM=GL_FALSE;
+
+ ti->whichTMU=FX_TMU_NONE;
+
+ ti->tm[FX_TMU0]=NULL;
+ ti->tm[FX_TMU1]=NULL;
+
+ ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+ ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
+
+ ti->sClamp=GR_TEXTURECLAMP_WRAP;
+ ti->tClamp=GR_TEXTURECLAMP_WRAP;
+
+ ti->mmMode=GR_MIPMAP_NEAREST;
+ ti->LODblend=FXFALSE;
+
+ for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
+ ti->mipmapLevel[i].data=NULL;
+ }
+
+ return ti;
+}
+
+void fxDDTexBind(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ tfxTexInfo *ti;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDTexBind(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
+ }
+
+ if(target!=GL_TEXTURE_2D)
+ return;
+
+ if (!tObj->DriverData) {
+ tObj->DriverData=fxAllocTexObjData(fxMesa);
+ }
+
+ ti=fxTMGetTexInfo(tObj);
+
+ fxMesa->texBindNumber++;
+ ti->lastTimeUsed=fxMesa->texBindNumber;
+
+ fxMesa->new_state|=FX_NEW_TEXTURING;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+void fxDDTexEnv(GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ if(param)
+ fprintf(stderr,"fxmesa: texenv(%x,%x)\n",pname,(GLint)(*param));
+ else
+ fprintf(stderr,"fxmesa: texenv(%x)\n",pname);
+ }
+
+ /* apply any lod biasing right now */
+ if (pname==GL_TEXTURE_LOD_BIAS_EXT) {
+ FX_grTexLodBiasValue(GR_TMU0,*param);
+
+ if(fxMesa->haveTwoTMUs) {
+ FX_grTexLodBiasValue(GR_TMU1,*param);
+ }
+
+ }
+
+ fxMesa->new_state|=FX_NEW_TEXTURING;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+void fxDDTexParam(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params)
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLenum param=(GLenum)(GLint)params[0];
+ tfxTexInfo *ti;
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDTexParam(%d,%x,%x,%x)\n",tObj->Name,(GLuint)tObj->DriverData,pname,param);
+ }
+
+ if(target!=GL_TEXTURE_2D)
+ return;
+
+ if (!tObj->DriverData)
+ tObj->DriverData=fxAllocTexObjData(fxMesa);
+
+ ti=fxTMGetTexInfo(tObj);
+
+ switch(pname) {
+
+ case GL_TEXTURE_MIN_FILTER:
+ switch(param) {
+ case GL_NEAREST:
+ ti->mmMode=GR_MIPMAP_DISABLE;
+ ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+ ti->LODblend=FXFALSE;
+ break;
+ case GL_LINEAR:
+ ti->mmMode=GR_MIPMAP_DISABLE;
+ ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+ ti->LODblend=FXFALSE;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ ti->mmMode=GR_MIPMAP_NEAREST;
+ ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+ ti->LODblend=FXFALSE;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ ti->mmMode=GR_MIPMAP_NEAREST;
+ ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+ ti->LODblend=FXFALSE;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ if(fxMesa->haveTwoTMUs) {
+ ti->mmMode=GR_MIPMAP_NEAREST;
+ ti->LODblend=FXTRUE;
+ } else {
+ ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
+ ti->LODblend=FXFALSE;
+ }
+ ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if(fxMesa->haveTwoTMUs) {
+ ti->mmMode=GR_MIPMAP_NEAREST;
+ ti->LODblend=FXTRUE;
+ } else {
+ ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
+ ti->LODblend=FXFALSE;
+ }
+ ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+ break;
+ default:
+ break;
+ }
+ fxTexInvalidate(ctx,tObj);
+ break;
+
+ case GL_TEXTURE_MAG_FILTER:
+ switch(param) {
+ case GL_NEAREST:
+ ti->maxFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+ break;
+ case GL_LINEAR:
+ ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
+ break;
+ default:
+ break;
+ }
+ fxTexInvalidate(ctx,tObj);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ switch(param) {
+ case GL_CLAMP:
+ ti->sClamp=GR_TEXTURECLAMP_CLAMP;
+ break;
+ case GL_REPEAT:
+ ti->sClamp=GR_TEXTURECLAMP_WRAP;
+ break;
+ default:
+ break;
+ }
+ fxMesa->new_state|=FX_NEW_TEXTURING;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+ break;
+
+ case GL_TEXTURE_WRAP_T:
+ switch(param) {
+ case GL_CLAMP:
+ ti->tClamp=GR_TEXTURECLAMP_CLAMP;
+ break;
+ case GL_REPEAT:
+ ti->tClamp=GR_TEXTURECLAMP_WRAP;
+ break;
+ default:
+ break;
+ }
+ fxMesa->new_state|=FX_NEW_TEXTURING;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ /* TO DO */
+ break;
+
+ case GL_TEXTURE_MIN_LOD:
+ /* TO DO */
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ /* TO DO */
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ fxTexInvalidate(ctx,tObj);
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ fxTexInvalidate(ctx,tObj);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void fxDDTexDel(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDTexDel(%d,%p)\n", tObj->Name, ti);
+ }
+
+ if (!ti)
+ return;
+
+ fxTMFreeTexture(fxMesa, tObj);
+
+ FREE(ti);
+ tObj->DriverData = NULL;
+
+ ctx->NewState |= NEW_TEXTURING;
+}
+
+
+
+/*
+ * Convert a gl_color_table texture palette to Glide's format.
+ */
+static void
+convertPalette(FxU32 data[256], const struct gl_color_table *table)
+{
+ const GLubyte *tableUB = (const GLubyte *) table->Table;
+ GLint width = table->Size;
+ FxU32 r, g, b, a;
+ GLint i;
+
+ ASSERT(table->TableType == GL_UNSIGNED_BYTE);
+
+ switch (table->Format) {
+ case GL_INTENSITY:
+ for (i = 0; i < width; i++) {
+ r = tableUB[i];
+ g = tableUB[i];
+ b = tableUB[i];
+ a = tableUB[i];
+ data[i] = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ break;
+ case GL_LUMINANCE:
+ for (i = 0; i < width; i++) {
+ r = tableUB[i];
+ g = tableUB[i];
+ b = tableUB[i];
+ a = 255;
+ data[i] = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ break;
+ 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;
+ 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;
+ case GL_RGB:
+ for (i = 0; i < width; i++) {
+ r = tableUB[i*3+0];
+ g = tableUB[i*3+1];
+ b = tableUB[i*3+2];
+ a = 255;
+ data[i] = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ break;
+ case GL_RGBA:
+ for (i = 0; i < width; i++) {
+ r = tableUB[i*4+0];
+ g = tableUB[i*4+1];
+ b = tableUB[i*4+2];
+ a = tableUB[i*4+3];
+ data[i] = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ break;
+ }
+}
+
+
+void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ if (tObj) {
+ /* per-texture palette */
+ tfxTexInfo *ti;
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n",
+ tObj->Name, (GLuint) tObj->DriverData);
+ }
+ if (!tObj->DriverData)
+ tObj->DriverData = fxAllocTexObjData(fxMesa);
+ ti = fxTMGetTexInfo(tObj);
+ convertPalette(ti->palette.data, &tObj->Palette);
+ fxTexInvalidate(ctx, tObj);
+ }
+ else {
+ /* global texture palette */
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n");
+ }
+ convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
+ fxMesa->new_state |= FX_NEW_TEXTURING;
+ ctx->Driver.RenderStart = fxSetupFXUnits;
+ }
+}
+
+
+void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state);
+ }
+
+ if (state) {
+ fxMesa->haveGlobalPaletteTexture = 1;
+
+ FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
+ if (fxMesa->haveTwoTMUs)
+ FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
+ }
+ else {
+ fxMesa->haveGlobalPaletteTexture = 0;
+
+ if ((ctx->Texture.Unit[0].Current == ctx->Texture.Unit[0].CurrentD[2]) &&
+ (ctx->Texture.Unit[0].Current != NULL)) {
+ struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current;
+
+ if (!tObj->DriverData)
+ tObj->DriverData = fxAllocTexObjData(fxMesa);
+
+ fxTexInvalidate(ctx, tObj);
+ }
+ }
+}
+
+
+static int logbase2(int n)
+{
+ GLint i = 1;
+ GLint log2 = 0;
+
+ if (n<0) {
+ return -1;
+ }
+
+ while (n > i) {
+ i *= 2;
+ log2++;
+ }
+ if (i != n) {
+ return -1;
+ }
+ else {
+ return log2;
+ }
+}
+
+/* Need different versions for different cpus.
+ */
+#define INT_TRICK(l2) (0x800000 * l2)
+
+
+int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
+ float *sscale, float *tscale,
+ int *i_sscale, int *i_tscale,
+ int *wscale, int *hscale)
+{
+
+ static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
+ GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
+
+ int logw,logh,ws,hs;
+ GrLOD_t l;
+ GrAspectRatio_t aspectratio;
+ float s,t;
+ int is,it;
+
+ logw=logbase2(w);
+ logh=logbase2(h);
+
+ switch(logw-logh) {
+ case 0:
+ aspectratio=GR_ASPECT_1x1;
+ l=lod[8-logw];
+ s=t=256.0f;
+ is=it=INT_TRICK(8);
+ ws=hs=1;
+ break;
+ case 1:
+ aspectratio=GR_ASPECT_2x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=128.0f;
+ is=INT_TRICK(8);it=INT_TRICK(7);
+ ws=1;
+ hs=1;
+ break;
+ case 2:
+ aspectratio=GR_ASPECT_4x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=64.0f;
+ is=INT_TRICK(8);it=INT_TRICK(6);
+ ws=1;
+ hs=1;
+ break;
+ case 3:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=1;
+ break;
+ case 4:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=2;
+ break;
+ case 5:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=4;
+ break;
+ case 6:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=8;
+ break;
+ case 7:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=16;
+ break;
+ case 8:
+ aspectratio=GR_ASPECT_8x1;
+ l=lod[8-logw];
+ s=256.0f;
+ t=32.0f;
+ is=INT_TRICK(8);it=INT_TRICK(5);
+ ws=1;
+ hs=32;
+ break;
+ case -1:
+ aspectratio=GR_ASPECT_1x2;
+ l=lod[8-logh];
+ s=128.0f;
+ t=256.0f;
+ is=INT_TRICK(7);it=INT_TRICK(8);
+ ws=1;
+ hs=1;
+ break;
+ case -2:
+ aspectratio=GR_ASPECT_1x4;
+ l=lod[8-logh];
+ s=64.0f;
+ t=256.0f;
+ is=INT_TRICK(6);it=INT_TRICK(8);
+ ws=1;
+ hs=1;
+ break;
+ case -3:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=1;
+ hs=1;
+ break;
+ case -4:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=2;
+ hs=1;
+ break;
+ case -5:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=4;
+ hs=1;
+ break;
+ case -6:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=8;
+ hs=1;
+ break;
+ case -7:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=16;
+ hs=1;
+ break;
+ case -8:
+ aspectratio=GR_ASPECT_1x8;
+ l=lod[8-logh];
+ s=32.0f;
+ t=256.0f;
+ is=INT_TRICK(5);it=INT_TRICK(8);
+ ws=32;
+ hs=1;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ if(lodlevel)
+ (*lodlevel)=l;
+
+ if(ar)
+ (*ar)=aspectratio;
+
+ if(sscale)
+ (*sscale)=s;
+
+ if(tscale)
+ (*tscale)=t;
+
+ if(wscale)
+ (*wscale)=ws;
+
+ if(hscale)
+ (*hscale)=hs;
+
+ if (i_sscale)
+ *i_sscale = is;
+
+ if (i_tscale)
+ *i_tscale = it;
+
+
+ return 1;
+}
+
+/*
+ * Given an OpenGL internal texture format, return the corresponding
+ * Glide internal texture format and base texture format.
+ */
+void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
+{
+ switch(glformat) {
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_INTENSITY_8;
+ if(ifmt)
+ (*ifmt)=GL_LUMINANCE;
+ 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:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
+ if(ifmt)
+ (*ifmt)=GL_LUMINANCE_ALPHA;
+ break;
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ALPHA_8;
+ if(ifmt)
+ (*ifmt)=GL_INTENSITY;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ALPHA_8;
+ if(ifmt)
+ (*ifmt)=GL_ALPHA;
+ 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:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_RGB_565;
+ if(ifmt)
+ (*ifmt)=GL_RGB;
+ 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:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ARGB_4444;
+ if(ifmt)
+ (*ifmt)=GL_RGBA;
+ break;
+ case GL_RGB5_A1:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_ARGB_1555;
+ if(ifmt)
+ (*ifmt)=GL_RGBA;
+ 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:
+ if(tfmt)
+ (*tfmt)=GR_TEXFMT_P_8;
+ if(ifmt)
+ (*ifmt)=GL_RGBA; /* XXX why is this RGBA? */
+ break;
+ default:
+ fprintf(stderr,
+ "fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
+ fxCloseHardware();
+ exit(-1);
+ break;
+ }
+}
+
+static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat,
+ const struct gl_texture_image *image)
+{
+ if(target != GL_TEXTURE_2D)
+ return GL_FALSE;
+
+ if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
+ NULL,NULL))
+ return GL_FALSE;
+
+ if (image->Border > 0)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+
+/**********************************************************************/
+/**** NEW TEXTURE IMAGE FUNCTIONS ****/
+/**********************************************************************/
+
+GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLboolean *retainInternalCopy)
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+
+ if (target != GL_TEXTURE_2D)
+ return GL_FALSE;
+
+ if (!texObj->DriverData)
+ texObj->DriverData = fxAllocTexObjData(fxMesa);
+
+ if (fxIsTexSupported(target, texImage->IntFormat, texImage)) {
+ GrTextureFormat_t gldformat;
+ tfxTexInfo *ti = fxTMGetTexInfo(texObj);
+ tfxMipMapLevel *mml = &ti->mipmapLevel[level];
+ GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride;
+ MesaIntTexFormat intFormat;
+
+ fxTexGetFormat(texImage->IntFormat, &gldformat, NULL);
+
+ fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
+ NULL,NULL, &wScale, &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 GL_FALSE;
+ }
+
+ _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 GL_FALSE;
+ mml->glideFormat = gldformat;
+ mml->width = dstWidth;
+ mml->height = dstHeight;
+ fxTexInvalidate(ctx, texObj);
+ }
+
+ dstStride = dstWidth * texelSize;
+
+ /* store the texture image */
+ if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data,
+ dstStride,
+ texImage->Width, texImage->Height,
+ format, type, pixels, packing)) {
+ return GL_FALSE;
+ }
+
+ if (ti->validated && ti->isInTM) {
+ /*printf("reloadmipmaplevels\n");*/
+ fxTMReloadMipMapLevel(fxMesa, texObj, level);
+ }
+ else {
+ /*printf("invalidate2\n");*/
+ fxTexInvalidate(ctx,texObj);
+ }
+
+ *retainInternalCopy = GL_FALSE;
+ return GL_TRUE;
+ }
+ else {
+ gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
+ return GL_FALSE;
+ }
+}
+
+
+GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ 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 (target != GL_TEXTURE_2D)
+ return GL_FALSE;
+
+ if (!texObj->DriverData)
+ return GL_FALSE;
+
+ ti = fxTMGetTexInfo(texObj);
+ mml = &ti->mipmapLevel[level];
+
+ fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
+ NULL,NULL, &wscale, &hscale);
+
+ assert(mml->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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ break;
+ default:
+ gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format");
+ result = GL_FALSE;
+ }
+
+ if (!result) {
+ return GL_FALSE;
+ }
+
+ if (ti->validated && ti->isInTM)
+ fxTMReloadMipMapLevel(fxMesa, texObj, level);
+ else
+ fxTexInvalidate(ctx, texObj);
+
+ return GL_TRUE;
+}
+
+
+static void PrintTexture(int w, int h, int c, const GLubyte *data)
+{
+ int i, j;
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (c==2)
+ printf("%02x %02x ", data[0], data[1]);
+ else if (c==3)
+ printf("%02x %02x %02x ", data[0], data[1], data[2]);
+ data += c;
+ }
+ printf("\n");
+ }
+}
+
+
+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;
+ }
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_ddtex(void)
+{
+ return 0;
+}
+
+#endif /* FX */