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

📄 i810texstate.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * GLX Hardware Device Driver for Intel i810 * Copyright (C) 1999 Keith Whitwell * * 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 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. * */#include "glheader.h"#include "macros.h"#include "mtypes.h"#include "texformat.h"#include "simple_list.h"#include "enums.h"#include "mm.h"#include "i810screen.h"#include "i810_dri.h"#include "i810context.h"#include "i810tex.h"#include "i810state.h"#include "i810ioctl.h"static void i810SetTexImages( i810ContextPtr imesa, 			      struct gl_texture_object *tObj ){   GLuint height, width, pitch, i, textureFormat, log_pitch;   i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];   GLint numLevels;   GLint log2Width, log2Height;/*     fprintf(stderr, "%s\n", __FUNCTION__); */   t->texelBytes = 2;   switch (baseImage->TexFormat->MesaFormat) {   case MESA_FORMAT_ARGB1555:      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB1555;      break;   case MESA_FORMAT_ARGB4444:      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;      break;   case MESA_FORMAT_RGB565:      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;      break;   case MESA_FORMAT_AL88:      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_AY88;      break;   case MESA_FORMAT_YCBCR:      textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y	  | MI1_COLOR_CONV_ENABLE;      break;   case MESA_FORMAT_YCBCR_REV:      textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB	  | MI1_COLOR_CONV_ENABLE;      break;   case MESA_FORMAT_CI8:      textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;      t->texelBytes = 1;      break;   default:      fprintf(stderr, "i810SetTexImages: bad image->Format\n" );      return;   }   driCalculateTextureFirstLastLevel( (driTextureObject *) t );   numLevels = t->base.lastLevel - t->base.firstLevel + 1;   log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;   log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;   /* Figure out the amount of memory required to hold all the mipmap    * levels.  Choose the smallest pitch to accomodate the largest    * mipmap:    */   width = tObj->Image[0][t->base.firstLevel]->Width * t->texelBytes;   for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )      log_pitch++;      /* All images must be loaded at this pitch.  Count the number of    * lines required:    */   for ( height = i = 0 ; i < numLevels ; i++ ) {      t->image[i].image = tObj->Image[0][t->base.firstLevel + i];      t->image[i].offset = height * pitch;      t->image[i].internalFormat = baseImage->_BaseFormat;      height += t->image[i].image->Height;   }   t->Pitch = pitch;   t->base.totalSize = height*pitch;   t->max_level = i-1;   t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;      t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch);    t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |				MLL_MAP_0  |				MLL_UPDATE_MAX_MIP | 				MLL_UPDATE_MIN_MIP |				((numLevels - 1) << MLL_MIN_MIP_SHIFT));   LOCK_HARDWARE( imesa );   i810UploadTexImagesLocked( imesa, t );   UNLOCK_HARDWARE( imesa );}/* ================================================================ * Texture combine functions */static void set_color_stage( unsigned color, int stage,			      i810ContextPtr imesa ){   if ( color != imesa->Setup[I810_CTXREG_MC0 + stage] ) {      I810_STATECHANGE( imesa, I810_UPLOAD_CTX );      imesa->Setup[I810_CTXREG_MC0 + stage] = color;   }}static void set_alpha_stage( unsigned alpha, int stage,				    i810ContextPtr imesa ){   if ( alpha != imesa->Setup[I810_CTXREG_MA0 + stage] ) {      I810_STATECHANGE( imesa, I810_UPLOAD_CTX );      imesa->Setup[I810_CTXREG_MA0 + stage] = alpha;   }}static const unsigned operand_modifiers[] = {   0,                       MC_ARG_INVERT,   MC_ARG_REPLICATE_ALPHA,  MC_ARG_INVERT | MC_ARG_REPLICATE_ALPHA};/** * Configure the hardware bits for the specified texture environment. * * Configures the hardware bits for the texture environment state for the * specified texture unit.  As combine stages are added, the values pointed * to by \c color_stage and \c alpha_stage are incremented. * * \param ctx          GL context pointer. * \param unit         Texture unit to be added. * \param color_stage  Next available hardware color combine stage. * \param alpha_stage  Next available hardware alpha combine stage. * * \returns * If the combine mode for the specified texture unit could be added without * requiring a software fallback, \c GL_TRUE is returned.  Otherwise, * \c GL_FALSE is returned. * * \todo * If the mode is (GL_REPLACE, GL_PREVIOUS), treat it as though the texture * stage is disabled.  That is, don't emit any combine stages. * * \todo * Add support for ATI_texture_env_combine3 modes.  This will require using * two combine stages. * * \todo * Add support for the missing \c GL_INTERPOLATE modes.  This will require * using all three combine stages.  There is a comment in the function * describing how this might work. * * \todo * If, after all the combine stages have been emitted, a texture is never * actually used, disable the texture unit.  That should save texture some * memory bandwidth.  This won't happen in this function, but this seems like * a reasonable place to make note of it. */static GLbooleani810UpdateTexEnvCombine( GLcontext *ctx, GLuint unit, 			 int * color_stage, int * alpha_stage ){   i810ContextPtr imesa = I810_CONTEXT(ctx);   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   GLuint color_arg[3] = {      MC_ARG_ONE,            MC_ARG_ONE,            MC_ARG_ONE   };   GLuint alpha_arg[3] = {      MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA   };   GLuint i;   GLuint color_combine, alpha_combine;   const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;   const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;   GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;   GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;   if ( !texUnit->_ReallyEnabled ) {      return GL_TRUE;   }         if ((*color_stage >= 3) || (*alpha_stage >= 3)) {      return GL_FALSE;   }   /* Step 1:    * Extract the color and alpha combine function arguments.    */   for ( i = 0 ; i < numColorArgs ; i++ ) {      unsigned op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;      assert(op >= 0);      assert(op <= 3);      switch ( texUnit->_CurrentCombine->SourceRGB[i] ) {      case GL_TEXTURE0:	 color_arg[i] = MC_ARG_TEX0_COLOR;	 break;      case GL_TEXTURE1:	 color_arg[i] = MC_ARG_TEX1_COLOR;	 break;      case GL_TEXTURE:	 color_arg[i] = (unit == 0) 	   ? MC_ARG_TEX0_COLOR : MC_ARG_TEX1_COLOR;	 break;      case GL_CONSTANT:	 color_arg[i] = MC_ARG_COLOR_FACTOR;	 break;      case GL_PRIMARY_COLOR:	 color_arg[i] = MC_ARG_ITERATED_COLOR;	 break;      case GL_PREVIOUS:	 color_arg[i] = (unit == 0)	   ? MC_ARG_ITERATED_COLOR : MC_ARG_CURRENT_COLOR;	 break;      case GL_ZERO:	 /* Toggle the low bit of the op value.  The is the 'invert' bit,	  * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op.	  */	 op ^= 1;	 /*FALLTHROUGH*/      case GL_ONE:	 color_arg[i] = MC_ARG_ONE;	 break;      default:	 return GL_FALSE;      }      color_arg[i] |= operand_modifiers[op];   }   for ( i = 0 ; i < numAlphaArgs ; i++ ) {      unsigned op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;      assert(op >= 0);      assert(op <= 1);      switch ( texUnit->_CurrentCombine->SourceA[i] ) {      case GL_TEXTURE0:	 alpha_arg[i] = MA_ARG_TEX0_ALPHA;	 break;      case GL_TEXTURE1:	 alpha_arg[i] = MA_ARG_TEX1_ALPHA;	 break;      case GL_TEXTURE:	 alpha_arg[i] = (unit == 0)	   ? MA_ARG_TEX0_ALPHA : MA_ARG_TEX1_ALPHA;	 break;      case GL_CONSTANT:	 alpha_arg[i] = MA_ARG_ALPHA_FACTOR;	 break;      case GL_PRIMARY_COLOR:	 alpha_arg[i] = MA_ARG_ITERATED_ALPHA;	 break;      case GL_PREVIOUS:	 alpha_arg[i] = (unit == 0)	   ? MA_ARG_ITERATED_ALPHA : MA_ARG_CURRENT_ALPHA;	 break;      case GL_ZERO:	 /* Toggle the low bit of the op value.  The is the 'invert' bit,	  * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op.	  */	 op ^= 1;	 /*FALLTHROUGH*/      case GL_ONE:	 if (i != 2) {	    return GL_FALSE;	 }	 alpha_arg[i] = MA_ARG_ONE;	 break;      default:	 return GL_FALSE;      }      alpha_arg[i] |= operand_modifiers[op];   }   /* Step 2:    * Build up the color and alpha combine functions.    */   switch ( texUnit->_CurrentCombine->ModeRGB ) {   case GL_REPLACE:      color_combine = MC_OP_ARG1;      break;   case GL_MODULATE:      color_combine = MC_OP_MODULATE + RGBshift;      RGBshift = 0;      break;   case GL_ADD:      color_combine = MC_OP_ADD;      break;   case GL_ADD_SIGNED:      color_combine = MC_OP_ADD_SIGNED;      break;   case GL_SUBTRACT:      color_combine = MC_OP_SUBTRACT;      break;   case GL_INTERPOLATE:      /* For interpolation, the i810 hardware has some limitations.  It       * can't handle using the secondary or diffuse color (diffuse alpha       * is okay) for the third argument.       *       * It is possible to emulate the missing modes by using multiple       * combine stages.  Unfortunately it requires all three stages to       * emulate a single interpolate stage.  The (arg0*arg2) portion is       * done in stage zero and writes to MC_DEST_ACCUMULATOR.  The       * (arg1*(1-arg2)) portion is done in stage 1, and the final stage is       * (MC_ARG1_ACCUMULATOR | MC_ARG2_CURRENT_COLOR | MC_OP_ADD).       *        * It can also be done without using the accumulator by rearranging       * the equation as (arg1 + (arg2 * (arg0 - arg1))).  Too bad the i810       * doesn't support the MODULATE_AND_ADD mode that the i830 supports.       * If it did, the interpolate could be done in only two stages.       */	       if ( (color_arg[2] & MC_ARG_INVERT) != 0 ) {	 unsigned temp = color_arg[0];	 color_arg[0] = color_arg[1];	 color_arg[1] = temp;	 color_arg[2] &= ~MC_ARG_INVERT;      }      switch (color_arg[2]) {      case (MC_ARG_ONE):      case (MC_ARG_ONE | MC_ARG_REPLICATE_ALPHA):	 color_combine = MC_OP_ARG1;	 color_arg[1] = MC_ARG_ONE;	 break;      case (MC_ARG_COLOR_FACTOR):	 return GL_FALSE;      case (MC_ARG_COLOR_FACTOR | MC_ARG_REPLICATE_ALPHA):

⌨️ 快捷键说明

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