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

📄 atifragshader.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * \file atifragshader.c * \author David Airlie * Copyright (C) 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, 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 * DAVID AIRLIE 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 "context.h"#include "hash.h"#include "imports.h"#include "macros.h"#include "enums.h"#include "mtypes.h"#include "atifragshader.h"#define MESA_DEBUG_ATI_FS 0static struct ati_fragment_shader DummyShader;/** * Allocate and initialize a new ATI fragment shader object. */struct ati_fragment_shader *_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id){   struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);   (void) ctx;   if (s) {      s->Id = id;      s->RefCount = 1;   }   return s;}/** * Delete the given ati fragment shader */void_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s){   GLuint i;   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {      if (s->Instructions[i])         _mesa_free(s->Instructions[i]);      if (s->SetupInst[i])         _mesa_free(s->SetupInst[i]);   }   _mesa_free(s);}static voidnew_arith_inst(struct ati_fragment_shader *prog){/* set "default" instruction as not all may get defined.   there is no specified way to express a nop with ati fragment shaders we use   GL_NONE as the op enum and just set some params to 0 - so nothing to do here */   prog->numArithInstr[prog->cur_pass >> 1]++;}static voidnew_tex_inst(struct ati_fragment_shader *prog){}static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype){   if (optype == curProg->last_optype) {      curProg->last_optype = 1;   }}#if MESA_DEBUG_ATI_FSstatic char *create_dst_mod_str(GLuint mod){   static char ret_str[1024];   _mesa_memset(ret_str, 0, 1024);   if (mod & GL_2X_BIT_ATI)      _mesa_strncat(ret_str, "|2X", 1024);   if (mod & GL_4X_BIT_ATI)      _mesa_strncat(ret_str, "|4X", 1024);   if (mod & GL_8X_BIT_ATI)      _mesa_strncat(ret_str, "|8X", 1024);   if (mod & GL_HALF_BIT_ATI)      _mesa_strncat(ret_str, "|HA", 1024);   if (mod & GL_QUARTER_BIT_ATI)      _mesa_strncat(ret_str, "|QU", 1024);   if (mod & GL_EIGHTH_BIT_ATI)      _mesa_strncat(ret_str, "|EI", 1024);   if (mod & GL_SATURATE_BIT_ATI)      _mesa_strncat(ret_str, "|SAT", 1024);   if (_mesa_strlen(ret_str) == 0)      _mesa_strncat(ret_str, "NONE", 1024);   return ret_str;}static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", 			    "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" };static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst,		     GLuint dstMask, GLuint dstMod, GLuint arg1,		     GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,		     GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,		     GLuint arg3Rep, GLuint arg3Mod){  char *op_name;  op_name = atifs_ops[(arg_count-1)+(optype?3:0)];    fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op),	      _mesa_lookup_enum_by_nr(dst));  if (!optype)    fprintf(stderr, ", %d", dstMask);    fprintf(stderr, ", %s", create_dst_mod_str(dstMod));    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1),	      _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod);  if (arg_count>1)    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2),	      _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod);  if (arg_count>2)    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3),	      _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod);  fprintf(stderr,")\n");}#endifstatic int check_arith_arg(struct ati_fragment_shader *curProg,			GLuint optype, GLuint arg, GLuint argRep){   GET_CURRENT_CONTEXT(ctx);   if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) &&      ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) &&      (arg != GL_ZERO) && (arg != GL_ONE) &&      (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) {      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)");      return 0;   }   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");      return 0;   }   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");      return 0;   }   if ((curProg->cur_pass == 1) &&      ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) {      curProg->interpinp1 = GL_TRUE;   }   return 1;}GLuint GLAPIENTRY_mesa_GenFragmentShadersATI(GLuint range){   GLuint first;   GLuint i;   GET_CURRENT_CONTEXT(ctx);   if (range == 0) {      _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)");      return 0;   }   if (ctx->ATIFragmentShader.Compiling) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)");      return 0;   }   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);   for (i = 0; i < range; i++) {      _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);   }   return first;}void GLAPIENTRY_mesa_BindFragmentShaderATI(GLuint id){   GET_CURRENT_CONTEXT(ctx);   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;   struct ati_fragment_shader *newProg;   if (ctx->ATIFragmentShader.Compiling) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");      return;   }   FLUSH_VERTICES(ctx, _NEW_PROGRAM);   if (curProg->Id == id) {      return;   }   /* unbind current */   if (curProg->Id != 0) {      curProg->RefCount--;      if (curProg->RefCount <= 0) {	 _mesa_HashRemove(ctx->Shared->ATIShaders, id);      }   }   /* find new shader */   if (id == 0) {      newProg = ctx->Shared->DefaultFragmentShader;   }   else {      newProg = (struct ati_fragment_shader *)         _mesa_HashLookup(ctx->Shared->ATIShaders, id);      if (!newProg || newProg == &DummyShader) {	 /* allocate a new program now */	 newProg = _mesa_new_ati_fragment_shader(ctx, id);	 if (!newProg) {	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");	    return;	 }	 _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);      }   }   /* do actual bind */   ctx->ATIFragmentShader.Current = newProg;   ASSERT(ctx->ATIFragmentShader.Current);   if (newProg)      newProg->RefCount++;   /*if (ctx->Driver.BindProgram)      ctx->Driver.BindProgram(ctx, target, prog); */}void GLAPIENTRY_mesa_DeleteFragmentShaderATI(GLuint id){   GET_CURRENT_CONTEXT(ctx);   if (ctx->ATIFragmentShader.Compiling) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)");      return;   }   if (id != 0) {      struct ati_fragment_shader *prog = (struct ati_fragment_shader *)	 _mesa_HashLookup(ctx->Shared->ATIShaders, id);      if (prog == &DummyShader) {	 _mesa_HashRemove(ctx->Shared->ATIShaders, id);      }      else if (prog) {	 if (ctx->ATIFragmentShader.Current &&	     ctx->ATIFragmentShader.Current->Id == id) {	     FLUSH_VERTICES(ctx, _NEW_PROGRAM);	    _mesa_BindFragmentShaderATI(0);	 }      }      /* The ID is immediately available for re-use now */      _mesa_HashRemove(ctx->Shared->ATIShaders, id);      prog->RefCount--;      if (prog->RefCount <= 0) {         _mesa_free(prog);      }   }}void GLAPIENTRY_mesa_BeginFragmentShaderATI(void){   GLint i;   GET_CURRENT_CONTEXT(ctx);   if (ctx->ATIFragmentShader.Compiling) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)");      return;   }   FLUSH_VERTICES(ctx, _NEW_PROGRAM);   /* if the shader was already defined free instructions and get new ones      (or, could use the same mem but would need to reinitialize) */   /* no idea if it's allowed to redefine a shader */   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {         if (ctx->ATIFragmentShader.Current->Instructions[i])            _mesa_free(ctx->ATIFragmentShader.Current->Instructions[i]);         if (ctx->ATIFragmentShader.Current->SetupInst[i])            _mesa_free(ctx->ATIFragmentShader.Current->SetupInst[i]);   }   /* malloc the instructions here - not sure if the best place but its      a start */   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {      ctx->ATIFragmentShader.Current->Instructions[i] =	 (struct atifs_instruction *)	 _mesa_calloc(sizeof(struct atifs_instruction) *		   (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI));      ctx->ATIFragmentShader.Current->SetupInst[i] =	 (struct atifs_setupinst *)	 _mesa_calloc(sizeof(struct atifs_setupinst) *		   (MAX_NUM_FRAGMENT_REGISTERS_ATI));   }/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */   ctx->ATIFragmentShader.Current->LocalConstDef = 0;   ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;   ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;   ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;   ctx->ATIFragmentShader.Current->regsAssigned[1] = 0;   ctx->ATIFragmentShader.Current->NumPasses = 0;   ctx->ATIFragmentShader.Current->cur_pass = 0;   ctx->ATIFragmentShader.Current->last_optype = 0;   ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE;   ctx->ATIFragmentShader.Current->isValid = GL_FALSE;   ctx->ATIFragmentShader.Current->swizzlerq = 0;   ctx->ATIFragmentShader.Compiling = 1;}void GLAPIENTRY_mesa_EndFragmentShaderATI(void){   GET_CURRENT_CONTEXT(ctx);   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;#if MESA_DEBUG_ATI_FS   GLint i, j;#endif   if (!ctx->ATIFragmentShader.Compiling) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)");      return;   }   if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)");   /* according to spec, DON'T return here */   }   match_pair_inst(curProg, 0);   ctx->ATIFragmentShader.Compiling = 0;   ctx->ATIFragmentShader.Current->isValid = GL_TRUE;   if ((ctx->ATIFragmentShader.Current->cur_pass == 0) ||      (ctx->ATIFragmentShader.Current->cur_pass == 2)) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)");   }   if (ctx->ATIFragmentShader.Current->cur_pass > 1)      ctx->ATIFragmentShader.Current->NumPasses = 2;   else ctx->ATIFragmentShader.Current->NumPasses = 1;   ctx->ATIFragmentShader.Current->cur_pass=0;

⌨️ 快捷键说明

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