glsl_types.cpp revision e94642eb0d99ff7f6cdaee31ed4f5f29bdabd6f7
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 "glsl_symbol_table.h"
27#include "glsl_parser_extras.h"
28#include "glsl_types.h"
29#include "builtin_types.h"
30extern "C" {
31#include "hash_table.h"
32}
33
34hash_table *glsl_type::array_types = NULL;
35
36static void
37add_types_to_symbol_table(glsl_symbol_table *symtab,
38			  const struct glsl_type *types,
39			  unsigned num_types, bool warn)
40{
41   (void) warn;
42
43   for (unsigned i = 0; i < num_types; i++) {
44      symtab->add_type(types[i].name, & types[i]);
45   }
46}
47
48
49void
50glsl_type::generate_110_types(glsl_symbol_table *symtab)
51{
52   add_types_to_symbol_table(symtab, builtin_core_types,
53			     Elements(builtin_core_types),
54			     false);
55   add_types_to_symbol_table(symtab, builtin_structure_types,
56			     Elements(builtin_structure_types),
57			     false);
58   add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
59			     Elements(builtin_110_deprecated_structure_types),
60			     false);
61   add_types_to_symbol_table(symtab, & void_type, 1, false);
62}
63
64
65void
66glsl_type::generate_120_types(glsl_symbol_table *symtab)
67{
68   generate_110_types(symtab);
69
70   add_types_to_symbol_table(symtab, builtin_120_types,
71			     Elements(builtin_120_types), false);
72}
73
74
75void
76glsl_type::generate_130_types(glsl_symbol_table *symtab)
77{
78   generate_120_types(symtab);
79
80   add_types_to_symbol_table(symtab, builtin_130_types,
81			     Elements(builtin_130_types), false);
82}
83
84
85void
86glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
87						bool warn)
88{
89   add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
90			     Elements(builtin_ARB_texture_rectangle_types),
91			     warn);
92}
93
94
95void
96glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
97					    bool warn)
98{
99   add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
100			     Elements(builtin_EXT_texture_array_types),
101			     warn);
102}
103
104
105void
106_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
107{
108   switch (state->language_version) {
109   case 110:
110      glsl_type::generate_110_types(state->symbols);
111      break;
112   case 120:
113      glsl_type::generate_120_types(state->symbols);
114      break;
115   case 130:
116      glsl_type::generate_130_types(state->symbols);
117      break;
118   default:
119      /* error */
120      break;
121   }
122
123   if (state->ARB_texture_rectangle_enable) {
124      glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
125					   state->ARB_texture_rectangle_warn);
126   }
127
128   if (state->EXT_texture_array_enable && state->language_version < 130) {
129      // These are already included in 130; don't create twice.
130      glsl_type::generate_EXT_texture_array_types(state->symbols,
131				       state->EXT_texture_array_warn);
132   }
133}
134
135
136const glsl_type *glsl_type::get_base_type() const
137{
138   switch (base_type) {
139   case GLSL_TYPE_UINT:
140      return uint_type;
141   case GLSL_TYPE_INT:
142      return int_type;
143   case GLSL_TYPE_FLOAT:
144      return float_type;
145   case GLSL_TYPE_BOOL:
146      return bool_type;
147   default:
148      return error_type;
149   }
150}
151
152
153ir_function *
154glsl_type::generate_constructor(glsl_symbol_table *symtab) const
155{
156   void *ctx = symtab;
157
158   /* Generate the function name and add it to the symbol table.
159    */
160   ir_function *const f = new(ctx) ir_function(name);
161
162   bool added = symtab->add_function(name, f);
163   assert(added);
164
165   ir_function_signature *const sig = new(ctx) ir_function_signature(this);
166   f->add_signature(sig);
167
168   ir_variable **declarations =
169      (ir_variable **) malloc(sizeof(ir_variable *) * this->length);
170   for (unsigned i = 0; i < length; i++) {
171      char *const param_name = (char *) malloc(10);
172
173      snprintf(param_name, 10, "p%08X", i);
174
175      ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
176	 ? new(ctx) ir_variable(fields.array, param_name)
177	 : new(ctx) ir_variable(fields.structure[i].type, param_name);
178
179      var->mode = ir_var_in;
180      declarations[i] = var;
181      sig->parameters.push_tail(var);
182   }
183
184   /* Generate the body of the constructor.  The body assigns each of the
185    * parameters to a portion of a local variable called __retval that has
186    * the same type as the constructor.  After initializing __retval,
187    * __retval is returned.
188    */
189   ir_variable *retval = new(ctx) ir_variable(this, "__retval");
190   sig->body.push_tail(retval);
191
192   for (unsigned i = 0; i < length; i++) {
193      ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
194	 ? (ir_dereference *) new(ctx) ir_dereference_array(retval,
195							    new(ctx) ir_constant(i))
196	 : (ir_dereference *) new(ctx) ir_dereference_record(retval,
197							     fields.structure[i].name);
198
199      ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
200      ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL);
201
202      sig->body.push_tail(assign);
203   }
204
205   free(declarations);
206
207   ir_dereference *const retref = new(ctx) ir_dereference_variable(retval);
208   ir_instruction *const inst = new(ctx) ir_return(retref);
209   sig->body.push_tail(inst);
210
211   return f;
212}
213
214
215glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) :
216   base_type(GLSL_TYPE_ARRAY),
217   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
218   sampler_type(0),
219   vector_elements(0), matrix_columns(0),
220   name(NULL), length(length)
221{
222   this->fields.array = array;
223
224   /* Allow a maximum of 10 characters for the array size.  This is enough
225    * for 32-bits of ~0.  The extra 3 are for the '[', ']', and terminating
226    * NUL.
227    */
228   const unsigned name_length = strlen(array->name) + 10 + 3;
229   char *const n = (char *) talloc_size(ctx, name_length);
230
231   if (length == 0)
232      snprintf(n, name_length, "%s[]", array->name);
233   else
234      snprintf(n, name_length, "%s[%u]", array->name, length);
235
236   this->name = n;
237}
238
239
240const glsl_type *
241glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
242{
243   if (base_type == GLSL_TYPE_VOID)
244      return &void_type;
245
246   if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
247      return error_type;
248
249   /* Treat GLSL vectors as Nx1 matrices.
250    */
251   if (columns == 1) {
252      switch (base_type) {
253      case GLSL_TYPE_UINT:
254	 return uint_type + (rows - 1);
255      case GLSL_TYPE_INT:
256	 return int_type + (rows - 1);
257      case GLSL_TYPE_FLOAT:
258	 return float_type + (rows - 1);
259      case GLSL_TYPE_BOOL:
260	 return bool_type + (rows - 1);
261      default:
262	 return error_type;
263      }
264   } else {
265      if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
266	 return error_type;
267
268      /* GLSL matrix types are named mat{COLUMNS}x{ROWS}.  Only the following
269       * combinations are valid:
270       *
271       *   1 2 3 4
272       * 1
273       * 2   x x x
274       * 3   x x x
275       * 4   x x x
276       */
277#define IDX(c,r) (((c-1)*3) + (r-1))
278
279      switch (IDX(columns, rows)) {
280      case IDX(2,2): return mat2_type;
281      case IDX(2,3): return mat2x3_type;
282      case IDX(2,4): return mat2x4_type;
283      case IDX(3,2): return mat3x2_type;
284      case IDX(3,3): return mat3_type;
285      case IDX(3,4): return mat3x4_type;
286      case IDX(4,2): return mat4x2_type;
287      case IDX(4,3): return mat4x3_type;
288      case IDX(4,4): return mat4_type;
289      default: return error_type;
290      }
291   }
292
293   assert(!"Should not get here.");
294   return error_type;
295}
296
297
298int
299glsl_type::array_key_compare(const void *a, const void *b)
300{
301   const glsl_type *const key1 = (glsl_type *) a;
302   const glsl_type *const key2 = (glsl_type *) b;
303
304   /* Return zero is the types match (there is zero difference) or non-zero
305    * otherwise.
306    */
307   return ((key1->fields.array == key2->fields.array)
308	   && (key1->length == key2->length)) ? 0 : 1;
309}
310
311
312unsigned
313glsl_type::array_key_hash(const void *a)
314{
315   const glsl_type *const key = (glsl_type *) a;
316
317   const struct {
318      const glsl_type *t;
319      unsigned l;
320      char nul;
321   } hash_key = {
322      key->fields.array,
323      key->length,
324      '\0'
325   };
326
327   return hash_table_string_hash(& hash_key);
328}
329
330
331const glsl_type *
332glsl_type::get_array_instance(void *ctx, const glsl_type *base,
333			      unsigned array_size)
334{
335   const glsl_type key(ctx, base, array_size);
336
337   if (array_types == NULL) {
338      array_types = hash_table_ctor(64, array_key_hash, array_key_compare);
339   }
340
341   const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key);
342   if (t == NULL) {
343      t = new(ctx) glsl_type(ctx, base, array_size);
344
345      hash_table_insert(array_types, (void *) t, t);
346   }
347
348   assert(t->base_type == GLSL_TYPE_ARRAY);
349   assert(t->length == array_size);
350   assert(t->fields.array == base);
351
352   return t;
353}
354
355
356const glsl_type *
357glsl_type::field_type(const char *name) const
358{
359   if (this->base_type != GLSL_TYPE_STRUCT)
360      return error_type;
361
362   for (unsigned i = 0; i < this->length; i++) {
363      if (strcmp(name, this->fields.structure[i].name) == 0)
364	 return this->fields.structure[i].type;
365   }
366
367   return error_type;
368}
369
370
371int
372glsl_type::field_index(const char *name) const
373{
374   if (this->base_type != GLSL_TYPE_STRUCT)
375      return -1;
376
377   for (unsigned i = 0; i < this->length; i++) {
378      if (strcmp(name, this->fields.structure[i].name) == 0)
379	 return i;
380   }
381
382   return -1;
383}
384
385
386unsigned
387glsl_type::component_slots() const
388{
389   switch (this->base_type) {
390   case GLSL_TYPE_UINT:
391   case GLSL_TYPE_INT:
392   case GLSL_TYPE_FLOAT:
393   case GLSL_TYPE_BOOL:
394      return this->components();
395
396   case GLSL_TYPE_STRUCT: {
397      unsigned size = 0;
398
399      for (unsigned i = 0; i < this->length; i++)
400	 size += this->fields.structure[i].type->component_slots();
401
402      return size;
403   }
404
405   case GLSL_TYPE_ARRAY:
406      return this->length * this->fields.array->component_slots();
407
408   default:
409      return 0;
410   }
411}
412