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

📄 r200_fragshader.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************** * * Copyright 2004 David Airlie * 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, 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 DAVID AIRLIE AND/OR ITS 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. * **************************************************************************/#include "main/glheader.h"#include "main/macros.h"#include "main/enums.h"#include "tnl/t_context.h"#include "shader/atifragshader.h"#include "shader/program.h"#include "r200_context.h"#include "r200_ioctl.h"#include "r200_tex.h"#define SET_INST(inst, type) afs_cmd[((inst<<2) + (type<<1) + 1)]#define SET_INST_2(inst, type) afs_cmd[((inst<<2) + (type<<1) + 2)]static void r200SetFragShaderArg( GLuint *afs_cmd, GLuint opnum, GLuint optype,				const struct atifragshader_src_register srcReg,				GLuint argPos, GLuint *tfactor ){   const GLuint index = srcReg.Index;   const GLuint srcmod = srcReg.argMod;   const GLuint srcrep = srcReg.argRep;   GLuint reg0 = 0;   GLuint reg2 = 0;   GLuint useOddSrc = 0;   switch(srcrep) {   case GL_RED:      reg2 |= R200_TXC_REPL_RED << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));      if (optype)	 useOddSrc = 1;      break;   case GL_GREEN:      reg2 |= R200_TXC_REPL_GREEN << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));      if (optype)	 useOddSrc = 1;      break;   case GL_BLUE:      if (!optype)	 reg2 |= R200_TXC_REPL_BLUE << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));      else	 useOddSrc = 1;      break;   case GL_ALPHA:      if (!optype)	 useOddSrc = 1;      break;   }   if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)      reg0 |= (((index - GL_REG_0_ATI)*2) + 10 + useOddSrc) << (5*argPos);   else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {      if ((*tfactor == 0) || (index == *tfactor)) {	 reg0 |= (R200_TXC_ARG_A_TFACTOR_COLOR + useOddSrc) << (5*argPos);	 reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR_SEL_SHIFT;	 *tfactor = index;      }      else {	 reg0 |= (R200_TXC_ARG_A_TFACTOR1_COLOR + useOddSrc) << (5*argPos);	 reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR1_SEL_SHIFT;      }   }   else if (index == GL_PRIMARY_COLOR_EXT) {      reg0 |= (R200_TXC_ARG_A_DIFFUSE_COLOR + useOddSrc) << (5*argPos);   }   else if (index == GL_SECONDARY_INTERPOLATOR_ATI) {      reg0 |= (R200_TXC_ARG_A_SPECULAR_COLOR + useOddSrc) << (5*argPos);   }   /* GL_ZERO is a noop, for GL_ONE we set the complement */   else if (index == GL_ONE) {      reg0 |= R200_TXC_COMP_ARG_A << (4*argPos);   }   if (srcmod & GL_COMP_BIT_ATI)      reg0 ^= R200_TXC_COMP_ARG_A << (4*argPos);   if (srcmod & GL_BIAS_BIT_ATI)      reg0 |= R200_TXC_BIAS_ARG_A << (4*argPos);   if (srcmod & GL_2X_BIT_ATI)      reg0 |= R200_TXC_SCALE_ARG_A << (4*argPos);   if (srcmod & GL_NEGATE_BIT_ATI)      reg0 ^= R200_TXC_NEG_ARG_A << (4*argPos);   SET_INST(opnum, optype) |= reg0;   SET_INST_2(opnum, optype) |= reg2;}static GLuint dstmask_table[8] ={   R200_TXC_OUTPUT_MASK_RGB,   R200_TXC_OUTPUT_MASK_R,   R200_TXC_OUTPUT_MASK_G,   R200_TXC_OUTPUT_MASK_RG,   R200_TXC_OUTPUT_MASK_B,   R200_TXC_OUTPUT_MASK_RB,   R200_TXC_OUTPUT_MASK_GB,   R200_TXC_OUTPUT_MASK_RGB};static void r200UpdateFSArith( GLcontext *ctx ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   GLuint *afs_cmd;   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;   GLuint pass;   R200_STATECHANGE( rmesa, afs[0] );   R200_STATECHANGE( rmesa, afs[1] );   if (shader->NumPasses < 2) {      afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;   }   else {      afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd;   }   for (pass = 0; pass < shader->NumPasses; pass++) {      GLuint opnum = 0;      GLuint pc;      for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {         GLuint optype;	 struct atifs_instruction *inst = &shader->Instructions[pass][pc];	 SET_INST(opnum, 0) = 0;	 SET_INST_2(opnum, 0) = 0;	 SET_INST(opnum, 1) = 0;	 SET_INST_2(opnum, 1) = 0;	 for (optype = 0; optype < 2; optype++) {	    GLuint tfactor = 0;	    if (inst->Opcode[optype]) {	       switch (inst->Opcode[optype]) {	       /* these are all MADD in disguise		  MADD is A * B + C		  so for GL_ADD use arg B/C and make A complement 0		  for GL_SUB use arg B/C, negate C and make A complement 0		  for GL_MOV use arg C		  for GL_MUL use arg A		  for GL_MAD all good */	       case GL_SUB_ATI:		  /* negate C */		  SET_INST(opnum, optype) |= R200_TXC_NEG_ARG_C;		  /* fallthrough */	       case GL_ADD_ATI:		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][0], 1, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][1], 2, &tfactor);		  /* A = complement 0 */		  SET_INST(opnum, optype) |= R200_TXC_COMP_ARG_A;		  SET_INST(opnum, optype) |= R200_TXC_OP_MADD;		  break;	       case GL_MOV_ATI:		  /* put arg0 in C */		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][0], 2, &tfactor);		  SET_INST(opnum, optype) |= R200_TXC_OP_MADD;		  break;	       case GL_MAD_ATI:		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][2], 2, &tfactor);		  /* fallthrough */	       case GL_MUL_ATI:		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][0], 0, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][1], 1, &tfactor);		  SET_INST(opnum, optype) |= R200_TXC_OP_MADD;		  break;	       case GL_LERP_ATI:		  /* arg order is not native chip order, swap A and C */		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][0], 2, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][1], 1, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][2], 0, &tfactor);		  SET_INST(opnum, optype) |= R200_TXC_OP_LERP;		  break;	       case GL_CND_ATI:		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][0], 0, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][1], 1, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][2], 2, &tfactor);		  SET_INST(opnum, optype) |= R200_TXC_OP_CONDITIONAL;		  break;	       case GL_CND0_ATI:		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][0], 0, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][1], 1, &tfactor);		  r200SetFragShaderArg(afs_cmd, opnum, optype,					inst->SrcReg[optype][2], 2, &tfactor);		  SET_INST(opnum, optype) |= R200_TXC_OP_CND0;		  break;		  /* cannot specify dot ops as alpha ops directly */	       case GL_DOT2_ADD_ATI:		  if (optype)		     SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;		  else {		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][0], 0, &tfactor);		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][1], 1, &tfactor);		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][2], 2, &tfactor);		     SET_INST(opnum, 0) |= R200_TXC_OP_DOT2_ADD;		  }		  break;	       case GL_DOT3_ATI:		  if (optype)		     SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;		  else {		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][0], 0, &tfactor);		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][1], 1, &tfactor);		     SET_INST(opnum, 0) |= R200_TXC_OP_DOT3;		  }		  break;	       case GL_DOT4_ATI:	       /* experimental verification: for dot4 setup of alpha args is needed		  (dstmod is ignored, though, so dot2/dot3 should be safe)		  the hardware apparently does R1*R2 + G1*G2 + B1*B2 + A3*A4		  but the API doesn't allow it */		  if (optype)		     SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;		  else {		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][0], 0, &tfactor);		     r200SetFragShaderArg(afs_cmd, opnum, 0,					inst->SrcReg[0][1], 1, &tfactor);		     r200SetFragShaderArg(afs_cmd, opnum, 1,					inst->SrcReg[0][0], 0, &tfactor);		     r200SetFragShaderArg(afs_cmd, opnum, 1,					inst->SrcReg[0][1], 1, &tfactor);		     SET_INST(opnum, optype) |= R200_TXC_OP_DOT4;		  }		  break;	       }	    }	    /* destination */	    if (inst->DstReg[optype].Index) {	       GLuint dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI;	       GLuint dstmask = inst->DstReg[optype].dstMask;	       GLuint sat = inst->DstReg[optype].dstMod & GL_SATURATE_BIT_ATI;	       GLuint dstmod = inst->DstReg[optype].dstMod;

⌨️ 快捷键说明

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