glsl_types.cpp revision 76deef138ee25ab57b4716aef41ce0c94081f20a
1/*
2 * Copyright © 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <cstdio>
25#include <stdlib.h>
26#include "main/core.h" /* for Elements */
27#include "glsl_symbol_table.h"
28#include "glsl_parser_extras.h"
29#include "glsl_types.h"
30#include "builtin_types.h"
31extern "C" {
32#include "program/hash_table.h"
33}
34
35hash_table *glsl_type::array_types = NULL;
36hash_table *glsl_type::record_types = NULL;
37void *glsl_type::mem_ctx = NULL;
38
39void
40glsl_type::init_talloc_type_ctx(void)
41{
42   if (glsl_type::mem_ctx == NULL) {
43      glsl_type::mem_ctx = talloc_autofree_context();
44      assert(glsl_type::mem_ctx != NULL);
45   }
46}
47
48glsl_type::glsl_type(GLenum gl_type,
49		     unsigned base_type, unsigned vector_elements,
50		     unsigned matrix_columns, const char *name) :
51   gl_type(gl_type),
52   base_type(base_type),
53   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
54   sampler_type(0),
55   vector_elements(vector_elements), matrix_columns(matrix_columns),
56   length(0)
57{
58   init_talloc_type_ctx();
59   this->name = talloc_strdup(this->mem_ctx, name);
60   /* Neither dimension is zero or both dimensions are zero.
61    */
62   assert((vector_elements == 0) == (matrix_columns == 0));
63   memset(& fields, 0, sizeof(fields));
64}
65
66glsl_type::glsl_type(GLenum gl_type,
67		     enum glsl_sampler_dim dim, bool shadow, bool array,
68		     unsigned type, const char *name) :
69   gl_type(gl_type),
70   base_type(GLSL_TYPE_SAMPLER),
71   sampler_dimensionality(dim), sampler_shadow(shadow),
72   sampler_array(array), sampler_type(type),
73   vector_elements(0), matrix_columns(0),
74   length(0)
75{
76   init_talloc_type_ctx();
77   this->name = talloc_strdup(this->mem_ctx, name);
78   memset(& fields, 0, sizeof(fields));
79}
80
81glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
82		     const char *name) :
83   base_type(GLSL_TYPE_STRUCT),
84   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
85   sampler_type(0),
86   vector_elements(0), matrix_columns(0),
87   length(num_fields)
88{
89   unsigned int i;
90
91   init_talloc_type_ctx();
92   this->name = talloc_strdup(this->mem_ctx, name);
93   this->fields.structure = talloc_array(this->mem_ctx,
94					 glsl_struct_field, length);
95   for (i = 0; i < length; i++) {
96      this->fields.structure[i].type = fields[i].type;
97      this->fields.structure[i].name = talloc_strdup(this->fields.structure,
98						     fields[i].name);
99   }
100}
101
102static void
103add_types_to_symbol_table(glsl_symbol_table *symtab,
104			  const struct glsl_type *types,
105			  unsigned num_types, bool warn)
106{
107   (void) warn;
108
109   for (unsigned i = 0; i < num_types; i++) {
110      symtab->add_type(types[i].name, & types[i]);
111   }
112}
113
114void
115glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
116{
117   add_types_to_symbol_table(symtab, builtin_core_types,
118			     Elements(builtin_core_types),
119			     false);
120   add_types_to_symbol_table(symtab, builtin_structure_types,
121			     Elements(builtin_structure_types),
122			     false);
123   add_types_to_symbol_table(symtab, &void_type, 1, false);
124}
125
126void
127glsl_type::generate_110_types(glsl_symbol_table *symtab)
128{
129   generate_100ES_types(symtab);
130
131   add_types_to_symbol_table(symtab, builtin_110_types,
132			     Elements(builtin_110_types),
133			     false);
134   add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
135			     Elements(builtin_110_deprecated_structure_types),
136			     false);
137}
138
139
140void
141glsl_type::generate_120_types(glsl_symbol_table *symtab)
142{
143   generate_110_types(symtab);
144
145   add_types_to_symbol_table(symtab, builtin_120_types,
146			     Elements(builtin_120_types), false);
147}
148
149
150void
151glsl_type::generate_130_types(glsl_symbol_table *symtab)
152{
153   generate_120_types(symtab);
154
155   add_types_to_symbol_table(symtab, builtin_130_types,
156			     Elements(builtin_130_types), false);
157   generate_EXT_texture_array_types(symtab, false);
158}
159
160
161void
162glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
163						bool warn)
164{
165   add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
166			     Elements(builtin_ARB_texture_rectangle_types),
167			     warn);
168}
169
170
171void
172glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
173					    bool warn)
174{
175   add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
176			     Elements(builtin_EXT_texture_array_types),
177			     warn);
178}
179
180
181void
182_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
183{
184   switch (state->language_version) {
185   case 100:
186      assert(state->es_shader);
187      glsl_type::generate_100ES_types(state->symbols);
188      break;
189   case 110:
190      glsl_type::generate_110_types(state->symbols);
191      break;
192   case 120:
193      glsl_type::generate_120_types(state->symbols);
194      break;
195   case 130:
196      glsl_type::generate_130_types(state->symbols);
197      break;
198   default:
199      /* error */
200      break;
201   }
202
203   if (state->ARB_texture_rectangle_enable) {
204      glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
205					   state->ARB_texture_rectangle_warn);
206   }
207
208   if (state->EXT_texture_array_enable && state->language_version < 130) {
209      // These are already included in 130; don't create twice.
210      glsl_type::generate_EXT_texture_array_types(state->symbols,
211				       state->EXT_texture_array_warn);
212   }
213}
214
215
216const glsl_type *glsl_type::get_base_type() const
217{
218   switch (base_type) {
219   case GLSL_TYPE_UINT:
220      return uint_type;
221   case GLSL_TYPE_INT:
222      return int_type;
223   case GLSL_TYPE_FLOAT:
224      return float_type;
225   case GLSL_TYPE_BOOL:
226      return bool_type;
227   default:
228      return error_type;
229   }
230}
231
232
233void
234_mesa_glsl_release_types(void)
235{
236   if (glsl_type::array_types != NULL) {
237      hash_table_dtor(glsl_type::array_types);
238      glsl_type::array_types = NULL;
239   }
240
241   if (glsl_type::record_types != NULL) {
242      hash_table_dtor(glsl_type::record_types);
243      glsl_type::record_types = NULL;
244   }
245}
246
247
248glsl_type::glsl_type(const glsl_type *array, unsigned length) :
249   base_type(GLSL_TYPE_ARRAY),
250   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
251   sampler_type(0),
252   vector_elements(0), matrix_columns(0),
253   name(NULL), length(length)
254{
255   this->fields.array = array;
256   /* Inherit the gl type of the base. The GL type is used for
257    * uniform/statevar handling in Mesa and the arrayness of the type
258    * is represented by the size rather than the type.
259    */
260   this->gl_type = array->gl_type;
261
262   /* Allow a maximum of 10 characters for the array size.  This is enough
263    * for 32-bits of ~0.  The extra 3 are for the '[', ']', and terminating
264    * NUL.
265    */
266   const unsigned name_length = strlen(array->name) + 10 + 3;
267   char *const n = (char *) talloc_size(this->mem_ctx, name_length);
268
269   if (length == 0)
270      snprintf(n, name_length, "%s[]", array->name);
271   else
272      snprintf(n, name_length, "%s[%u]", array->name, length);
273
274   this->name = n;
275}
276
277
278const glsl_type *
279glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
280{
281   if (base_type == GLSL_TYPE_VOID)
282      return &void_type;
283
284   if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
285      return error_type;
286
287   /* Treat GLSL vectors as Nx1 matrices.
288    */
289   if (columns == 1) {
290      switch (base_type) {
291      case GLSL_TYPE_UINT:
292	 return uint_type + (rows - 1);
293      case GLSL_TYPE_INT:
294	 return int_type + (rows - 1);
295      case GLSL_TYPE_FLOAT:
296	 return float_type + (rows - 1);
297      case GLSL_TYPE_BOOL:
298	 return bool_type + (rows - 1);
299      default:
300	 return error_type;
301      }
302   } else {
303      if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
304	 return error_type;
305
306      /* GLSL matrix types are named mat{COLUMNS}x{ROWS}.  Only the following
307       * combinations are valid:
308       *
309       *   1 2 3 4
310       * 1
311       * 2   x x x
312       * 3   x x x
313       * 4   x x x
314       */
315#define IDX(c,r) (((c-1)*3) + (r-1))
316
317      switch (IDX(columns, rows)) {
318      case IDX(2,2): return mat2_type;
319      case IDX(2,3): return mat2x3_type;
320      case IDX(2,4): return mat2x4_type;
321      case IDX(3,2): return mat3x2_type;
322      case IDX(3,3): return mat3_type;
323      case IDX(3,4): return mat3x4_type;
324      case IDX(4,2): return mat4x2_type;
325      case IDX(4,3): return mat4x3_type;
326      case IDX(4,4): return mat4_type;
327      default: return error_type;
328      }
329   }
330
331   assert(!"Should not get here.");
332   return error_type;
333}
334
335
336const glsl_type *
337glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
338{
339
340   if (array_types == NULL) {
341      array_types = hash_table_ctor(64, hash_table_string_hash,
342				    hash_table_string_compare);
343   }
344
345   /* Generate a name using the base type pointer in the key.  This is
346    * done because the name of the base type may not be unique across
347    * shaders.  For example, two shaders may have different record types
348    * named 'foo'.
349    */
350   char key[128];
351   snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
352
353   const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
354   if (t == NULL) {
355      t = new glsl_type(base, array_size);
356
357      hash_table_insert(array_types, (void *) t, talloc_strdup(mem_ctx, key));
358   }
359
360   assert(t->base_type == GLSL_TYPE_ARRAY);
361   assert(t->length == array_size);
362   assert(t->fields.array == base);
363
364   return t;
365}
366
367
368int
369glsl_type::record_key_compare(const void *a, const void *b)
370{
371   const glsl_type *const key1 = (glsl_type *) a;
372   const glsl_type *const key2 = (glsl_type *) b;
373
374   /* Return zero is the types match (there is zero difference) or non-zero
375    * otherwise.
376    */
377   if (strcmp(key1->name, key2->name) != 0)
378      return 1;
379
380   if (key1->length != key2->length)
381      return 1;
382
383   for (unsigned i = 0; i < key1->length; i++) {
384      if (key1->fields.structure[i].type != key2->fields.structure[i].type)
385	 return 1;
386      if (strcmp(key1->fields.structure[i].name,
387		 key2->fields.structure[i].name) != 0)
388	 return 1;
389   }
390
391   return 0;
392}
393
394
395unsigned
396glsl_type::record_key_hash(const void *a)
397{
398   const glsl_type *const key = (glsl_type *) a;
399   char hash_key[128];
400   unsigned size = 0;
401
402   size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
403
404   for (unsigned i = 0; i < key->length; i++) {
405      if (size >= sizeof(hash_key))
406	 break;
407
408      size += snprintf(& hash_key[size], sizeof(hash_key) - size,
409		       "%p", (void *) key->fields.structure[i].type);
410   }
411
412   return hash_table_string_hash(& hash_key);
413}
414
415
416const glsl_type *
417glsl_type::get_record_instance(const glsl_struct_field *fields,
418			       unsigned num_fields,
419			       const char *name)
420{
421   const glsl_type key(fields, num_fields, name);
422
423   if (record_types == NULL) {
424      record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
425   }
426
427   const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
428   if (t == NULL) {
429      t = new glsl_type(fields, num_fields, name);
430
431      hash_table_insert(record_types, (void *) t, t);
432   }
433
434   assert(t->base_type == GLSL_TYPE_STRUCT);
435   assert(t->length == num_fields);
436   assert(strcmp(t->name, name) == 0);
437
438   return t;
439}
440
441
442const glsl_type *
443glsl_type::field_type(const char *name) const
444{
445   if (this->base_type != GLSL_TYPE_STRUCT)
446      return error_type;
447
448   for (unsigned i = 0; i < this->length; i++) {
449      if (strcmp(name, this->fields.structure[i].name) == 0)
450	 return this->fields.structure[i].type;
451   }
452
453   return error_type;
454}
455
456
457int
458glsl_type::field_index(const char *name) const
459{
460   if (this->base_type != GLSL_TYPE_STRUCT)
461      return -1;
462
463   for (unsigned i = 0; i < this->length; i++) {
464      if (strcmp(name, this->fields.structure[i].name) == 0)
465	 return i;
466   }
467
468   return -1;
469}
470
471
472unsigned
473glsl_type::component_slots() const
474{
475   switch (this->base_type) {
476   case GLSL_TYPE_UINT:
477   case GLSL_TYPE_INT:
478   case GLSL_TYPE_FLOAT:
479   case GLSL_TYPE_BOOL:
480      return this->components();
481
482   case GLSL_TYPE_STRUCT: {
483      unsigned size = 0;
484
485      for (unsigned i = 0; i < this->length; i++)
486	 size += this->fields.structure[i].type->component_slots();
487
488      return size;
489   }
490
491   case GLSL_TYPE_ARRAY:
492      return this->length * this->fields.array->component_slots();
493
494   default:
495      return 0;
496   }
497}
498