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

📄 slang_typeinfo.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 2005-2006  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_assemble_typeinfo.c * slang type info * \author Michal Krol */#include "main/imports.h"#include "shader/prog_instruction.h"#include "slang_typeinfo.h"#include "slang_compile.h"#include "slang_log.h"#include "slang_mem.h"/** * Checks if a field selector is a general swizzle (an r-value swizzle * with replicated components or an l-value swizzle mask) for a * vector.  Returns GL_TRUE if this is the case, <swz> is filled with * swizzle information.  Returns GL_FALSE otherwise. */GLboolean_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz){   GLuint i;   GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;   /* init to undefined.    * We rely on undefined/nil values to distinguish between    * regular swizzles and writemasks.    * For example, the swizzle ".xNNN" is the writemask ".x".    * That's different than the swizzle ".xxxx".    */   for (i = 0; i < 4; i++)      swz->swizzle[i] = SWIZZLE_NIL;   /* the swizzle can be at most 4-component long */   swz->num_components = slang_string_length(field);   if (swz->num_components > 4)      return GL_FALSE;   for (i = 0; i < swz->num_components; i++) {      /* mark which swizzle group is used */      switch (field[i]) {      case 'x':      case 'y':      case 'z':      case 'w':         xyzw = GL_TRUE;         break;      case 'r':      case 'g':      case 'b':      case 'a':         rgba = GL_TRUE;         break;      case 's':      case 't':      case 'p':      case 'q':         stpq = GL_TRUE;         break;      default:         return GL_FALSE;      }      /* collect swizzle component */      switch (field[i]) {      case 'x':      case 'r':      case 's':         swz->swizzle[i] = 0;         break;      case 'y':      case 'g':      case 't':         swz->swizzle[i] = 1;         break;      case 'z':      case 'b':      case 'p':         swz->swizzle[i] = 2;         break;      case 'w':      case 'a':      case 'q':         swz->swizzle[i] = 3;         break;      }      /* check if the component is valid for given vector's row count */      if (rows <= swz->swizzle[i])         return GL_FALSE;   }   /* only one swizzle group can be used */   if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))      return GL_FALSE;   return GL_TRUE;}/** * Checks if a general swizzle is an l-value swizzle - these swizzles * do not have duplicated fields.  Returns GL_TRUE if this is a * swizzle mask.  Returns GL_FALSE otherwise */GLboolean_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows){   GLuint i, c = 0;   /* the swizzle may not be longer than the vector dim */   if (swz->num_components > rows)      return GL_FALSE;   /* the swizzle components cannot be duplicated */   for (i = 0; i < swz->num_components; i++) {      if ((c & (1 << swz->swizzle[i])) != 0)         return GL_FALSE;      c |= 1 << swz->swizzle[i];   }   return GL_TRUE;}/** * Combines (multiplies) two swizzles to form single swizzle. * Example: "vec.wzyx.yx" --> "vec.zw". */GLvoid_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left,                         const slang_swizzle * right){   GLuint i;   dst->num_components = right->num_components;   for (i = 0; i < right->num_components; i++)      dst->swizzle[i] = left->swizzle[right->swizzle[i]];}GLvoidslang_type_specifier_ctr(slang_type_specifier * self){   self->type = SLANG_SPEC_VOID;   self->_struct = NULL;   self->_array = NULL;}GLvoidslang_type_specifier_dtr(slang_type_specifier * self){   if (self->_struct != NULL) {      slang_struct_destruct(self->_struct);      _slang_free(self->_struct);   }   if (self->_array != NULL) {      slang_type_specifier_dtr(self->_array);      _slang_free(self->_array);   }}GLbooleanslang_type_specifier_copy(slang_type_specifier * x,                          const slang_type_specifier * y){   slang_type_specifier z;   slang_type_specifier_ctr(&z);   z.type = y->type;   if (z.type == SLANG_SPEC_STRUCT) {      z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));      if (z._struct == NULL) {         slang_type_specifier_dtr(&z);         return GL_FALSE;      }      if (!slang_struct_construct(z._struct)) {         _slang_free(z._struct);         slang_type_specifier_dtr(&z);         return GL_FALSE;      }      if (!slang_struct_copy(z._struct, y->_struct)) {         slang_type_specifier_dtr(&z);         return GL_FALSE;      }   }   else if (z.type == SLANG_SPEC_ARRAY) {      z._array = (slang_type_specifier *)         _slang_alloc(sizeof(slang_type_specifier));      if (z._array == NULL) {         slang_type_specifier_dtr(&z);         return GL_FALSE;      }      slang_type_specifier_ctr(z._array);      if (!slang_type_specifier_copy(z._array, y->_array)) {         slang_type_specifier_dtr(&z);         return GL_FALSE;      }   }   slang_type_specifier_dtr(x);   *x = z;   return GL_TRUE;}/** * Test if two types are equal. */GLbooleanslang_type_specifier_equal(const slang_type_specifier * x,                           const slang_type_specifier * y){   if (x->type != y->type)      return GL_FALSE;   if (x->type == SLANG_SPEC_STRUCT)      return slang_struct_equal(x->_struct, y->_struct);   if (x->type == SLANG_SPEC_ARRAY)      return slang_type_specifier_equal(x->_array, y->_array);   return GL_TRUE;}/** * As above, but allow float/int casting. */static GLbooleanslang_type_specifier_compatible(const slang_type_specifier * x,                                const slang_type_specifier * y){   /* special case: float == int */   if (x->type == SLANG_SPEC_INT && y->type == SLANG_SPEC_FLOAT) {      return GL_TRUE;   }   /* XXX may need to add bool/int compatibility, etc */   if (x->type != y->type)      return GL_FALSE;   if (x->type == SLANG_SPEC_STRUCT)      return slang_struct_equal(x->_struct, y->_struct);   if (x->type == SLANG_SPEC_ARRAY)      return slang_type_specifier_compatible(x->_array, y->_array);   return GL_TRUE;}GLbooleanslang_typeinfo_construct(slang_typeinfo * ti){   _mesa_bzero(ti, sizeof(*ti));   slang_type_specifier_ctr(&ti->spec);   ti->array_len = 0;   return GL_TRUE;}GLvoidslang_typeinfo_destruct(slang_typeinfo * ti){   slang_type_specifier_dtr(&ti->spec);}/** * Determine the return type of a function. * \param a_name  the function name * \param param  function parameters (overloading) * \param num_params  number of parameters to function * \param space  namespace to search * \param spec  returns the type * \param funFound  returns pointer to the function, or NULL if not found. * \return GL_TRUE for success, GL_FALSE if failure (bad function name) */static GLboolean_slang_typeof_function(slang_atom a_name,                       slang_operation * params, GLuint num_params,                       const slang_name_space * space,                       slang_type_specifier * spec,                       slang_function **funFound,                       slang_atom_pool *atoms, slang_info_log *log){   GLboolean error;   *funFound = _slang_locate_function(space->funcs, a_name, params,                                      num_params, space, atoms, log, &error);   if (error)      return GL_FALSE;   if (!*funFound)      return GL_TRUE;  /* yes, not false */   return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier);}/** * Determine the type of a math function. * \param name  name of the operator, one of +,-,*,/ or unary - * \param params  array of function parameters * \param num_params  number of parameters * \param space  namespace to use * \param spec  returns the function's type * \param atoms  atom pool * \return GL_TRUE for success, GL_FALSE if failure */static GLbooleantypeof_math_call(const char *name, slang_operation *call,                 const slang_name_space * space,                 slang_type_specifier * spec,                 slang_atom_pool * atoms,                 slang_info_log *log){   if (call->fun) {      /* we've previously resolved this function call */      slang_type_specifier_copy(spec, &call->fun->header.type.specifier);      return GL_TRUE;   }   else {      slang_atom atom;      slang_function *fun;      /* number of params: */      assert(call->num_children == 1 || call->num_children == 2);      atom = slang_atom_pool_atom(atoms, name);      if (!_slang_typeof_function(atom, call->children, call->num_children,                                  space, spec, &fun, atoms, log))         return GL_FALSE;      if (fun) {         /* Save pointer to save time in future */         call->fun = fun;

⌨️ 快捷键说明

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