glsl2: Don't claim a match on structure types with different field names.
[mesa.git] / src / glsl / glsl_types.cpp
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"
30 extern "C" {
31 #include "hash_table.h"
32 }
33
34 hash_table *glsl_type::array_types = NULL;
35 hash_table *glsl_type::record_types = NULL;
36 void *glsl_type::ctx = NULL;
37
38 glsl_type::glsl_type(GLenum gl_type,
39 unsigned base_type, unsigned vector_elements,
40 unsigned matrix_columns, const char *name) :
41 gl_type(gl_type),
42 base_type(base_type),
43 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
44 sampler_type(0),
45 vector_elements(vector_elements), matrix_columns(matrix_columns),
46 name(name),
47 length(0)
48 {
49 /* Neither dimension is zero or both dimensions are zero.
50 */
51 assert((vector_elements == 0) == (matrix_columns == 0));
52 memset(& fields, 0, sizeof(fields));
53 }
54
55 glsl_type::glsl_type(GLenum gl_type,
56 enum glsl_sampler_dim dim, bool shadow, bool array,
57 unsigned type, const char *name) :
58 gl_type(gl_type),
59 base_type(GLSL_TYPE_SAMPLER),
60 sampler_dimensionality(dim), sampler_shadow(shadow),
61 sampler_array(array), sampler_type(type),
62 vector_elements(0), matrix_columns(0),
63 name(name),
64 length(0)
65 {
66 memset(& fields, 0, sizeof(fields));
67 }
68
69 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
70 const char *name) :
71 base_type(GLSL_TYPE_STRUCT),
72 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
73 sampler_type(0),
74 vector_elements(0), matrix_columns(0),
75 name(name),
76 length(num_fields)
77 {
78 this->fields.structure = fields;
79 }
80
81 static void
82 add_types_to_symbol_table(glsl_symbol_table *symtab,
83 const struct glsl_type *types,
84 unsigned num_types, bool warn)
85 {
86 (void) warn;
87
88 for (unsigned i = 0; i < num_types; i++) {
89 symtab->add_type(types[i].name, & types[i]);
90 }
91 }
92
93
94 void
95 glsl_type::generate_110_types(glsl_symbol_table *symtab)
96 {
97 add_types_to_symbol_table(symtab, builtin_core_types,
98 Elements(builtin_core_types),
99 false);
100 add_types_to_symbol_table(symtab, builtin_structure_types,
101 Elements(builtin_structure_types),
102 false);
103 add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
104 Elements(builtin_110_deprecated_structure_types),
105 false);
106 add_types_to_symbol_table(symtab, & void_type, 1, false);
107 }
108
109
110 void
111 glsl_type::generate_120_types(glsl_symbol_table *symtab)
112 {
113 generate_110_types(symtab);
114
115 add_types_to_symbol_table(symtab, builtin_120_types,
116 Elements(builtin_120_types), false);
117 }
118
119
120 void
121 glsl_type::generate_130_types(glsl_symbol_table *symtab)
122 {
123 generate_120_types(symtab);
124
125 add_types_to_symbol_table(symtab, builtin_130_types,
126 Elements(builtin_130_types), false);
127 }
128
129
130 void
131 glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
132 bool warn)
133 {
134 add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
135 Elements(builtin_ARB_texture_rectangle_types),
136 warn);
137 }
138
139
140 void
141 glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
142 bool warn)
143 {
144 add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
145 Elements(builtin_EXT_texture_array_types),
146 warn);
147 }
148
149
150 void
151 _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
152 {
153 switch (state->language_version) {
154 case 110:
155 glsl_type::generate_110_types(state->symbols);
156 break;
157 case 120:
158 glsl_type::generate_120_types(state->symbols);
159 break;
160 case 130:
161 glsl_type::generate_130_types(state->symbols);
162 break;
163 default:
164 /* error */
165 break;
166 }
167
168 if (state->ARB_texture_rectangle_enable) {
169 glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
170 state->ARB_texture_rectangle_warn);
171 }
172
173 if (state->EXT_texture_array_enable && state->language_version < 130) {
174 // These are already included in 130; don't create twice.
175 glsl_type::generate_EXT_texture_array_types(state->symbols,
176 state->EXT_texture_array_warn);
177 }
178 }
179
180
181 const glsl_type *glsl_type::get_base_type() const
182 {
183 switch (base_type) {
184 case GLSL_TYPE_UINT:
185 return uint_type;
186 case GLSL_TYPE_INT:
187 return int_type;
188 case GLSL_TYPE_FLOAT:
189 return float_type;
190 case GLSL_TYPE_BOOL:
191 return bool_type;
192 default:
193 return error_type;
194 }
195 }
196
197
198 void
199 _mesa_glsl_release_types(void)
200 {
201 if (glsl_type::array_types != NULL) {
202 hash_table_dtor(glsl_type::array_types);
203 glsl_type::array_types = NULL;
204 }
205
206 if (glsl_type::record_types != NULL) {
207 hash_table_dtor(glsl_type::record_types);
208 glsl_type::record_types = NULL;
209 }
210
211 if (glsl_type::ctx != NULL) {
212 talloc_free(glsl_type::ctx);
213 glsl_type::ctx = NULL;
214 }
215 }
216
217
218 ir_function *
219 glsl_type::generate_constructor(glsl_symbol_table *symtab) const
220 {
221 void *ctx = symtab;
222
223 /* Generate the function name and add it to the symbol table.
224 */
225 ir_function *const f = new(ctx) ir_function(name);
226
227 bool added = symtab->add_function(name, f);
228 assert(added);
229
230 ir_function_signature *const sig = new(ctx) ir_function_signature(this);
231 f->add_signature(sig);
232
233 ir_variable **declarations =
234 (ir_variable **) malloc(sizeof(ir_variable *) * this->length);
235 for (unsigned i = 0; i < length; i++) {
236 char *const param_name = (char *) malloc(10);
237
238 snprintf(param_name, 10, "p%08X", i);
239
240 ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
241 ? new(ctx) ir_variable(fields.array, param_name)
242 : new(ctx) ir_variable(fields.structure[i].type, param_name);
243
244 var->mode = ir_var_in;
245 declarations[i] = var;
246 sig->parameters.push_tail(var);
247 }
248
249 /* Generate the body of the constructor. The body assigns each of the
250 * parameters to a portion of a local variable called __retval that has
251 * the same type as the constructor. After initializing __retval,
252 * __retval is returned.
253 */
254 ir_variable *retval = new(ctx) ir_variable(this, "__retval");
255 sig->body.push_tail(retval);
256
257 for (unsigned i = 0; i < length; i++) {
258 ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
259 ? (ir_dereference *) new(ctx) ir_dereference_array(retval,
260 new(ctx) ir_constant(i))
261 : (ir_dereference *) new(ctx) ir_dereference_record(retval,
262 fields.structure[i].name);
263
264 ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
265 ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL);
266
267 sig->body.push_tail(assign);
268 }
269
270 free(declarations);
271
272 ir_dereference *const retref = new(ctx) ir_dereference_variable(retval);
273 ir_instruction *const inst = new(ctx) ir_return(retref);
274 sig->body.push_tail(inst);
275
276 return f;
277 }
278
279
280 glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) :
281 base_type(GLSL_TYPE_ARRAY),
282 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
283 sampler_type(0),
284 vector_elements(0), matrix_columns(0),
285 name(NULL), length(length)
286 {
287 this->fields.array = array;
288 /* Inherit the gl type of the base. The GL type is used for
289 * uniform/statevar handling in Mesa and the arrayness of the type
290 * is represented by the size rather than the type.
291 */
292 this->gl_type = array->gl_type;
293
294 /* Allow a maximum of 10 characters for the array size. This is enough
295 * for 32-bits of ~0. The extra 3 are for the '[', ']', and terminating
296 * NUL.
297 */
298 const unsigned name_length = strlen(array->name) + 10 + 3;
299 char *const n = (char *) talloc_size(ctx, name_length);
300
301 if (length == 0)
302 snprintf(n, name_length, "%s[]", array->name);
303 else
304 snprintf(n, name_length, "%s[%u]", array->name, length);
305
306 this->name = n;
307 }
308
309
310 const glsl_type *
311 glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
312 {
313 if (base_type == GLSL_TYPE_VOID)
314 return &void_type;
315
316 if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
317 return error_type;
318
319 /* Treat GLSL vectors as Nx1 matrices.
320 */
321 if (columns == 1) {
322 switch (base_type) {
323 case GLSL_TYPE_UINT:
324 return uint_type + (rows - 1);
325 case GLSL_TYPE_INT:
326 return int_type + (rows - 1);
327 case GLSL_TYPE_FLOAT:
328 return float_type + (rows - 1);
329 case GLSL_TYPE_BOOL:
330 return bool_type + (rows - 1);
331 default:
332 return error_type;
333 }
334 } else {
335 if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
336 return error_type;
337
338 /* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following
339 * combinations are valid:
340 *
341 * 1 2 3 4
342 * 1
343 * 2 x x x
344 * 3 x x x
345 * 4 x x x
346 */
347 #define IDX(c,r) (((c-1)*3) + (r-1))
348
349 switch (IDX(columns, rows)) {
350 case IDX(2,2): return mat2_type;
351 case IDX(2,3): return mat2x3_type;
352 case IDX(2,4): return mat2x4_type;
353 case IDX(3,2): return mat3x2_type;
354 case IDX(3,3): return mat3_type;
355 case IDX(3,4): return mat3x4_type;
356 case IDX(4,2): return mat4x2_type;
357 case IDX(4,3): return mat4x3_type;
358 case IDX(4,4): return mat4_type;
359 default: return error_type;
360 }
361 }
362
363 assert(!"Should not get here.");
364 return error_type;
365 }
366
367
368 int
369 glsl_type::array_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 return ((key1->fields.array == key2->fields.array)
378 && (key1->length == key2->length)) ? 0 : 1;
379 }
380
381
382 unsigned
383 glsl_type::array_key_hash(const void *a)
384 {
385 const glsl_type *const key = (glsl_type *) a;
386
387 const struct {
388 const glsl_type *t;
389 unsigned l;
390 char nul;
391 } hash_key = {
392 key->fields.array,
393 key->length,
394 '\0'
395 };
396
397 return hash_table_string_hash(& hash_key);
398 }
399
400
401 const glsl_type *
402 glsl_type::get_array_instance(void *ctx, const glsl_type *base,
403 unsigned array_size)
404 {
405 const glsl_type key(ctx, base, array_size);
406
407 if (array_types == NULL) {
408 array_types = hash_table_ctor(64, array_key_hash, array_key_compare);
409 }
410
411 const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key);
412 if (t == NULL) {
413 t = new glsl_type(ctx, base, array_size);
414
415 hash_table_insert(array_types, (void *) t, t);
416 }
417
418 assert(t->base_type == GLSL_TYPE_ARRAY);
419 assert(t->length == array_size);
420 assert(t->fields.array == base);
421
422 return t;
423 }
424
425
426 int
427 glsl_type::record_key_compare(const void *a, const void *b)
428 {
429 const glsl_type *const key1 = (glsl_type *) a;
430 const glsl_type *const key2 = (glsl_type *) b;
431
432 /* Return zero is the types match (there is zero difference) or non-zero
433 * otherwise.
434 */
435 if (strcmp(key1->name, key2->name) != 0)
436 return 1;
437
438 if (key1->length != key2->length)
439 return 1;
440
441 for (unsigned i = 0; i < key1->length; i++) {
442 if (key1->fields.structure[i].type != key2->fields.structure[i].type)
443 return 1;
444 if (strcmp(key1->fields.structure[i].name,
445 key2->fields.structure[i].name) != 0)
446 return 1;
447 }
448
449 return 0;
450 }
451
452
453 unsigned
454 glsl_type::record_key_hash(const void *a)
455 {
456 const glsl_type *const key = (glsl_type *) a;
457 char hash_key[128];
458 unsigned size = 0;
459
460 size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
461
462 for (unsigned i = 0; i < key->length; i++) {
463 if (size >= sizeof(hash_key))
464 break;
465
466 size += snprintf(& hash_key[size], sizeof(hash_key) - size,
467 "%p", key->fields.structure[i].type);
468 }
469
470 return hash_table_string_hash(& hash_key);
471 }
472
473
474 const glsl_type *
475 glsl_type::get_record_instance(const glsl_struct_field *fields,
476 unsigned num_fields,
477 const char *name)
478 {
479 const glsl_type key(fields, num_fields, name);
480
481 if (record_types == NULL) {
482 record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
483 }
484
485 const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
486 if (t == NULL) {
487 t = new glsl_type(fields, num_fields, name);
488
489 hash_table_insert(record_types, (void *) t, t);
490 }
491
492 assert(t->base_type == GLSL_TYPE_STRUCT);
493 assert(t->length == num_fields);
494 assert(strcmp(t->name, name) == 0);
495
496 return t;
497 }
498
499
500 const glsl_type *
501 glsl_type::field_type(const char *name) const
502 {
503 if (this->base_type != GLSL_TYPE_STRUCT)
504 return error_type;
505
506 for (unsigned i = 0; i < this->length; i++) {
507 if (strcmp(name, this->fields.structure[i].name) == 0)
508 return this->fields.structure[i].type;
509 }
510
511 return error_type;
512 }
513
514
515 int
516 glsl_type::field_index(const char *name) const
517 {
518 if (this->base_type != GLSL_TYPE_STRUCT)
519 return -1;
520
521 for (unsigned i = 0; i < this->length; i++) {
522 if (strcmp(name, this->fields.structure[i].name) == 0)
523 return i;
524 }
525
526 return -1;
527 }
528
529
530 unsigned
531 glsl_type::component_slots() const
532 {
533 switch (this->base_type) {
534 case GLSL_TYPE_UINT:
535 case GLSL_TYPE_INT:
536 case GLSL_TYPE_FLOAT:
537 case GLSL_TYPE_BOOL:
538 return this->components();
539
540 case GLSL_TYPE_STRUCT: {
541 unsigned size = 0;
542
543 for (unsigned i = 0; i < this->length; i++)
544 size += this->fields.structure[i].type->component_slots();
545
546 return size;
547 }
548
549 case GLSL_TYPE_ARRAY:
550 return this->length * this->fields.array->component_slots();
551
552 default:
553 return 0;
554 }
555 }