11591693c7b415e9869157c711fe11263c95d74eDavid Li/*
21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2009 Intel Corporation
31591693c7b415e9869157c711fe11263c95d74eDavid Li *
41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a
51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"),
61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation
71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the
91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions:
101591693c7b415e9869157c711fe11263c95d74eDavid Li *
111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next
121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the
131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software.
141591693c7b415e9869157c711fe11263c95d74eDavid Li *
151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE.
221591693c7b415e9869157c711fe11263c95d74eDavid Li */
231591693c7b415e9869157c711fe11263c95d74eDavid Li
241591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdio>
251591693c7b415e9869157c711fe11263c95d74eDavid Li#include <stdlib.h>
261591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/core.h" /* for Elements */
271591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_symbol_table.h"
281591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_parser_extras.h"
291591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h"
301591693c7b415e9869157c711fe11263c95d74eDavid Li#include "builtin_types.h"
311591693c7b415e9869157c711fe11263c95d74eDavid Liextern "C" {
321591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program/hash_table.h"
331591693c7b415e9869157c711fe11263c95d74eDavid Li}
341591693c7b415e9869157c711fe11263c95d74eDavid Li
351591693c7b415e9869157c711fe11263c95d74eDavid Lihash_table *glsl_type::array_types = NULL;
361591693c7b415e9869157c711fe11263c95d74eDavid Lihash_table *glsl_type::record_types = NULL;
371591693c7b415e9869157c711fe11263c95d74eDavid Livoid *glsl_type::mem_ctx = NULL;
381591693c7b415e9869157c711fe11263c95d74eDavid Li
391591693c7b415e9869157c711fe11263c95d74eDavid Livoid
40d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Liglsl_type::init_hieralloc_type_ctx(void)
411591693c7b415e9869157c711fe11263c95d74eDavid Li{
421591693c7b415e9869157c711fe11263c95d74eDavid Li   if (glsl_type::mem_ctx == NULL) {
43d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      glsl_type::mem_ctx = hieralloc_autofree_context();
441591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(glsl_type::mem_ctx != NULL);
451591693c7b415e9869157c711fe11263c95d74eDavid Li   }
461591693c7b415e9869157c711fe11263c95d74eDavid Li}
471591693c7b415e9869157c711fe11263c95d74eDavid Li
481591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::glsl_type(GLenum gl_type,
491591693c7b415e9869157c711fe11263c95d74eDavid Li		     glsl_base_type base_type, unsigned vector_elements,
501591693c7b415e9869157c711fe11263c95d74eDavid Li		     unsigned matrix_columns, const char *name) :
511591693c7b415e9869157c711fe11263c95d74eDavid Li   gl_type(gl_type),
521591693c7b415e9869157c711fe11263c95d74eDavid Li   base_type(base_type),
531591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
541591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_type(0),
551591693c7b415e9869157c711fe11263c95d74eDavid Li   vector_elements(vector_elements), matrix_columns(matrix_columns),
561591693c7b415e9869157c711fe11263c95d74eDavid Li   length(0)
571591693c7b415e9869157c711fe11263c95d74eDavid Li{
58d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   init_hieralloc_type_ctx();
59d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   this->name = hieralloc_strdup(this->mem_ctx, name);
601591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Neither dimension is zero or both dimensions are zero.
611591693c7b415e9869157c711fe11263c95d74eDavid Li    */
621591693c7b415e9869157c711fe11263c95d74eDavid Li   assert((vector_elements == 0) == (matrix_columns == 0));
631591693c7b415e9869157c711fe11263c95d74eDavid Li   memset(& fields, 0, sizeof(fields));
641591693c7b415e9869157c711fe11263c95d74eDavid Li}
651591693c7b415e9869157c711fe11263c95d74eDavid Li
661591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::glsl_type(GLenum gl_type,
671591693c7b415e9869157c711fe11263c95d74eDavid Li		     enum glsl_sampler_dim dim, bool shadow, bool array,
681591693c7b415e9869157c711fe11263c95d74eDavid Li		     unsigned type, const char *name) :
691591693c7b415e9869157c711fe11263c95d74eDavid Li   gl_type(gl_type),
701591693c7b415e9869157c711fe11263c95d74eDavid Li   base_type(GLSL_TYPE_SAMPLER),
711591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_dimensionality(dim), sampler_shadow(shadow),
721591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_array(array), sampler_type(type),
731591693c7b415e9869157c711fe11263c95d74eDavid Li   vector_elements(0), matrix_columns(0),
741591693c7b415e9869157c711fe11263c95d74eDavid Li   length(0)
751591693c7b415e9869157c711fe11263c95d74eDavid Li{
76d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   init_hieralloc_type_ctx();
77d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   this->name = hieralloc_strdup(this->mem_ctx, name);
781591693c7b415e9869157c711fe11263c95d74eDavid Li   memset(& fields, 0, sizeof(fields));
791591693c7b415e9869157c711fe11263c95d74eDavid Li}
801591693c7b415e9869157c711fe11263c95d74eDavid Li
811591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
821591693c7b415e9869157c711fe11263c95d74eDavid Li		     const char *name) :
831591693c7b415e9869157c711fe11263c95d74eDavid Li   base_type(GLSL_TYPE_STRUCT),
841591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
851591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_type(0),
861591693c7b415e9869157c711fe11263c95d74eDavid Li   vector_elements(0), matrix_columns(0),
871591693c7b415e9869157c711fe11263c95d74eDavid Li   length(num_fields)
881591693c7b415e9869157c711fe11263c95d74eDavid Li{
891591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned int i;
901591693c7b415e9869157c711fe11263c95d74eDavid Li
91d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   init_hieralloc_type_ctx();
92d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   this->name = hieralloc_strdup(this->mem_ctx, name);
93d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   this->fields.structure = hieralloc_array(this->mem_ctx,
941591693c7b415e9869157c711fe11263c95d74eDavid Li					 glsl_struct_field, length);
951591693c7b415e9869157c711fe11263c95d74eDavid Li   for (i = 0; i < length; i++) {
961591693c7b415e9869157c711fe11263c95d74eDavid Li      this->fields.structure[i].type = fields[i].type;
97d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      this->fields.structure[i].name = hieralloc_strdup(this->fields.structure,
981591693c7b415e9869157c711fe11263c95d74eDavid Li						     fields[i].name);
991591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1001591693c7b415e9869157c711fe11263c95d74eDavid Li}
1011591693c7b415e9869157c711fe11263c95d74eDavid Li
1021591693c7b415e9869157c711fe11263c95d74eDavid Listatic void
1031591693c7b415e9869157c711fe11263c95d74eDavid Liadd_types_to_symbol_table(glsl_symbol_table *symtab,
1041591693c7b415e9869157c711fe11263c95d74eDavid Li			  const struct glsl_type *types,
1051591693c7b415e9869157c711fe11263c95d74eDavid Li			  unsigned num_types, bool warn)
1061591693c7b415e9869157c711fe11263c95d74eDavid Li{
1071591693c7b415e9869157c711fe11263c95d74eDavid Li   (void) warn;
1081591693c7b415e9869157c711fe11263c95d74eDavid Li
1091591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_types; i++) {
1101591693c7b415e9869157c711fe11263c95d74eDavid Li      symtab->add_type(types[i].name, & types[i]);
1111591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1121591693c7b415e9869157c711fe11263c95d74eDavid Li}
1131591693c7b415e9869157c711fe11263c95d74eDavid Li
1141591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1151591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::generate_100ES_types(glsl_symbol_table *symtab)
1161591693c7b415e9869157c711fe11263c95d74eDavid Li{
1171591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_core_types,
1181591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_core_types),
1191591693c7b415e9869157c711fe11263c95d74eDavid Li			     false);
1201591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_structure_types,
1211591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_structure_types),
1221591693c7b415e9869157c711fe11263c95d74eDavid Li			     false);
1231591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, &void_type, 1, false);
1241591693c7b415e9869157c711fe11263c95d74eDavid Li}
1251591693c7b415e9869157c711fe11263c95d74eDavid Li
1261591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1271591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::generate_110_types(glsl_symbol_table *symtab)
1281591693c7b415e9869157c711fe11263c95d74eDavid Li{
1291591693c7b415e9869157c711fe11263c95d74eDavid Li   generate_100ES_types(symtab);
1301591693c7b415e9869157c711fe11263c95d74eDavid Li
1311591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_110_types,
1321591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_110_types),
1331591693c7b415e9869157c711fe11263c95d74eDavid Li			     false);
1341591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
1351591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_110_deprecated_structure_types),
1361591693c7b415e9869157c711fe11263c95d74eDavid Li			     false);
1371591693c7b415e9869157c711fe11263c95d74eDavid Li}
1381591693c7b415e9869157c711fe11263c95d74eDavid Li
1391591693c7b415e9869157c711fe11263c95d74eDavid Li
1401591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1411591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::generate_120_types(glsl_symbol_table *symtab)
1421591693c7b415e9869157c711fe11263c95d74eDavid Li{
1431591693c7b415e9869157c711fe11263c95d74eDavid Li   generate_110_types(symtab);
1441591693c7b415e9869157c711fe11263c95d74eDavid Li
1451591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_120_types,
1461591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_120_types), false);
1471591693c7b415e9869157c711fe11263c95d74eDavid Li}
1481591693c7b415e9869157c711fe11263c95d74eDavid Li
1491591693c7b415e9869157c711fe11263c95d74eDavid Li
1501591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1511591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::generate_130_types(glsl_symbol_table *symtab)
1521591693c7b415e9869157c711fe11263c95d74eDavid Li{
1531591693c7b415e9869157c711fe11263c95d74eDavid Li   generate_120_types(symtab);
1541591693c7b415e9869157c711fe11263c95d74eDavid Li
1551591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_130_types,
1561591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_130_types), false);
1571591693c7b415e9869157c711fe11263c95d74eDavid Li   generate_EXT_texture_array_types(symtab, false);
1581591693c7b415e9869157c711fe11263c95d74eDavid Li}
1591591693c7b415e9869157c711fe11263c95d74eDavid Li
1601591693c7b415e9869157c711fe11263c95d74eDavid Li
1611591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1621591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
1631591693c7b415e9869157c711fe11263c95d74eDavid Li						bool warn)
1641591693c7b415e9869157c711fe11263c95d74eDavid Li{
1651591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
1661591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_ARB_texture_rectangle_types),
1671591693c7b415e9869157c711fe11263c95d74eDavid Li			     warn);
1681591693c7b415e9869157c711fe11263c95d74eDavid Li}
1691591693c7b415e9869157c711fe11263c95d74eDavid Li
1701591693c7b415e9869157c711fe11263c95d74eDavid Li
1711591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1721591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
1731591693c7b415e9869157c711fe11263c95d74eDavid Li					    bool warn)
1741591693c7b415e9869157c711fe11263c95d74eDavid Li{
1751591693c7b415e9869157c711fe11263c95d74eDavid Li   add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
1761591693c7b415e9869157c711fe11263c95d74eDavid Li			     Elements(builtin_EXT_texture_array_types),
1771591693c7b415e9869157c711fe11263c95d74eDavid Li			     warn);
1781591693c7b415e9869157c711fe11263c95d74eDavid Li}
1791591693c7b415e9869157c711fe11263c95d74eDavid Li
1801591693c7b415e9869157c711fe11263c95d74eDavid Li
1811591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1821591693c7b415e9869157c711fe11263c95d74eDavid Li_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
1831591693c7b415e9869157c711fe11263c95d74eDavid Li{
1841591693c7b415e9869157c711fe11263c95d74eDavid Li   switch (state->language_version) {
1851591693c7b415e9869157c711fe11263c95d74eDavid Li   case 100:
1861591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(state->es_shader);
1871591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::generate_100ES_types(state->symbols);
1881591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1891591693c7b415e9869157c711fe11263c95d74eDavid Li   case 110:
1901591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::generate_110_types(state->symbols);
1911591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1921591693c7b415e9869157c711fe11263c95d74eDavid Li   case 120:
1931591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::generate_120_types(state->symbols);
1941591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1951591693c7b415e9869157c711fe11263c95d74eDavid Li   case 130:
1961591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::generate_130_types(state->symbols);
1971591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1981591693c7b415e9869157c711fe11263c95d74eDavid Li   default:
1991591693c7b415e9869157c711fe11263c95d74eDavid Li      /* error */
2001591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2011591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2021591693c7b415e9869157c711fe11263c95d74eDavid Li
2031591693c7b415e9869157c711fe11263c95d74eDavid Li   if (state->ARB_texture_rectangle_enable) {
2041591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
2051591693c7b415e9869157c711fe11263c95d74eDavid Li					   state->ARB_texture_rectangle_warn);
2061591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2071591693c7b415e9869157c711fe11263c95d74eDavid Li
2081591693c7b415e9869157c711fe11263c95d74eDavid Li   if (state->EXT_texture_array_enable && state->language_version < 130) {
2091591693c7b415e9869157c711fe11263c95d74eDavid Li      // These are already included in 130; don't create twice.
2101591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::generate_EXT_texture_array_types(state->symbols,
2111591693c7b415e9869157c711fe11263c95d74eDavid Li				       state->EXT_texture_array_warn);
2121591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2131591693c7b415e9869157c711fe11263c95d74eDavid Li}
2141591693c7b415e9869157c711fe11263c95d74eDavid Li
2151591693c7b415e9869157c711fe11263c95d74eDavid Li
2161591693c7b415e9869157c711fe11263c95d74eDavid Liconst glsl_type *glsl_type::get_base_type() const
2171591693c7b415e9869157c711fe11263c95d74eDavid Li{
2181591693c7b415e9869157c711fe11263c95d74eDavid Li   switch (base_type) {
2191591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_UINT:
2201591693c7b415e9869157c711fe11263c95d74eDavid Li      return uint_type;
2211591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_INT:
2221591693c7b415e9869157c711fe11263c95d74eDavid Li      return int_type;
2231591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_FLOAT:
2241591693c7b415e9869157c711fe11263c95d74eDavid Li      return float_type;
2251591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_BOOL:
2261591693c7b415e9869157c711fe11263c95d74eDavid Li      return bool_type;
2271591693c7b415e9869157c711fe11263c95d74eDavid Li   default:
2281591693c7b415e9869157c711fe11263c95d74eDavid Li      return error_type;
2291591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2301591693c7b415e9869157c711fe11263c95d74eDavid Li}
2311591693c7b415e9869157c711fe11263c95d74eDavid Li
2321591693c7b415e9869157c711fe11263c95d74eDavid Li
2331591693c7b415e9869157c711fe11263c95d74eDavid Livoid
2341591693c7b415e9869157c711fe11263c95d74eDavid Li_mesa_glsl_release_types(void)
2351591693c7b415e9869157c711fe11263c95d74eDavid Li{
2361591693c7b415e9869157c711fe11263c95d74eDavid Li   if (glsl_type::array_types != NULL) {
2371591693c7b415e9869157c711fe11263c95d74eDavid Li      hash_table_dtor(glsl_type::array_types);
2381591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::array_types = NULL;
2391591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2401591693c7b415e9869157c711fe11263c95d74eDavid Li
2411591693c7b415e9869157c711fe11263c95d74eDavid Li   if (glsl_type::record_types != NULL) {
2421591693c7b415e9869157c711fe11263c95d74eDavid Li      hash_table_dtor(glsl_type::record_types);
2431591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_type::record_types = NULL;
2441591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2451591693c7b415e9869157c711fe11263c95d74eDavid Li}
2461591693c7b415e9869157c711fe11263c95d74eDavid Li
2471591693c7b415e9869157c711fe11263c95d74eDavid Li
2481591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::glsl_type(const glsl_type *array, unsigned length) :
2491591693c7b415e9869157c711fe11263c95d74eDavid Li   base_type(GLSL_TYPE_ARRAY),
2501591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
2511591693c7b415e9869157c711fe11263c95d74eDavid Li   sampler_type(0),
2521591693c7b415e9869157c711fe11263c95d74eDavid Li   vector_elements(0), matrix_columns(0),
2531591693c7b415e9869157c711fe11263c95d74eDavid Li   name(NULL), length(length)
2541591693c7b415e9869157c711fe11263c95d74eDavid Li{
2551591693c7b415e9869157c711fe11263c95d74eDavid Li   this->fields.array = array;
2561591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Inherit the gl type of the base. The GL type is used for
2571591693c7b415e9869157c711fe11263c95d74eDavid Li    * uniform/statevar handling in Mesa and the arrayness of the type
2581591693c7b415e9869157c711fe11263c95d74eDavid Li    * is represented by the size rather than the type.
2591591693c7b415e9869157c711fe11263c95d74eDavid Li    */
2601591693c7b415e9869157c711fe11263c95d74eDavid Li   this->gl_type = array->gl_type;
2611591693c7b415e9869157c711fe11263c95d74eDavid Li
2621591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Allow a maximum of 10 characters for the array size.  This is enough
2631591693c7b415e9869157c711fe11263c95d74eDavid Li    * for 32-bits of ~0.  The extra 3 are for the '[', ']', and terminating
2641591693c7b415e9869157c711fe11263c95d74eDavid Li    * NUL.
2651591693c7b415e9869157c711fe11263c95d74eDavid Li    */
2661591693c7b415e9869157c711fe11263c95d74eDavid Li   const unsigned name_length = strlen(array->name) + 10 + 3;
267d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   char *const n = (char *) hieralloc_size(this->mem_ctx, name_length);
2681591693c7b415e9869157c711fe11263c95d74eDavid Li
2691591693c7b415e9869157c711fe11263c95d74eDavid Li   if (length == 0)
2701591693c7b415e9869157c711fe11263c95d74eDavid Li      snprintf(n, name_length, "%s[]", array->name);
2711591693c7b415e9869157c711fe11263c95d74eDavid Li   else
2721591693c7b415e9869157c711fe11263c95d74eDavid Li      snprintf(n, name_length, "%s[%u]", array->name, length);
2731591693c7b415e9869157c711fe11263c95d74eDavid Li
2741591693c7b415e9869157c711fe11263c95d74eDavid Li   this->name = n;
2751591693c7b415e9869157c711fe11263c95d74eDavid Li}
2761591693c7b415e9869157c711fe11263c95d74eDavid Li
2771591693c7b415e9869157c711fe11263c95d74eDavid Li
2781591693c7b415e9869157c711fe11263c95d74eDavid Liconst glsl_type *
2791591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
2801591693c7b415e9869157c711fe11263c95d74eDavid Li{
2811591693c7b415e9869157c711fe11263c95d74eDavid Li   if (base_type == GLSL_TYPE_VOID)
2821591693c7b415e9869157c711fe11263c95d74eDavid Li      return &void_type;
2831591693c7b415e9869157c711fe11263c95d74eDavid Li
2841591693c7b415e9869157c711fe11263c95d74eDavid Li   if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
2851591693c7b415e9869157c711fe11263c95d74eDavid Li      return error_type;
2861591693c7b415e9869157c711fe11263c95d74eDavid Li
2871591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Treat GLSL vectors as Nx1 matrices.
2881591693c7b415e9869157c711fe11263c95d74eDavid Li    */
2891591693c7b415e9869157c711fe11263c95d74eDavid Li   if (columns == 1) {
2901591693c7b415e9869157c711fe11263c95d74eDavid Li      switch (base_type) {
2911591693c7b415e9869157c711fe11263c95d74eDavid Li      case GLSL_TYPE_UINT:
2921591693c7b415e9869157c711fe11263c95d74eDavid Li	 return uint_type + (rows - 1);
2931591693c7b415e9869157c711fe11263c95d74eDavid Li      case GLSL_TYPE_INT:
2941591693c7b415e9869157c711fe11263c95d74eDavid Li	 return int_type + (rows - 1);
2951591693c7b415e9869157c711fe11263c95d74eDavid Li      case GLSL_TYPE_FLOAT:
2961591693c7b415e9869157c711fe11263c95d74eDavid Li	 return float_type + (rows - 1);
2971591693c7b415e9869157c711fe11263c95d74eDavid Li      case GLSL_TYPE_BOOL:
2981591693c7b415e9869157c711fe11263c95d74eDavid Li	 return bool_type + (rows - 1);
2991591693c7b415e9869157c711fe11263c95d74eDavid Li      default:
3001591693c7b415e9869157c711fe11263c95d74eDavid Li	 return error_type;
3011591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3021591693c7b415e9869157c711fe11263c95d74eDavid Li   } else {
3031591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
3041591693c7b415e9869157c711fe11263c95d74eDavid Li	 return error_type;
3051591693c7b415e9869157c711fe11263c95d74eDavid Li
3061591693c7b415e9869157c711fe11263c95d74eDavid Li      /* GLSL matrix types are named mat{COLUMNS}x{ROWS}.  Only the following
3071591693c7b415e9869157c711fe11263c95d74eDavid Li       * combinations are valid:
3081591693c7b415e9869157c711fe11263c95d74eDavid Li       *
3091591693c7b415e9869157c711fe11263c95d74eDavid Li       *   1 2 3 4
3101591693c7b415e9869157c711fe11263c95d74eDavid Li       * 1
3111591693c7b415e9869157c711fe11263c95d74eDavid Li       * 2   x x x
3121591693c7b415e9869157c711fe11263c95d74eDavid Li       * 3   x x x
3131591693c7b415e9869157c711fe11263c95d74eDavid Li       * 4   x x x
3141591693c7b415e9869157c711fe11263c95d74eDavid Li       */
3151591693c7b415e9869157c711fe11263c95d74eDavid Li#define IDX(c,r) (((c-1)*3) + (r-1))
3161591693c7b415e9869157c711fe11263c95d74eDavid Li
3171591693c7b415e9869157c711fe11263c95d74eDavid Li      switch (IDX(columns, rows)) {
3181591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(2,2): return mat2_type;
3191591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(2,3): return mat2x3_type;
3201591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(2,4): return mat2x4_type;
3211591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(3,2): return mat3x2_type;
3221591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(3,3): return mat3_type;
3231591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(3,4): return mat3x4_type;
3241591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(4,2): return mat4x2_type;
3251591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(4,3): return mat4x3_type;
3261591693c7b415e9869157c711fe11263c95d74eDavid Li      case IDX(4,4): return mat4_type;
3271591693c7b415e9869157c711fe11263c95d74eDavid Li      default: return error_type;
3281591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3291591693c7b415e9869157c711fe11263c95d74eDavid Li   }
3301591693c7b415e9869157c711fe11263c95d74eDavid Li
3311591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(!"Should not get here.");
3321591693c7b415e9869157c711fe11263c95d74eDavid Li   return error_type;
3331591693c7b415e9869157c711fe11263c95d74eDavid Li}
3341591693c7b415e9869157c711fe11263c95d74eDavid Li
3351591693c7b415e9869157c711fe11263c95d74eDavid Li
3361591693c7b415e9869157c711fe11263c95d74eDavid Liconst glsl_type *
3371591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
3381591693c7b415e9869157c711fe11263c95d74eDavid Li{
3391591693c7b415e9869157c711fe11263c95d74eDavid Li
3401591693c7b415e9869157c711fe11263c95d74eDavid Li   if (array_types == NULL) {
3411591693c7b415e9869157c711fe11263c95d74eDavid Li      array_types = hash_table_ctor(64, hash_table_string_hash,
3421591693c7b415e9869157c711fe11263c95d74eDavid Li				    hash_table_string_compare);
3431591693c7b415e9869157c711fe11263c95d74eDavid Li   }
3441591693c7b415e9869157c711fe11263c95d74eDavid Li
3451591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Generate a name using the base type pointer in the key.  This is
3461591693c7b415e9869157c711fe11263c95d74eDavid Li    * done because the name of the base type may not be unique across
3471591693c7b415e9869157c711fe11263c95d74eDavid Li    * shaders.  For example, two shaders may have different record types
3481591693c7b415e9869157c711fe11263c95d74eDavid Li    * named 'foo'.
3491591693c7b415e9869157c711fe11263c95d74eDavid Li    */
3501591693c7b415e9869157c711fe11263c95d74eDavid Li   char key[128];
3511591693c7b415e9869157c711fe11263c95d74eDavid Li   snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
3521591693c7b415e9869157c711fe11263c95d74eDavid Li
3531591693c7b415e9869157c711fe11263c95d74eDavid Li   const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
3541591693c7b415e9869157c711fe11263c95d74eDavid Li   if (t == NULL) {
3551591693c7b415e9869157c711fe11263c95d74eDavid Li      t = new glsl_type(base, array_size);
3561591693c7b415e9869157c711fe11263c95d74eDavid Li
357d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      hash_table_insert(array_types, (void *) t, hieralloc_strdup(mem_ctx, key));
3581591693c7b415e9869157c711fe11263c95d74eDavid Li   }
3591591693c7b415e9869157c711fe11263c95d74eDavid Li
3601591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(t->base_type == GLSL_TYPE_ARRAY);
3611591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(t->length == array_size);
3621591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(t->fields.array == base);
3631591693c7b415e9869157c711fe11263c95d74eDavid Li
3641591693c7b415e9869157c711fe11263c95d74eDavid Li   return t;
3651591693c7b415e9869157c711fe11263c95d74eDavid Li}
3661591693c7b415e9869157c711fe11263c95d74eDavid Li
3671591693c7b415e9869157c711fe11263c95d74eDavid Li
3681591693c7b415e9869157c711fe11263c95d74eDavid Liint
3691591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::record_key_compare(const void *a, const void *b)
3701591693c7b415e9869157c711fe11263c95d74eDavid Li{
3711591693c7b415e9869157c711fe11263c95d74eDavid Li   const glsl_type *const key1 = (glsl_type *) a;
3721591693c7b415e9869157c711fe11263c95d74eDavid Li   const glsl_type *const key2 = (glsl_type *) b;
3731591693c7b415e9869157c711fe11263c95d74eDavid Li
3741591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Return zero is the types match (there is zero difference) or non-zero
3751591693c7b415e9869157c711fe11263c95d74eDavid Li    * otherwise.
3761591693c7b415e9869157c711fe11263c95d74eDavid Li    */
3771591693c7b415e9869157c711fe11263c95d74eDavid Li   if (strcmp(key1->name, key2->name) != 0)
3781591693c7b415e9869157c711fe11263c95d74eDavid Li      return 1;
3791591693c7b415e9869157c711fe11263c95d74eDavid Li
3801591693c7b415e9869157c711fe11263c95d74eDavid Li   if (key1->length != key2->length)
3811591693c7b415e9869157c711fe11263c95d74eDavid Li      return 1;
3821591693c7b415e9869157c711fe11263c95d74eDavid Li
3831591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < key1->length; i++) {
3841591693c7b415e9869157c711fe11263c95d74eDavid Li      if (key1->fields.structure[i].type != key2->fields.structure[i].type)
3851591693c7b415e9869157c711fe11263c95d74eDavid Li	 return 1;
3861591693c7b415e9869157c711fe11263c95d74eDavid Li      if (strcmp(key1->fields.structure[i].name,
3871591693c7b415e9869157c711fe11263c95d74eDavid Li		 key2->fields.structure[i].name) != 0)
3881591693c7b415e9869157c711fe11263c95d74eDavid Li	 return 1;
3891591693c7b415e9869157c711fe11263c95d74eDavid Li   }
3901591693c7b415e9869157c711fe11263c95d74eDavid Li
3911591693c7b415e9869157c711fe11263c95d74eDavid Li   return 0;
3921591693c7b415e9869157c711fe11263c95d74eDavid Li}
3931591693c7b415e9869157c711fe11263c95d74eDavid Li
3941591693c7b415e9869157c711fe11263c95d74eDavid Li
3951591693c7b415e9869157c711fe11263c95d74eDavid Liunsigned
3961591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::record_key_hash(const void *a)
3971591693c7b415e9869157c711fe11263c95d74eDavid Li{
3981591693c7b415e9869157c711fe11263c95d74eDavid Li   const glsl_type *const key = (glsl_type *) a;
3991591693c7b415e9869157c711fe11263c95d74eDavid Li   char hash_key[128];
4001591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned size = 0;
4011591693c7b415e9869157c711fe11263c95d74eDavid Li
4021591693c7b415e9869157c711fe11263c95d74eDavid Li   size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
4031591693c7b415e9869157c711fe11263c95d74eDavid Li
4041591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < key->length; i++) {
4051591693c7b415e9869157c711fe11263c95d74eDavid Li      if (size >= sizeof(hash_key))
4061591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
4071591693c7b415e9869157c711fe11263c95d74eDavid Li
4081591693c7b415e9869157c711fe11263c95d74eDavid Li      size += snprintf(& hash_key[size], sizeof(hash_key) - size,
4091591693c7b415e9869157c711fe11263c95d74eDavid Li		       "%p", (void *) key->fields.structure[i].type);
4101591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4111591693c7b415e9869157c711fe11263c95d74eDavid Li
4121591693c7b415e9869157c711fe11263c95d74eDavid Li   return hash_table_string_hash(& hash_key);
4131591693c7b415e9869157c711fe11263c95d74eDavid Li}
4141591693c7b415e9869157c711fe11263c95d74eDavid Li
4151591693c7b415e9869157c711fe11263c95d74eDavid Li
4161591693c7b415e9869157c711fe11263c95d74eDavid Liconst glsl_type *
4171591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::get_record_instance(const glsl_struct_field *fields,
4181591693c7b415e9869157c711fe11263c95d74eDavid Li			       unsigned num_fields,
4191591693c7b415e9869157c711fe11263c95d74eDavid Li			       const char *name)
4201591693c7b415e9869157c711fe11263c95d74eDavid Li{
4211591693c7b415e9869157c711fe11263c95d74eDavid Li   const glsl_type key(fields, num_fields, name);
4221591693c7b415e9869157c711fe11263c95d74eDavid Li
4231591693c7b415e9869157c711fe11263c95d74eDavid Li   if (record_types == NULL) {
4241591693c7b415e9869157c711fe11263c95d74eDavid Li      record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
4251591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4261591693c7b415e9869157c711fe11263c95d74eDavid Li
4271591693c7b415e9869157c711fe11263c95d74eDavid Li   const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
4281591693c7b415e9869157c711fe11263c95d74eDavid Li   if (t == NULL) {
4291591693c7b415e9869157c711fe11263c95d74eDavid Li      t = new glsl_type(fields, num_fields, name);
4301591693c7b415e9869157c711fe11263c95d74eDavid Li
4311591693c7b415e9869157c711fe11263c95d74eDavid Li      hash_table_insert(record_types, (void *) t, t);
4321591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4331591693c7b415e9869157c711fe11263c95d74eDavid Li
4341591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(t->base_type == GLSL_TYPE_STRUCT);
4351591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(t->length == num_fields);
4361591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(strcmp(t->name, name) == 0);
4371591693c7b415e9869157c711fe11263c95d74eDavid Li
4381591693c7b415e9869157c711fe11263c95d74eDavid Li   return t;
4391591693c7b415e9869157c711fe11263c95d74eDavid Li}
4401591693c7b415e9869157c711fe11263c95d74eDavid Li
4411591693c7b415e9869157c711fe11263c95d74eDavid Li
4421591693c7b415e9869157c711fe11263c95d74eDavid Liconst glsl_type *
4431591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::field_type(const char *name) const
4441591693c7b415e9869157c711fe11263c95d74eDavid Li{
4451591693c7b415e9869157c711fe11263c95d74eDavid Li   if (this->base_type != GLSL_TYPE_STRUCT)
4461591693c7b415e9869157c711fe11263c95d74eDavid Li      return error_type;
4471591693c7b415e9869157c711fe11263c95d74eDavid Li
4481591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < this->length; i++) {
4491591693c7b415e9869157c711fe11263c95d74eDavid Li      if (strcmp(name, this->fields.structure[i].name) == 0)
4501591693c7b415e9869157c711fe11263c95d74eDavid Li	 return this->fields.structure[i].type;
4511591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4521591693c7b415e9869157c711fe11263c95d74eDavid Li
4531591693c7b415e9869157c711fe11263c95d74eDavid Li   return error_type;
4541591693c7b415e9869157c711fe11263c95d74eDavid Li}
4551591693c7b415e9869157c711fe11263c95d74eDavid Li
4561591693c7b415e9869157c711fe11263c95d74eDavid Li
4571591693c7b415e9869157c711fe11263c95d74eDavid Liint
4581591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::field_index(const char *name) const
4591591693c7b415e9869157c711fe11263c95d74eDavid Li{
4601591693c7b415e9869157c711fe11263c95d74eDavid Li   if (this->base_type != GLSL_TYPE_STRUCT)
4611591693c7b415e9869157c711fe11263c95d74eDavid Li      return -1;
4621591693c7b415e9869157c711fe11263c95d74eDavid Li
4631591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < this->length; i++) {
4641591693c7b415e9869157c711fe11263c95d74eDavid Li      if (strcmp(name, this->fields.structure[i].name) == 0)
4651591693c7b415e9869157c711fe11263c95d74eDavid Li	 return i;
4661591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4671591693c7b415e9869157c711fe11263c95d74eDavid Li
4681591693c7b415e9869157c711fe11263c95d74eDavid Li   return -1;
4691591693c7b415e9869157c711fe11263c95d74eDavid Li}
4701591693c7b415e9869157c711fe11263c95d74eDavid Li
4711591693c7b415e9869157c711fe11263c95d74eDavid Li
4721591693c7b415e9869157c711fe11263c95d74eDavid Liunsigned
4731591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_type::component_slots() const
4741591693c7b415e9869157c711fe11263c95d74eDavid Li{
4751591693c7b415e9869157c711fe11263c95d74eDavid Li   switch (this->base_type) {
4761591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_UINT:
4771591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_INT:
4781591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_FLOAT:
4791591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_BOOL:
4801591693c7b415e9869157c711fe11263c95d74eDavid Li      return this->components();
4811591693c7b415e9869157c711fe11263c95d74eDavid Li
4821591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_STRUCT: {
4831591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned size = 0;
4841591693c7b415e9869157c711fe11263c95d74eDavid Li
4851591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned i = 0; i < this->length; i++)
4861591693c7b415e9869157c711fe11263c95d74eDavid Li	 size += this->fields.structure[i].type->component_slots();
4871591693c7b415e9869157c711fe11263c95d74eDavid Li
4881591693c7b415e9869157c711fe11263c95d74eDavid Li      return size;
4891591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4901591693c7b415e9869157c711fe11263c95d74eDavid Li
4911591693c7b415e9869157c711fe11263c95d74eDavid Li   case GLSL_TYPE_ARRAY:
4921591693c7b415e9869157c711fe11263c95d74eDavid Li      return this->length * this->fields.array->component_slots();
4931591693c7b415e9869157c711fe11263c95d74eDavid Li
4941591693c7b415e9869157c711fe11263c95d74eDavid Li   default:
4951591693c7b415e9869157c711fe11263c95d74eDavid Li      return 0;
4961591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4971591693c7b415e9869157c711fe11263c95d74eDavid Li}
498