glsl: Add simple vector type accessor helpers.
[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 <stdio.h>
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"
31 extern "C" {
32 #include "program/hash_table.h"
33 }
34
35 hash_table *glsl_type::array_types = NULL;
36 hash_table *glsl_type::record_types = NULL;
37 hash_table *glsl_type::interface_types = NULL;
38 void *glsl_type::mem_ctx = NULL;
39
40 void
41 glsl_type::init_ralloc_type_ctx(void)
42 {
43 if (glsl_type::mem_ctx == NULL) {
44 glsl_type::mem_ctx = ralloc_autofree_context();
45 assert(glsl_type::mem_ctx != NULL);
46 }
47 }
48
49 glsl_type::glsl_type(GLenum gl_type,
50 glsl_base_type base_type, unsigned vector_elements,
51 unsigned matrix_columns, const char *name) :
52 gl_type(gl_type),
53 base_type(base_type),
54 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
55 sampler_type(0), interface_packing(0),
56 vector_elements(vector_elements), matrix_columns(matrix_columns),
57 length(0)
58 {
59 init_ralloc_type_ctx();
60 assert(name != NULL);
61 this->name = ralloc_strdup(this->mem_ctx, name);
62 /* Neither dimension is zero or both dimensions are zero.
63 */
64 assert((vector_elements == 0) == (matrix_columns == 0));
65 memset(& fields, 0, sizeof(fields));
66 }
67
68 glsl_type::glsl_type(GLenum gl_type,
69 enum glsl_sampler_dim dim, bool shadow, bool array,
70 unsigned type, const char *name) :
71 gl_type(gl_type),
72 base_type(GLSL_TYPE_SAMPLER),
73 sampler_dimensionality(dim), sampler_shadow(shadow),
74 sampler_array(array), sampler_type(type), interface_packing(0),
75 vector_elements(0), matrix_columns(0),
76 length(0)
77 {
78 init_ralloc_type_ctx();
79 assert(name != NULL);
80 this->name = ralloc_strdup(this->mem_ctx, name);
81 memset(& fields, 0, sizeof(fields));
82 }
83
84 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
85 const char *name) :
86 gl_type(0),
87 base_type(GLSL_TYPE_STRUCT),
88 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
89 sampler_type(0), interface_packing(0),
90 vector_elements(0), matrix_columns(0),
91 length(num_fields)
92 {
93 unsigned int i;
94
95 init_ralloc_type_ctx();
96 assert(name != NULL);
97 this->name = ralloc_strdup(this->mem_ctx, name);
98 this->fields.structure = ralloc_array(this->mem_ctx,
99 glsl_struct_field, length);
100 for (i = 0; i < length; i++) {
101 this->fields.structure[i].type = fields[i].type;
102 this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
103 fields[i].name);
104 this->fields.structure[i].row_major = fields[i].row_major;
105 }
106 }
107
108 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
109 enum glsl_interface_packing packing, const char *name) :
110 gl_type(0),
111 base_type(GLSL_TYPE_INTERFACE),
112 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
113 sampler_type(0), interface_packing((unsigned) packing),
114 vector_elements(0), matrix_columns(0),
115 length(num_fields)
116 {
117 unsigned int i;
118
119 init_ralloc_type_ctx();
120 assert(name != NULL);
121 this->name = ralloc_strdup(this->mem_ctx, name);
122 this->fields.structure = ralloc_array(this->mem_ctx,
123 glsl_struct_field, length);
124 for (i = 0; i < length; i++) {
125 this->fields.structure[i].type = fields[i].type;
126 this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
127 fields[i].name);
128 this->fields.structure[i].row_major = fields[i].row_major;
129 }
130 }
131
132 static void
133 add_types_to_symbol_table(glsl_symbol_table *symtab,
134 const struct glsl_type *types,
135 unsigned num_types, bool warn,
136 bool skip_1d)
137 {
138 (void) warn;
139
140 for (unsigned i = 0; i < num_types; i++) {
141 if (skip_1d && types[i].base_type == GLSL_TYPE_SAMPLER
142 && types[i].sampler_dimensionality == GLSL_SAMPLER_DIM_1D)
143 continue;
144
145 symtab->add_type(types[i].name, & types[i]);
146 }
147 }
148
149 bool
150 glsl_type::contains_sampler() const
151 {
152 if (this->is_array()) {
153 return this->fields.array->contains_sampler();
154 } else if (this->is_record()) {
155 for (unsigned int i = 0; i < this->length; i++) {
156 if (this->fields.structure[i].type->contains_sampler())
157 return true;
158 }
159 return false;
160 } else {
161 return this->is_sampler();
162 }
163 }
164
165
166 bool
167 glsl_type::contains_integer() const
168 {
169 if (this->is_array()) {
170 return this->fields.array->contains_integer();
171 } else if (this->is_record()) {
172 for (unsigned int i = 0; i < this->length; i++) {
173 if (this->fields.structure[i].type->contains_integer())
174 return true;
175 }
176 return false;
177 } else {
178 return this->is_integer();
179 }
180 }
181
182
183 gl_texture_index
184 glsl_type::sampler_index() const
185 {
186 const glsl_type *const t = (this->is_array()) ? this->fields.array : this;
187
188 assert(t->is_sampler());
189
190 switch (t->sampler_dimensionality) {
191 case GLSL_SAMPLER_DIM_1D:
192 return (t->sampler_array) ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
193 case GLSL_SAMPLER_DIM_2D:
194 return (t->sampler_array) ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
195 case GLSL_SAMPLER_DIM_3D:
196 return TEXTURE_3D_INDEX;
197 case GLSL_SAMPLER_DIM_CUBE:
198 return (t->sampler_array) ? TEXTURE_CUBE_ARRAY_INDEX : TEXTURE_CUBE_INDEX;
199 case GLSL_SAMPLER_DIM_RECT:
200 return TEXTURE_RECT_INDEX;
201 case GLSL_SAMPLER_DIM_BUF:
202 return TEXTURE_BUFFER_INDEX;
203 case GLSL_SAMPLER_DIM_EXTERNAL:
204 return TEXTURE_EXTERNAL_INDEX;
205 case GLSL_SAMPLER_DIM_MS:
206 return (t->sampler_array) ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX;
207 default:
208 assert(!"Should not get here.");
209 return TEXTURE_BUFFER_INDEX;
210 }
211 }
212
213 void
214 glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
215 {
216 bool skip_1d = false;
217 add_types_to_symbol_table(symtab, builtin_core_types,
218 Elements(builtin_core_types),
219 false, skip_1d);
220 add_types_to_symbol_table(symtab, builtin_structure_types,
221 Elements(builtin_structure_types),
222 false, skip_1d);
223 add_types_to_symbol_table(symtab, void_type, 1, false, skip_1d);
224 }
225
226 void
227 glsl_type::generate_300ES_types(glsl_symbol_table *symtab)
228 {
229 /* GLSL 3.00 ES types are the same as GLSL 1.30 types, except that 1D
230 * samplers are skipped, and samplerCubeShadow is added.
231 */
232 bool add_deprecated = false;
233 bool skip_1d = true;
234
235 generate_130_types(symtab, add_deprecated, skip_1d);
236
237 add_types_to_symbol_table(symtab, &_samplerCubeShadow_type, 1, false,
238 skip_1d);
239 }
240
241 void
242 glsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated,
243 bool skip_1d)
244 {
245 generate_100ES_types(symtab);
246
247 add_types_to_symbol_table(symtab, builtin_110_types,
248 Elements(builtin_110_types),
249 false, skip_1d);
250 add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false, skip_1d);
251 if (add_deprecated) {
252 add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
253 Elements(builtin_110_deprecated_structure_types),
254 false, skip_1d);
255 }
256 }
257
258
259 void
260 glsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated,
261 bool skip_1d)
262 {
263 generate_110_types(symtab, add_deprecated, skip_1d);
264
265 add_types_to_symbol_table(symtab, builtin_120_types,
266 Elements(builtin_120_types), false, skip_1d);
267 }
268
269
270 void
271 glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated,
272 bool skip_1d)
273 {
274 generate_120_types(symtab, add_deprecated, skip_1d);
275
276 add_types_to_symbol_table(symtab, builtin_130_types,
277 Elements(builtin_130_types), false, skip_1d);
278 generate_EXT_texture_array_types(symtab, false);
279 }
280
281
282 void
283 glsl_type::generate_140_types(glsl_symbol_table *symtab)
284 {
285 bool skip_1d = false;
286
287 generate_130_types(symtab, false, skip_1d);
288
289 add_types_to_symbol_table(symtab, builtin_140_types,
290 Elements(builtin_140_types), false, skip_1d);
291
292 add_types_to_symbol_table(symtab, builtin_EXT_texture_buffer_object_types,
293 Elements(builtin_EXT_texture_buffer_object_types),
294 false, skip_1d);
295 }
296
297
298 void
299 glsl_type::generate_150_types(glsl_symbol_table *symtab)
300 {
301 generate_140_types(symtab);
302 generate_ARB_texture_multisample_types(symtab, false);
303 }
304
305
306 void
307 glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
308 bool warn)
309 {
310 bool skip_1d = false;
311
312 add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
313 Elements(builtin_ARB_texture_rectangle_types),
314 warn, skip_1d);
315 }
316
317
318 void
319 glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
320 bool warn)
321 {
322 bool skip_1d = false;
323
324 add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
325 Elements(builtin_EXT_texture_array_types),
326 warn, skip_1d);
327 }
328
329
330 void
331 glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn)
332 {
333 bool skip_1d = false;
334
335 add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn, skip_1d);
336 }
337
338
339 void
340 glsl_type::generate_OES_EGL_image_external_types(glsl_symbol_table *symtab,
341 bool warn)
342 {
343 bool skip_1d = false;
344
345 add_types_to_symbol_table(symtab, builtin_OES_EGL_image_external_types,
346 Elements(builtin_OES_EGL_image_external_types),
347 warn, skip_1d);
348 }
349
350 void
351 glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab,
352 bool warn)
353 {
354 bool skip_1d = false;
355
356 add_types_to_symbol_table(symtab, builtin_ARB_texture_cube_map_array_types,
357 Elements(builtin_ARB_texture_cube_map_array_types),
358 warn, skip_1d);
359 }
360
361 void
362 glsl_type::generate_ARB_texture_multisample_types(glsl_symbol_table *symtab,
363 bool warn)
364 {
365 bool skip_1d = false;
366 add_types_to_symbol_table(symtab, builtin_ARB_texture_multisample_types,
367 Elements(builtin_ARB_texture_multisample_types),
368 warn, skip_1d);
369 }
370
371 void
372 _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
373 {
374 if (state->es_shader) {
375 switch (state->language_version) {
376 case 100:
377 assert(state->es_shader);
378 glsl_type::generate_100ES_types(state->symbols);
379 break;
380 case 300:
381 glsl_type::generate_300ES_types(state->symbols);
382 break;
383 default:
384 assert(!"Unexpected language version");
385 break;
386 }
387 } else {
388 bool skip_1d = false;
389 switch (state->language_version) {
390 case 110:
391 glsl_type::generate_110_types(state->symbols, true, skip_1d);
392 break;
393 case 120:
394 glsl_type::generate_120_types(state->symbols, true, skip_1d);
395 break;
396 case 130:
397 glsl_type::generate_130_types(state->symbols, true, skip_1d);
398 break;
399 case 140:
400 glsl_type::generate_140_types(state->symbols);
401 break;
402 case 150:
403 glsl_type::generate_150_types(state->symbols);
404 break;
405 default:
406 assert(!"Unexpected language version");
407 break;
408 }
409 }
410
411 if (state->ARB_texture_rectangle_enable ||
412 state->is_version(140, 0)) {
413 glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
414 state->ARB_texture_rectangle_warn);
415 }
416 if (state->OES_texture_3D_enable
417 && state->is_version(0, 100)) {
418 glsl_type::generate_OES_texture_3D_types(state->symbols,
419 state->OES_texture_3D_warn);
420 }
421
422 if (state->EXT_texture_array_enable
423 && !state->is_version(130, 0)) {
424 // These are already included in 130; don't create twice.
425 glsl_type::generate_EXT_texture_array_types(state->symbols,
426 state->EXT_texture_array_warn);
427 }
428
429 /* We cannot check for language_version == 100 here because we need the
430 * types to support fixed-function program generation. But this is fine
431 * since the extension is never enabled for OpenGL contexts.
432 */
433 if (state->OES_EGL_image_external_enable) {
434 glsl_type::generate_OES_EGL_image_external_types(state->symbols,
435 state->OES_EGL_image_external_warn);
436 }
437
438 if (state->ARB_texture_cube_map_array_enable) {
439 glsl_type::generate_ARB_texture_cube_map_array_types(state->symbols,
440 state->ARB_texture_cube_map_array_warn);
441 }
442
443 if (state->ARB_texture_multisample_enable) {
444 glsl_type::generate_ARB_texture_multisample_types(state->symbols,
445 state->ARB_texture_multisample_warn);
446 }
447 }
448
449
450 const glsl_type *glsl_type::get_base_type() const
451 {
452 switch (base_type) {
453 case GLSL_TYPE_UINT:
454 return uint_type;
455 case GLSL_TYPE_INT:
456 return int_type;
457 case GLSL_TYPE_FLOAT:
458 return float_type;
459 case GLSL_TYPE_BOOL:
460 return bool_type;
461 default:
462 return error_type;
463 }
464 }
465
466
467 const glsl_type *glsl_type::get_scalar_type() const
468 {
469 const glsl_type *type = this;
470
471 /* Handle arrays */
472 while (type->base_type == GLSL_TYPE_ARRAY)
473 type = type->fields.array;
474
475 /* Handle vectors and matrices */
476 switch (type->base_type) {
477 case GLSL_TYPE_UINT:
478 return uint_type;
479 case GLSL_TYPE_INT:
480 return int_type;
481 case GLSL_TYPE_FLOAT:
482 return float_type;
483 case GLSL_TYPE_BOOL:
484 return bool_type;
485 default:
486 /* Handle everything else */
487 return type;
488 }
489 }
490
491
492 void
493 _mesa_glsl_release_types(void)
494 {
495 if (glsl_type::array_types != NULL) {
496 hash_table_dtor(glsl_type::array_types);
497 glsl_type::array_types = NULL;
498 }
499
500 if (glsl_type::record_types != NULL) {
501 hash_table_dtor(glsl_type::record_types);
502 glsl_type::record_types = NULL;
503 }
504 }
505
506
507 glsl_type::glsl_type(const glsl_type *array, unsigned length) :
508 base_type(GLSL_TYPE_ARRAY),
509 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
510 sampler_type(0), interface_packing(0),
511 vector_elements(0), matrix_columns(0),
512 name(NULL), length(length)
513 {
514 this->fields.array = array;
515 /* Inherit the gl type of the base. The GL type is used for
516 * uniform/statevar handling in Mesa and the arrayness of the type
517 * is represented by the size rather than the type.
518 */
519 this->gl_type = array->gl_type;
520
521 /* Allow a maximum of 10 characters for the array size. This is enough
522 * for 32-bits of ~0. The extra 3 are for the '[', ']', and terminating
523 * NUL.
524 */
525 const unsigned name_length = strlen(array->name) + 10 + 3;
526 char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
527
528 if (length == 0)
529 snprintf(n, name_length, "%s[]", array->name);
530 else
531 snprintf(n, name_length, "%s[%u]", array->name, length);
532
533 this->name = n;
534 }
535
536
537 const glsl_type *const
538 glsl_type::vec(unsigned components)
539 {
540 if (components == 0 || components > 4)
541 return error_type;
542
543 static const glsl_type *const ts[] = {
544 float_type, vec2_type, vec3_type, vec4_type
545 };
546 return ts[components - 1];
547 }
548
549
550 const glsl_type *const
551 glsl_type::ivec(unsigned components)
552 {
553 if (components == 0 || components > 4)
554 return error_type;
555
556 static const glsl_type *const ts[] = {
557 int_type, ivec2_type, ivec3_type, ivec4_type
558 };
559 return ts[components - 1];
560 }
561
562
563 const glsl_type *const
564 glsl_type::uvec(unsigned components)
565 {
566 if (components == 0 || components > 4)
567 return error_type;
568
569 static const glsl_type *const ts[] = {
570 uint_type, uvec2_type, uvec3_type, uvec4_type
571 };
572 return ts[components - 1];
573 }
574
575
576 const glsl_type *const
577 glsl_type::bvec(unsigned components)
578 {
579 if (components == 0 || components > 4)
580 return error_type;
581
582 static const glsl_type *const ts[] = {
583 bool_type, bvec2_type, bvec3_type, bvec4_type
584 };
585 return ts[components - 1];
586 }
587
588
589 const glsl_type *
590 glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
591 {
592 if (base_type == GLSL_TYPE_VOID)
593 return void_type;
594
595 if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
596 return error_type;
597
598 /* Treat GLSL vectors as Nx1 matrices.
599 */
600 if (columns == 1) {
601 switch (base_type) {
602 case GLSL_TYPE_UINT:
603 return uint_type + (rows - 1);
604 case GLSL_TYPE_INT:
605 return int_type + (rows - 1);
606 case GLSL_TYPE_FLOAT:
607 return float_type + (rows - 1);
608 case GLSL_TYPE_BOOL:
609 return bool_type + (rows - 1);
610 default:
611 return error_type;
612 }
613 } else {
614 if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
615 return error_type;
616
617 /* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following
618 * combinations are valid:
619 *
620 * 1 2 3 4
621 * 1
622 * 2 x x x
623 * 3 x x x
624 * 4 x x x
625 */
626 #define IDX(c,r) (((c-1)*3) + (r-1))
627
628 switch (IDX(columns, rows)) {
629 case IDX(2,2): return mat2_type;
630 case IDX(2,3): return mat2x3_type;
631 case IDX(2,4): return mat2x4_type;
632 case IDX(3,2): return mat3x2_type;
633 case IDX(3,3): return mat3_type;
634 case IDX(3,4): return mat3x4_type;
635 case IDX(4,2): return mat4x2_type;
636 case IDX(4,3): return mat4x3_type;
637 case IDX(4,4): return mat4_type;
638 default: return error_type;
639 }
640 }
641
642 assert(!"Should not get here.");
643 return error_type;
644 }
645
646
647 const glsl_type *
648 glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
649 {
650
651 if (array_types == NULL) {
652 array_types = hash_table_ctor(64, hash_table_string_hash,
653 hash_table_string_compare);
654 }
655
656 /* Generate a name using the base type pointer in the key. This is
657 * done because the name of the base type may not be unique across
658 * shaders. For example, two shaders may have different record types
659 * named 'foo'.
660 */
661 char key[128];
662 snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
663
664 const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
665 if (t == NULL) {
666 t = new glsl_type(base, array_size);
667
668 hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key));
669 }
670
671 assert(t->base_type == GLSL_TYPE_ARRAY);
672 assert(t->length == array_size);
673 assert(t->fields.array == base);
674
675 return t;
676 }
677
678
679 int
680 glsl_type::record_key_compare(const void *a, const void *b)
681 {
682 const glsl_type *const key1 = (glsl_type *) a;
683 const glsl_type *const key2 = (glsl_type *) b;
684
685 /* Return zero is the types match (there is zero difference) or non-zero
686 * otherwise.
687 */
688 if (strcmp(key1->name, key2->name) != 0)
689 return 1;
690
691 if (key1->length != key2->length)
692 return 1;
693
694 if (key1->interface_packing != key2->interface_packing)
695 return 1;
696
697 for (unsigned i = 0; i < key1->length; i++) {
698 if (key1->fields.structure[i].type != key2->fields.structure[i].type)
699 return 1;
700 if (strcmp(key1->fields.structure[i].name,
701 key2->fields.structure[i].name) != 0)
702 return 1;
703 if (key1->fields.structure[i].row_major
704 != key2->fields.structure[i].row_major)
705 return 1;
706 }
707
708 return 0;
709 }
710
711
712 unsigned
713 glsl_type::record_key_hash(const void *a)
714 {
715 const glsl_type *const key = (glsl_type *) a;
716 char hash_key[128];
717 unsigned size = 0;
718
719 size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
720
721 for (unsigned i = 0; i < key->length; i++) {
722 if (size >= sizeof(hash_key))
723 break;
724
725 size += snprintf(& hash_key[size], sizeof(hash_key) - size,
726 "%p", (void *) key->fields.structure[i].type);
727 }
728
729 return hash_table_string_hash(& hash_key);
730 }
731
732
733 const glsl_type *
734 glsl_type::get_record_instance(const glsl_struct_field *fields,
735 unsigned num_fields,
736 const char *name)
737 {
738 const glsl_type key(fields, num_fields, name);
739
740 if (record_types == NULL) {
741 record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
742 }
743
744 const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
745 if (t == NULL) {
746 t = new glsl_type(fields, num_fields, name);
747
748 hash_table_insert(record_types, (void *) t, t);
749 }
750
751 assert(t->base_type == GLSL_TYPE_STRUCT);
752 assert(t->length == num_fields);
753 assert(strcmp(t->name, name) == 0);
754
755 return t;
756 }
757
758
759 const glsl_type *
760 glsl_type::get_interface_instance(const glsl_struct_field *fields,
761 unsigned num_fields,
762 enum glsl_interface_packing packing,
763 const char *name)
764 {
765 const glsl_type key(fields, num_fields, packing, name);
766
767 if (interface_types == NULL) {
768 interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
769 }
770
771 const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
772 if (t == NULL) {
773 t = new glsl_type(fields, num_fields, packing, name);
774
775 hash_table_insert(interface_types, (void *) t, t);
776 }
777
778 assert(t->base_type == GLSL_TYPE_INTERFACE);
779 assert(t->length == num_fields);
780 assert(strcmp(t->name, name) == 0);
781
782 return t;
783 }
784
785
786 const glsl_type *
787 glsl_type::field_type(const char *name) const
788 {
789 if (this->base_type != GLSL_TYPE_STRUCT
790 && this->base_type != GLSL_TYPE_INTERFACE)
791 return error_type;
792
793 for (unsigned i = 0; i < this->length; i++) {
794 if (strcmp(name, this->fields.structure[i].name) == 0)
795 return this->fields.structure[i].type;
796 }
797
798 return error_type;
799 }
800
801
802 int
803 glsl_type::field_index(const char *name) const
804 {
805 if (this->base_type != GLSL_TYPE_STRUCT
806 && this->base_type != GLSL_TYPE_INTERFACE)
807 return -1;
808
809 for (unsigned i = 0; i < this->length; i++) {
810 if (strcmp(name, this->fields.structure[i].name) == 0)
811 return i;
812 }
813
814 return -1;
815 }
816
817
818 unsigned
819 glsl_type::component_slots() const
820 {
821 switch (this->base_type) {
822 case GLSL_TYPE_UINT:
823 case GLSL_TYPE_INT:
824 case GLSL_TYPE_FLOAT:
825 case GLSL_TYPE_BOOL:
826 return this->components();
827
828 case GLSL_TYPE_STRUCT:
829 case GLSL_TYPE_INTERFACE: {
830 unsigned size = 0;
831
832 for (unsigned i = 0; i < this->length; i++)
833 size += this->fields.structure[i].type->component_slots();
834
835 return size;
836 }
837
838 case GLSL_TYPE_ARRAY:
839 return this->length * this->fields.array->component_slots();
840
841 case GLSL_TYPE_SAMPLER:
842 case GLSL_TYPE_VOID:
843 case GLSL_TYPE_ERROR:
844 break;
845 }
846
847 return 0;
848 }
849
850 bool
851 glsl_type::can_implicitly_convert_to(const glsl_type *desired) const
852 {
853 if (this == desired)
854 return true;
855
856 /* There is no conversion among matrix types. */
857 if (this->matrix_columns > 1 || desired->matrix_columns > 1)
858 return false;
859
860 /* int and uint can be converted to float. */
861 return desired->is_float()
862 && this->is_integer()
863 && this->vector_elements == desired->vector_elements;
864 }
865
866 unsigned
867 glsl_type::std140_base_alignment(bool row_major) const
868 {
869 /* (1) If the member is a scalar consuming <N> basic machine units, the
870 * base alignment is <N>.
871 *
872 * (2) If the member is a two- or four-component vector with components
873 * consuming <N> basic machine units, the base alignment is 2<N> or
874 * 4<N>, respectively.
875 *
876 * (3) If the member is a three-component vector with components consuming
877 * <N> basic machine units, the base alignment is 4<N>.
878 */
879 if (this->is_scalar() || this->is_vector()) {
880 switch (this->vector_elements) {
881 case 1:
882 return 4;
883 case 2:
884 return 8;
885 case 3:
886 case 4:
887 return 16;
888 }
889 }
890
891 /* (4) If the member is an array of scalars or vectors, the base alignment
892 * and array stride are set to match the base alignment of a single
893 * array element, according to rules (1), (2), and (3), and rounded up
894 * to the base alignment of a vec4. The array may have padding at the
895 * end; the base offset of the member following the array is rounded up
896 * to the next multiple of the base alignment.
897 *
898 * (6) If the member is an array of <S> column-major matrices with <C>
899 * columns and <R> rows, the matrix is stored identically to a row of
900 * <S>*<C> column vectors with <R> components each, according to rule
901 * (4).
902 *
903 * (8) If the member is an array of <S> row-major matrices with <C> columns
904 * and <R> rows, the matrix is stored identically to a row of <S>*<R>
905 * row vectors with <C> components each, according to rule (4).
906 *
907 * (10) If the member is an array of <S> structures, the <S> elements of
908 * the array are laid out in order, according to rule (9).
909 */
910 if (this->is_array()) {
911 if (this->fields.array->is_scalar() ||
912 this->fields.array->is_vector() ||
913 this->fields.array->is_matrix()) {
914 return MAX2(this->fields.array->std140_base_alignment(row_major), 16);
915 } else {
916 assert(this->fields.array->is_record());
917 return this->fields.array->std140_base_alignment(row_major);
918 }
919 }
920
921 /* (5) If the member is a column-major matrix with <C> columns and
922 * <R> rows, the matrix is stored identically to an array of
923 * <C> column vectors with <R> components each, according to
924 * rule (4).
925 *
926 * (7) If the member is a row-major matrix with <C> columns and <R>
927 * rows, the matrix is stored identically to an array of <R>
928 * row vectors with <C> components each, according to rule (4).
929 */
930 if (this->is_matrix()) {
931 const struct glsl_type *vec_type, *array_type;
932 int c = this->matrix_columns;
933 int r = this->vector_elements;
934
935 if (row_major) {
936 vec_type = get_instance(GLSL_TYPE_FLOAT, c, 1);
937 array_type = glsl_type::get_array_instance(vec_type, r);
938 } else {
939 vec_type = get_instance(GLSL_TYPE_FLOAT, r, 1);
940 array_type = glsl_type::get_array_instance(vec_type, c);
941 }
942
943 return array_type->std140_base_alignment(false);
944 }
945
946 /* (9) If the member is a structure, the base alignment of the
947 * structure is <N>, where <N> is the largest base alignment
948 * value of any of its members, and rounded up to the base
949 * alignment of a vec4. The individual members of this
950 * sub-structure are then assigned offsets by applying this set
951 * of rules recursively, where the base offset of the first
952 * member of the sub-structure is equal to the aligned offset
953 * of the structure. The structure may have padding at the end;
954 * the base offset of the member following the sub-structure is
955 * rounded up to the next multiple of the base alignment of the
956 * structure.
957 */
958 if (this->is_record()) {
959 unsigned base_alignment = 16;
960 for (unsigned i = 0; i < this->length; i++) {
961 const struct glsl_type *field_type = this->fields.structure[i].type;
962 base_alignment = MAX2(base_alignment,
963 field_type->std140_base_alignment(row_major));
964 }
965 return base_alignment;
966 }
967
968 assert(!"not reached");
969 return -1;
970 }
971
972 unsigned
973 glsl_type::std140_size(bool row_major) const
974 {
975 /* (1) If the member is a scalar consuming <N> basic machine units, the
976 * base alignment is <N>.
977 *
978 * (2) If the member is a two- or four-component vector with components
979 * consuming <N> basic machine units, the base alignment is 2<N> or
980 * 4<N>, respectively.
981 *
982 * (3) If the member is a three-component vector with components consuming
983 * <N> basic machine units, the base alignment is 4<N>.
984 */
985 if (this->is_scalar() || this->is_vector()) {
986 return this->vector_elements * 4;
987 }
988
989 /* (5) If the member is a column-major matrix with <C> columns and
990 * <R> rows, the matrix is stored identically to an array of
991 * <C> column vectors with <R> components each, according to
992 * rule (4).
993 *
994 * (6) If the member is an array of <S> column-major matrices with <C>
995 * columns and <R> rows, the matrix is stored identically to a row of
996 * <S>*<C> column vectors with <R> components each, according to rule
997 * (4).
998 *
999 * (7) If the member is a row-major matrix with <C> columns and <R>
1000 * rows, the matrix is stored identically to an array of <R>
1001 * row vectors with <C> components each, according to rule (4).
1002 *
1003 * (8) If the member is an array of <S> row-major matrices with <C> columns
1004 * and <R> rows, the matrix is stored identically to a row of <S>*<R>
1005 * row vectors with <C> components each, according to rule (4).
1006 */
1007 if (this->is_matrix() || (this->is_array() &&
1008 this->fields.array->is_matrix())) {
1009 const struct glsl_type *element_type;
1010 const struct glsl_type *vec_type;
1011 unsigned int array_len;
1012
1013 if (this->is_array()) {
1014 element_type = this->fields.array;
1015 array_len = this->length;
1016 } else {
1017 element_type = this;
1018 array_len = 1;
1019 }
1020
1021 if (row_major) {
1022 vec_type = get_instance(GLSL_TYPE_FLOAT,
1023 element_type->matrix_columns, 1);
1024 array_len *= element_type->vector_elements;
1025 } else {
1026 vec_type = get_instance(GLSL_TYPE_FLOAT,
1027 element_type->vector_elements, 1);
1028 array_len *= element_type->matrix_columns;
1029 }
1030 const glsl_type *array_type = glsl_type::get_array_instance(vec_type,
1031 array_len);
1032
1033 return array_type->std140_size(false);
1034 }
1035
1036 /* (4) If the member is an array of scalars or vectors, the base alignment
1037 * and array stride are set to match the base alignment of a single
1038 * array element, according to rules (1), (2), and (3), and rounded up
1039 * to the base alignment of a vec4. The array may have padding at the
1040 * end; the base offset of the member following the array is rounded up
1041 * to the next multiple of the base alignment.
1042 *
1043 * (10) If the member is an array of <S> structures, the <S> elements of
1044 * the array are laid out in order, according to rule (9).
1045 */
1046 if (this->is_array()) {
1047 if (this->fields.array->is_record()) {
1048 return this->length * this->fields.array->std140_size(row_major);
1049 } else {
1050 unsigned element_base_align =
1051 this->fields.array->std140_base_alignment(row_major);
1052 return this->length * MAX2(element_base_align, 16);
1053 }
1054 }
1055
1056 /* (9) If the member is a structure, the base alignment of the
1057 * structure is <N>, where <N> is the largest base alignment
1058 * value of any of its members, and rounded up to the base
1059 * alignment of a vec4. The individual members of this
1060 * sub-structure are then assigned offsets by applying this set
1061 * of rules recursively, where the base offset of the first
1062 * member of the sub-structure is equal to the aligned offset
1063 * of the structure. The structure may have padding at the end;
1064 * the base offset of the member following the sub-structure is
1065 * rounded up to the next multiple of the base alignment of the
1066 * structure.
1067 */
1068 if (this->is_record()) {
1069 unsigned size = 0;
1070 for (unsigned i = 0; i < this->length; i++) {
1071 const struct glsl_type *field_type = this->fields.structure[i].type;
1072 unsigned align = field_type->std140_base_alignment(row_major);
1073 size = glsl_align(size, align);
1074 size += field_type->std140_size(row_major);
1075 }
1076 size = glsl_align(size,
1077 this->fields.structure[0].type->std140_base_alignment(row_major));
1078 return size;
1079 }
1080
1081 assert(!"not reached");
1082 return -1;
1083 }