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