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

📄 s_context.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Mesa 3-D graphics library * Version:  7.1 * * Copyright (C) 1999-2008  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: *    Keith Whitwell <keith@tungstengraphics.com> *    Brian Paul */#include "imports.h"#include "bufferobj.h"#include "context.h"#include "colormac.h"#include "mtypes.h"#include "teximage.h"#include "swrast.h"#include "shader/prog_parameter.h"#include "shader/prog_statevars.h"#include "s_blend.h"#include "s_context.h"#include "s_lines.h"#include "s_points.h"#include "s_span.h"#include "s_triangle.h"#include "s_texfilter.h"/** * Recompute the value of swrast->_RasterMask, etc. according to * the current context.  The _RasterMask field can be easily tested by * drivers to determine certain basic GL state (does the primitive need * stenciling, logic-op, fog, etc?). */static void_swrast_update_rasterflags( GLcontext *ctx ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   GLbitfield rasterMask = 0;   if (ctx->Color.AlphaEnabled)           rasterMask |= ALPHATEST_BIT;   if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;   if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;   if (swrast->_FogEnabled)               rasterMask |= FOG_BIT;   if (ctx->Scissor.Enabled)              rasterMask |= CLIP_BIT;   if (ctx->Stencil.Enabled)              rasterMask |= STENCIL_BIT;   if (ctx->Visual.rgbMode) {      const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);      if (colorMask != 0xffffffff)        rasterMask |= MASKING_BIT;      if (ctx->Color._LogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;      if (ctx->Texture._EnabledUnits)     rasterMask |= TEXTURE_BIT;   }   else {      if (ctx->Color.IndexMask != 0xffffffff) rasterMask |= MASKING_BIT;      if (ctx->Color.IndexLogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;   }   if (   ctx->Viewport.X < 0       || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width       || ctx->Viewport.Y < 0       || ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) {      rasterMask |= CLIP_BIT;   }   if (ctx->Query.CurrentOcclusionObject)      rasterMask |= OCCLUSION_BIT;   /* If we're not drawing to exactly one color buffer set the    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no    * buffers or the RGBA or CI mask disables all writes.    */   if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {      /* more than one color buffer designated for writing (or zero buffers) */      rasterMask |= MULTI_DRAW_BIT;   }   else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) {      rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */   }   else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) {      rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */   }   if (ctx->FragmentProgram._Current) {      rasterMask |= FRAGPROG_BIT;   }   if (ctx->ATIFragmentShader._Enabled) {      rasterMask |= ATIFRAGSHADER_BIT;   }#if CHAN_TYPE == GL_FLOAT   if (ctx->Color.ClampFragmentColor == GL_TRUE) {      rasterMask |= CLAMPING_BIT;   }#endif   SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask;}/** * Examine polygon cull state to compute the _BackfaceCullSign field. * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces, * and 1 if culling front-faces.  The Polygon FrontFace state also * factors in. */static void_swrast_update_polygon( GLcontext *ctx ){   GLfloat backface_sign;   if (ctx->Polygon.CullFlag) {      switch (ctx->Polygon.CullFaceMode) {      case GL_BACK:         backface_sign = -1.0;	 break;      case GL_FRONT:         backface_sign = 1.0;	 break;      case GL_FRONT_AND_BACK:         /* fallthrough */      default:	 backface_sign = 0.0;      }   }   else {      backface_sign = 0.0;   }   SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign;   /* This is for front/back-face determination, but not for culling */   SWRAST_CONTEXT(ctx)->_BackfaceSign      = (ctx->Polygon.FrontFace == GL_CW) ? -1.0 : 1.0;}/** * Update the _PreferPixelFog field to indicate if we need to compute * fog blend factors (from the fog coords) per-fragment. */static void_swrast_update_fog_hint( GLcontext *ctx ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||                              ctx->FragmentProgram._Current ||			      (ctx->Hint.Fog == GL_NICEST &&			       swrast->AllowPixelFog));}/** * Update the swrast->_AnyTextureCombine flag. */static void_swrast_update_texture_env( GLcontext *ctx ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   GLuint i;   swrast->_AnyTextureCombine = GL_FALSE;   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {      if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||          ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {         swrast->_AnyTextureCombine = GL_TRUE;         return;      }   }}/** * Determine if we can defer texturing/shading until after Z/stencil * testing.  This potentially allows us to skip texturing/shading for * lots of fragments. */static void_swrast_update_deferred_texture(GLcontext *ctx){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   if (ctx->Color.AlphaEnabled) {      /* alpha test depends on post-texture/shader colors */      swrast->_DeferredTexture = GL_FALSE;   }   else {      const struct gl_fragment_program *fprog         = ctx->FragmentProgram._Current;      if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) {         /* Z comes from fragment program/shader */         swrast->_DeferredTexture = GL_FALSE;      }      else if (ctx->Query.CurrentOcclusionObject) {         /* occlusion query depends on shader discard/kill results */         swrast->_DeferredTexture = GL_FALSE;      }      else {         swrast->_DeferredTexture = GL_TRUE;      }   }}/** * Update swrast->_FogColor and swrast->_FogEnable values. */static void_swrast_update_fog_state( GLcontext *ctx ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;   /* determine if fog is needed, and if so, which fog mode */   swrast->_FogEnabled = GL_FALSE;   if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {      if (fp->FogOption != GL_NONE) {         swrast->_FogEnabled = GL_TRUE;         swrast->_FogMode = fp->FogOption;      }   }   else if (ctx->Fog.Enabled) {      swrast->_FogEnabled = GL_TRUE;      swrast->_FogMode = ctx->Fog.Mode;   }}/** * Update state for running fragment programs.  Basically, load the * program parameters with current state values. */static void_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState){   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;   if (fp) {#if 0      /* XXX Need a way to trigger the initial loading of parameters       * even when there's no recent state changes.       */      if (fp->Base.Parameters->StateFlags & newState)#endif         _mesa_load_state_parameters(ctx, fp->Base.Parameters);   }}#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK |	\			     _NEW_TEXTURE |		\			     _NEW_HINT |		\			     _NEW_POLYGON )/* State referenced by _swrast_choose_triangle, _swrast_choose_line. */#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED |		\			      _NEW_RENDERMODE|			\                              _NEW_POLYGON|			\                              _NEW_DEPTH|			\                              _NEW_STENCIL|			\                              _NEW_COLOR|			\                              _NEW_TEXTURE|			\                              _SWRAST_NEW_RASTERMASK|		\                              _NEW_LIGHT|			\                              _NEW_FOG |			\			      _DD_NEW_SEPARATE_SPECULAR)#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED |		\			  _NEW_RENDERMODE|		\                          _NEW_LINE|			\                          _NEW_TEXTURE|			\                          _NEW_LIGHT|			\                          _NEW_FOG|			\                          _NEW_DEPTH |			\                          _DD_NEW_SEPARATE_SPECULAR)#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED |	\			   _NEW_RENDERMODE |		\			   _NEW_POINT |			\			   _NEW_TEXTURE |		\			   _NEW_LIGHT |			\			   _NEW_FOG |			\                           _DD_NEW_SEPARATE_SPECULAR)#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR/** * Stub for swrast->Triangle to select a true triangle function * after a state change. */static void_swrast_validate_triangle( GLcontext *ctx,			   const SWvertex *v0,                           const SWvertex *v1,                           const SWvertex *v2 ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   _swrast_validate_derived( ctx );   swrast->choose_triangle( ctx );   ASSERT(swrast->Triangle);   if (ctx->Texture._EnabledUnits == 0       && NEED_SECONDARY_COLOR(ctx)       && !ctx->FragmentProgram._Current) {      /* separate specular color, but no texture */      swrast->SpecTriangle = swrast->Triangle;      swrast->Triangle = _swrast_add_spec_terms_triangle;   }   swrast->Triangle( ctx, v0, v1, v2 );}/** * Called via swrast->Line.  Examine current GL state and choose a software * line routine.  Then call it. */static void_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   _swrast_validate_derived( ctx );   swrast->choose_line( ctx );   ASSERT(swrast->Line);   if (ctx->Texture._EnabledUnits == 0       && NEED_SECONDARY_COLOR(ctx)       && !ctx->FragmentProgram._Current) {      swrast->SpecLine = swrast->Line;      swrast->Line = _swrast_add_spec_terms_line;   }   swrast->Line( ctx, v0, v1 );}/** * Called via swrast->Point.  Examine current GL state and choose a software * point routine.  Then call it. */static void_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   _swrast_validate_derived( ctx );   swrast->choose_point( ctx );   if (ctx->Texture._EnabledUnits == 0       && NEED_SECONDARY_COLOR(ctx)       && !ctx->FragmentProgram._Current) {      swrast->SpecPoint = swrast->Point;      swrast->Point = _swrast_add_spec_terms_point;   }   swrast->Point( ctx, v0 );}/** * Called via swrast->BlendFunc.  Examine GL state to choose a blending * function, then call it. */static void _ASMAPI_swrast_validate_blend_func(GLcontext *ctx, GLuint n, const GLubyte mask[],                            GLvoid *src, const GLvoid *dst,                            GLenum chanType ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   _swrast_validate_derived( ctx ); /* why is this needed? */   _swrast_choose_blend_func( ctx, chanType );   swrast->BlendFunc( ctx, n, mask, src, dst, chanType );}/** * Make sure we have texture image data for all the textures we may need * for subsequent rendering. */static void_swrast_validate_texture_images(GLcontext *ctx){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   GLuint u;   if (!swrast->ValidateTextureImage || !ctx->Texture._EnabledUnits) {      /* no textures enabled, or no way to validate images! */      return;   }   for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {      if (ctx->Texture.Unit[u]._ReallyEnabled) {         struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;         ASSERT(texObj);         if (texObj) {            GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;            GLuint face;            for (face = 0; face < numFaces; face++) {               GLint lvl;               for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {                  struct gl_texture_image *texImg = texObj->Image[face][lvl];                  if (texImg && !texImg->Data) {                     swrast->ValidateTextureImage(ctx, texObj, face, lvl);                     ASSERT(texObj->Image[face][lvl]->Data);                  }               }            }         }      }   }}/** * Free the texture image data attached to all currently enabled * textures.  Meant to be called by device drivers when transitioning * from software to hardware rendering. */void_swrast_eject_texture_images(GLcontext *ctx){   GLuint u;   if (!ctx->Texture._EnabledUnits) {      /* no textures enabled */      return;   }   for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {      if (ctx->Texture.Unit[u]._ReallyEnabled) {         struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;         ASSERT(texObj);         if (texObj) {            GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;            GLuint face;            for (face = 0; face < numFaces; face++) {               GLint lvl;               for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {                  struct gl_texture_image *texImg = texObj->Image[face][lvl];                  if (texImg && texImg->Data) {                     _mesa_free_texmemory(texImg->Data);                     texImg->Data = NULL;                  }               }            }

⌨️ 快捷键说明

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