glsl_types.cpp revision 29285882676388aacff123e8bdf025904abf8ea9
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#include "hash_table.h" 31 32 33hash_table *glsl_type::array_types = NULL; 34 35static void 36add_types_to_symbol_table(glsl_symbol_table *symtab, 37 const struct glsl_type *types, 38 unsigned num_types, bool warn) 39{ 40 (void) warn; 41 42 for (unsigned i = 0; i < num_types; i++) { 43 symtab->add_type(types[i].name, & types[i]); 44 } 45} 46 47 48static void 49generate_110_types(glsl_symbol_table *symtab) 50{ 51 add_types_to_symbol_table(symtab, builtin_core_types, 52 Elements(builtin_core_types), 53 false); 54 add_types_to_symbol_table(symtab, builtin_structure_types, 55 Elements(builtin_structure_types), 56 false); 57 add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types, 58 Elements(builtin_110_deprecated_structure_types), 59 false); 60 add_types_to_symbol_table(symtab, & void_type, 1, false); 61} 62 63 64static void 65generate_120_types(glsl_symbol_table *symtab) 66{ 67 generate_110_types(symtab); 68 69 add_types_to_symbol_table(symtab, builtin_120_types, 70 Elements(builtin_120_types), false); 71} 72 73 74static void 75generate_130_types(glsl_symbol_table *symtab) 76{ 77 generate_120_types(symtab); 78 79 add_types_to_symbol_table(symtab, builtin_130_types, 80 Elements(builtin_130_types), false); 81} 82 83 84static void 85generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab, bool warn) 86{ 87 add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types, 88 Elements(builtin_ARB_texture_rectangle_types), 89 warn); 90} 91 92 93static void 94generate_EXT_texture_array_types(glsl_symbol_table *symtab, bool warn) 95{ 96 add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types, 97 Elements(builtin_EXT_texture_array_types), 98 warn); 99} 100 101 102void 103_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) 104{ 105 switch (state->language_version) { 106 case 110: 107 generate_110_types(state->symbols); 108 break; 109 case 120: 110 generate_120_types(state->symbols); 111 break; 112 case 130: 113 generate_130_types(state->symbols); 114 break; 115 default: 116 /* error */ 117 break; 118 } 119 120 if (state->ARB_texture_rectangle_enable) { 121 generate_ARB_texture_rectangle_types(state->symbols, 122 state->ARB_texture_rectangle_warn); 123 } 124 125 if (state->EXT_texture_array_enable && state->language_version < 130) { 126 // These are already included in 130; don't create twice. 127 generate_EXT_texture_array_types(state->symbols, 128 state->EXT_texture_array_warn); 129 } 130} 131 132 133const glsl_type *glsl_type::get_base_type() const 134{ 135 switch (base_type) { 136 case GLSL_TYPE_UINT: 137 return uint_type; 138 case GLSL_TYPE_INT: 139 return int_type; 140 case GLSL_TYPE_FLOAT: 141 return float_type; 142 case GLSL_TYPE_BOOL: 143 return bool_type; 144 default: 145 return error_type; 146 } 147} 148 149 150ir_function * 151glsl_type::generate_constructor(glsl_symbol_table *symtab) const 152{ 153 void *ctx = symtab; 154 155 /* Generate the function name and add it to the symbol table. 156 */ 157 ir_function *const f = new(ctx) ir_function(name); 158 159 bool added = symtab->add_function(name, f); 160 assert(added); 161 162 ir_function_signature *const sig = new(ctx) ir_function_signature(this); 163 f->add_signature(sig); 164 165 ir_variable **declarations = 166 (ir_variable **) malloc(sizeof(ir_variable *) * this->length); 167 for (unsigned i = 0; i < length; i++) { 168 char *const param_name = (char *) malloc(10); 169 170 snprintf(param_name, 10, "p%08X", i); 171 172 ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY) 173 ? new(ctx) ir_variable(fields.array, param_name) 174 : new(ctx) ir_variable(fields.structure[i].type, param_name); 175 176 var->mode = ir_var_in; 177 declarations[i] = var; 178 sig->parameters.push_tail(var); 179 } 180 181 /* Generate the body of the constructor. The body assigns each of the 182 * parameters to a portion of a local variable called __retval that has 183 * the same type as the constructor. After initializing __retval, 184 * __retval is returned. 185 */ 186 ir_variable *retval = new(ctx) ir_variable(this, "__retval"); 187 sig->body.push_tail(retval); 188 189 for (unsigned i = 0; i < length; i++) { 190 ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY) 191 ? (ir_dereference *) new(ctx) ir_dereference_array(retval, 192 new(ctx) ir_constant(i)) 193 : (ir_dereference *) new(ctx) ir_dereference_record(retval, 194 fields.structure[i].name); 195 196 ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]); 197 ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL); 198 199 sig->body.push_tail(assign); 200 } 201 202 free(declarations); 203 204 ir_dereference *const retref = new(ctx) ir_dereference_variable(retval); 205 ir_instruction *const inst = new(ctx) ir_return(retref); 206 sig->body.push_tail(inst); 207 208 return f; 209} 210 211 212/** 213 * Generate the function intro for a constructor 214 * 215 * \param type Data type to be constructed 216 * \param count Number of parameters to this concrete constructor. Most 217 * types have at least two constructors. One will take a 218 * single scalar parameter and the other will take "N" 219 * scalar parameters. 220 * \param parameters Storage for the list of parameters. These are 221 * typically stored in an \c ir_function_signature. 222 * \param declarations Pointers to the variable declarations for the function 223 * parameters. These are used later to avoid having to use 224 * the symbol table. 225 */ 226static ir_function_signature * 227generate_constructor_intro(void *ctx, 228 const glsl_type *type, unsigned parameter_count, 229 ir_variable **declarations) 230{ 231 /* Names of parameters used in vector and matrix constructors 232 */ 233 static const char *const names[] = { 234 "a", "b", "c", "d", "e", "f", "g", "h", 235 "i", "j", "k", "l", "m", "n", "o", "p", 236 }; 237 238 assert(parameter_count <= Elements(names)); 239 240 const glsl_type *const parameter_type = type->get_base_type(); 241 242 ir_function_signature *const signature = new(ctx) ir_function_signature(type); 243 244 for (unsigned i = 0; i < parameter_count; i++) { 245 ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]); 246 247 var->mode = ir_var_in; 248 signature->parameters.push_tail(var); 249 250 declarations[i] = var; 251 } 252 253 ir_variable *retval = new(ctx) ir_variable(type, "__retval"); 254 signature->body.push_tail(retval); 255 256 declarations[16] = retval; 257 return signature; 258} 259 260 261/** 262 * Generate the body of a vector constructor that takes a single scalar 263 */ 264static void 265generate_vec_body_from_scalar(void *ctx, 266 exec_list *instructions, 267 ir_variable **declarations) 268{ 269 ir_instruction *inst; 270 271 /* Generate a single assignment of the parameter to __retval.x and return 272 * __retval.xxxx for however many vector components there are. 273 */ 274 ir_dereference *const lhs_ref = 275 new(ctx) ir_dereference_variable(declarations[16]); 276 ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]); 277 278 ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); 279 280 inst = new(ctx) ir_assignment(lhs, rhs, NULL); 281 instructions->push_tail(inst); 282 283 ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]); 284 285 ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0, 286 declarations[16]->type->vector_elements); 287 288 inst = new(ctx) ir_return(retval); 289 instructions->push_tail(inst); 290} 291 292 293/** 294 * Generate the body of a vector constructor that takes multiple scalars 295 */ 296static void 297generate_vec_body_from_N_scalars(void *ctx, 298 exec_list *instructions, 299 ir_variable **declarations) 300{ 301 ir_instruction *inst; 302 const glsl_type *const vec_type = declarations[16]->type; 303 304 /* Generate an assignment of each parameter to a single component of 305 * __retval.x and return __retval. 306 */ 307 for (unsigned i = 0; i < vec_type->vector_elements; i++) { 308 ir_dereference *const lhs_ref = 309 new(ctx) ir_dereference_variable(declarations[16]); 310 ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]); 311 312 ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1); 313 314 inst = new(ctx) ir_assignment(lhs, rhs, NULL); 315 instructions->push_tail(inst); 316 } 317 318 ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]); 319 320 inst = new(ctx) ir_return(retval); 321 instructions->push_tail(inst); 322} 323 324 325/** 326 * Generate the body of a matrix constructor that takes a single scalar 327 */ 328static void 329generate_mat_body_from_scalar(void *ctx, 330 exec_list *instructions, 331 ir_variable **declarations) 332{ 333 ir_instruction *inst; 334 335 /* Generate an assignment of the parameter to the X component of a 336 * temporary vector. Set the remaining fields of the vector to 0. The 337 * size of the vector is equal to the number of rows of the matrix. 338 * 339 * Set each column of the matrix to a successive "rotation" of the 340 * temporary vector. This fills the matrix with 0s, but writes the single 341 * scalar along the matrix's diagonal. 342 * 343 * For a mat4x3, this is equivalent to: 344 * 345 * vec3 tmp; 346 * mat4x3 __retval; 347 * tmp.x = a; 348 * tmp.y = 0.0; 349 * tmp.z = 0.0; 350 * __retval[0] = tmp.xyy; 351 * __retval[1] = tmp.yxy; 352 * __retval[2] = tmp.yyx; 353 * __retval[3] = tmp.yyy; 354 */ 355 const glsl_type *const column_type = declarations[16]->type->column_type(); 356 const glsl_type *const row_type = declarations[16]->type->row_type(); 357 358 ir_variable *const column = new(ctx) ir_variable(column_type, "v"); 359 360 instructions->push_tail(column); 361 362 ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column); 363 ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]); 364 365 ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); 366 367 inst = new(ctx) ir_assignment(lhs, rhs, NULL); 368 instructions->push_tail(inst); 369 370 for (unsigned i = 1; i < column_type->vector_elements; i++) { 371 ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column); 372 ir_constant *const zero = new(ctx) ir_constant(0.0f); 373 374 ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1); 375 376 inst = new(ctx) ir_assignment(lhs, zero, NULL); 377 instructions->push_tail(inst); 378 } 379 380 381 for (unsigned i = 0; i < row_type->vector_elements; i++) { 382 static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 }; 383 ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column); 384 385 /* This will be .xyyy when i=0, .yxyy when i=1, etc. 386 */ 387 ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i], 388 swiz[5 - i], swiz[6 - i], 389 column_type->vector_elements); 390 391 ir_constant *const idx = new(ctx) ir_constant(int(i)); 392 ir_dereference *const lhs = 393 new(ctx) ir_dereference_array(declarations[16], idx); 394 395 inst = new(ctx) ir_assignment(lhs, rhs, NULL); 396 instructions->push_tail(inst); 397 } 398 399 ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]); 400 inst = new(ctx) ir_return(retval); 401 instructions->push_tail(inst); 402} 403 404 405/** 406 * Generate the body of a vector constructor that takes multiple scalars 407 */ 408static void 409generate_mat_body_from_N_scalars(void *ctx, 410 exec_list *instructions, 411 ir_variable **declarations) 412{ 413 ir_instruction *inst; 414 const glsl_type *const row_type = declarations[16]->type->row_type(); 415 const glsl_type *const column_type = declarations[16]->type->column_type(); 416 417 /* Generate an assignment of each parameter to a single component of 418 * of a particular column of __retval and return __retval. 419 */ 420 for (unsigned i = 0; i < column_type->vector_elements; i++) { 421 for (unsigned j = 0; j < row_type->vector_elements; j++) { 422 ir_constant *row_index = new(ctx) ir_constant(int(i)); 423 ir_dereference *const row_access = 424 new(ctx) ir_dereference_array(declarations[16], row_index); 425 426 ir_swizzle *component_access = new(ctx) ir_swizzle(row_access, 427 j, 0, 0, 0, 1); 428 429 const unsigned param = (i * row_type->vector_elements) + j; 430 ir_dereference *const rhs = 431 new(ctx) ir_dereference_variable(declarations[param]); 432 433 inst = new(ctx) ir_assignment(component_access, rhs, NULL); 434 instructions->push_tail(inst); 435 } 436 } 437 438 ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]); 439 440 inst = new(ctx) ir_return(retval); 441 instructions->push_tail(inst); 442} 443 444 445/** 446 * Generate the constructors for a set of GLSL types 447 * 448 * Constructor implementations are added to \c instructions, and the symbols 449 * are added to \c symtab. 450 */ 451static void 452generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types, 453 unsigned num_types, exec_list *instructions) 454{ 455 void *ctx = symtab; 456 ir_variable *declarations[17]; 457 458 for (unsigned i = 0; i < num_types; i++) { 459 /* Only numeric and boolean vectors and matrices get constructors here. 460 * Structures need to be handled elsewhere. It is expected that scalar 461 * constructors are never actually called, so they are not generated. 462 */ 463 if (!types[i].is_numeric() && !types[i].is_boolean()) 464 continue; 465 466 if (types[i].is_scalar()) 467 continue; 468 469 /* Generate the function block, add it to the symbol table, and emit it. 470 */ 471 ir_function *const f = new(ctx) ir_function(types[i].name); 472 473 bool added = symtab->add_function(types[i].name, f); 474 assert(added); 475 476 instructions->push_tail(f); 477 478 /* Each type has several basic constructors. The total number of forms 479 * depends on the derived type. 480 * 481 * Vectors: 1 scalar, N scalars 482 * Matrices: 1 scalar, NxM scalars 483 * 484 * Several possible types of constructors are not included in this list. 485 * 486 * Scalar constructors are not included. The expectation is that the 487 * IR generator won't actually generate these as constructor calls. The 488 * expectation is that it will just generate the necessary type 489 * conversion. 490 * 491 * Matrix contructors from matrices are also not included. The 492 * expectation is that the IR generator will generate a call to the 493 * appropriate from-scalars constructor. 494 */ 495 ir_function_signature *const sig = 496 generate_constructor_intro(ctx, &types[i], 1, declarations); 497 f->add_signature(sig); 498 499 if (types[i].is_vector()) { 500 generate_vec_body_from_scalar(ctx, &sig->body, declarations); 501 502 ir_function_signature *const vec_sig = 503 generate_constructor_intro(ctx, 504 &types[i], types[i].vector_elements, 505 declarations); 506 f->add_signature(vec_sig); 507 508 generate_vec_body_from_N_scalars(ctx, &vec_sig->body, declarations); 509 } else { 510 assert(types[i].is_matrix()); 511 512 generate_mat_body_from_scalar(ctx, &sig->body, declarations); 513 514 ir_function_signature *const mat_sig = 515 generate_constructor_intro(ctx, 516 &types[i], 517 (types[i].vector_elements 518 * types[i].matrix_columns), 519 declarations); 520 f->add_signature(mat_sig); 521 522 generate_mat_body_from_N_scalars(ctx, &mat_sig->body, declarations); 523 } 524 } 525} 526 527 528void 529generate_110_constructors(glsl_symbol_table *symtab, exec_list *instructions) 530{ 531 generate_constructor(symtab, builtin_core_types, 532 Elements(builtin_core_types), instructions); 533} 534 535 536void 537generate_120_constructors(glsl_symbol_table *symtab, exec_list *instructions) 538{ 539 generate_110_constructors(symtab, instructions); 540 541 generate_constructor(symtab, builtin_120_types, 542 Elements(builtin_120_types), instructions); 543} 544 545 546void 547generate_130_constructors(glsl_symbol_table *symtab, exec_list *instructions) 548{ 549 generate_120_constructors(symtab, instructions); 550 551 generate_constructor(symtab, builtin_130_types, 552 Elements(builtin_130_types), instructions); 553} 554 555 556void 557_mesa_glsl_initialize_constructors(exec_list *instructions, 558 struct _mesa_glsl_parse_state *state) 559{ 560 switch (state->language_version) { 561 case 110: 562 generate_110_constructors(state->symbols, instructions); 563 break; 564 case 120: 565 generate_120_constructors(state->symbols, instructions); 566 break; 567 case 130: 568 generate_130_constructors(state->symbols, instructions); 569 break; 570 default: 571 /* error */ 572 break; 573 } 574} 575 576 577glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : 578 base_type(GLSL_TYPE_ARRAY), 579 sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), 580 sampler_type(0), 581 vector_elements(0), matrix_columns(0), 582 name(NULL), length(length) 583{ 584 this->fields.array = array; 585 586 /* Allow a maximum of 10 characters for the array size. This is enough 587 * for 32-bits of ~0. The extra 3 are for the '[', ']', and terminating 588 * NUL. 589 */ 590 const unsigned name_length = strlen(array->name) + 10 + 3; 591 char *const n = (char *) talloc_size(ctx, name_length); 592 593 if (length == 0) 594 snprintf(n, name_length, "%s[]", array->name); 595 else 596 snprintf(n, name_length, "%s[%u]", array->name, length); 597 598 this->name = n; 599} 600 601 602const glsl_type * 603glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) 604{ 605 if (base_type == GLSL_TYPE_VOID) 606 return &void_type; 607 608 if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4)) 609 return error_type; 610 611 /* Treat GLSL vectors as Nx1 matrices. 612 */ 613 if (columns == 1) { 614 switch (base_type) { 615 case GLSL_TYPE_UINT: 616 return uint_type + (rows - 1); 617 case GLSL_TYPE_INT: 618 return int_type + (rows - 1); 619 case GLSL_TYPE_FLOAT: 620 return float_type + (rows - 1); 621 case GLSL_TYPE_BOOL: 622 return bool_type + (rows - 1); 623 default: 624 return error_type; 625 } 626 } else { 627 if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1)) 628 return error_type; 629 630 /* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following 631 * combinations are valid: 632 * 633 * 1 2 3 4 634 * 1 635 * 2 x x x 636 * 3 x x x 637 * 4 x x x 638 */ 639#define IDX(c,r) (((c-1)*3) + (r-1)) 640 641 switch (IDX(columns, rows)) { 642 case IDX(2,2): return mat2_type; 643 case IDX(2,3): return mat2x3_type; 644 case IDX(2,4): return mat2x4_type; 645 case IDX(3,2): return mat3x2_type; 646 case IDX(3,3): return mat3_type; 647 case IDX(3,4): return mat3x4_type; 648 case IDX(4,2): return mat4x2_type; 649 case IDX(4,3): return mat4x3_type; 650 case IDX(4,4): return mat4_type; 651 default: return error_type; 652 } 653 } 654 655 assert(!"Should not get here."); 656 return error_type; 657} 658 659 660int 661glsl_type::array_key_compare(const void *a, const void *b) 662{ 663 const glsl_type *const key1 = (glsl_type *) a; 664 const glsl_type *const key2 = (glsl_type *) b; 665 666 /* Return zero is the types match (there is zero difference) or non-zero 667 * otherwise. 668 */ 669 return ((key1->fields.array == key2->fields.array) 670 && (key1->length == key2->length)) ? 0 : 1; 671} 672 673 674unsigned 675glsl_type::array_key_hash(const void *a) 676{ 677 const glsl_type *const key = (glsl_type *) a; 678 679 const struct { 680 const glsl_type *t; 681 unsigned l; 682 char nul; 683 } hash_key = { 684 key->fields.array, 685 key->length, 686 '\0' 687 }; 688 689 return hash_table_string_hash(& hash_key); 690} 691 692 693const glsl_type * 694glsl_type::get_array_instance(void *ctx, const glsl_type *base, 695 unsigned array_size) 696{ 697 const glsl_type key(ctx, base, array_size); 698 699 if (array_types == NULL) { 700 array_types = hash_table_ctor(64, array_key_hash, array_key_compare); 701 } 702 703 const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key); 704 if (t == NULL) { 705 t = new(ctx) glsl_type(ctx, base, array_size); 706 707 hash_table_insert(array_types, (void *) t, t); 708 } 709 710 assert(t->base_type == GLSL_TYPE_ARRAY); 711 assert(t->length == array_size); 712 assert(t->fields.array == base); 713 714 return t; 715} 716 717 718const glsl_type * 719glsl_type::field_type(const char *name) const 720{ 721 if (this->base_type != GLSL_TYPE_STRUCT) 722 return error_type; 723 724 for (unsigned i = 0; i < this->length; i++) { 725 if (strcmp(name, this->fields.structure[i].name) == 0) 726 return this->fields.structure[i].type; 727 } 728 729 return error_type; 730} 731 732 733int 734glsl_type::field_index(const char *name) const 735{ 736 if (this->base_type != GLSL_TYPE_STRUCT) 737 return -1; 738 739 for (unsigned i = 0; i < this->length; i++) { 740 if (strcmp(name, this->fields.structure[i].name) == 0) 741 return i; 742 } 743 744 return -1; 745} 746 747 748unsigned 749glsl_type::component_slots() const 750{ 751 switch (this->base_type) { 752 case GLSL_TYPE_UINT: 753 case GLSL_TYPE_INT: 754 case GLSL_TYPE_FLOAT: 755 case GLSL_TYPE_BOOL: 756 return this->components(); 757 758 case GLSL_TYPE_STRUCT: { 759 unsigned size = 0; 760 761 for (unsigned i = 0; i < this->length; i++) 762 size += this->fields.structure[i].type->component_slots(); 763 764 return size; 765 } 766 767 case GLSL_TYPE_ARRAY: 768 return this->length * this->fields.array->component_slots(); 769 770 default: 771 return 0; 772 } 773} 774