2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * \file slang_typeinfo.c
31 #include "main/imports.h"
32 #include "shader/prog_instruction.h"
33 #include "slang_typeinfo.h"
34 #include "slang_compile.h"
35 #include "slang_log.h"
36 #include "slang_mem.h"
40 * Checks if a field selector is a general swizzle (an r-value swizzle
41 * with replicated components or an l-value swizzle mask) for a
42 * vector. Returns GL_TRUE if this is the case, <swz> is filled with
43 * swizzle information. Returns GL_FALSE otherwise.
46 _slang_is_swizzle(const char *field
, GLuint rows
, slang_swizzle
* swz
)
49 GLboolean xyzw
= GL_FALSE
, rgba
= GL_FALSE
, stpq
= GL_FALSE
;
52 * We rely on undefined/nil values to distinguish between
53 * regular swizzles and writemasks.
54 * For example, the swizzle ".xNNN" is the writemask ".x".
55 * That's different than the swizzle ".xxxx".
57 for (i
= 0; i
< 4; i
++)
58 swz
->swizzle
[i
] = SWIZZLE_NIL
;
60 /* the swizzle can be at most 4-component long */
61 swz
->num_components
= slang_string_length(field
);
62 if (swz
->num_components
> 4)
65 for (i
= 0; i
< swz
->num_components
; i
++) {
66 /* mark which swizzle group is used */
90 /* collect swizzle component */
114 /* check if the component is valid for given vector's row count */
115 if (rows
<= swz
->swizzle
[i
])
119 /* only one swizzle group can be used */
120 if ((xyzw
&& rgba
) || (xyzw
&& stpq
) || (rgba
&& stpq
))
129 * Checks if a general swizzle is an l-value swizzle - these swizzles
130 * do not have duplicated fields. Returns GL_TRUE if this is a
131 * swizzle mask. Returns GL_FALSE otherwise
134 _slang_is_swizzle_mask(const slang_swizzle
* swz
, GLuint rows
)
138 /* the swizzle may not be longer than the vector dim */
139 if (swz
->num_components
> rows
)
142 /* the swizzle components cannot be duplicated */
143 for (i
= 0; i
< swz
->num_components
; i
++) {
144 if ((c
& (1 << swz
->swizzle
[i
])) != 0)
146 c
|= 1 << swz
->swizzle
[i
];
154 * Combines (multiplies) two swizzles to form single swizzle.
155 * Example: "vec.wzyx.yx" --> "vec.zw".
158 _slang_multiply_swizzles(slang_swizzle
* dst
, const slang_swizzle
* left
,
159 const slang_swizzle
* right
)
163 dst
->num_components
= right
->num_components
;
164 for (i
= 0; i
< right
->num_components
; i
++)
165 dst
->swizzle
[i
] = left
->swizzle
[right
->swizzle
[i
]];
172 slang_type_specifier_type type
;
173 } type_specifier_type_name
;
175 static const type_specifier_type_name type_specifier_type_names
[] = {
176 {"void", SLANG_SPEC_VOID
},
177 {"bool", SLANG_SPEC_BOOL
},
178 {"bvec2", SLANG_SPEC_BVEC2
},
179 {"bvec3", SLANG_SPEC_BVEC3
},
180 {"bvec4", SLANG_SPEC_BVEC4
},
181 {"int", SLANG_SPEC_INT
},
182 {"ivec2", SLANG_SPEC_IVEC2
},
183 {"ivec3", SLANG_SPEC_IVEC3
},
184 {"ivec4", SLANG_SPEC_IVEC4
},
185 {"float", SLANG_SPEC_FLOAT
},
186 {"vec2", SLANG_SPEC_VEC2
},
187 {"vec3", SLANG_SPEC_VEC3
},
188 {"vec4", SLANG_SPEC_VEC4
},
189 {"mat2", SLANG_SPEC_MAT2
},
190 {"mat3", SLANG_SPEC_MAT3
},
191 {"mat4", SLANG_SPEC_MAT4
},
192 {"mat2x3", SLANG_SPEC_MAT23
},
193 {"mat3x2", SLANG_SPEC_MAT32
},
194 {"mat2x4", SLANG_SPEC_MAT24
},
195 {"mat4x2", SLANG_SPEC_MAT42
},
196 {"mat3x4", SLANG_SPEC_MAT34
},
197 {"mat4x3", SLANG_SPEC_MAT43
},
198 {"sampler1D", SLANG_SPEC_SAMPLER1D
},
199 {"sampler2D", SLANG_SPEC_SAMPLER2D
},
200 {"sampler3D", SLANG_SPEC_SAMPLER3D
},
201 {"samplerCube", SLANG_SPEC_SAMPLERCUBE
},
202 {"sampler1DShadow", SLANG_SPEC_SAMPLER1DSHADOW
},
203 {"sampler2DShadow", SLANG_SPEC_SAMPLER2DSHADOW
},
204 {"sampler2DRect", SLANG_SPEC_SAMPLER2DRECT
},
205 {"sampler2DRectShadow", SLANG_SPEC_SAMPLER2DRECTSHADOW
},
206 {NULL
, SLANG_SPEC_VOID
}
209 slang_type_specifier_type
210 slang_type_specifier_type_from_string(const char *name
)
212 const type_specifier_type_name
*p
= type_specifier_type_names
;
213 while (p
->name
!= NULL
) {
214 if (slang_string_compare(p
->name
, name
) == 0)
222 slang_type_specifier_type_to_string(slang_type_specifier_type type
)
224 const type_specifier_type_name
*p
= type_specifier_type_names
;
225 while (p
->name
!= NULL
) {
233 /* slang_fully_specified_type */
236 slang_fully_specified_type_construct(slang_fully_specified_type
* type
)
238 type
->qualifier
= SLANG_QUAL_NONE
;
239 slang_type_specifier_ctr(&type
->specifier
);
244 slang_fully_specified_type_destruct(slang_fully_specified_type
* type
)
246 slang_type_specifier_dtr(&type
->specifier
);
250 slang_fully_specified_type_copy(slang_fully_specified_type
* x
,
251 const slang_fully_specified_type
* y
)
253 slang_fully_specified_type z
;
255 if (!slang_fully_specified_type_construct(&z
))
257 z
.qualifier
= y
->qualifier
;
258 z
.precision
= y
->precision
;
259 z
.variant
= y
->variant
;
260 z
.centroid
= y
->centroid
;
261 z
.array_len
= y
->array_len
;
262 if (!slang_type_specifier_copy(&z
.specifier
, &y
->specifier
)) {
263 slang_fully_specified_type_destruct(&z
);
266 slang_fully_specified_type_destruct(x
);
274 slang_type_specifier_ctr(slang_type_specifier
* self
)
276 self
->type
= SLANG_SPEC_VOID
;
277 self
->_struct
= NULL
;
282 slang_type_specifier_dtr(slang_type_specifier
* self
)
284 if (self
->_struct
!= NULL
) {
285 slang_struct_destruct(self
->_struct
);
286 _slang_free(self
->_struct
);
288 if (self
->_array
!= NULL
) {
289 slang_type_specifier_dtr(self
->_array
);
290 _slang_free(self
->_array
);
294 slang_type_specifier
*
295 slang_type_specifier_new(slang_type_specifier_type type
,
296 struct slang_struct_
*_struct
,
297 struct slang_type_specifier_
*_array
)
299 slang_type_specifier
*spec
=
300 (slang_type_specifier
*) _slang_alloc(sizeof(slang_type_specifier
));
303 spec
->_struct
= _struct
;
304 spec
->_array
= _array
;
310 slang_type_specifier_copy(slang_type_specifier
* x
,
311 const slang_type_specifier
* y
)
313 slang_type_specifier z
;
315 slang_type_specifier_ctr(&z
);
317 if (z
.type
== SLANG_SPEC_STRUCT
) {
318 z
._struct
= (slang_struct
*) _slang_alloc(sizeof(slang_struct
));
319 if (z
._struct
== NULL
) {
320 slang_type_specifier_dtr(&z
);
323 if (!slang_struct_construct(z
._struct
)) {
324 _slang_free(z
._struct
);
325 slang_type_specifier_dtr(&z
);
328 if (!slang_struct_copy(z
._struct
, y
->_struct
)) {
329 slang_type_specifier_dtr(&z
);
333 else if (z
.type
== SLANG_SPEC_ARRAY
) {
334 z
._array
= (slang_type_specifier
*)
335 _slang_alloc(sizeof(slang_type_specifier
));
336 if (z
._array
== NULL
) {
337 slang_type_specifier_dtr(&z
);
340 slang_type_specifier_ctr(z
._array
);
341 if (!slang_type_specifier_copy(z
._array
, y
->_array
)) {
342 slang_type_specifier_dtr(&z
);
346 slang_type_specifier_dtr(x
);
353 * Test if two types are equal.
356 slang_type_specifier_equal(const slang_type_specifier
* x
,
357 const slang_type_specifier
* y
)
359 if (x
->type
!= y
->type
)
361 if (x
->type
== SLANG_SPEC_STRUCT
)
362 return slang_struct_equal(x
->_struct
, y
->_struct
);
363 if (x
->type
== SLANG_SPEC_ARRAY
)
364 return slang_type_specifier_equal(x
->_array
, y
->_array
);
370 * As above, but allow float/int casting.
373 slang_type_specifier_compatible(const slang_type_specifier
* x
,
374 const slang_type_specifier
* y
)
376 /* special case: float == int */
377 if (x
->type
== SLANG_SPEC_INT
&& y
->type
== SLANG_SPEC_FLOAT
) {
380 /* XXX may need to add bool/int compatibility, etc */
382 if (x
->type
!= y
->type
)
384 if (x
->type
== SLANG_SPEC_STRUCT
)
385 return slang_struct_equal(x
->_struct
, y
->_struct
);
386 if (x
->type
== SLANG_SPEC_ARRAY
)
387 return slang_type_specifier_compatible(x
->_array
, y
->_array
);
393 slang_typeinfo_construct(slang_typeinfo
* ti
)
395 _mesa_bzero(ti
, sizeof(*ti
));
396 slang_type_specifier_ctr(&ti
->spec
);
402 slang_typeinfo_destruct(slang_typeinfo
* ti
)
404 slang_type_specifier_dtr(&ti
->spec
);
410 * Determine the return type of a function.
411 * \param a_name the function name
412 * \param param function parameters (overloading)
413 * \param num_params number of parameters to function
414 * \param space namespace to search
415 * \param spec returns the type
416 * \param funFound returns pointer to the function, or NULL if not found.
417 * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
420 _slang_typeof_function(slang_atom a_name
,
421 slang_operation
* params
, GLuint num_params
,
422 const slang_name_space
* space
,
423 slang_type_specifier
* spec
,
424 slang_function
**funFound
,
425 slang_atom_pool
*atoms
, slang_info_log
*log
)
429 *funFound
= _slang_function_locate(space
->funcs
, a_name
, params
,
430 num_params
, space
, atoms
, log
, &error
);
435 return GL_TRUE
; /* yes, not false */
437 return slang_type_specifier_copy(spec
, &(*funFound
)->header
.type
.specifier
);
442 * Determine the type of a math function.
443 * \param name name of the operator, one of +,-,*,/ or unary -
444 * \param params array of function parameters
445 * \param num_params number of parameters
446 * \param space namespace to use
447 * \param spec returns the function's type
448 * \param atoms atom pool
449 * \return GL_TRUE for success, GL_FALSE if failure
452 typeof_math_call(const char *name
, slang_operation
*call
,
453 const slang_name_space
* space
,
454 slang_type_specifier
* spec
,
455 slang_atom_pool
* atoms
,
459 /* we've previously resolved this function call */
460 slang_type_specifier_copy(spec
, &call
->fun
->header
.type
.specifier
);
467 /* number of params: */
468 assert(call
->num_children
== 1 || call
->num_children
== 2);
470 atom
= slang_atom_pool_atom(atoms
, name
);
471 if (!_slang_typeof_function(atom
, call
->children
, call
->num_children
,
472 space
, spec
, &fun
, atoms
, log
))
476 /* Save pointer to save time in future */
486 * Determine the return type of an operation.
487 * \param op the operation node
488 * \param space the namespace to use
489 * \param ti the returned type
490 * \param atoms atom pool
491 * \return GL_TRUE for success, GL_FALSE if failure
494 _slang_typeof_operation(slang_operation
* op
,
495 const slang_name_space
* space
,
497 slang_atom_pool
* atoms
,
500 ti
->can_be_referenced
= GL_FALSE
;
501 ti
->is_swizzled
= GL_FALSE
;
504 case SLANG_OPER_BLOCK_NO_NEW_SCOPE
:
505 case SLANG_OPER_BLOCK_NEW_SCOPE
:
507 case SLANG_OPER_BREAK
:
508 case SLANG_OPER_CONTINUE
:
509 case SLANG_OPER_DISCARD
:
510 case SLANG_OPER_RETURN
:
512 case SLANG_OPER_WHILE
:
515 case SLANG_OPER_VOID
:
516 ti
->spec
.type
= SLANG_SPEC_VOID
;
518 case SLANG_OPER_EXPRESSION
:
519 case SLANG_OPER_ASSIGN
:
520 case SLANG_OPER_ADDASSIGN
:
521 case SLANG_OPER_SUBASSIGN
:
522 case SLANG_OPER_MULASSIGN
:
523 case SLANG_OPER_DIVASSIGN
:
524 case SLANG_OPER_PREINCREMENT
:
525 case SLANG_OPER_PREDECREMENT
:
526 if (!_slang_typeof_operation(op
->children
, space
, ti
, atoms
, log
))
529 case SLANG_OPER_LITERAL_BOOL
:
530 if (op
->literal_size
== 1)
531 ti
->spec
.type
= SLANG_SPEC_BOOL
;
532 else if (op
->literal_size
== 2)
533 ti
->spec
.type
= SLANG_SPEC_BVEC2
;
534 else if (op
->literal_size
== 3)
535 ti
->spec
.type
= SLANG_SPEC_BVEC3
;
536 else if (op
->literal_size
== 4)
537 ti
->spec
.type
= SLANG_SPEC_BVEC4
;
540 "Unexpected bool literal_size %d in _slang_typeof_operation()",
542 ti
->spec
.type
= SLANG_SPEC_BOOL
;
545 case SLANG_OPER_LOGICALOR
:
546 case SLANG_OPER_LOGICALXOR
:
547 case SLANG_OPER_LOGICALAND
:
548 case SLANG_OPER_EQUAL
:
549 case SLANG_OPER_NOTEQUAL
:
550 case SLANG_OPER_LESS
:
551 case SLANG_OPER_GREATER
:
552 case SLANG_OPER_LESSEQUAL
:
553 case SLANG_OPER_GREATEREQUAL
:
555 ti
->spec
.type
= SLANG_SPEC_BOOL
;
557 case SLANG_OPER_LITERAL_INT
:
558 if (op
->literal_size
== 1)
559 ti
->spec
.type
= SLANG_SPEC_INT
;
560 else if (op
->literal_size
== 2)
561 ti
->spec
.type
= SLANG_SPEC_IVEC2
;
562 else if (op
->literal_size
== 3)
563 ti
->spec
.type
= SLANG_SPEC_IVEC3
;
564 else if (op
->literal_size
== 4)
565 ti
->spec
.type
= SLANG_SPEC_IVEC4
;
568 "Unexpected int literal_size %d in _slang_typeof_operation()",
570 ti
->spec
.type
= SLANG_SPEC_INT
;
573 case SLANG_OPER_LITERAL_FLOAT
:
574 if (op
->literal_size
== 1)
575 ti
->spec
.type
= SLANG_SPEC_FLOAT
;
576 else if (op
->literal_size
== 2)
577 ti
->spec
.type
= SLANG_SPEC_VEC2
;
578 else if (op
->literal_size
== 3)
579 ti
->spec
.type
= SLANG_SPEC_VEC3
;
580 else if (op
->literal_size
== 4)
581 ti
->spec
.type
= SLANG_SPEC_VEC4
;
584 "Unexpected float literal_size %d in _slang_typeof_operation()",
586 ti
->spec
.type
= SLANG_SPEC_FLOAT
;
589 case SLANG_OPER_IDENTIFIER
:
590 case SLANG_OPER_VARIABLE_DECL
:
593 var
= _slang_variable_locate(op
->locals
, op
->a_id
, GL_TRUE
);
595 slang_info_log_error(log
, "undefined variable '%s'",
599 if (!slang_type_specifier_copy(&ti
->spec
, &var
->type
.specifier
)) {
600 slang_info_log_memory(log
);
603 ti
->can_be_referenced
= GL_TRUE
;
604 if (var
->type
.specifier
.type
== SLANG_SPEC_ARRAY
&&
605 var
->type
.array_len
>= 1) {
606 /* the datatype is an array, ex: float[3] x; */
607 ti
->array_len
= var
->type
.array_len
;
610 /* the variable is an array, ex: float x[3]; */
611 ti
->array_len
= var
->array_len
;
615 case SLANG_OPER_SEQUENCE
:
616 /* TODO: check [0] and [1] if they match */
617 if (!_slang_typeof_operation(&op
->children
[1], space
, ti
, atoms
, log
)) {
620 ti
->can_be_referenced
= GL_FALSE
;
621 ti
->is_swizzled
= GL_FALSE
;
623 /*case SLANG_OPER_MODASSIGN: */
624 /*case SLANG_OPER_LSHASSIGN: */
625 /*case SLANG_OPER_RSHASSIGN: */
626 /*case SLANG_OPER_ORASSIGN: */
627 /*case SLANG_OPER_XORASSIGN: */
628 /*case SLANG_OPER_ANDASSIGN: */
629 case SLANG_OPER_SELECT
:
630 /* TODO: check [1] and [2] if they match */
631 if (!_slang_typeof_operation(&op
->children
[1], space
, ti
, atoms
, log
)) {
634 ti
->can_be_referenced
= GL_FALSE
;
635 ti
->is_swizzled
= GL_FALSE
;
637 /*case SLANG_OPER_BITOR: */
638 /*case SLANG_OPER_BITXOR: */
639 /*case SLANG_OPER_BITAND: */
640 /*case SLANG_OPER_LSHIFT: */
641 /*case SLANG_OPER_RSHIFT: */
643 assert(op
->num_children
== 2);
644 if (!typeof_math_call("+", op
, space
, &ti
->spec
, atoms
, log
))
647 case SLANG_OPER_SUBTRACT
:
648 assert(op
->num_children
== 2);
649 if (!typeof_math_call("-", op
, space
, &ti
->spec
, atoms
, log
))
652 case SLANG_OPER_MULTIPLY
:
653 assert(op
->num_children
== 2);
654 if (!typeof_math_call("*", op
, space
, &ti
->spec
, atoms
, log
))
657 case SLANG_OPER_DIVIDE
:
658 assert(op
->num_children
== 2);
659 if (!typeof_math_call("/", op
, space
, &ti
->spec
, atoms
, log
))
662 /*case SLANG_OPER_MODULUS: */
663 case SLANG_OPER_PLUS
:
664 if (!_slang_typeof_operation(op
->children
, space
, ti
, atoms
, log
))
666 ti
->can_be_referenced
= GL_FALSE
;
667 ti
->is_swizzled
= GL_FALSE
;
669 case SLANG_OPER_MINUS
:
670 assert(op
->num_children
== 1);
671 if (!typeof_math_call("-", op
, space
, &ti
->spec
, atoms
, log
))
674 /*case SLANG_OPER_COMPLEMENT: */
675 case SLANG_OPER_SUBSCRIPT
:
679 if (!slang_typeinfo_construct(&_ti
))
681 if (!_slang_typeof_operation(op
->children
, space
, &_ti
, atoms
, log
)) {
682 slang_typeinfo_destruct(&_ti
);
685 ti
->can_be_referenced
= _ti
.can_be_referenced
;
686 if (_ti
.spec
.type
== SLANG_SPEC_ARRAY
) {
687 if (!slang_type_specifier_copy(&ti
->spec
, _ti
.spec
._array
)) {
688 slang_typeinfo_destruct(&_ti
);
693 if (!_slang_type_is_vector(_ti
.spec
.type
)
694 && !_slang_type_is_matrix(_ti
.spec
.type
)) {
695 slang_typeinfo_destruct(&_ti
);
696 slang_info_log_error(log
, "cannot index a non-array type");
699 ti
->spec
.type
= _slang_type_base(_ti
.spec
.type
);
701 slang_typeinfo_destruct(&_ti
);
704 case SLANG_OPER_CALL
:
705 if (op
->array_constructor
) {
706 /* build array typeinfo */
707 ti
->spec
.type
= SLANG_SPEC_ARRAY
;
708 ti
->spec
._array
= (slang_type_specifier
*)
709 _slang_alloc(sizeof(slang_type_specifier
));
710 slang_type_specifier_ctr(ti
->spec
._array
);
712 ti
->spec
._array
->type
=
713 slang_type_specifier_type_from_string((char *) op
->a_id
);
714 ti
->array_len
= op
->num_children
;
717 /* we've resolved this call before */
718 slang_type_specifier_copy(&ti
->spec
, &op
->fun
->header
.type
.specifier
);
722 if (!_slang_typeof_function(op
->a_id
, op
->children
, op
->num_children
,
723 space
, &ti
->spec
, &fun
, atoms
, log
))
726 /* save result for future use */
731 slang_struct_scope_find(space
->structs
, op
->a_id
, GL_TRUE
);
733 /* struct initializer */
734 ti
->spec
.type
= SLANG_SPEC_STRUCT
;
736 (slang_struct
*) _slang_alloc(sizeof(slang_struct
));
737 if (ti
->spec
._struct
== NULL
)
739 if (!slang_struct_construct(ti
->spec
._struct
)) {
740 _slang_free(ti
->spec
._struct
);
741 ti
->spec
._struct
= NULL
;
744 if (!slang_struct_copy(ti
->spec
._struct
, s
))
748 /* float, int, vec4, mat3, etc. constructor? */
750 slang_type_specifier_type type
;
752 name
= slang_atom_pool_id(atoms
, op
->a_id
);
753 type
= slang_type_specifier_type_from_string(name
);
754 if (type
== SLANG_SPEC_VOID
) {
755 slang_info_log_error(log
, "undefined function '%s'", name
);
758 ti
->spec
.type
= type
;
763 case SLANG_OPER_METHOD
:
764 /* at this time, GLSL 1.20 only has one method: array.length()
765 * which returns an integer.
767 ti
->spec
.type
= SLANG_SPEC_INT
;
769 case SLANG_OPER_FIELD
:
773 if (!slang_typeinfo_construct(&_ti
))
775 if (!_slang_typeof_operation(op
->children
, space
, &_ti
, atoms
, log
)) {
776 slang_typeinfo_destruct(&_ti
);
779 if (_ti
.spec
.type
== SLANG_SPEC_STRUCT
) {
780 slang_variable
*field
;
782 field
= _slang_variable_locate(_ti
.spec
._struct
->fields
, op
->a_id
,
785 slang_typeinfo_destruct(&_ti
);
788 if (!slang_type_specifier_copy(&ti
->spec
, &field
->type
.specifier
)) {
789 slang_typeinfo_destruct(&_ti
);
792 ti
->can_be_referenced
= _ti
.can_be_referenced
;
797 slang_type_specifier_type base
;
799 /* determine the swizzle of the field expression */
800 if (!_slang_type_is_vector(_ti
.spec
.type
)) {
801 slang_typeinfo_destruct(&_ti
);
802 slang_info_log_error(log
, "Can't swizzle scalar expression");
805 rows
= _slang_type_dim(_ti
.spec
.type
);
806 swizzle
= slang_atom_pool_id(atoms
, op
->a_id
);
807 if (!_slang_is_swizzle(swizzle
, rows
, &ti
->swz
)) {
808 slang_typeinfo_destruct(&_ti
);
809 slang_info_log_error(log
, "bad swizzle '%s'", swizzle
);
812 ti
->is_swizzled
= GL_TRUE
;
813 ti
->can_be_referenced
= _ti
.can_be_referenced
814 && _slang_is_swizzle_mask(&ti
->swz
, rows
);
815 if (_ti
.is_swizzled
) {
818 /* swizzle the swizzle */
819 _slang_multiply_swizzles(&swz
, &_ti
.swz
, &ti
->swz
);
822 base
= _slang_type_base(_ti
.spec
.type
);
823 switch (ti
->swz
.num_components
) {
825 ti
->spec
.type
= base
;
829 case SLANG_SPEC_FLOAT
:
830 ti
->spec
.type
= SLANG_SPEC_VEC2
;
833 ti
->spec
.type
= SLANG_SPEC_IVEC2
;
835 case SLANG_SPEC_BOOL
:
836 ti
->spec
.type
= SLANG_SPEC_BVEC2
;
844 case SLANG_SPEC_FLOAT
:
845 ti
->spec
.type
= SLANG_SPEC_VEC3
;
848 ti
->spec
.type
= SLANG_SPEC_IVEC3
;
850 case SLANG_SPEC_BOOL
:
851 ti
->spec
.type
= SLANG_SPEC_BVEC3
;
859 case SLANG_SPEC_FLOAT
:
860 ti
->spec
.type
= SLANG_SPEC_VEC4
;
863 ti
->spec
.type
= SLANG_SPEC_IVEC4
;
865 case SLANG_SPEC_BOOL
:
866 ti
->spec
.type
= SLANG_SPEC_BVEC4
;
876 slang_typeinfo_destruct(&_ti
);
879 case SLANG_OPER_POSTINCREMENT
:
880 case SLANG_OPER_POSTDECREMENT
:
881 if (!_slang_typeof_operation(op
->children
, space
, ti
, atoms
, log
))
883 ti
->can_be_referenced
= GL_FALSE
;
884 ti
->is_swizzled
= GL_FALSE
;
895 * Determine if a type is a matrix.
896 * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
899 _slang_type_is_matrix(slang_type_specifier_type ty
)
902 case SLANG_SPEC_MAT2
:
903 case SLANG_SPEC_MAT3
:
904 case SLANG_SPEC_MAT4
:
905 case SLANG_SPEC_MAT23
:
906 case SLANG_SPEC_MAT32
:
907 case SLANG_SPEC_MAT24
:
908 case SLANG_SPEC_MAT42
:
909 case SLANG_SPEC_MAT34
:
910 case SLANG_SPEC_MAT43
:
919 * Determine if a type is a vector.
920 * \return GL_TRUE if is a vector, GL_FALSE otherwise.
923 _slang_type_is_vector(slang_type_specifier_type ty
)
926 case SLANG_SPEC_VEC2
:
927 case SLANG_SPEC_VEC3
:
928 case SLANG_SPEC_VEC4
:
929 case SLANG_SPEC_IVEC2
:
930 case SLANG_SPEC_IVEC3
:
931 case SLANG_SPEC_IVEC4
:
932 case SLANG_SPEC_BVEC2
:
933 case SLANG_SPEC_BVEC3
:
934 case SLANG_SPEC_BVEC4
:
943 * Determine if a type is a float, float vector or float matrix.
944 * \return GL_TRUE if so, GL_FALSE otherwise
947 _slang_type_is_float_vec_mat(slang_type_specifier_type ty
)
950 case SLANG_SPEC_FLOAT
:
951 case SLANG_SPEC_VEC2
:
952 case SLANG_SPEC_VEC3
:
953 case SLANG_SPEC_VEC4
:
954 case SLANG_SPEC_MAT2
:
955 case SLANG_SPEC_MAT3
:
956 case SLANG_SPEC_MAT4
:
957 case SLANG_SPEC_MAT23
:
958 case SLANG_SPEC_MAT32
:
959 case SLANG_SPEC_MAT24
:
960 case SLANG_SPEC_MAT42
:
961 case SLANG_SPEC_MAT34
:
962 case SLANG_SPEC_MAT43
:
971 * Given a vector type, return the type of the vector's elements.
972 * For a matrix, return the type of the columns.
974 slang_type_specifier_type
975 _slang_type_base(slang_type_specifier_type ty
)
978 case SLANG_SPEC_FLOAT
:
979 case SLANG_SPEC_VEC2
:
980 case SLANG_SPEC_VEC3
:
981 case SLANG_SPEC_VEC4
:
982 return SLANG_SPEC_FLOAT
;
984 case SLANG_SPEC_IVEC2
:
985 case SLANG_SPEC_IVEC3
:
986 case SLANG_SPEC_IVEC4
:
987 return SLANG_SPEC_INT
;
988 case SLANG_SPEC_BOOL
:
989 case SLANG_SPEC_BVEC2
:
990 case SLANG_SPEC_BVEC3
:
991 case SLANG_SPEC_BVEC4
:
992 return SLANG_SPEC_BOOL
;
993 case SLANG_SPEC_MAT2
:
994 return SLANG_SPEC_VEC2
;
995 case SLANG_SPEC_MAT3
:
996 return SLANG_SPEC_VEC3
;
997 case SLANG_SPEC_MAT4
:
998 return SLANG_SPEC_VEC4
;
999 case SLANG_SPEC_MAT23
:
1000 return SLANG_SPEC_VEC3
;
1001 case SLANG_SPEC_MAT32
:
1002 return SLANG_SPEC_VEC2
;
1003 case SLANG_SPEC_MAT24
:
1004 return SLANG_SPEC_VEC4
;
1005 case SLANG_SPEC_MAT42
:
1006 return SLANG_SPEC_VEC2
;
1007 case SLANG_SPEC_MAT34
:
1008 return SLANG_SPEC_VEC4
;
1009 case SLANG_SPEC_MAT43
:
1010 return SLANG_SPEC_VEC3
;
1012 return SLANG_SPEC_VOID
;
1018 * Return the dimensionality of a vector, or for a matrix, return number
1022 _slang_type_dim(slang_type_specifier_type ty
)
1025 case SLANG_SPEC_FLOAT
:
1026 case SLANG_SPEC_INT
:
1027 case SLANG_SPEC_BOOL
:
1029 case SLANG_SPEC_VEC2
:
1030 case SLANG_SPEC_IVEC2
:
1031 case SLANG_SPEC_BVEC2
:
1032 case SLANG_SPEC_MAT2
:
1034 case SLANG_SPEC_VEC3
:
1035 case SLANG_SPEC_IVEC3
:
1036 case SLANG_SPEC_BVEC3
:
1037 case SLANG_SPEC_MAT3
:
1039 case SLANG_SPEC_VEC4
:
1040 case SLANG_SPEC_IVEC4
:
1041 case SLANG_SPEC_BVEC4
:
1042 case SLANG_SPEC_MAT4
:
1045 case SLANG_SPEC_MAT23
:
1047 case SLANG_SPEC_MAT32
:
1049 case SLANG_SPEC_MAT24
:
1051 case SLANG_SPEC_MAT42
:
1053 case SLANG_SPEC_MAT34
:
1055 case SLANG_SPEC_MAT43
:
1065 * Return the GL_* type that corresponds to a SLANG_SPEC_* type.
1068 _slang_gltype_from_specifier(const slang_type_specifier
*type
)
1070 switch (type
->type
) {
1071 case SLANG_SPEC_BOOL
:
1073 case SLANG_SPEC_BVEC2
:
1074 return GL_BOOL_VEC2
;
1075 case SLANG_SPEC_BVEC3
:
1076 return GL_BOOL_VEC3
;
1077 case SLANG_SPEC_BVEC4
:
1078 return GL_BOOL_VEC4
;
1079 case SLANG_SPEC_INT
:
1081 case SLANG_SPEC_IVEC2
:
1083 case SLANG_SPEC_IVEC3
:
1085 case SLANG_SPEC_IVEC4
:
1087 case SLANG_SPEC_FLOAT
:
1089 case SLANG_SPEC_VEC2
:
1090 return GL_FLOAT_VEC2
;
1091 case SLANG_SPEC_VEC3
:
1092 return GL_FLOAT_VEC3
;
1093 case SLANG_SPEC_VEC4
:
1094 return GL_FLOAT_VEC4
;
1095 case SLANG_SPEC_MAT2
:
1096 return GL_FLOAT_MAT2
;
1097 case SLANG_SPEC_MAT3
:
1098 return GL_FLOAT_MAT3
;
1099 case SLANG_SPEC_MAT4
:
1100 return GL_FLOAT_MAT4
;
1101 case SLANG_SPEC_MAT23
:
1102 return GL_FLOAT_MAT2x3
;
1103 case SLANG_SPEC_MAT32
:
1104 return GL_FLOAT_MAT3x2
;
1105 case SLANG_SPEC_MAT24
:
1106 return GL_FLOAT_MAT2x4
;
1107 case SLANG_SPEC_MAT42
:
1108 return GL_FLOAT_MAT4x2
;
1109 case SLANG_SPEC_MAT34
:
1110 return GL_FLOAT_MAT3x4
;
1111 case SLANG_SPEC_MAT43
:
1112 return GL_FLOAT_MAT4x3
;
1113 case SLANG_SPEC_SAMPLER1D
:
1114 return GL_SAMPLER_1D
;
1115 case SLANG_SPEC_SAMPLER2D
:
1116 return GL_SAMPLER_2D
;
1117 case SLANG_SPEC_SAMPLER3D
:
1118 return GL_SAMPLER_3D
;
1119 case SLANG_SPEC_SAMPLERCUBE
:
1120 return GL_SAMPLER_CUBE
;
1121 case SLANG_SPEC_SAMPLER1DSHADOW
:
1122 return GL_SAMPLER_1D_SHADOW
;
1123 case SLANG_SPEC_SAMPLER2DSHADOW
:
1124 return GL_SAMPLER_2D_SHADOW
;
1125 case SLANG_SPEC_SAMPLER2DRECT
:
1126 return GL_SAMPLER_2D_RECT_ARB
;
1127 case SLANG_SPEC_SAMPLER2DRECTSHADOW
:
1128 return GL_SAMPLER_2D_RECT_SHADOW_ARB
;
1129 case SLANG_SPEC_ARRAY
:
1130 return _slang_gltype_from_specifier(type
->_array
);
1131 case SLANG_SPEC_STRUCT
: