1a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick/*
2a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Copyright © 2009 Intel Corporation
3a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *
4a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a
5a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * copy of this software and associated documentation files (the "Software"),
6a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * to deal in the Software without restriction, including without limitation
7a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * and/or sell copies of the Software, and to permit persons to whom the
9a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Software is furnished to do so, subject to the following conditions:
10a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *
11a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * The above copyright notice and this permission notice (including the next
12a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * paragraph) shall be included in all copies or substantial portions of the
13a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Software.
14a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *
15a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * DEALINGS IN THE SOFTWARE.
22a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick */
23a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
24497baf4e4a6a0a2f247c7bfb9bf69a2b93c2c19fIan Romanick#include <stdio.h>
25a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include <stdlib.h>
26bfd7c9ac228c7ed8aec04c3b3aa33f40ee00b035Chia-I Wu#include "main/core.h" /* for Elements */
278bde4cec6b189564b1f2d58514bd7e7a4b40f714Ian Romanick#include "glsl_symbol_table.h"
28a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include "glsl_parser_extras.h"
29a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include "glsl_types.h"
30a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include "builtin_types.h"
313d6012303c3ce24c75d209267e6914f706d025c5Eric Anholtextern "C" {
3231747155ea3a24190277b125bd188ac8689af719Aras Pranckevicius#include "program/hash_table.h"
333d6012303c3ce24c75d209267e6914f706d025c5Eric Anholt}
34a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
35548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanickhash_table *glsl_type::array_types = NULL;
3649e3577b91f44013746f7a3db411e7041b7d899eIan Romanickhash_table *glsl_type::record_types = NULL;
37ad98aa9d93646600cc95b3e45a40eec26f18988aKenneth Graunkevoid *glsl_type::mem_ctx = NULL;
38548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
39cf41c8a0d8dac52bafb7c3e85171566c492786abIan Romanickvoid
40d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunkeglsl_type::init_ralloc_type_ctx(void)
4185cd64ee170e578317a6aa41d824314550a318acEric Anholt{
42ad98aa9d93646600cc95b3e45a40eec26f18988aKenneth Graunke   if (glsl_type::mem_ctx == NULL) {
43d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      glsl_type::mem_ctx = ralloc_autofree_context();
44ad98aa9d93646600cc95b3e45a40eec26f18988aKenneth Graunke      assert(glsl_type::mem_ctx != NULL);
4585cd64ee170e578317a6aa41d824314550a318acEric Anholt   }
4685cd64ee170e578317a6aa41d824314550a318acEric Anholt}
4785cd64ee170e578317a6aa41d824314550a318acEric Anholt
4831bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanickglsl_type::glsl_type(GLenum gl_type,
495dc74e9c77de7d30ac08c25f224ffa93006d8d7cKenneth Graunke		     glsl_base_type base_type, unsigned vector_elements,
5031bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick		     unsigned matrix_columns, const char *name) :
5131bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   gl_type(gl_type),
5231bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   base_type(base_type),
5331bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
5431bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   sampler_type(0),
5531bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   vector_elements(vector_elements), matrix_columns(matrix_columns),
5631bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   length(0)
5731bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick{
58d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   init_ralloc_type_ctx();
59d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   this->name = ralloc_strdup(this->mem_ctx, name);
6031bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   /* Neither dimension is zero or both dimensions are zero.
6131bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick    */
6231bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   assert((vector_elements == 0) == (matrix_columns == 0));
6331bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   memset(& fields, 0, sizeof(fields));
6431bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick}
6531bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick
6631bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanickglsl_type::glsl_type(GLenum gl_type,
6731bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick		     enum glsl_sampler_dim dim, bool shadow, bool array,
6831bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick		     unsigned type, const char *name) :
6931bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   gl_type(gl_type),
7031bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   base_type(GLSL_TYPE_SAMPLER),
7131bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   sampler_dimensionality(dim), sampler_shadow(shadow),
7231bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   sampler_array(array), sampler_type(type),
7331bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   vector_elements(0), matrix_columns(0),
7431bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   length(0)
7531bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick{
76d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   init_ralloc_type_ctx();
77d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   this->name = ralloc_strdup(this->mem_ctx, name);
7831bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick   memset(& fields, 0, sizeof(fields));
7931bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick}
8031bcce04b1f9c8c5e33370e26a3a9d6e60049aa8Ian Romanick
8172e627d02a78cbf40c861384293e355588fd0977Ian Romanickglsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
8272e627d02a78cbf40c861384293e355588fd0977Ian Romanick		     const char *name) :
8372e627d02a78cbf40c861384293e355588fd0977Ian Romanick   base_type(GLSL_TYPE_STRUCT),
8472e627d02a78cbf40c861384293e355588fd0977Ian Romanick   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
8572e627d02a78cbf40c861384293e355588fd0977Ian Romanick   sampler_type(0),
8672e627d02a78cbf40c861384293e355588fd0977Ian Romanick   vector_elements(0), matrix_columns(0),
8772e627d02a78cbf40c861384293e355588fd0977Ian Romanick   length(num_fields)
8872e627d02a78cbf40c861384293e355588fd0977Ian Romanick{
8921b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt   unsigned int i;
9021b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt
91d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   init_ralloc_type_ctx();
92d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   this->name = ralloc_strdup(this->mem_ctx, name);
93d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   this->fields.structure = ralloc_array(this->mem_ctx,
9421b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt					 glsl_struct_field, length);
9521b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt   for (i = 0; i < length; i++) {
9621b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt      this->fields.structure[i].type = fields[i].type;
97d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
9821b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt						     fields[i].name);
9921b0dbd79937e9d6787f045af7d60d4b6c649ec8Eric Anholt   }
10072e627d02a78cbf40c861384293e355588fd0977Ian Romanick}
10172e627d02a78cbf40c861384293e355588fd0977Ian Romanick
102a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatic void
1038bde4cec6b189564b1f2d58514bd7e7a4b40f714Ian Romanickadd_types_to_symbol_table(glsl_symbol_table *symtab,
104a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick			  const struct glsl_type *types,
1050c824653952a67722c242616bb34a4796b42f660Ian Romanick			  unsigned num_types, bool warn)
106a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick{
1070c824653952a67722c242616bb34a4796b42f660Ian Romanick   (void) warn;
108a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
1090c824653952a67722c242616bb34a4796b42f660Ian Romanick   for (unsigned i = 0; i < num_types; i++) {
1108bde4cec6b189564b1f2d58514bd7e7a4b40f714Ian Romanick      symtab->add_type(types[i].name, & types[i]);
111a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   }
112a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
113a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
114ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berrybool
115ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berryglsl_type::contains_sampler() const
116ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry{
117ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry   if (this->is_array()) {
118ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry      return this->fields.array->contains_sampler();
119ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry   } else if (this->is_record()) {
120ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry      for (unsigned int i = 0; i < this->length; i++) {
121ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry	 if (this->fields.structure[i].type->contains_sampler())
122ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry	    return true;
123ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry      }
124ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry      return false;
125ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry   } else {
126ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry      return this->is_sampler();
127ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry   }
128ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry}
129ddc1c96390b685bb95f7431e862c3a64fcefa085Paul Berry
13032be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanickgl_texture_index
13132be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanickglsl_type::sampler_index() const
13232be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick{
13332be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   const glsl_type *const t = (this->is_array()) ? this->fields.array : this;
13432be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick
13532be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   assert(t->is_sampler());
13632be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick
13732be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   switch (t->sampler_dimensionality) {
13832be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_1D:
13932be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      return (t->sampler_array) ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
14032be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_2D:
14132be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      return (t->sampler_array) ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
14232be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_3D:
14332be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      return TEXTURE_3D_INDEX;
14432be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_CUBE:
14532be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      return TEXTURE_CUBE_INDEX;
14632be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_RECT:
14732be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      return TEXTURE_RECT_INDEX;
14832be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_BUF:
149e9bcf4d56b8ae128204fb95693c6f81a6b724052Vinson Lee      return TEXTURE_BUFFER_INDEX;
15032be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   case GLSL_SAMPLER_DIM_EXTERNAL:
15132be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      return TEXTURE_EXTERNAL_INDEX;
15232be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   default:
15332be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick      assert(!"Should not get here.");
154e9bcf4d56b8ae128204fb95693c6f81a6b724052Vinson Lee      return TEXTURE_BUFFER_INDEX;
15532be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick   }
15632be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick}
15732be81de39f7548e353afabf1215b0ea7c7b0916Ian Romanick
158e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickvoid
15976deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunkeglsl_type::generate_100ES_types(glsl_symbol_table *symtab)
160a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick{
161a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   add_types_to_symbol_table(symtab, builtin_core_types,
1620c824653952a67722c242616bb34a4796b42f660Ian Romanick			     Elements(builtin_core_types),
1630c824653952a67722c242616bb34a4796b42f660Ian Romanick			     false);
164a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   add_types_to_symbol_table(symtab, builtin_structure_types,
1650c824653952a67722c242616bb34a4796b42f660Ian Romanick			     Elements(builtin_structure_types),
1660c824653952a67722c242616bb34a4796b42f660Ian Romanick			     false);
1675c229e5fbd8ffa573ab2c1225f182036792a75afKenneth Graunke   add_types_to_symbol_table(symtab, void_type, 1, false);
16876deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke}
16976deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke
17076deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunkevoid
1710225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholtglsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated)
17276deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke{
17376deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke   generate_100ES_types(symtab);
17476deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke
17576deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke   add_types_to_symbol_table(symtab, builtin_110_types,
17676deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke			     Elements(builtin_110_types),
17776deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke			     false);
1780a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke   add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false);
1790225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt   if (add_deprecated) {
1800225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt      add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
1810225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt				Elements(builtin_110_deprecated_structure_types),
1820225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt				false);
1830225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt   }
184a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
185a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
186a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
187e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickvoid
1880225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholtglsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated)
189a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick{
1900225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt   generate_110_types(symtab, add_deprecated);
191a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
192a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   add_types_to_symbol_table(symtab, builtin_120_types,
1930c824653952a67722c242616bb34a4796b42f660Ian Romanick			     Elements(builtin_120_types), false);
194a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
195a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
196a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
197e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickvoid
1980225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholtglsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated)
199a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick{
2000225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt   generate_120_types(symtab, add_deprecated);
201a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
202a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   add_types_to_symbol_table(symtab, builtin_130_types,
2030c824653952a67722c242616bb34a4796b42f660Ian Romanick			     Elements(builtin_130_types), false);
2040a09d679ca97dcb634a939df2110a90c9504e2ecIan Romanick   generate_EXT_texture_array_types(symtab, false);
2050c824653952a67722c242616bb34a4796b42f660Ian Romanick}
2060c824653952a67722c242616bb34a4796b42f660Ian Romanick
2070c824653952a67722c242616bb34a4796b42f660Ian Romanick
208e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickvoid
2093645b77b7162913b504a49fc42d785fde27df3f3Eric Anholtglsl_type::generate_140_types(glsl_symbol_table *symtab)
2103645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt{
2110225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt   generate_130_types(symtab, false);
2123645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt
2133645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt   add_types_to_symbol_table(symtab, builtin_140_types,
2143645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt			     Elements(builtin_140_types), false);
215659855252107debc47dbac8ec7985e1024d7ab5cEric Anholt
216659855252107debc47dbac8ec7985e1024d7ab5cEric Anholt   add_types_to_symbol_table(symtab, builtin_EXT_texture_buffer_object_types,
217659855252107debc47dbac8ec7985e1024d7ab5cEric Anholt			     Elements(builtin_EXT_texture_buffer_object_types),
218659855252107debc47dbac8ec7985e1024d7ab5cEric Anholt			     false);
2193645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt}
2203645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt
2213645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt
2223645b77b7162913b504a49fc42d785fde27df3f3Eric Anholtvoid
223e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickglsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
224e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanick						bool warn)
2250c824653952a67722c242616bb34a4796b42f660Ian Romanick{
2260c824653952a67722c242616bb34a4796b42f660Ian Romanick   add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
2270c824653952a67722c242616bb34a4796b42f660Ian Romanick			     Elements(builtin_ARB_texture_rectangle_types),
2280c824653952a67722c242616bb34a4796b42f660Ian Romanick			     warn);
229a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
230a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
231a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
232e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickvoid
233e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanickglsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
234e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanick					    bool warn)
2350d80f71867e561c541bf8832a182401297972543Kenneth Graunke{
2360d80f71867e561c541bf8832a182401297972543Kenneth Graunke   add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
2370d80f71867e561c541bf8832a182401297972543Kenneth Graunke			     Elements(builtin_EXT_texture_array_types),
2380d80f71867e561c541bf8832a182401297972543Kenneth Graunke			     warn);
2390d80f71867e561c541bf8832a182401297972543Kenneth Graunke}
2400d80f71867e561c541bf8832a182401297972543Kenneth Graunke
2410d80f71867e561c541bf8832a182401297972543Kenneth Graunke
242a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickvoid
2430a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunkeglsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn)
2440a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke{
2450a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke   add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn);
2460a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke}
2470a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke
2480a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke
2490a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunkevoid
2502903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wuglsl_type::generate_OES_EGL_image_external_types(glsl_symbol_table *symtab,
2512903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu						 bool warn)
2522903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu{
2532903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu   add_types_to_symbol_table(symtab, builtin_OES_EGL_image_external_types,
2542903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu			     Elements(builtin_OES_EGL_image_external_types),
2552903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu			     warn);
2562903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu}
2572903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu
2582903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wuvoid
259a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
260a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick{
261a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   switch (state->language_version) {
26276deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke   case 100:
26376deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke      assert(state->es_shader);
26476deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke      glsl_type::generate_100ES_types(state->symbols);
26576deef138ee25ab57b4716aef41ce0c94081f20aKenneth Graunke      break;
266a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   case 110:
2670225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt      glsl_type::generate_110_types(state->symbols, true);
268a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick      break;
269a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   case 120:
2700225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt      glsl_type::generate_120_types(state->symbols, true);
271a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick      break;
272a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   case 130:
2730225a15b6907b51dbbc9602a1f0cb07ee809f496Eric Anholt      glsl_type::generate_130_types(state->symbols, true);
274a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick      break;
275c5ff9a8b9e3cafb3764e620add2900656c59606bEric Anholt   case 140:
2763645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt      glsl_type::generate_140_types(state->symbols);
277c5ff9a8b9e3cafb3764e620add2900656c59606bEric Anholt      break;
278a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   default:
279a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick      /* error */
280a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick      break;
281a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick   }
2820c824653952a67722c242616bb34a4796b42f660Ian Romanick
2833645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt   if (state->ARB_texture_rectangle_enable ||
2843645b77b7162913b504a49fc42d785fde27df3f3Eric Anholt       state->language_version >= 140) {
285e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanick      glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
2860c824653952a67722c242616bb34a4796b42f660Ian Romanick					   state->ARB_texture_rectangle_warn);
2870c824653952a67722c242616bb34a4796b42f660Ian Romanick   }
2880a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke   if (state->OES_texture_3D_enable && state->language_version == 100) {
2890a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke      glsl_type::generate_OES_texture_3D_types(state->symbols,
2900a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke					       state->OES_texture_3D_warn);
2910a163cf56d1e412629cb802480998a982a47bb3cKenneth Graunke   }
2920d80f71867e561c541bf8832a182401297972543Kenneth Graunke
2930d80f71867e561c541bf8832a182401297972543Kenneth Graunke   if (state->EXT_texture_array_enable && state->language_version < 130) {
2940d80f71867e561c541bf8832a182401297972543Kenneth Graunke      // These are already included in 130; don't create twice.
295e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7Ian Romanick      glsl_type::generate_EXT_texture_array_types(state->symbols,
2960d80f71867e561c541bf8832a182401297972543Kenneth Graunke				       state->EXT_texture_array_warn);
2970d80f71867e561c541bf8832a182401297972543Kenneth Graunke   }
2982903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu
2992903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu   /* We cannot check for language_version == 100 here because we need the
3002903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu    * types to support fixed-function program generation.  But this is fine
3012903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu    * since the extension is never enabled for OpenGL contexts.
3022903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu    */
3032903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu   if (state->OES_EGL_image_external_enable) {
3042903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu      glsl_type::generate_OES_EGL_image_external_types(state->symbols,
3052903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu					       state->OES_EGL_image_external_warn);
3062903816aadb281716b6c59a5a48aeadb84a08f50Chia-I Wu   }
307a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
308a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
309a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
310bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanickconst glsl_type *glsl_type::get_base_type() const
311bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick{
312bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   switch (base_type) {
313bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   case GLSL_TYPE_UINT:
3140471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      return uint_type;
315bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   case GLSL_TYPE_INT:
3160471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      return int_type;
317bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   case GLSL_TYPE_FLOAT:
3180471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      return float_type;
319bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   case GLSL_TYPE_BOOL:
3200471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      return bool_type;
321bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   default:
3220471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      return error_type;
323bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick   }
324bb7e00a1cd63f3012226253bb0121922419a5f23Ian Romanick}
3253209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick
3263209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick
327fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berryconst glsl_type *glsl_type::get_scalar_type() const
328fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry{
329fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   const glsl_type *type = this;
330fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry
331fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   /* Handle arrays */
332fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   while (type->base_type == GLSL_TYPE_ARRAY)
333fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry      type = type->fields.array;
334fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry
335fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   /* Handle vectors and matrices */
336fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   switch (type->base_type) {
337fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   case GLSL_TYPE_UINT:
338fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry      return uint_type;
339fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   case GLSL_TYPE_INT:
340fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry      return int_type;
341fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   case GLSL_TYPE_FLOAT:
342fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry      return float_type;
343fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   default:
344fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry      /* Handle everything else */
345fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry      return type;
346fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry   }
347fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry}
348fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry
349fa0066ae2b2d304065ee8d93d9b5ecc8b457425aPaul Berry
350efc15f862b08a9f035c06a79bc43848cca740372Ian Romanickvoid
351efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick_mesa_glsl_release_types(void)
352efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick{
353efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick   if (glsl_type::array_types != NULL) {
354efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick      hash_table_dtor(glsl_type::array_types);
355efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick      glsl_type::array_types = NULL;
356efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick   }
357efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick
358efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick   if (glsl_type::record_types != NULL) {
359efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick      hash_table_dtor(glsl_type::record_types);
360efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick      glsl_type::record_types = NULL;
361efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick   }
362efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick}
363efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick
364efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick
365f38d15b80d4e4c8ecb7a76087cdc49835f0aa271Ian Romanickglsl_type::glsl_type(const glsl_type *array, unsigned length) :
3660bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   base_type(GLSL_TYPE_ARRAY),
3670bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
3680bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   sampler_type(0),
3690bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   vector_elements(0), matrix_columns(0),
3700bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   name(NULL), length(length)
3710bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick{
3720bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   this->fields.array = array;
373288733f6001a2148d6689587d9a05e6909e88a61Eric Anholt   /* Inherit the gl type of the base. The GL type is used for
374288733f6001a2148d6689587d9a05e6909e88a61Eric Anholt    * uniform/statevar handling in Mesa and the arrayness of the type
375288733f6001a2148d6689587d9a05e6909e88a61Eric Anholt    * is represented by the size rather than the type.
376288733f6001a2148d6689587d9a05e6909e88a61Eric Anholt    */
377288733f6001a2148d6689587d9a05e6909e88a61Eric Anholt   this->gl_type = array->gl_type;
3780bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick
3790bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   /* Allow a maximum of 10 characters for the array size.  This is enough
3800bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick    * for 32-bits of ~0.  The extra 3 are for the '[', ']', and terminating
3810bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick    * NUL.
3820bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick    */
3830bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   const unsigned name_length = strlen(array->name) + 10 + 3;
384d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
3850bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick
3860bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   if (length == 0)
3870bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick      snprintf(n, name_length, "%s[]", array->name);
3880bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   else
3890bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick      snprintf(n, name_length, "%s[%u]", array->name, length);
3900bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick
3910bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick   this->name = n;
3920bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick}
3930bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick
3940bf381016524ac58f5961877ea0e8651c4922ca3Ian Romanick
3953209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanickconst glsl_type *
3963209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanickglsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
3973209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick{
398ab372dab2a013e5d0c8ee57bb799a76c9a78abf2Eric Anholt   if (base_type == GLSL_TYPE_VOID)
3995c229e5fbd8ffa573ab2c1225f182036792a75afKenneth Graunke      return void_type;
400ab372dab2a013e5d0c8ee57bb799a76c9a78abf2Eric Anholt
4013209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick   if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
4020471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      return error_type;
4033209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick
4043209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick   /* Treat GLSL vectors as Nx1 matrices.
4053209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick    */
4063209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick   if (columns == 1) {
4073209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      switch (base_type) {
4083209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case GLSL_TYPE_UINT:
4090471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick	 return uint_type + (rows - 1);
4103209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case GLSL_TYPE_INT:
4110471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick	 return int_type + (rows - 1);
4123209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case GLSL_TYPE_FLOAT:
4130471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick	 return float_type + (rows - 1);
4143209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case GLSL_TYPE_BOOL:
4150471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick	 return bool_type + (rows - 1);
4163209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      default:
4170471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick	 return error_type;
4183209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      }
4193209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick   } else {
4203209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
4210471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick	 return error_type;
4223209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick
4233209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      /* GLSL matrix types are named mat{COLUMNS}x{ROWS}.  Only the following
4243209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       * combinations are valid:
4253209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       *
4263209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       *   1 2 3 4
4273209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       * 1
4283209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       * 2   x x x
4293209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       * 3   x x x
4303209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       * 4   x x x
4313209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick       */
4323209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick#define IDX(c,r) (((c-1)*3) + (r-1))
4333209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick
4343209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      switch (IDX(columns, rows)) {
4353209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(2,2): return mat2_type;
4363209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(2,3): return mat2x3_type;
4373209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(2,4): return mat2x4_type;
4383209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(3,2): return mat3x2_type;
4393209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(3,3): return mat3_type;
4403209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(3,4): return mat3x4_type;
4413209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(4,2): return mat4x2_type;
4423209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(4,3): return mat4x3_type;
4433209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      case IDX(4,4): return mat4_type;
4440471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick      default: return error_type;
4453209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick      }
4463209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick   }
4473209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick
4483209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick   assert(!"Should not get here.");
4490471e8b0896e05b3bc81ccad6184e6e35fb61425Ian Romanick   return error_type;
4503209c4e3692eaa9468aadcd21ce402e6b0d5b7ddIan Romanick}
451548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
452548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
453548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanickconst glsl_type *
454f38d15b80d4e4c8ecb7a76087cdc49835f0aa271Ian Romanickglsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
455548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick{
456548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
457548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   if (array_types == NULL) {
45842f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick      array_types = hash_table_ctor(64, hash_table_string_hash,
45942f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick				    hash_table_string_compare);
460548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   }
461548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
46242f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick   /* Generate a name using the base type pointer in the key.  This is
46342f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick    * done because the name of the base type may not be unique across
46442f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick    * shaders.  For example, two shaders may have different record types
46542f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick    * named 'foo'.
46642f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick    */
46742f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick   char key[128];
4689f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul   snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
46942f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick
47042f3e7b6d7b42218feafe85a2328d8ce86fcce93Ian Romanick   const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
471548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   if (t == NULL) {
472f38d15b80d4e4c8ecb7a76087cdc49835f0aa271Ian Romanick      t = new glsl_type(base, array_size);
473548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
474d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key));
475548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   }
476548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
477548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   assert(t->base_type == GLSL_TYPE_ARRAY);
478548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   assert(t->length == array_size);
479548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   assert(t->fields.array == base);
480548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick
481548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick   return t;
482548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5dIan Romanick}
4838f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick
4848f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick
48549e3577b91f44013746f7a3db411e7041b7d899eIan Romanickint
48649e3577b91f44013746f7a3db411e7041b7d899eIan Romanickglsl_type::record_key_compare(const void *a, const void *b)
48749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick{
48849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   const glsl_type *const key1 = (glsl_type *) a;
48949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   const glsl_type *const key2 = (glsl_type *) b;
49049e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
49149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   /* Return zero is the types match (there is zero difference) or non-zero
49249e3577b91f44013746f7a3db411e7041b7d899eIan Romanick    * otherwise.
49349e3577b91f44013746f7a3db411e7041b7d899eIan Romanick    */
49449e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   if (strcmp(key1->name, key2->name) != 0)
49549e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      return 1;
49649e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
49749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   if (key1->length != key2->length)
49849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      return 1;
49949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
500b6e92ad7da9d4f00607caca90bd0b8853623a493Eric Anholt   for (unsigned i = 0; i < key1->length; i++) {
50149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      if (key1->fields.structure[i].type != key2->fields.structure[i].type)
50249e3577b91f44013746f7a3db411e7041b7d899eIan Romanick	 return 1;
503b6e92ad7da9d4f00607caca90bd0b8853623a493Eric Anholt      if (strcmp(key1->fields.structure[i].name,
504b6e92ad7da9d4f00607caca90bd0b8853623a493Eric Anholt		 key2->fields.structure[i].name) != 0)
505b6e92ad7da9d4f00607caca90bd0b8853623a493Eric Anholt	 return 1;
506b6e92ad7da9d4f00607caca90bd0b8853623a493Eric Anholt   }
50749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
50849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   return 0;
50949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick}
51049e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
51149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
51249e3577b91f44013746f7a3db411e7041b7d899eIan Romanickunsigned
51349e3577b91f44013746f7a3db411e7041b7d899eIan Romanickglsl_type::record_key_hash(const void *a)
51449e3577b91f44013746f7a3db411e7041b7d899eIan Romanick{
51549e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   const glsl_type *const key = (glsl_type *) a;
51649e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   char hash_key[128];
51749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   unsigned size = 0;
51849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
51949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
52049e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
52149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   for (unsigned i = 0; i < key->length; i++) {
52249e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      if (size >= sizeof(hash_key))
52349e3577b91f44013746f7a3db411e7041b7d899eIan Romanick	 break;
52449e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
52549e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      size += snprintf(& hash_key[size], sizeof(hash_key) - size,
5269f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul		       "%p", (void *) key->fields.structure[i].type);
52749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   }
52849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
52949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   return hash_table_string_hash(& hash_key);
53049e3577b91f44013746f7a3db411e7041b7d899eIan Romanick}
53149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
53249e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
53349e3577b91f44013746f7a3db411e7041b7d899eIan Romanickconst glsl_type *
53449e3577b91f44013746f7a3db411e7041b7d899eIan Romanickglsl_type::get_record_instance(const glsl_struct_field *fields,
53549e3577b91f44013746f7a3db411e7041b7d899eIan Romanick			       unsigned num_fields,
53649e3577b91f44013746f7a3db411e7041b7d899eIan Romanick			       const char *name)
53749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick{
53849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   const glsl_type key(fields, num_fields, name);
53949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
54049e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   if (record_types == NULL) {
54149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
54249e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   }
54349e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
54449e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
54549e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   if (t == NULL) {
546e1374d48ded09dba576f5a2b86c3d11984d1f7c4Ian Romanick      t = new glsl_type(fields, num_fields, name);
54749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
54849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick      hash_table_insert(record_types, (void *) t, t);
54949e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   }
55049e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
55149e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   assert(t->base_type == GLSL_TYPE_STRUCT);
55249e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   assert(t->length == num_fields);
55349e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   assert(strcmp(t->name, name) == 0);
55449e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
55549e3577b91f44013746f7a3db411e7041b7d899eIan Romanick   return t;
55649e3577b91f44013746f7a3db411e7041b7d899eIan Romanick}
55749e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
55849e3577b91f44013746f7a3db411e7041b7d899eIan Romanick
5598f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanickconst glsl_type *
5608f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanickglsl_type::field_type(const char *name) const
5618f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick{
5628f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick   if (this->base_type != GLSL_TYPE_STRUCT)
5638f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick      return error_type;
5648f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick
5658f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick   for (unsigned i = 0; i < this->length; i++) {
5668f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick      if (strcmp(name, this->fields.structure[i].name) == 0)
5678f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick	 return this->fields.structure[i].type;
5688f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick   }
5698f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick
5708f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick   return error_type;
5718f755dcb67848966c350883ad6fbb50547d9ec24Ian Romanick}
572eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick
573eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick
574eeedd355cfc2f0c578282657bd4259440a88742cIan Romanickint
575eeedd355cfc2f0c578282657bd4259440a88742cIan Romanickglsl_type::field_index(const char *name) const
576eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick{
577eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick   if (this->base_type != GLSL_TYPE_STRUCT)
578eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick      return -1;
579eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick
580eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick   for (unsigned i = 0; i < this->length; i++) {
581eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick      if (strcmp(name, this->fields.structure[i].name) == 0)
582eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick	 return i;
583eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick   }
584eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick
585eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick   return -1;
586eeedd355cfc2f0c578282657bd4259440a88742cIan Romanick}
58757bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
58857bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
58957bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanickunsigned
59057bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanickglsl_type::component_slots() const
59157bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick{
59257bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   switch (this->base_type) {
59357bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   case GLSL_TYPE_UINT:
59457bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   case GLSL_TYPE_INT:
59557bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   case GLSL_TYPE_FLOAT:
59657bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   case GLSL_TYPE_BOOL:
59757bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick      return this->components();
59857bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
59957bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   case GLSL_TYPE_STRUCT: {
60057bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick      unsigned size = 0;
60157bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
60257bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick      for (unsigned i = 0; i < this->length; i++)
60357bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick	 size += this->fields.structure[i].type->component_slots();
60457bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
60557bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick      return size;
60657bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   }
60757bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
60857bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   case GLSL_TYPE_ARRAY:
60957bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick      return this->length * this->fields.array->component_slots();
61057bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick
61157bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   default:
61257bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick      return 0;
61357bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick   }
61457bb893a46ced683792f8e7ebdffbb5c5a892b84Ian Romanick}
615200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace
616200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versacebool
617200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versaceglsl_type::can_implicitly_convert_to(const glsl_type *desired) const
618200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace{
619200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace   if (this == desired)
620200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace      return true;
621200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace
622200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace   /* There is no conversion among matrix types. */
623200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace   if (this->matrix_columns > 1 || desired->matrix_columns > 1)
624200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace      return false;
625200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace
626200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace   /* int and uint can be converted to float. */
627200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace   return desired->is_float()
628200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace          && this->is_integer()
629200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace          && this->vector_elements == desired->vector_elements;
630200e4972c1579e8dfaa6f11eee2a7e54baad4852Chad Versace}
6318ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
6328ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholtunsigned
6338ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholtglsl_type::std140_base_alignment(bool row_major) const
6348ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt{
6358ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (1) If the member is a scalar consuming <N> basic machine units, the
6368ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     base alignment is <N>.
6378ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
6388ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (2) If the member is a two- or four-component vector with components
6398ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     consuming <N> basic machine units, the base alignment is 2<N> or
6408ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     4<N>, respectively.
6418ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
6428ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (3) If the member is a three-component vector with components consuming
6438ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <N> basic machine units, the base alignment is 4<N>.
6448ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
6458ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_scalar() || this->is_vector()) {
6468ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      switch (this->vector_elements) {
6478ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      case 1:
6488ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return 4;
6498ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      case 2:
6508ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return 8;
6518ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      case 3:
6528ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      case 4:
6538ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return 16;
6548ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
6558ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
6568ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
6578ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (4) If the member is an array of scalars or vectors, the base alignment
6588ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     and array stride are set to match the base alignment of a single
6598ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     array element, according to rules (1), (2), and (3), and rounded up
6608ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     to the base alignment of a vec4. The array may have padding at the
6618ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     end; the base offset of the member following the array is rounded up
6628ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     to the next multiple of the base alignment.
6638ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
6648ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (6) If the member is an array of <S> column-major matrices with <C>
6658ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     columns and <R> rows, the matrix is stored identically to a row of
6668ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <S>*<C> column vectors with <R> components each, according to rule
6678ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     (4).
6688ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
6698ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (8) If the member is an array of <S> row-major matrices with <C> columns
6708ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     and <R> rows, the matrix is stored identically to a row of <S>*<R>
6718ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     row vectors with <C> components each, according to rule (4).
6728ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
6738ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (10) If the member is an array of <S> structures, the <S> elements of
6748ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *      the array are laid out in order, according to rule (9).
6758ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
6768ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_array()) {
6778ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      if (this->fields.array->is_scalar() ||
6788ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	  this->fields.array->is_vector() ||
6798ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	  this->fields.array->is_matrix()) {
6808ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return MAX2(this->fields.array->std140_base_alignment(row_major), 16);
6818ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      } else {
6828ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 assert(this->fields.array->is_record());
6838ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return this->fields.array->std140_base_alignment(row_major);
6848ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
6858ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
6868ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
6878ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (5) If the member is a column-major matrix with <C> columns and
6888ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <R> rows, the matrix is stored identically to an array of
6898ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <C> column vectors with <R> components each, according to
6908ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     rule (4).
6918ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
6928ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (7) If the member is a row-major matrix with <C> columns and <R>
6938ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     rows, the matrix is stored identically to an array of <R>
6948ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     row vectors with <C> components each, according to rule (4).
6958ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
6968ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_matrix()) {
697ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt      const struct glsl_type *vec_type, *array_type;
698ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt      int c = this->matrix_columns;
699ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt      int r = this->vector_elements;
700ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt
7018ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      if (row_major) {
702ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt	 vec_type = get_instance(GLSL_TYPE_FLOAT, c, 1);
703ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt	 array_type = glsl_type::get_array_instance(vec_type, r);
7048ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      } else {
705ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt	 vec_type = get_instance(GLSL_TYPE_FLOAT, r, 1);
706ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt	 array_type = glsl_type::get_array_instance(vec_type, c);
7078ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
7088ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
709ffb2d430596258aaeaf3b7ae7f295036ea4094d5Eric Anholt      return array_type->std140_base_alignment(false);
7108ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
7118ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7128ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (9) If the member is a structure, the base alignment of the
7138ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     structure is <N>, where <N> is the largest base alignment
7148ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     value of any of its members, and rounded up to the base
7158ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     alignment of a vec4. The individual members of this
7168ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     sub-structure are then assigned offsets by applying this set
7178ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     of rules recursively, where the base offset of the first
7188ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     member of the sub-structure is equal to the aligned offset
7198ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     of the structure. The structure may have padding at the end;
7208ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     the base offset of the member following the sub-structure is
7218ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     rounded up to the next multiple of the base alignment of the
7228ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     structure.
7238ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
7248ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_record()) {
7258ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      unsigned base_alignment = 16;
7268ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      for (unsigned i = 0; i < this->length; i++) {
7278ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 const struct glsl_type *field_type = this->fields.structure[i].type;
7288ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 base_alignment = MAX2(base_alignment,
7298ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt			       field_type->std140_base_alignment(row_major));
7308ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
7318ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      return base_alignment;
7328ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
7338ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7348ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   assert(!"not reached");
7358ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   return -1;
7368ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt}
7378ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7388ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholtstatic unsigned
7398ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholtalign(unsigned val, unsigned align)
7408ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt{
7418ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   return (val + align - 1) / align * align;
7428ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt}
7438ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7448ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholtunsigned
7458ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholtglsl_type::std140_size(bool row_major) const
7468ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt{
7478ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (1) If the member is a scalar consuming <N> basic machine units, the
7488ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     base alignment is <N>.
7498ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
7508ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (2) If the member is a two- or four-component vector with components
7518ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     consuming <N> basic machine units, the base alignment is 2<N> or
7528ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     4<N>, respectively.
7538ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
7548ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (3) If the member is a three-component vector with components consuming
7558ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <N> basic machine units, the base alignment is 4<N>.
7568ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
7578ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_scalar() || this->is_vector()) {
7588ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      return this->vector_elements * 4;
7598ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
7608ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7618ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (5) If the member is a column-major matrix with <C> columns and
7628ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <R> rows, the matrix is stored identically to an array of
7638ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <C> column vectors with <R> components each, according to
7648ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     rule (4).
7658ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
7668ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (6) If the member is an array of <S> column-major matrices with <C>
7678ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     columns and <R> rows, the matrix is stored identically to a row of
7688ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     <S>*<C> column vectors with <R> components each, according to rule
7698ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     (4).
7708ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
7718ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (7) If the member is a row-major matrix with <C> columns and <R>
7728ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     rows, the matrix is stored identically to an array of <R>
7738ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     row vectors with <C> components each, according to rule (4).
7748ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
7758ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (8) If the member is an array of <S> row-major matrices with <C> columns
7768ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     and <R> rows, the matrix is stored identically to a row of <S>*<R>
7778ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     row vectors with <C> components each, according to rule (4).
7788ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
7798ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_matrix() || (this->is_array() &&
7808ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt			     this->fields.array->is_matrix())) {
7818ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      const struct glsl_type *element_type;
7828ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      const struct glsl_type *vec_type;
7838ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      unsigned int array_len;
7848ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7858ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      if (this->is_array()) {
7868ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 element_type = this->fields.array;
7878ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 array_len = this->length;
7888ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      } else {
7898ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 element_type = this;
7908ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 array_len = 1;
7918ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
7928ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
7938ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      if (row_major) {
7948ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 vec_type = get_instance(GLSL_TYPE_FLOAT,
7958ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt				 element_type->matrix_columns, 1);
7968ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 array_len *= element_type->vector_elements;
7978ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      } else {
7988ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 vec_type = get_instance(GLSL_TYPE_FLOAT,
7998ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt				 element_type->vector_elements, 1);
8008ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 array_len *= element_type->matrix_columns;
8018ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
8028ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      const glsl_type *array_type = glsl_type::get_array_instance(vec_type,
8038ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt								  array_len);
8048ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
8058ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      return array_type->std140_size(false);
8068ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
8078ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
8088ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (4) If the member is an array of scalars or vectors, the base alignment
8098ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     and array stride are set to match the base alignment of a single
8108ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     array element, according to rules (1), (2), and (3), and rounded up
8118ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     to the base alignment of a vec4. The array may have padding at the
8128ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     end; the base offset of the member following the array is rounded up
8138ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     to the next multiple of the base alignment.
8148ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *
8158ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    * (10) If the member is an array of <S> structures, the <S> elements of
8168ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *      the array are laid out in order, according to rule (9).
8178ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
8188ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_array()) {
8198ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      if (this->fields.array->is_record()) {
8208ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return this->length * this->fields.array->std140_size(row_major);
8218ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      } else {
8228ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 unsigned element_base_align =
8238ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	    this->fields.array->std140_base_alignment(row_major);
8248ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 return this->length * MAX2(element_base_align, 16);
8258ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
8268ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
8278ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
8288ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   /* (9) If the member is a structure, the base alignment of the
8298ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     structure is <N>, where <N> is the largest base alignment
8308ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     value of any of its members, and rounded up to the base
8318ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     alignment of a vec4. The individual members of this
8328ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     sub-structure are then assigned offsets by applying this set
8338ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     of rules recursively, where the base offset of the first
8348ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     member of the sub-structure is equal to the aligned offset
8358ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     of the structure. The structure may have padding at the end;
8368ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     the base offset of the member following the sub-structure is
8378ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     rounded up to the next multiple of the base alignment of the
8388ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    *     structure.
8398ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt    */
8408ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   if (this->is_record()) {
8418ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      unsigned size = 0;
8428ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      for (unsigned i = 0; i < this->length; i++) {
8438ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 const struct glsl_type *field_type = this->fields.structure[i].type;
8448ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 unsigned align = field_type->std140_base_alignment(row_major);
8458ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 size = (size + align - 1) / align * align;
8468ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt	 size += field_type->std140_size(row_major);
8478ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      }
8488ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      size = align(size,
8498ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt		   this->fields.structure[0].type->std140_base_alignment(row_major));
8508ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt      return size;
8518ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   }
8528ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt
8538ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   assert(!"not reached");
8548ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt   return -1;
8558ab5842a6d992956ee365c0e0232c6e6b907863eEric Anholt}
856