📄 fxsetup.c
字号:
/* * Mesa 3-D graphics library * Version: 4.0 * * 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"), * 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. *//* Authors: * David Bucciarelli * Brian Paul * Daryll Strauss * Keith Whitwell * Daniel Borca * Hiroshi Morii *//* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */#ifdef HAVE_CONFIG_H#include "conf.h"#endif#if defined(FX)#include "fxdrv.h"#include "enums.h"#include "tnl.h"#include "tnl/t_context.h"#include "swrast.h"#include "texstore.h"static voidfxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj){ tfxTexInfo *ti = fxTMGetTexInfo(tObj); GLint minl, maxl; if (ti->validated) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxTexValidate(NOP)\n"); } return; } if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxTexValidate(%p (%d))\n", (void *)tObj, tObj->Name); } ti->tObj = tObj; minl = ti->minLevel = tObj->BaseLevel; maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->MaxLog2);#if FX_RESCALE_BIG_TEXURES_HACK{ fxMesaContext fxMesa = FX_CONTEXT(ctx); /* [dBorca] * Fake textures larger than HW supports: * 1) we have mipmaps. Then we just push up to the first supported * LOD. A possible drawback is that Mesa will ignore the skipped * LODs on further texture handling. * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How? * 2) we don't have mipmaps. We need to rescale the big LOD in place. * The above approach is somehow dumb! we might have rescaled * once in TexImage2D to accomodate aspect ratio, and now we * are rescaling again. The thing is, in TexImage2D we don't * know whether we'll hit 1) or 2) by the time of validation. */ if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) { /* no mipmaps! */ struct gl_texture_image *texImage = tObj->Image[0][minl]; tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); GLint _w, _h, maxSize = 1 << fxMesa->textureMaxLod; if ((mml->width > maxSize) || (mml->height > maxSize)) { /* need to rescale */ GLint texelBytes = texImage->TexFormat->TexelBytes; GLvoid *texImage_Data = texImage->Data; _w = MIN2(texImage->Width, maxSize); _h = MIN2(texImage->Height, maxSize); if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxTexValidate: rescaling %d x %d -> %d x %d\n", texImage->Width, texImage->Height, _w, _h); } /* we should leave these as is and... (!) */ texImage->Width = _w; texImage->Height = _h; fxTexGetInfo(_w, _h, NULL, NULL, NULL, NULL, &(mml->wScale), &(mml->hScale)); _w *= mml->wScale; _h *= mml->hScale; texImage->Data = _mesa_malloc(_w * _h * texelBytes); _mesa_rescale_teximage2d(texelBytes, mml->width, _w * texelBytes, /* dst stride */ mml->width, mml->height, /* src */ _w, _h, /* dst */ texImage_Data /*src*/, texImage->Data /*dst*/ ); _mesa_free(texImage_Data); mml->width = _w; mml->height = _h; /* (!) ... and set mml->wScale = _w / texImage->Width */ } } else { /* mipmapping */ if (maxl - minl > fxMesa->textureMaxLod) { /* skip a certain number of LODs */ minl += maxl - fxMesa->textureMaxLod; if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxTexValidate: skipping %d LODs\n", minl - ti->minLevel); } ti->minLevel = tObj->BaseLevel = minl; } }}#endif fxTexGetInfo(tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height, &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)), &(ti->sScale), &(ti->tScale), NULL, NULL); if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) fxTexGetInfo(tObj->Image[0][maxl]->Width, tObj->Image[0][maxl]->Height, &(FX_smallLodLog2(ti->info)), NULL, NULL, NULL, NULL, NULL); else FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info); /* [dBorca] this is necessary because of fxDDCompressedTexImage2D */ if (ti->padded) { struct gl_texture_image *texImage = tObj->Image[0][minl]; tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); if (mml->wScale != 1 || mml->hScale != 1) { ti->sScale /= mml->wScale; ti->tScale /= mml->hScale; } } ti->baseLevelInternalFormat = tObj->Image[0][minl]->Format; ti->validated = GL_TRUE; ti->info.data = NULL;}static voidfxPrintUnitsMode(const char *msg, GLuint mode){ fprintf(stderr, "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", msg, mode, (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "", (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "", (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "", (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "", (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "", (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "", (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "", (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "", (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "", (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "", (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "", (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "", (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "", (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "", (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "", (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "", (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "", (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "", (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "", (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "", (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "", (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "", (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "", (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : "");}static GLuintfxGetTexSetConfiguration(GLcontext * ctx, struct gl_texture_object *tObj0, struct gl_texture_object *tObj1){ GLuint unitsmode = 0; GLuint envmode = 0; GLuint ifmt = 0; if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 || (ctx->Point.SmoothFlag) || (ctx->Line.SmoothFlag) || (ctx->Polygon.SmoothFlag)) unitsmode |= FX_UM_ALPHA_ITERATED; else unitsmode |= FX_UM_ALPHA_CONSTANT; if (ctx->Light.ShadeModel == GL_SMOOTH || 1) unitsmode |= FX_UM_COLOR_ITERATED; else unitsmode |= FX_UM_COLOR_CONSTANT; /* OpenGL Feeds Texture 0 into Texture 1 Glide Feeds Texture 1 into Texture 0 */ if (tObj0) { tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0); switch (ti0->baseLevelInternalFormat) { case GL_ALPHA: ifmt |= FX_UM_E0_ALPHA; break; case GL_LUMINANCE: ifmt |= FX_UM_E0_LUMINANCE; break; case GL_LUMINANCE_ALPHA: ifmt |= FX_UM_E0_LUMINANCE_ALPHA; break; case GL_INTENSITY: ifmt |= FX_UM_E0_INTENSITY; break; case GL_RGB: ifmt |= FX_UM_E0_RGB; break; case GL_RGBA: ifmt |= FX_UM_E0_RGBA; break; } switch (ctx->Texture.Unit[0].EnvMode) { case GL_DECAL: envmode |= FX_UM_E0_DECAL; break; case GL_MODULATE: envmode |= FX_UM_E0_MODULATE; break; case GL_REPLACE: envmode |= FX_UM_E0_REPLACE; break; case GL_BLEND: envmode |= FX_UM_E0_BLEND; break; case GL_ADD: envmode |= FX_UM_E0_ADD; break; default: /* do nothing */ break; } } if (tObj1) { tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1); switch (ti1->baseLevelInternalFormat) { case GL_ALPHA: ifmt |= FX_UM_E1_ALPHA; break; case GL_LUMINANCE: ifmt |= FX_UM_E1_LUMINANCE; break; case GL_LUMINANCE_ALPHA: ifmt |= FX_UM_E1_LUMINANCE_ALPHA; break; case GL_INTENSITY: ifmt |= FX_UM_E1_INTENSITY; break; case GL_RGB: ifmt |= FX_UM_E1_RGB; break; case GL_RGBA: ifmt |= FX_UM_E1_RGBA; break; default: /* do nothing */ break; } switch (ctx->Texture.Unit[1].EnvMode) { case GL_DECAL: envmode |= FX_UM_E1_DECAL; break; case GL_MODULATE: envmode |= FX_UM_E1_MODULATE; break; case GL_REPLACE: envmode |= FX_UM_E1_REPLACE; break; case GL_BLEND: envmode |= FX_UM_E1_BLEND; break; case GL_ADD: envmode |= FX_UM_E1_ADD; break; default: /* do nothing */ break; } } unitsmode |= (ifmt | envmode); if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) fxPrintUnitsMode("fxGetTexSetConfiguration", unitsmode); return unitsmode;}/************************************************************************//************************* Rendering Mode SetUp *************************//************************************************************************//************************* Single Texture Set ***************************/static voidfxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj){ tfxTexInfo *ti = fxTMGetTexInfo(tObj); int tmu; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj, tObj->Name); } ti->lastTimeUsed = fxMesa->texBindNumber; /* Make sure we're not loaded incorrectly */ if (ti->isInTM) { if (ti->LODblend) { if (ti->whichTMU != FX_TMU_SPLIT) fxTMMoveOutTM(fxMesa, tObj); } else { if (ti->whichTMU == FX_TMU_SPLIT) fxTMMoveOutTM(fxMesa, tObj); } } /* Make sure we're loaded correctly */ if (!ti->isInTM) { if (ti->LODblend) fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT); else { if (fxMesa->haveTwoTMUs) { if (fxTMCheckStartAddr(fxMesa, FX_TMU0, ti)) { fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); } else { fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU1); } } else fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); } } 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, "fxSetupSingleTMU_NoLock: uploading texture palette\n"); } grTexDownloadTable(ti->paltype, &(ti->palette)); } grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp); grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp); grTexFilterMode(GR_TMU0, ti->minFilt, ti->maxFilt); grTexFilterMode(GR_TMU1, ti->minFilt, ti->maxFilt); grTexMipMapMode(GR_TMU0, ti->mmMode, ti->LODblend); grTexMipMapMode(GR_TMU1, ti->mmMode, ti->LODblend); grTexSource(GR_TMU0, ti->tm[FX_TMU0]->startAddr, GR_MIPMAPLEVELMASK_ODD, &(ti->info)); grTexSource(GR_TMU1, ti->tm[FX_TMU1]->startAddr, GR_MIPMAPLEVELMASK_EVEN, &(ti->info)); } else { if (ti->whichTMU == FX_TMU_BOTH) tmu = FX_TMU0; else tmu = ti->whichTMU; /* pointcast */ if ((ti->info.format == GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading texture palette\n"); } fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette)); } /* 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 * texture memory, so perhaps it's not a good idea.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -