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_assemble_typeinfo.c
32 #include "slang_typeinfo.h"
33 #include "slang_compile.h"
34 #include "slang_error.h"
35 #include "prog_instruction.h"
41 * Checks if a field selector is a general swizzle (an r-value swizzle
42 * with replicated components or an l-value swizzle mask) for a
43 * vector. Returns GL_TRUE if this is the case, <swz> is filled with
44 * swizzle information. Returns GL_FALSE otherwise.
47 _slang_is_swizzle(const char *field
, GLuint rows
, slang_swizzle
* swz
)
50 GLboolean xyzw
= GL_FALSE
, rgba
= GL_FALSE
, stpq
= GL_FALSE
;
53 * We rely on undefined/nil values to distinguish between
54 * regular swizzles and writemasks.
55 * For example, the swizzle ".xNNN" is the writemask ".x".
56 * That's different than the swizzle ".xxxx".
58 for (i
= 0; i
< 4; i
++)
59 swz
->swizzle
[i
] = SWIZZLE_NIL
;
61 /* the swizzle can be at most 4-component long */
62 swz
->num_components
= slang_string_length(field
);
63 if (swz
->num_components
> 4)
66 for (i
= 0; i
< swz
->num_components
; i
++) {
67 /* mark which swizzle group is used */
91 /* collect swizzle component */
115 /* check if the component is valid for given vector's row count */
116 if (rows
<= swz
->swizzle
[i
])
120 /* only one swizzle group can be used */
121 if ((xyzw
&& rgba
) || (xyzw
&& stpq
) || (rgba
&& stpq
))
130 * Checks if a general swizzle is an l-value swizzle - these swizzles
131 * do not have duplicated fields. Returns GL_TRUE if this is a
132 * swizzle mask. Returns GL_FALSE otherwise
135 _slang_is_swizzle_mask(const slang_swizzle
* swz
, GLuint rows
)
139 /* the swizzle may not be longer than the vector dim */
140 if (swz
->num_components
> rows
)
143 /* the swizzle components cannot be duplicated */
144 for (i
= 0; i
< swz
->num_components
; i
++) {
145 if ((c
& (1 << swz
->swizzle
[i
])) != 0)
147 c
|= 1 << swz
->swizzle
[i
];
155 * Combines (multiplies) two swizzles to form single swizzle.
156 * Example: "vec.wzyx.yx" --> "vec.zw".
159 _slang_multiply_swizzles(slang_swizzle
* dst
, const slang_swizzle
* left
,
160 const slang_swizzle
* right
)
164 dst
->num_components
= right
->num_components
;
165 for (i
= 0; i
< right
->num_components
; i
++)
166 dst
->swizzle
[i
] = left
->swizzle
[right
->swizzle
[i
]];
171 slang_type_specifier_ctr(slang_type_specifier
* self
)
173 self
->type
= SLANG_SPEC_VOID
;
174 self
->_struct
= NULL
;
179 slang_type_specifier_dtr(slang_type_specifier
* self
)
181 if (self
->_struct
!= NULL
) {
182 slang_struct_destruct(self
->_struct
);
183 slang_alloc_free(self
->_struct
);
185 if (self
->_array
!= NULL
) {
186 slang_type_specifier_dtr(self
->_array
);
187 slang_alloc_free(self
->_array
);
192 slang_type_specifier_copy(slang_type_specifier
* x
,
193 const slang_type_specifier
* y
)
195 slang_type_specifier z
;
197 slang_type_specifier_ctr(&z
);
199 if (z
.type
== SLANG_SPEC_STRUCT
) {
200 z
._struct
= (slang_struct
*) slang_alloc_malloc(sizeof(slang_struct
));
201 if (z
._struct
== NULL
) {
202 slang_type_specifier_dtr(&z
);
205 if (!slang_struct_construct(z
._struct
)) {
206 slang_alloc_free(z
._struct
);
207 slang_type_specifier_dtr(&z
);
210 if (!slang_struct_copy(z
._struct
, y
->_struct
)) {
211 slang_type_specifier_dtr(&z
);
215 else if (z
.type
== SLANG_SPEC_ARRAY
) {
217 (slang_type_specifier
*)
218 slang_alloc_malloc(sizeof(slang_type_specifier
));
219 if (z
._array
== NULL
) {
220 slang_type_specifier_dtr(&z
);
223 slang_type_specifier_ctr(z
._array
);
224 if (!slang_type_specifier_copy(z
._array
, y
->_array
)) {
225 slang_type_specifier_dtr(&z
);
229 slang_type_specifier_dtr(x
);
236 * Test if two types are equal.
239 slang_type_specifier_equal(const slang_type_specifier
* x
,
240 const slang_type_specifier
* y
)
242 if (x
->type
!= y
->type
)
244 if (x
->type
== SLANG_SPEC_STRUCT
)
245 return slang_struct_equal(x
->_struct
, y
->_struct
);
246 if (x
->type
== SLANG_SPEC_ARRAY
)
247 return slang_type_specifier_equal(x
->_array
, y
->_array
);
253 * As above, but allow float/int casting.
256 slang_type_specifier_compatible(const slang_type_specifier
* x
,
257 const slang_type_specifier
* y
)
259 /* special case: float == int */
260 if (x
->type
== SLANG_SPEC_INT
&& y
->type
== SLANG_SPEC_FLOAT
) {
263 /* XXX may need to add bool/int compatibility, etc */
265 if (x
->type
!= y
->type
)
267 if (x
->type
== SLANG_SPEC_STRUCT
)
268 return slang_struct_equal(x
->_struct
, y
->_struct
);
269 if (x
->type
== SLANG_SPEC_ARRAY
)
270 return slang_type_specifier_compatible(x
->_array
, y
->_array
);
276 slang_typeinfo_construct(slang_typeinfo
* ti
)
278 slang_type_specifier_ctr(&ti
->spec
);
284 slang_typeinfo_destruct(slang_typeinfo
* ti
)
286 slang_type_specifier_dtr(&ti
->spec
);
291 * Determine the return type of a function.
292 * \param name name of the function
293 * \param params array of function parameters
294 * \param num_params number of parameters
295 * \param space namespace to use
296 * \param spec returns the function's type
297 * \param atoms atom pool
298 * \return GL_TRUE for success, GL_FALSE if failure
301 typeof_existing_function(const char *name
, const slang_operation
* params
,
303 const slang_name_space
* space
,
304 slang_type_specifier
* spec
,
305 slang_atom_pool
* atoms
)
310 atom
= slang_atom_pool_atom(atoms
, name
);
311 if (!_slang_typeof_function(atom
, params
, num_params
, space
, spec
,
318 _slang_typeof_operation(const slang_assemble_ctx
* A
,
319 const slang_operation
* op
,
322 return _slang_typeof_operation_(op
, &A
->space
, ti
, A
->atoms
);
327 * Determine the return type of an operation.
328 * \param op the operation node
329 * \param space the namespace to use
330 * \param ti the returned type
331 * \param atoms atom pool
332 * \return GL_TRUE for success, GL_FALSE if failure
335 _slang_typeof_operation_(const slang_operation
* op
,
336 const slang_name_space
* space
,
338 slang_atom_pool
* atoms
)
340 ti
->can_be_referenced
= GL_FALSE
;
341 ti
->is_swizzled
= GL_FALSE
;
344 case SLANG_OPER_BLOCK_NO_NEW_SCOPE
:
345 case SLANG_OPER_BLOCK_NEW_SCOPE
:
346 case SLANG_OPER_VARIABLE_DECL
:
348 case SLANG_OPER_BREAK
:
349 case SLANG_OPER_CONTINUE
:
350 case SLANG_OPER_DISCARD
:
351 case SLANG_OPER_RETURN
:
353 case SLANG_OPER_WHILE
:
356 case SLANG_OPER_VOID
:
357 ti
->spec
.type
= SLANG_SPEC_VOID
;
359 case SLANG_OPER_EXPRESSION
:
360 case SLANG_OPER_ASSIGN
:
361 case SLANG_OPER_ADDASSIGN
:
362 case SLANG_OPER_SUBASSIGN
:
363 case SLANG_OPER_MULASSIGN
:
364 case SLANG_OPER_DIVASSIGN
:
365 case SLANG_OPER_PREINCREMENT
:
366 case SLANG_OPER_PREDECREMENT
:
367 if (!_slang_typeof_operation_(op
->children
, space
, ti
, atoms
))
370 case SLANG_OPER_LITERAL_BOOL
:
371 if (op
->literal_size
== 1)
372 ti
->spec
.type
= SLANG_SPEC_BOOL
;
373 else if (op
->literal_size
== 2)
374 ti
->spec
.type
= SLANG_SPEC_BVEC2
;
375 else if (op
->literal_size
== 3)
376 ti
->spec
.type
= SLANG_SPEC_BVEC3
;
377 else if (op
->literal_size
== 4)
378 ti
->spec
.type
= SLANG_SPEC_BVEC4
;
381 "Unexpected bool literal_size %d in _slang_typeof_operation()",
383 ti
->spec
.type
= SLANG_SPEC_BOOL
;
386 case SLANG_OPER_LOGICALOR
:
387 case SLANG_OPER_LOGICALXOR
:
388 case SLANG_OPER_LOGICALAND
:
389 case SLANG_OPER_EQUAL
:
390 case SLANG_OPER_NOTEQUAL
:
391 case SLANG_OPER_LESS
:
392 case SLANG_OPER_GREATER
:
393 case SLANG_OPER_LESSequal
:
394 case SLANG_OPER_GREATERequal
:
396 ti
->spec
.type
= SLANG_SPEC_BOOL
;
398 case SLANG_OPER_LITERAL_INT
:
399 if (op
->literal_size
== 1)
400 ti
->spec
.type
= SLANG_SPEC_INT
;
401 else if (op
->literal_size
== 2)
402 ti
->spec
.type
= SLANG_SPEC_IVEC2
;
403 else if (op
->literal_size
== 3)
404 ti
->spec
.type
= SLANG_SPEC_IVEC3
;
405 else if (op
->literal_size
== 4)
406 ti
->spec
.type
= SLANG_SPEC_IVEC4
;
409 "Unexpected int literal_size %d in _slang_typeof_operation()",
411 ti
->spec
.type
= SLANG_SPEC_INT
;
414 case SLANG_OPER_LITERAL_FLOAT
:
415 if (op
->literal_size
== 1)
416 ti
->spec
.type
= SLANG_SPEC_FLOAT
;
417 else if (op
->literal_size
== 2)
418 ti
->spec
.type
= SLANG_SPEC_VEC2
;
419 else if (op
->literal_size
== 3)
420 ti
->spec
.type
= SLANG_SPEC_VEC3
;
421 else if (op
->literal_size
== 4)
422 ti
->spec
.type
= SLANG_SPEC_VEC4
;
425 "Unexpected float literal_size %d in _slang_typeof_operation()",
427 ti
->spec
.type
= SLANG_SPEC_FLOAT
;
430 case SLANG_OPER_IDENTIFIER
:
433 var
= _slang_locate_variable(op
->locals
, op
->a_id
, GL_TRUE
);
435 RETURN_ERROR2("undefined variable", (char *) op
->a_id
, 0);
436 if (!slang_type_specifier_copy(&ti
->spec
, &var
->type
.specifier
))
437 RETURN_OUT_OF_MEMORY();
438 ti
->can_be_referenced
= GL_TRUE
;
439 ti
->array_len
= var
->array_len
;
442 case SLANG_OPER_SEQUENCE
:
443 /* TODO: check [0] and [1] if they match */
444 if (!_slang_typeof_operation_(&op
->children
[1], space
, ti
, atoms
))
446 ti
->can_be_referenced
= GL_FALSE
;
447 ti
->is_swizzled
= GL_FALSE
;
449 /*case SLANG_OPER_MODASSIGN: */
450 /*case SLANG_OPER_LSHASSIGN: */
451 /*case SLANG_OPER_RSHASSIGN: */
452 /*case SLANG_OPER_ORASSIGN: */
453 /*case SLANG_OPER_XORASSIGN: */
454 /*case SLANG_OPER_ANDASSIGN: */
455 case SLANG_OPER_SELECT
:
456 /* TODO: check [1] and [2] if they match */
457 if (!_slang_typeof_operation_(&op
->children
[1], space
, ti
, atoms
))
459 ti
->can_be_referenced
= GL_FALSE
;
460 ti
->is_swizzled
= GL_FALSE
;
462 /*case SLANG_OPER_BITOR: */
463 /*case SLANG_OPER_BITXOR: */
464 /*case SLANG_OPER_BITAND: */
465 /*case SLANG_OPER_LSHIFT: */
466 /*case SLANG_OPER_RSHIFT: */
468 if (!typeof_existing_function("+", op
->children
, 2, space
,
472 case SLANG_OPER_SUBTRACT
:
473 if (!typeof_existing_function("-", op
->children
, 2, space
,
477 case SLANG_OPER_MULTIPLY
:
478 if (!typeof_existing_function("*", op
->children
, 2, space
,
482 case SLANG_OPER_DIVIDE
:
483 if (!typeof_existing_function("/", op
->children
, 2, space
,
487 /*case SLANG_OPER_MODULUS: */
488 case SLANG_OPER_PLUS
:
489 if (!_slang_typeof_operation_(op
->children
, space
, ti
, atoms
))
491 ti
->can_be_referenced
= GL_FALSE
;
492 ti
->is_swizzled
= GL_FALSE
;
494 case SLANG_OPER_MINUS
:
495 if (!typeof_existing_function("-", op
->children
, 1, space
,
499 /*case SLANG_OPER_COMPLEMENT: */
500 case SLANG_OPER_SUBSCRIPT
:
504 if (!slang_typeinfo_construct(&_ti
))
506 if (!_slang_typeof_operation_(op
->children
, space
, &_ti
, atoms
)) {
507 slang_typeinfo_destruct(&_ti
);
510 ti
->can_be_referenced
= _ti
.can_be_referenced
;
511 if (_ti
.spec
.type
== SLANG_SPEC_ARRAY
) {
512 if (!slang_type_specifier_copy(&ti
->spec
, _ti
.spec
._array
)) {
513 slang_typeinfo_destruct(&_ti
);
518 if (!_slang_type_is_vector(_ti
.spec
.type
)
519 && !_slang_type_is_matrix(_ti
.spec
.type
)) {
520 slang_typeinfo_destruct(&_ti
);
521 RETURN_ERROR("cannot index a non-array type", 0);
523 ti
->spec
.type
= _slang_type_base(_ti
.spec
.type
);
525 slang_typeinfo_destruct(&_ti
);
528 case SLANG_OPER_CALL
:
532 if (!_slang_typeof_function(op
->a_id
, op
->children
, op
->num_children
,
533 space
, &ti
->spec
, &exists
, atoms
))
537 slang_struct_scope_find(space
->structs
, op
->a_id
, GL_TRUE
);
539 ti
->spec
.type
= SLANG_SPEC_STRUCT
;
541 (slang_struct
*) slang_alloc_malloc(sizeof(slang_struct
));
542 if (ti
->spec
._struct
== NULL
)
544 if (!slang_struct_construct(ti
->spec
._struct
)) {
545 slang_alloc_free(ti
->spec
._struct
);
546 ti
->spec
._struct
= NULL
;
549 if (!slang_struct_copy(ti
->spec
._struct
, s
))
554 slang_type_specifier_type type
;
556 name
= slang_atom_pool_id(atoms
, op
->a_id
);
557 type
= slang_type_specifier_type_from_string(name
);
558 if (type
== SLANG_SPEC_VOID
)
559 RETURN_ERROR2("function not found", name
, 0);
560 ti
->spec
.type
= type
;
565 case SLANG_OPER_FIELD
:
569 if (!slang_typeinfo_construct(&_ti
))
571 if (!_slang_typeof_operation_(op
->children
, space
, &_ti
, atoms
)) {
572 slang_typeinfo_destruct(&_ti
);
575 if (_ti
.spec
.type
== SLANG_SPEC_STRUCT
) {
576 slang_variable
*field
;
578 field
= _slang_locate_variable(_ti
.spec
._struct
->fields
, op
->a_id
,
581 slang_typeinfo_destruct(&_ti
);
584 if (!slang_type_specifier_copy(&ti
->spec
, &field
->type
.specifier
)) {
585 slang_typeinfo_destruct(&_ti
);
588 ti
->can_be_referenced
= _ti
.can_be_referenced
;
593 slang_type_specifier_type base
;
595 /* determine the swizzle of the field expression */
597 if (!_slang_type_is_vector(_ti
.spec
.type
)) {
598 slang_typeinfo_destruct(&_ti
);
599 RETURN_ERROR("Can't swizzle scalar expression", 0);
602 rows
= _slang_type_dim(_ti
.spec
.type
);
603 swizzle
= slang_atom_pool_id(atoms
, op
->a_id
);
604 if (!_slang_is_swizzle(swizzle
, rows
, &ti
->swz
)) {
605 slang_typeinfo_destruct(&_ti
);
606 RETURN_ERROR("Bad swizzle", 0);
608 ti
->is_swizzled
= GL_TRUE
;
609 ti
->can_be_referenced
= _ti
.can_be_referenced
610 && _slang_is_swizzle_mask(&ti
->swz
, rows
);
611 if (_ti
.is_swizzled
) {
614 /* swizzle the swizzle */
615 _slang_multiply_swizzles(&swz
, &_ti
.swz
, &ti
->swz
);
618 base
= _slang_type_base(_ti
.spec
.type
);
619 switch (ti
->swz
.num_components
) {
621 ti
->spec
.type
= base
;
625 case SLANG_SPEC_FLOAT
:
626 ti
->spec
.type
= SLANG_SPEC_VEC2
;
629 ti
->spec
.type
= SLANG_SPEC_IVEC2
;
631 case SLANG_SPEC_BOOL
:
632 ti
->spec
.type
= SLANG_SPEC_BVEC2
;
640 case SLANG_SPEC_FLOAT
:
641 ti
->spec
.type
= SLANG_SPEC_VEC3
;
644 ti
->spec
.type
= SLANG_SPEC_IVEC3
;
646 case SLANG_SPEC_BOOL
:
647 ti
->spec
.type
= SLANG_SPEC_BVEC3
;
655 case SLANG_SPEC_FLOAT
:
656 ti
->spec
.type
= SLANG_SPEC_VEC4
;
659 ti
->spec
.type
= SLANG_SPEC_IVEC4
;
661 case SLANG_SPEC_BOOL
:
662 ti
->spec
.type
= SLANG_SPEC_BVEC4
;
672 slang_typeinfo_destruct(&_ti
);
675 case SLANG_OPER_POSTINCREMENT
:
676 case SLANG_OPER_POSTDECREMENT
:
677 if (!_slang_typeof_operation_(op
->children
, space
, ti
, atoms
))
679 ti
->can_be_referenced
= GL_FALSE
;
680 ti
->is_swizzled
= GL_FALSE
;
691 * Lookup a function according to name and parameter count/types.
694 _slang_locate_function(const slang_function_scope
* funcs
, slang_atom a_name
,
695 const slang_operation
* args
, GLuint num_args
,
696 const slang_name_space
* space
, slang_atom_pool
* atoms
)
700 for (i
= 0; i
< funcs
->num_functions
; i
++) {
701 slang_function
*f
= &funcs
->functions
[i
];
702 const GLuint haveRetValue
= _slang_function_has_return_value(f
);
705 if (a_name
!= f
->header
.a_name
)
707 if (f
->param_count
- haveRetValue
!= num_args
)
710 /* compare parameter / argument types */
711 for (j
= 0; j
< num_args
; j
++) {
714 if (!slang_typeinfo_construct(&ti
))
716 if (!_slang_typeof_operation_(&args
[j
], space
, &ti
, atoms
)) {
717 slang_typeinfo_destruct(&ti
);
720 if (!slang_type_specifier_compatible(&ti
.spec
,
721 &f
->parameters
->variables
[j
]->type
.specifier
)) {
722 slang_typeinfo_destruct(&ti
);
725 slang_typeinfo_destruct(&ti
);
727 /* "out" and "inout" formal parameter requires the actual
728 * parameter to be l-value.
730 if (!ti
.can_be_referenced
&&
731 (f
->parameters
->variables
[j
]->type
.qualifier
== SLANG_QUAL_OUT
||
732 f
->parameters
->variables
[j
]->type
.qualifier
== SLANG_QUAL_INOUT
))
738 if (funcs
->outer_scope
!= NULL
)
739 return _slang_locate_function(funcs
->outer_scope
, a_name
, args
,
740 num_args
, space
, atoms
);
747 * Determine the return type of a function.
748 * \param a_name the function name
749 * \param param function parameters (overloading)
750 * \param num_params number of parameters to function
751 * \param space namespace to search
752 * \param exists returns GL_TRUE or GL_FALSE to indicate existance of function
753 * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
756 _slang_typeof_function(slang_atom a_name
, const slang_operation
* params
,
758 const slang_name_space
* space
,
759 slang_type_specifier
* spec
, GLboolean
* exists
,
760 slang_atom_pool
* atoms
)
762 slang_function
*fun
= _slang_locate_function(space
->funcs
, a_name
, params
,
763 num_params
, space
, atoms
);
764 *exists
= fun
!= NULL
;
766 return GL_TRUE
; /* yes, not false */
767 return slang_type_specifier_copy(spec
, &fun
->header
.type
.specifier
);
773 * Determine if a type is a matrix.
774 * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
777 _slang_type_is_matrix(slang_type_specifier_type ty
)
780 case SLANG_SPEC_MAT2
:
781 case SLANG_SPEC_MAT3
:
782 case SLANG_SPEC_MAT4
:
791 * Determine if a type is a vector.
792 * \return GL_TRUE if is a vector, GL_FALSE otherwise.
795 _slang_type_is_vector(slang_type_specifier_type ty
)
798 case SLANG_SPEC_VEC2
:
799 case SLANG_SPEC_VEC3
:
800 case SLANG_SPEC_VEC4
:
801 case SLANG_SPEC_IVEC2
:
802 case SLANG_SPEC_IVEC3
:
803 case SLANG_SPEC_IVEC4
:
804 case SLANG_SPEC_BVEC2
:
805 case SLANG_SPEC_BVEC3
:
806 case SLANG_SPEC_BVEC4
:
815 * Given a vector type, return the type of the vector's elements
817 slang_type_specifier_type
818 _slang_type_base(slang_type_specifier_type ty
)
821 case SLANG_SPEC_FLOAT
:
822 case SLANG_SPEC_VEC2
:
823 case SLANG_SPEC_VEC3
:
824 case SLANG_SPEC_VEC4
:
825 return SLANG_SPEC_FLOAT
;
827 case SLANG_SPEC_IVEC2
:
828 case SLANG_SPEC_IVEC3
:
829 case SLANG_SPEC_IVEC4
:
830 return SLANG_SPEC_INT
;
831 case SLANG_SPEC_BOOL
:
832 case SLANG_SPEC_BVEC2
:
833 case SLANG_SPEC_BVEC3
:
834 case SLANG_SPEC_BVEC4
:
835 return SLANG_SPEC_BOOL
;
836 case SLANG_SPEC_MAT2
:
837 return SLANG_SPEC_VEC2
;
838 case SLANG_SPEC_MAT3
:
839 return SLANG_SPEC_VEC3
;
840 case SLANG_SPEC_MAT4
:
841 return SLANG_SPEC_VEC4
;
843 return SLANG_SPEC_VOID
;
849 * Return the dimensionality of a vector or matrix type.
852 _slang_type_dim(slang_type_specifier_type ty
)
855 case SLANG_SPEC_FLOAT
:
857 case SLANG_SPEC_BOOL
:
859 case SLANG_SPEC_VEC2
:
860 case SLANG_SPEC_IVEC2
:
861 case SLANG_SPEC_BVEC2
:
862 case SLANG_SPEC_MAT2
:
864 case SLANG_SPEC_VEC3
:
865 case SLANG_SPEC_IVEC3
:
866 case SLANG_SPEC_BVEC3
:
867 case SLANG_SPEC_MAT3
:
869 case SLANG_SPEC_VEC4
:
870 case SLANG_SPEC_IVEC4
:
871 case SLANG_SPEC_BVEC4
:
872 case SLANG_SPEC_MAT4
: