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