📄 mga_texstate.c
字号:
/* * Copyright 2000-2001 VA Linux Systems, Inc. * (c) Copyright IBM Corporation 2002 * 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 * on the rights to use, copy, modify, merge, publish, distribute, sub * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS, IBM AND/OR THEIR SUPPLIERS 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: * Ian Romanick <idr@us.ibm.com> * Keith Whitwell <keithw@tungstengraphics.com> *//* $XFree86:$ */#include <stdlib.h>#include "mm.h"#include "mgacontext.h"#include "mgatex.h"#include "mgaregs.h"#include "mgatris.h"#include "mgaioctl.h"#include "context.h"#include "enums.h"#include "macros.h"#include "imports.h"#include "simple_list.h"#include "texformat.h"#define MGA_USE_TABLE_FOR_FORMAT#ifdef MGA_USE_TABLE_FOR_FORMAT#define TMC_nr_tformat (MESA_FORMAT_YCBCR_REV + 1)static const unsigned TMC_tformat[ TMC_nr_tformat ] ={ [MESA_FORMAT_ARGB8888] = TMC_tformat_tw32, [MESA_FORMAT_RGB565] = TMC_tformat_tw16, [MESA_FORMAT_ARGB4444] = TMC_tformat_tw12, [MESA_FORMAT_ARGB1555] = TMC_tformat_tw15, [MESA_FORMAT_AL88] = TMC_tformat_tw8al, [MESA_FORMAT_I8] = TMC_tformat_tw8a, [MESA_FORMAT_CI8] = TMC_tformat_tw8 , [MESA_FORMAT_YCBCR] = TMC_tformat_tw422uyvy, [MESA_FORMAT_YCBCR_REV] = TMC_tformat_tw422,};#endifstatic voidmgaSetTexImages( mgaContextPtr mmesa, const struct gl_texture_object * tObj ){ mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; struct gl_texture_image *baseImage = tObj->Image[0][ tObj->BaseLevel ]; GLint totalSize; GLint width, height; GLint i; GLint numLevels; GLint log2Width, log2Height; GLuint txformat = 0; GLint ofs; /* Set the hardware texture format */#ifndef MGA_USE_TABLE_FOR_FORMAT switch (baseImage->TexFormat->MesaFormat) { case MESA_FORMAT_ARGB8888: txformat = TMC_tformat_tw32; break; case MESA_FORMAT_RGB565: txformat = TMC_tformat_tw16; break; case MESA_FORMAT_ARGB4444: txformat = TMC_tformat_tw12; break; case MESA_FORMAT_ARGB1555: txformat = TMC_tformat_tw15; break; case MESA_FORMAT_AL88: txformat = TMC_tformat_tw8al; break; case MESA_FORMAT_I8: txformat = TMC_tformat_tw8a; break; case MESA_FORMAT_CI8: txformat = TMC_tformat_tw8; break; case MESA_FORMAT_YCBCR: txformat = TMC_tformat_tw422uyvy; break; case MESA_FORMAT_YCBCR_REV: txformat = TMC_tformat_tw422; break; default: _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); return; }#else if ( (baseImage->TexFormat->MesaFormat >= TMC_nr_tformat) || (TMC_tformat[ baseImage->TexFormat->MesaFormat ] == 0) ) { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); return; } txformat = TMC_tformat[ baseImage->TexFormat->MesaFormat ];#endif /* MGA_USE_TABLE_FOR_FORMAT */ driCalculateTextureFirstLastLevel( (driTextureObject *) t ); if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { log2Width = 0; log2Height = 0; } else { log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2; log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2; } width = tObj->Image[0][t->base.firstLevel]->Width; height = tObj->Image[0][t->base.firstLevel]->Height; numLevels = MIN2( t->base.lastLevel - t->base.firstLevel + 1, MGA_IS_G200(mmesa) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS); totalSize = 0; for ( i = 0 ; i < numLevels ; i++ ) { const struct gl_texture_image * const texImage = tObj->Image[0][ i + t->base.firstLevel ]; int size; if (texImage == NULL) break; size = texImage->Width * texImage->Height * baseImage->TexFormat->TexelBytes; t->offsets[i] = totalSize; t->base.dirty_images[0] |= (1<<i); /* All mipmaps must be 32-byte aligned */ totalSize += (size + 31) & ~31; /* Since G400 calculates the offsets in hardware * it can't handle more than one < 32 byte mipmap. * * Further testing has indicated that it can't * handle any < 32 byte mipmaps. */ if (MGA_IS_G400( mmesa ) && size <= 32) { i++; break; } } /* save these values */ numLevels = i; t->base.lastLevel = t->base.firstLevel + numLevels - 1; t->base.totalSize = totalSize; /* setup hardware register values */ t->setup.texctl &= (TMC_tformat_MASK & TMC_tpitch_MASK & TMC_tpitchext_MASK); t->setup.texctl |= txformat; /* Set the texture width. In order to support non-power of 2 textures and * textures larger than 1024 texels wide, "linear" pitch must be used. For * the linear pitch, if the width is 2048, a value of zero is used. */ t->setup.texctl |= TMC_tpitchlin_enable; t->setup.texctl |= MGA_FIELD( TMC_tpitchext, width & (2048 - 1) ); /* G400 specifies the number of mip levels in a strange way. Since there * are up to 11 levels, it requires 4 bits. Three of the bits are at the * high end of TEXFILTER. The other bit is in the middle. Weird. */ numLevels--; t->setup.texfilter &= TF_mapnb_MASK & TF_mapnbhigh_MASK & TF_reserved_MASK; t->setup.texfilter |= MGA_FIELD( TF_mapnb, numLevels & 0x7 ); t->setup.texfilter |= MGA_FIELD( TF_mapnbhigh, (numLevels >> 3) & 0x1 ); /* warp texture registers */ ofs = MGA_IS_G200(mmesa) ? 28 : 11; t->setup.texwidth = (MGA_FIELD(TW_twmask, width - 1) | MGA_FIELD(TW_rfw, (10 - log2Width - 8) & 63 ) | MGA_FIELD(TW_tw, (log2Width + ofs ) | 0x40 )); t->setup.texheight = (MGA_FIELD(TH_thmask, height - 1) | MGA_FIELD(TH_rfh, (10 - log2Height - 8) & 63 ) | MGA_FIELD(TH_th, (log2Height + ofs ) | 0x40 )); mgaUploadTexImages( mmesa, t );}/* ================================================================ * Texture unit state management */static void mgaUpdateTextureEnvG200( GLcontext *ctx, GLuint unit ){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current; mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; if (tObj != ctx->Texture.Unit[0].Current2D && tObj != ctx->Texture.Unit[0].CurrentRect) return; t->setup.texctl &= ~TMC_tmodulate_enable; t->setup.texctl2 &= ~(TMC_decalblend_enable | TMC_idecal_enable | TMC_decaldis_enable); switch (ctx->Texture.Unit[0].EnvMode) { case GL_REPLACE: if (format == GL_ALPHA) t->setup.texctl2 |= TMC_idecal_enable; if (format == GL_RGB || format == GL_LUMINANCE) mmesa->hw.alpha_sel = AC_alphasel_diffused; else mmesa->hw.alpha_sel = AC_alphasel_fromtex; break; case GL_MODULATE: t->setup.texctl |= TMC_tmodulate_enable; if (format == GL_ALPHA) t->setup.texctl2 |= (TMC_idecal_enable | TMC_decaldis_enable); if (format == GL_RGB || format == GL_LUMINANCE) mmesa->hw.alpha_sel = AC_alphasel_diffused; else mmesa->hw.alpha_sel = AC_alphasel_modulated; break; case GL_DECAL: if (format == GL_RGB || format == GL_RGBA) t->setup.texctl2 |= TMC_decalblend_enable; else t->setup.texctl2 |= TMC_idecal_enable; mmesa->hw.alpha_sel = AC_alphasel_diffused; break; case GL_BLEND: if (format == GL_ALPHA) { t->setup.texctl2 |= TMC_idecal_enable; mmesa->hw.alpha_sel = AC_alphasel_modulated; } else { t->texenv_fallback = GL_TRUE; } break; default: break; }}#define MGA_REPLACE 0#define MGA_MODULATE 1#define MGA_DECAL 2#define MGA_ADD 3#define MGA_MAX_COMBFUNC 4static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] ={ /* Unit 0: */ { /* GL_REPLACE * Cv = Cs * Av = Af */ (TD0_color_sel_arg1 | TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2), /* GL_MODULATE * Cv = Cf Cs * Av = Af */ (TD0_color_arg2_diffuse | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2), /* GL_DECAL * Cv = Cs * Av = Af */ (TD0_color_sel_arg1 | TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2), /* GL_ADD * Cv = Cf + Cs * Av = Af */ (TD0_color_arg2_diffuse | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2), }, /* Unit 1: */ { /* GL_REPLACE * Cv = Cs * Av = Ap */ (TD0_color_sel_arg1 | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2), /* GL_MODULATE * Cv = Cp Cs * Av = Ap */ (TD0_color_arg2_prevstage | TD0_color_sel_mul | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2), /* GL_DECAL * Cv = Cs * Av = Ap */ (TD0_color_sel_arg1 | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2), /* GL_ADD * Cv = Cp + Cs * Av = Ap */ (TD0_color_arg2_prevstage | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2), },};static const GLuint g400_color_alpha_combine[][MGA_MAX_COMBFUNC] ={ /* Unit 0: */ { /* GL_REPLACE * Cv = Cs * Av = As */ (TD0_color_sel_arg1 | TD0_alpha_sel_arg1), /* GL_MODULATE * Cv = Cf Cs * Av = Af As */ (TD0_color_arg2_diffuse | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul), /* GL_DECAL * tmp = Cf ( 1 - As ) * Cv = tmp + Cs As * Av = Af */ (TD0_color_arg2_diffuse | TD0_color_alpha_currtex | TD0_color_alpha1inv_enable | TD0_color_arg1mul_alpha1 | TD0_color_blend_enable | TD0_color_arg1add_mulout | TD0_color_arg2add_mulout | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2), /* GL_ADD * Cv = Cf + Cs * Av = Af As */ (TD0_color_arg2_diffuse | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul), }, /* Unit 1: */ { /* GL_REPLACE * Cv = Cs * Av = As */ (TD0_color_sel_arg1 | TD0_alpha_sel_arg1), /* GL_MODULATE * Cv = Cp Cs * Av = Ap As */ (TD0_color_arg2_prevstage | TD0_color_sel_mul | TD0_alpha_arg2_prevstage | TD0_alpha_sel_mul), /* GL_DECAL * tmp = Cp ( 1 - As ) * Cv = tmp + Cs As * Av = Ap */ (TD0_color_arg2_prevstage | TD0_color_alpha_currtex | TD0_color_alpha1inv_enable | TD0_color_arg1mul_alpha1 | TD0_color_blend_enable | TD0_color_arg1add_mulout | TD0_color_arg2add_mulout | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2), /* GL_ADD * Cv = Cp + Cs * Av = Ap As */ (TD0_color_arg2_prevstage | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_prevstage | TD0_alpha_sel_mul), },};static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -