⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdfx_tex.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*- mode: c; c-basic-offset: 3 -*- * * Copyright 2000 VA Linux Systems Inc., Fremont, California. * * 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 (including the next * paragraph) 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 * VA LINUX SYSTEMS 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. *//* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.7 2002/11/05 17:46:10 tsi Exp $ *//* * New fixes: *	Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004 * * Original rewrite: *	Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 * * Authors: *	Gareth Hughes <gareth@valinux.com> *	Brian Paul <brianp@valinux.com> * */#include "enums.h"#include "image.h"#include "mipmap.h"#include "texcompress.h"#include "texformat.h"#include "teximage.h"#include "texstore.h"#include "texobj.h"#include "tdfx_context.h"#include "tdfx_tex.h"#include "tdfx_texman.h"/* no borders! can't halve 1x1! (stride > width * comp) not allowed */static void_mesa_halve2x2_teximage2d ( GLcontext *ctx,			    struct gl_texture_image *texImage,			    GLuint bytesPerPixel,			    GLint srcWidth, GLint srcHeight,			    const GLvoid *srcImage, GLvoid *dstImage ){   GLint i, j, k;   GLint dstWidth = srcWidth / 2;   GLint dstHeight = srcHeight / 2;   GLint srcRowStride = srcWidth * bytesPerPixel;   GLubyte *src = (GLubyte *)srcImage;   GLubyte *dst = dstImage;   GLuint dstImageOffsets = 0;   GLuint bpt = 0;   GLubyte *_s = NULL;   GLubyte *_d = NULL;   GLenum _t = 0;   if (texImage->TexFormat->MesaFormat == MESA_FORMAT_RGB565) {      _t = GL_UNSIGNED_SHORT_5_6_5_REV;      bpt = bytesPerPixel;   } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) {      _t = GL_UNSIGNED_SHORT_4_4_4_4_REV;      bpt = bytesPerPixel;   } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) {      _t = GL_UNSIGNED_SHORT_1_5_5_5_REV;      bpt = bytesPerPixel;   }   if (bpt) {      bytesPerPixel = 4;      srcRowStride = srcWidth * bytesPerPixel;      if (dstWidth == 0) {         dstWidth = 1;      }      if (dstHeight == 0) {         dstHeight = 1;      }      _s = src = MALLOC(srcRowStride * srcHeight);      _d = dst = MALLOC(dstWidth * bytesPerPixel * dstHeight);      _mesa_texstore_rgba8888(ctx, 2, GL_RGBA,                              &_mesa_texformat_rgba8888_rev, src,                              0, 0, 0, /* dstX/Y/Zoffset */                              srcRowStride, /* dstRowStride */                              &dstImageOffsets,                              srcWidth, srcHeight, 1,                              texImage->_BaseFormat, _t, srcImage, &ctx->DefaultPacking);   }   if (srcHeight == 1) {      for (i = 0; i < dstWidth; i++) {         for (k = 0; k < bytesPerPixel; k++) {            dst[0] = (src[0] + src[bytesPerPixel] + 1) / 2;            src++;            dst++;         }         src += bytesPerPixel;      }   } else if (srcWidth == 1) {      for (j = 0; j < dstHeight; j++) {         for (k = 0; k < bytesPerPixel; k++) {            dst[0] = (src[0] + src[srcRowStride] + 1) / 2;            src++;            dst++;         }         src += srcRowStride;      }   } else {      for (j = 0; j < dstHeight; j++) {         for (i = 0; i < dstWidth; i++) {            for (k = 0; k < bytesPerPixel; k++) {               dst[0] = (src[0] +                         src[bytesPerPixel] +                         src[srcRowStride] +                         src[srcRowStride + bytesPerPixel] + 2) / 4;               src++;               dst++;            }            src += bytesPerPixel;         }         src += srcRowStride;      }   }   if (bpt) {      src = _s;      dst = _d;      texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,                                      texImage->TexFormat, dstImage,                                      0, 0, 0, /* dstX/Y/Zoffset */                                      dstWidth * bpt,                                      &dstImageOffsets,                                      dstWidth, dstHeight, 1,                                      GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking);      FREE(dst);      FREE(src);   }}static intlogbase2(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;    }}/* * Compute various texture image parameters. * Input:  w, h - source texture width and height * Output:  lodlevel - Glide lod level token for the larger texture dimension *          aspectratio - Glide aspect ratio token *          sscale - S scale factor used during triangle setup *          tscale - T scale factor used during triangle setup *          wscale - OpenGL -> Glide image width scale factor *          hscale - OpenGL -> Glide image height scale factor * * Sample results: *      w    h       lodlevel               aspectRatio *     128  128  GR_LOD_LOG2_128 (=7)  GR_ASPECT_LOG2_1x1 (=0) *      64   64  GR_LOD_LOG2_64 (=6)   GR_ASPECT_LOG2_1x1 (=0) *      64   32  GR_LOD_LOG2_64 (=6)   GR_ASPECT_LOG2_2x1 (=1) *      32   64  GR_LOD_LOG2_64 (=6)   GR_ASPECT_LOG2_1x2 (=-1) *      32   32  GR_LOD_LOG2_32 (=5)   GR_ASPECT_LOG2_1x1 (=0) */static voidtdfxTexGetInfo(const GLcontext *ctx, int w, int h,               GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,               float *sscale, float *tscale,               int *wscale, int *hscale){    int logw, logh, ar, lod, ws, hs;    float s, t;    ASSERT(w >= 1);    ASSERT(h >= 1);    logw = logbase2(w);    logh = logbase2(h);    ar = logw - logh;  /* aspect ratio = difference in log dimensions */    s = t = 256.0;    ws = hs = 1;    /* Hardware only allows a maximum aspect ratio of 8x1, so handle       |ar| > 3 by scaling the image and using an 8x1 aspect ratio */    if (ar >= 0) {        ASSERT(w >= h);        lod = logw;        if (ar <= GR_ASPECT_LOG2_8x1) {            t = 256 >> ar;        }        else {            /* have to stretch image height */            t = 32.0;            hs = 1 << (ar - 3);            ar = GR_ASPECT_LOG2_8x1;        }    }    else {        ASSERT(w < h);        lod = logh;        if (ar >= GR_ASPECT_LOG2_1x8) {            s = 256 >> -ar;        }        else {            /* have to stretch image width */            s = 32.0;            ws = 1 << (-ar - 3);            ar = GR_ASPECT_LOG2_1x8;        }    }    if (lodlevel)        *lodlevel = (GrLOD_t) lod;    if (aspectratio)        *aspectratio = (GrAspectRatio_t) ar;    if (sscale)        *sscale = s;    if (tscale)        *tscale = t;    if (wscale)        *wscale = ws;    if (hscale)        *hscale = hs;}/* * We need to call this when a texture object's minification filter * or texture image sizes change. */static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj){    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);    GLint minl, maxl;    if (!ti)       return;    minl = maxl = tObj->BaseLevel;    if (tObj->Image[0][minl]) {       maxl = MIN2(tObj->MaxLevel, tObj->Image[0][minl]->MaxLog2);       /* compute largeLodLog2, aspect ratio and texcoord scale factors */       tdfxTexGetInfo(ctx, tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,                      &ti->info.largeLodLog2,                      &ti->info.aspectRatioLog2,                      &(ti->sScale), &(ti->tScale), NULL, NULL);    }    if (tObj->Image[0][maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {        /* mipmapping: need to compute smallLodLog2 */        tdfxTexGetInfo(ctx, tObj->Image[0][maxl]->Width,                       tObj->Image[0][maxl]->Height,                       &ti->info.smallLodLog2, NULL,                       NULL, NULL, NULL, NULL);    }    else {        /* not mipmapping: smallLodLog2 = largeLodLog2 */        ti->info.smallLodLog2 = ti->info.largeLodLog2;        maxl = minl;    }    ti->minLevel = minl;    ti->maxLevel = maxl;    ti->info.data = NULL;   /* this is necessary because of fxDDCompressedTexImage2D */   if (ti->padded) {      struct gl_texture_image *texImage = tObj->Image[0][minl];      tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);      if (mml->wScale != 1 || mml->hScale != 1) {         ti->sScale /= mml->wScale;         ti->tScale /= mml->hScale;      }   }}static tdfxTexInfo *fxAllocTexObjData(tdfxContextPtr fxMesa){    tdfxTexInfo *ti;    if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) {        _mesa_problem(NULL, "tdfx driver: out of memory");        return NULL;    }    ti->isInTM = GL_FALSE;    ti->whichTMU = TDFX_TMU_NONE;    ti->tm[TDFX_TMU0] = NULL;    ti->tm[TDFX_TMU1] = NULL;    ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;    ti->magFilt = GR_TEXTUREFILTER_BILINEAR;    ti->sClamp = GR_TEXTURECLAMP_WRAP;    ti->tClamp = GR_TEXTURECLAMP_WRAP;    ti->mmMode = GR_MIPMAP_NEAREST;    ti->LODblend = FXFALSE;    return ti;}/* * Called via glBindTexture. */static voidtdfxBindTexture(GLcontext * ctx, GLenum target,                  struct gl_texture_object *tObj){    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);    tdfxTexInfo *ti;    if (MESA_VERBOSE & VERBOSE_DRIVER) {        fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,                tObj->DriverData);    }    if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D))        return;    if (!tObj->DriverData) {        tObj->DriverData = fxAllocTexObjData(fxMesa);    }    ti = TDFX_TEXTURE_DATA(tObj);    ti->lastTimeUsed = fxMesa->texBindNumber++;    fxMesa->new_state |= TDFX_NEW_TEXTURE;}/* * Called via glTexEnv. */static voidtdfxTexEnv(GLcontext * ctx, GLenum target, GLenum pname,             const GLfloat * param){    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);    if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {        if (param)            fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,                    (GLint) (*param));        else            fprintf(stderr, "fxmesa: texenv(%x)\n", pname);    }    /* XXX this is a bit of a hack to force the Glide texture     * state to be updated.     */    fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit]  = 0;    fxMesa->new_state |= TDFX_NEW_TEXTURE;}/* * Called via glTexParameter. */static voidtdfxTexParameter(GLcontext * ctx, GLenum target,                   struct gl_texture_object *tObj,                   GLenum pname, const GLfloat * params){    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);    GLenum param = (GLenum) (GLint) params[0];    tdfxTexInfo *ti;    if (MESA_VERBOSE & VERBOSE_DRIVER) {        fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,                tObj->DriverData, pname, param);    }    if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D))        return;    if (!tObj->DriverData)        tObj->DriverData = fxAllocTexObjData(fxMesa);    ti = TDFX_TEXTURE_DATA(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_LINEAR:            if (!fxMesa->Glide.HaveCombineExt) {                 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;            }            /* XXX Voodoo3/Banshee mipmap blending seems to produce             * incorrectly filtered colors for the smallest mipmap levels.             * To work-around we fall-through here and use a different filter.             */        case GL_NEAREST_MIPMAP_NEAREST:            ti->mmMode = GR_MIPMAP_NEAREST;            ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;            ti->LODblend = FXFALSE;            break;        case GL_LINEAR_MIPMAP_LINEAR:            if (!fxMesa->Glide.HaveCombineExt) {                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;            }            /* XXX Voodoo3/Banshee mipmap blending seems to produce             * incorrectly filtered colors for the smallest mipmap levels.             * To work-around we fall-through here and use a different filter.             */        case GL_LINEAR_MIPMAP_NEAREST:            ti->mmMode = GR_MIPMAP_NEAREST;            ti->minFilt = GR_TEXTUREFILTER_BILINEAR;            ti->LODblend = FXFALSE;            break;        default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -