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

📄 s_nvfragprog.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2005  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. *//* * Regarding GL_NV_fragment_program: * * Portions of this software may use or implement intellectual * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims * any and all warranties with respect to such intellectual property, * including any use thereof or modifications thereto. */#include "glheader.h"#include "colormac.h"#include "context.h"#include "program_instruction.h"#include "program.h"#include "s_nvfragprog.h"#include "s_span.h"/* if 1, print some debugging info */#define DEBUG_FRAG 0/** * Fetch a texel. */static voidfetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,             GLuint unit, GLfloat color[4] ){   GLchan rgba[4];   SWcontext *swrast = SWRAST_CONTEXT(ctx);   /* XXX use a float-valued TextureSample routine here!!! */   swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,                               1, (const GLfloat (*)[4]) texcoord,                               &lambda, &rgba);   color[0] = CHAN_TO_FLOAT(rgba[0]);   color[1] = CHAN_TO_FLOAT(rgba[1]);   color[2] = CHAN_TO_FLOAT(rgba[2]);   color[3] = CHAN_TO_FLOAT(rgba[3]);}/** * Fetch a texel with the given partial derivatives to compute a level * of detail in the mipmap. */static voidfetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],                   const GLfloat texdx[4], const GLfloat texdy[4],                   GLuint unit, GLfloat color[4] ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;   const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];   const GLfloat texW = (GLfloat) texImg->WidthScale;   const GLfloat texH = (GLfloat) texImg->HeightScale;   GLchan rgba[4];   GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */                                         texdx[1], texdy[1], /* dt/dx, dt/dy */                                         texdx[3], texdy[2], /* dq/dx, dq/dy */                                         texW, texH,                                         texcoord[0], texcoord[1], texcoord[3],                                         1.0F / texcoord[3]);   swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,                               1, (const GLfloat (*)[4]) texcoord,                               &lambda, &rgba);   color[0] = CHAN_TO_FLOAT(rgba[0]);   color[1] = CHAN_TO_FLOAT(rgba[1]);   color[2] = CHAN_TO_FLOAT(rgba[2]);   color[3] = CHAN_TO_FLOAT(rgba[3]);}/** * Return a pointer to the 4-element float vector specified by the given * source register. */static INLINE const GLfloat *get_register_pointer( GLcontext *ctx,                      const struct prog_src_register *source,                      const struct fp_machine *machine,                      const struct fragment_program *program ){   const GLfloat *src;   switch (source->File) {      case PROGRAM_TEMPORARY:         ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_TEMPS);         src = machine->Temporaries[source->Index];         break;      case PROGRAM_INPUT:         ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS);         src = machine->Inputs[source->Index];         break;      case PROGRAM_OUTPUT:         /* This is only for PRINT */         ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);         src = machine->Outputs[source->Index];         break;      case PROGRAM_LOCAL_PARAM:         ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);         src = program->Base.LocalParams[source->Index];         break;      case PROGRAM_ENV_PARAM:         ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS);         src = ctx->FragmentProgram.Parameters[source->Index];         break;      case PROGRAM_STATE_VAR:         /* Fallthrough */      case PROGRAM_NAMED_PARAM:         ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters);         src = program->Base.Parameters->ParameterValues[source->Index];         break;      default:         _mesa_problem(ctx, "Invalid input register file %d in fetch_vector4", source->File);         src = NULL;   }   return src;}/** * Fetch a 4-element float vector from the given source register. * Apply swizzling and negating as needed. */static voidfetch_vector4( GLcontext *ctx,               const struct prog_src_register *source,               const struct fp_machine *machine,               const struct fragment_program *program,               GLfloat result[4] ){   const GLfloat *src = get_register_pointer(ctx, source, machine, program);   ASSERT(src);   result[0] = src[GET_SWZ(source->Swizzle, 0)];   result[1] = src[GET_SWZ(source->Swizzle, 1)];   result[2] = src[GET_SWZ(source->Swizzle, 2)];   result[3] = src[GET_SWZ(source->Swizzle, 3)];   if (source->NegateBase) {      result[0] = -result[0];      result[1] = -result[1];      result[2] = -result[2];      result[3] = -result[3];   }   if (source->Abs) {      result[0] = FABSF(result[0]);      result[1] = FABSF(result[1]);      result[2] = FABSF(result[2]);      result[3] = FABSF(result[3]);   }   if (source->NegateAbs) {      result[0] = -result[0];      result[1] = -result[1];      result[2] = -result[2];      result[3] = -result[3];   }}/** * Fetch the derivative with respect to X for the given register. * \return GL_TRUE if it was easily computed or GL_FALSE if we * need to execute another instance of the program (ugh)! */static GLbooleanfetch_vector4_deriv( GLcontext *ctx,                     const struct prog_src_register *source,                     const struct sw_span *span,                     char xOrY, GLint column, GLfloat result[4] ){   GLfloat src[4];   ASSERT(xOrY == 'X' || xOrY == 'Y');   switch (source->Index) {   case FRAG_ATTRIB_WPOS:      if (xOrY == 'X') {         src[0] = 1.0;         src[1] = 0.0;         src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF;         src[3] = span->dwdx;      }      else {         src[0] = 0.0;         src[1] = 1.0;         src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF;         src[3] = span->dwdy;      }      break;   case FRAG_ATTRIB_COL0:      if (xOrY == 'X') {         src[0] = span->drdx * (1.0F / CHAN_MAXF);         src[1] = span->dgdx * (1.0F / CHAN_MAXF);         src[2] = span->dbdx * (1.0F / CHAN_MAXF);         src[3] = span->dadx * (1.0F / CHAN_MAXF);      }      else {         src[0] = span->drdy * (1.0F / CHAN_MAXF);         src[1] = span->dgdy * (1.0F / CHAN_MAXF);         src[2] = span->dbdy * (1.0F / CHAN_MAXF);         src[3] = span->dady * (1.0F / CHAN_MAXF);      }      break;   case FRAG_ATTRIB_COL1:      if (xOrY == 'X') {         src[0] = span->dsrdx * (1.0F / CHAN_MAXF);         src[1] = span->dsgdx * (1.0F / CHAN_MAXF);         src[2] = span->dsbdx * (1.0F / CHAN_MAXF);         src[3] = 0.0; /* XXX need this */      }      else {         src[0] = span->dsrdy * (1.0F / CHAN_MAXF);         src[1] = span->dsgdy * (1.0F / CHAN_MAXF);         src[2] = span->dsbdy * (1.0F / CHAN_MAXF);         src[3] = 0.0; /* XXX need this */      }      break;   case FRAG_ATTRIB_FOGC:      if (xOrY == 'X') {         src[0] = span->dfogdx;         src[1] = 0.0;         src[2] = 0.0;         src[3] = 0.0;      }      else {         src[0] = span->dfogdy;         src[1] = 0.0;         src[2] = 0.0;         src[3] = 0.0;      }      break;   case FRAG_ATTRIB_TEX0:   case FRAG_ATTRIB_TEX1:   case FRAG_ATTRIB_TEX2:   case FRAG_ATTRIB_TEX3:   case FRAG_ATTRIB_TEX4:   case FRAG_ATTRIB_TEX5:   case FRAG_ATTRIB_TEX6:   case FRAG_ATTRIB_TEX7:      if (xOrY == 'X') {         const GLuint u = source->Index - FRAG_ATTRIB_TEX0;         /* this is a little tricky - I think I've got it right */         const GLfloat invQ = 1.0f / (span->tex[u][3]                                      + span->texStepX[u][3] * column);         src[0] = span->texStepX[u][0] * invQ;         src[1] = span->texStepX[u][1] * invQ;         src[2] = span->texStepX[u][2] * invQ;         src[3] = span->texStepX[u][3] * invQ;      }      else {         const GLuint u = source->Index - FRAG_ATTRIB_TEX0;         /* Tricky, as above, but in Y direction */         const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]);         src[0] = span->texStepY[u][0] * invQ;         src[1] = span->texStepY[u][1] * invQ;         src[2] = span->texStepY[u][2] * invQ;         src[3] = span->texStepY[u][3] * invQ;      }      break;   default:      return GL_FALSE;   }   result[0] = src[GET_SWZ(source->Swizzle, 0)];   result[1] = src[GET_SWZ(source->Swizzle, 1)];   result[2] = src[GET_SWZ(source->Swizzle, 2)];   result[3] = src[GET_SWZ(source->Swizzle, 3)];   if (source->NegateBase) {      result[0] = -result[0];      result[1] = -result[1];      result[2] = -result[2];      result[3] = -result[3];   }   if (source->Abs) {      result[0] = FABSF(result[0]);      result[1] = FABSF(result[1]);      result[2] = FABSF(result[2]);      result[3] = FABSF(result[3]);   }   if (source->NegateAbs) {      result[0] = -result[0];      result[1] = -result[1];      result[2] = -result[2];      result[3] = -result[3];   }   return GL_TRUE;}/** * As above, but only return result[0] element. */static voidfetch_vector1( GLcontext *ctx,               const struct prog_src_register *source,               const struct fp_machine *machine,               const struct fragment_program *program,               GLfloat result[4] ){   const GLfloat *src = get_register_pointer(ctx, source, machine, program);   ASSERT(src);   result[0] = src[GET_SWZ(source->Swizzle, 0)];   if (source->NegateBase) {      result[0] = -result[0];   }   if (source->Abs) {      result[0] = FABSF(result[0]);   }   if (source->NegateAbs) {      result[0] = -result[0];   }}/** * Test value against zero and return GT, LT, EQ or UN if NaN. */static INLINE GLuintgenerate_cc( float value ){   if (value != value)      return COND_UN;  /* NaN */   if (value > 0.0F)      return COND_GT;   if (value < 0.0F)      return COND_LT;   return COND_EQ;}/** * Test if the ccMaskRule is satisfied by the given condition code. * Used to mask destination writes according to the current condition codee. */static INLINE GLbooleantest_cc(GLuint condCode, GLuint ccMaskRule){   switch (ccMaskRule) {   case COND_EQ: return (condCode == COND_EQ);   case COND_NE: return (condCode != COND_EQ);   case COND_LT: return (condCode == COND_LT);   case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);   case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);   case COND_GT: return (condCode == COND_GT);   case COND_TR: return GL_TRUE;

⌨️ 快捷键说明

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