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

📄 slang_codegen.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Mesa 3-D graphics library * Version:  7.1 * * Copyright (C) 2005-2007  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. *//** * \file slang_codegen.c * Generate IR tree from AST. * \author Brian Paul *//*** *** NOTES: *** The new_() functions return a new instance of a simple IR node. *** The gen_() functions generate larger IR trees from the simple nodes. ***/#include "main/imports.h"#include "main/macros.h"#include "main/mtypes.h"#include "shader/program.h"#include "shader/prog_instruction.h"#include "shader/prog_parameter.h"#include "shader/prog_print.h"#include "shader/prog_statevars.h"#include "slang_typeinfo.h"#include "slang_codegen.h"#include "slang_compile.h"#include "slang_label.h"#include "slang_mem.h"#include "slang_simplify.h"#include "slang_emit.h"#include "slang_vartable.h"#include "slang_ir.h"#include "slang_print.h"static slang_ir_node *_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);static GLbooleanis_sampler_type(const slang_fully_specified_type *t){   switch (t->specifier.type) {   case SLANG_SPEC_SAMPLER1D:   case SLANG_SPEC_SAMPLER2D:   case SLANG_SPEC_SAMPLER3D:   case SLANG_SPEC_SAMPLERCUBE:   case SLANG_SPEC_SAMPLER1DSHADOW:   case SLANG_SPEC_SAMPLER2DSHADOW:   case SLANG_SPEC_SAMPLER2DRECT:   case SLANG_SPEC_SAMPLER2DRECTSHADOW:      return GL_TRUE;   default:      return GL_FALSE;   }}/** * Return the offset (in floats or ints) of the named field within * the given struct.  Return -1 if field not found. * If field is NULL, return the size of the struct instead. */static GLint_slang_field_offset(const slang_type_specifier *spec, slang_atom field){   GLint offset = 0;   GLuint i;   for (i = 0; i < spec->_struct->fields->num_variables; i++) {      const slang_variable *v = spec->_struct->fields->variables[i];      const GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier);      if (sz > 1) {         /* types larger than 1 float are register (4-float) aligned */         offset = (offset + 3) & ~3;      }      if (field && v->a_name == field) {         return offset;      }      offset += sz;   }   if (field)      return -1; /* field not found */   else      return offset;  /* struct size */}/** * Return the size (in floats) of the given type specifier. * If the size is greater than 4, the size should be a multiple of 4 * so that the correct number of 4-float registers are allocated. * For example, a mat3x2 is size 12 because we want to store the * 3 columns in 3 float[4] registers. */GLuint_slang_sizeof_type_specifier(const slang_type_specifier *spec){   GLuint sz;   switch (spec->type) {   case SLANG_SPEC_VOID:      sz = 0;      break;   case SLANG_SPEC_BOOL:      sz = 1;      break;   case SLANG_SPEC_BVEC2:      sz = 2;      break;   case SLANG_SPEC_BVEC3:      sz = 3;      break;   case SLANG_SPEC_BVEC4:      sz = 4;      break;   case SLANG_SPEC_INT:      sz = 1;      break;   case SLANG_SPEC_IVEC2:      sz = 2;      break;   case SLANG_SPEC_IVEC3:      sz = 3;      break;   case SLANG_SPEC_IVEC4:      sz = 4;      break;   case SLANG_SPEC_FLOAT:      sz = 1;      break;   case SLANG_SPEC_VEC2:      sz = 2;      break;   case SLANG_SPEC_VEC3:      sz = 3;      break;   case SLANG_SPEC_VEC4:      sz = 4;      break;   case SLANG_SPEC_MAT2:      sz = 2 * 4; /* 2 columns (regs) */      break;   case SLANG_SPEC_MAT3:      sz = 3 * 4;      break;   case SLANG_SPEC_MAT4:      sz = 4 * 4;      break;   case SLANG_SPEC_MAT23:      sz = 2 * 4; /* 2 columns (regs) */      break;   case SLANG_SPEC_MAT32:      sz = 3 * 4; /* 3 columns (regs) */      break;   case SLANG_SPEC_MAT24:      sz = 2 * 4;      break;   case SLANG_SPEC_MAT42:      sz = 4 * 4; /* 4 columns (regs) */      break;   case SLANG_SPEC_MAT34:      sz = 3 * 4;      break;   case SLANG_SPEC_MAT43:      sz = 4 * 4; /* 4 columns (regs) */      break;   case SLANG_SPEC_SAMPLER1D:   case SLANG_SPEC_SAMPLER2D:   case SLANG_SPEC_SAMPLER3D:   case SLANG_SPEC_SAMPLERCUBE:   case SLANG_SPEC_SAMPLER1DSHADOW:   case SLANG_SPEC_SAMPLER2DSHADOW:   case SLANG_SPEC_SAMPLER2DRECT:   case SLANG_SPEC_SAMPLER2DRECTSHADOW:      sz = 1; /* a sampler is basically just an integer index */      break;   case SLANG_SPEC_STRUCT:      sz = _slang_field_offset(spec, 0); /* special use */      if (sz > 4) {         sz = (sz + 3) & ~0x3; /* round up to multiple of four */      }      break;   case SLANG_SPEC_ARRAY:      sz = _slang_sizeof_type_specifier(spec->_array);      break;   default:      _mesa_problem(NULL, "Unexpected type in _slang_sizeof_type_specifier()");      sz = 0;   }   if (sz > 4) {      /* if size is > 4, it should be a multiple of four */      assert((sz & 0x3) == 0);   }   return sz;}/** * Establish the binding between a slang_ir_node and a slang_variable. * Then, allocate/attach a slang_ir_storage object to the IR node if needed. * The IR node must be a IR_VAR or IR_VAR_DECL node. * \param n  the IR node * \param var  the variable to associate with the IR node */static void_slang_attach_storage(slang_ir_node *n, slang_variable *var){   assert(n);   assert(var);   assert(n->Opcode == IR_VAR || n->Opcode == IR_VAR_DECL);   assert(!n->Var || n->Var == var);   n->Var = var;   if (!n->Store) {      /* need to setup storage */      if (n->Var && n->Var->aux) {         /* node storage info = var storage info */         n->Store = (slang_ir_storage *) n->Var->aux;      }      else {         /* alloc new storage info */         n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -7, -5);#if 0         printf("%s var=%s Store=%p Size=%d\n", __FUNCTION__,                (char*) var->a_name,                (void*) n->Store, n->Store->Size);#endif         if (n->Var)            n->Var->aux = n->Store;         assert(n->Var->aux);      }   }}/** * Return the TEXTURE_*_INDEX value that corresponds to a sampler type, * or -1 if the type is not a sampler. */static GLintsampler_to_texture_index(const slang_type_specifier_type type){   switch (type) {   case SLANG_SPEC_SAMPLER1D:      return TEXTURE_1D_INDEX;   case SLANG_SPEC_SAMPLER2D:      return TEXTURE_2D_INDEX;   case SLANG_SPEC_SAMPLER3D:      return TEXTURE_3D_INDEX;   case SLANG_SPEC_SAMPLERCUBE:      return TEXTURE_CUBE_INDEX;   case SLANG_SPEC_SAMPLER1DSHADOW:      return TEXTURE_1D_INDEX; /* XXX fix */   case SLANG_SPEC_SAMPLER2DSHADOW:      return TEXTURE_2D_INDEX; /* XXX fix */   case SLANG_SPEC_SAMPLER2DRECT:      return TEXTURE_RECT_INDEX;   case SLANG_SPEC_SAMPLER2DRECTSHADOW:      return TEXTURE_RECT_INDEX; /* XXX fix */   default:      return -1;   }}#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)/** * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to * a vertex or fragment program input variable.  Return -1 if the input * name is invalid. * XXX return size too */static GLint_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut){   struct input_info {      const char *Name;      GLuint Attrib;      GLuint Swizzle;   };   static const struct input_info vertInputs[] = {      { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP },      { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP },      { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP },      { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP },      { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX },      { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP },      { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP },      { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP },      { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP },      { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP },      { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP },      { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP },      { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP },      { NULL, 0, SWIZZLE_NOOP }   };   static const struct input_info fragInputs[] = {      { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP },      { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP },      { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP },      { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP },      /* note: we're packing several quantities into the fogcoord vector */      { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX },      { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/      { "gl_PointCoord", FRAG_ATTRIB_FOGC, SWIZZLE_ZWWW },      { NULL, 0, SWIZZLE_NOOP }   };   GLuint i;   const struct input_info *inputs      = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs;   ASSERT(MAX_TEXTURE_UNITS == 8); /* if this fails, fix vertInputs above */   for (i = 0; inputs[i].Name; i++) {      if (strcmp(inputs[i].Name, name) == 0) {         /* found */         *swizzleOut = inputs[i].Swizzle;         return inputs[i].Attrib;      }   }   return -1;}/** * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to * a vertex or fragment program output variable.  Return -1 for an invalid * output name. */static GLint_slang_output_index(const char *name, GLenum target){   struct output_info {      const char *Name;      GLuint Attrib;   };   static const struct output_info vertOutputs[] = {      { "gl_Position", VERT_RESULT_HPOS },      { "gl_FrontColor", VERT_RESULT_COL0 },      { "gl_BackColor", VERT_RESULT_BFC0 },      { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },      { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },      { "gl_TexCoord", VERT_RESULT_TEX0 },      { "gl_FogFragCoord", VERT_RESULT_FOGC },      { "gl_PointSize", VERT_RESULT_PSIZ },      { NULL, 0 }   };   static const struct output_info fragOutputs[] = {      { "gl_FragColor", FRAG_RESULT_COLR },      { "gl_FragDepth", FRAG_RESULT_DEPR },      { "gl_FragData", FRAG_RESULT_DATA0 },      { NULL, 0 }   };   GLuint i;   const struct output_info *outputs      = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs;   for (i = 0; outputs[i].Name; i++) {      if (strcmp(outputs[i].Name, name) == 0) {         /* found */         return outputs[i].Attrib;      }   }   return -1;}/**********************************************************************//** * Map "_asm foo" to IR_FOO, etc. */typedef struct{   const char *Name;   slang_ir_opcode Opcode;   GLuint HaveRetValue, NumParams;} slang_asm_info;static slang_asm_info AsmInfo[] = {   /* vec4 binary op */   { "vec4_add", IR_ADD, 1, 2 },   { "vec4_subtract", IR_SUB, 1, 2 },   { "vec4_multiply", IR_MUL, 1, 2 },   { "vec4_dot", IR_DOT4, 1, 2 },   { "vec3_dot", IR_DOT3, 1, 2 },   { "vec3_cross", IR_CROSS, 1, 2 },   { "vec4_lrp", IR_LRP, 1, 3 },   { "vec4_min", IR_MIN, 1, 2 },   { "vec4_max", IR_MAX, 1, 2 },   { "vec4_clamp", IR_CLAMP, 1, 3 },   { "vec4_seq", IR_SEQUAL, 1, 2 },   { "vec4_sne", IR_SNEQUAL, 1, 2 },   { "vec4_sge", IR_SGE, 1, 2 },   { "vec4_sgt", IR_SGT, 1, 2 },   { "vec4_sle", IR_SLE, 1, 2 },   { "vec4_slt", IR_SLT, 1, 2 },   /* vec4 unary */   { "vec4_move", IR_MOVE, 1, 1 },   { "vec4_floor", IR_FLOOR, 1, 1 },   { "vec4_frac", IR_FRAC, 1, 1 },   { "vec4_abs", IR_ABS, 1, 1 },   { "vec4_negate", IR_NEG, 1, 1 },   { "vec4_ddx", IR_DDX, 1, 1 },   { "vec4_ddy", IR_DDY, 1, 1 },   /* float binary op */   { "float_power", IR_POW, 1, 2 },   /* texture / sampler */   { "vec4_tex1d", IR_TEX, 1, 2 },   { "vec4_texb1d", IR_TEXB, 1, 2 },  /* 1d w/ bias */   { "vec4_texp1d", IR_TEXP, 1, 2 },  /* 1d w/ projection */   { "vec4_tex2d", IR_TEX, 1, 2 },   { "vec4_texb2d", IR_TEXB, 1, 2 },  /* 2d w/ bias */   { "vec4_texp2d", IR_TEXP, 1, 2 },  /* 2d w/ projection */   { "vec4_tex3d", IR_TEX, 1, 2 },   { "vec4_texb3d", IR_TEXB, 1, 2 },  /* 3d w/ bias */   { "vec4_texp3d", IR_TEXP, 1, 2 },  /* 3d w/ projection */   { "vec4_texcube", IR_TEX, 1, 2 },  /* cubemap */   { "vec4_tex_rect", IR_TEX, 1, 2 }, /* rectangle */   { "vec4_texp_rect", IR_TEX, 1, 2 },/* rectangle w/ projection */   /* unary op */   { "ivec4_to_vec4", IR_I_TO_F, 1, 1 }, /* int[4] to float[4] */   { "vec4_to_ivec4", IR_F_TO_I, 1, 1 },  /* float[4] to int[4] */   { "float_exp", IR_EXP, 1, 1 },   { "float_exp2", IR_EXP2, 1, 1 },   { "float_log2", IR_LOG2, 1, 1 },   { "float_rsq", IR_RSQ, 1, 1 },   { "float_rcp", IR_RCP, 1, 1 },   { "float_sine", IR_SIN, 1, 1 },

⌨️ 快捷键说明

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