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
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
]];
170 slang_type_specifier_ctr(slang_type_specifier
* self
)
172 self
->type
= SLANG_SPEC_VOID
;
173 self
->_struct
= NULL
;
178 slang_type_specifier_dtr(slang_type_specifier
* self
)
180 if (self
->_struct
!= NULL
) {
181 slang_struct_destruct(self
->_struct
);
182 _slang_free(self
->_struct
);
184 if (self
->_array
!= NULL
) {
185 slang_type_specifier_dtr(self
->_array
);
186 _slang_free(self
->_array
);
191 slang_type_specifier_copy(slang_type_specifier
* x
,
192 const slang_type_specifier
* y
)
194 slang_type_specifier z
;
196 slang_type_specifier_ctr(&z
);
198 if (z
.type
== SLANG_SPEC_STRUCT
) {
199 z
._struct
= (slang_struct
*) _slang_alloc(sizeof(slang_struct
));
200 if (z
._struct
== NULL
) {
201 slang_type_specifier_dtr(&z
);
204 if (!slang_struct_construct(z
._struct
)) {
205 _slang_free(z
._struct
);
206 slang_type_specifier_dtr(&z
);
209 if (!slang_struct_copy(z
._struct
, y
->_struct
)) {
210 slang_type_specifier_dtr(&z
);
214 else if (z
.type
== SLANG_SPEC_ARRAY
) {
215 z
._array
= (slang_type_specifier
*)
216 _slang_alloc(sizeof(slang_type_specifier
));
217 if (z
._array
== NULL
) {
218 slang_type_specifier_dtr(&z
);
221 slang_type_specifier_ctr(z
._array
);
222 if (!slang_type_specifier_copy(z
._array
, y
->_array
)) {
223 slang_type_specifier_dtr(&z
);
227 slang_type_specifier_dtr(x
);
234 * Test if two types are equal.
237 slang_type_specifier_equal(const slang_type_specifier
* x
,
238 const slang_type_specifier
* y
)
240 if (x
->type
!= y
->type
)
242 if (x
->type
== SLANG_SPEC_STRUCT
)
243 return slang_struct_equal(x
->_struct
, y
->_struct
);
244 if (x
->type
== SLANG_SPEC_ARRAY
)
245 return slang_type_specifier_equal(x
->_array
, y
->_array
);
251 * As above, but allow float/int casting.
254 slang_type_specifier_compatible(const slang_type_specifier
* x
,
255 const slang_type_specifier
* y
)
257 /* special case: float == int */
258 if (x
->type
== SLANG_SPEC_INT
&& y
->type
== SLANG_SPEC_FLOAT
) {
261 /* XXX may need to add bool/int compatibility, etc */
263 if (x
->type
!= y
->type
)
265 if (x
->type
== SLANG_SPEC_STRUCT
)
266 return slang_struct_equal(x
->_struct
, y
->_struct
);
267 if (x
->type
== SLANG_SPEC_ARRAY
)
268 return slang_type_specifier_compatible(x
->_array
, y
->_array
);
274 slang_typeinfo_construct(slang_typeinfo
* ti
)
276 /*_mesa_bzero(ti, sizeof(*ti));*/
277 slang_type_specifier_ctr(&ti
->spec
);
283 slang_typeinfo_destruct(slang_typeinfo
* ti
)
285 slang_type_specifier_dtr(&ti
->spec
);
291 * Determine the return type of a function.
292 * \param a_name the function name
293 * \param param function parameters (overloading)
294 * \param num_params number of parameters to function
295 * \param space namespace to search
296 * \param spec returns the type
297 * \param funFound returns pointer to the function, or NULL if not found.
298 * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
301 _slang_typeof_function(slang_atom a_name
,
302 slang_operation
* params
, GLuint num_params
,
303 const slang_name_space
* space
,
304 slang_type_specifier
* spec
,
305 slang_function
**funFound
,
306 slang_atom_pool
*atoms
, slang_info_log
*log
)
310 *funFound
= _slang_locate_function(space
->funcs
, a_name
, params
,
311 num_params
, space
, atoms
, log
, &error
);
316 return GL_TRUE
; /* yes, not false */
318 return slang_type_specifier_copy(spec
, &(*funFound
)->header
.type
.specifier
);
323 * Determine the type of a math function.
324 * \param name name of the operator, one of +,-,*,/ or unary -
325 * \param params array of function parameters
326 * \param num_params number of parameters
327 * \param space namespace to use
328 * \param spec returns the function's type
329 * \param atoms atom pool
330 * \return GL_TRUE for success, GL_FALSE if failure
333 typeof_math_call(const char *name
, slang_operation
*call
,
334 const slang_name_space
* space
,
335 slang_type_specifier
* spec
,
336 slang_atom_pool
* atoms
,
340 /* we've previously resolved this function call */
341 slang_type_specifier_copy(spec
, &call
->fun
->header
.type
.specifier
);
348 /* number of params: */
349 assert(call
->num_children
== 1 || call
->num_children
== 2);
351 atom
= slang_atom_pool_atom(atoms
, name
);
352 if (!_slang_typeof_function(atom
, call
->children
, call
->num_children
,
353 space
, spec
, &fun
, atoms
, log
))
357 /* Save pointer to save time in future */
366 _slang_typeof_operation(const slang_assemble_ctx
* A
,
367 slang_operation
* op
,
370 return _slang_typeof_operation_(op
, &A
->space
, ti
, A
->atoms
, A
->log
);
375 * Determine the return type of an operation.
376 * \param op the operation node
377 * \param space the namespace to use
378 * \param ti the returned type
379 * \param atoms atom pool
380 * \return GL_TRUE for success, GL_FALSE if failure
383 _slang_typeof_operation_(slang_operation
* op
,
384 const slang_name_space
* space
,
386 slang_atom_pool
* atoms
,
389 ti
->can_be_referenced
= GL_FALSE
;
390 ti
->is_swizzled
= GL_FALSE
;
393 case SLANG_OPER_BLOCK_NO_NEW_SCOPE
:
394 case SLANG_OPER_BLOCK_NEW_SCOPE
:
396 case SLANG_OPER_BREAK
:
397 case SLANG_OPER_CONTINUE
:
398 case SLANG_OPER_DISCARD
:
399 case SLANG_OPER_RETURN
:
401 case SLANG_OPER_WHILE
:
404 case SLANG_OPER_VOID
:
405 ti
->spec
.type
= SLANG_SPEC_VOID
;
407 case SLANG_OPER_EXPRESSION
:
408 case SLANG_OPER_ASSIGN
:
409 case SLANG_OPER_ADDASSIGN
:
410 case SLANG_OPER_SUBASSIGN
:
411 case SLANG_OPER_MULASSIGN
:
412 case SLANG_OPER_DIVASSIGN
:
413 case SLANG_OPER_PREINCREMENT
:
414 case SLANG_OPER_PREDECREMENT
:
415 if (!_slang_typeof_operation_(op
->children
, space
, ti
, atoms
, log
))
418 case SLANG_OPER_LITERAL_BOOL
:
419 if (op
->literal_size
== 1)
420 ti
->spec
.type
= SLANG_SPEC_BOOL
;
421 else if (op
->literal_size
== 2)
422 ti
->spec
.type
= SLANG_SPEC_BVEC2
;
423 else if (op
->literal_size
== 3)
424 ti
->spec
.type
= SLANG_SPEC_BVEC3
;
425 else if (op
->literal_size
== 4)
426 ti
->spec
.type
= SLANG_SPEC_BVEC4
;
429 "Unexpected bool literal_size %d in _slang_typeof_operation()",
431 ti
->spec
.type
= SLANG_SPEC_BOOL
;
434 case SLANG_OPER_LOGICALOR
:
435 case SLANG_OPER_LOGICALXOR
:
436 case SLANG_OPER_LOGICALAND
:
437 case SLANG_OPER_EQUAL
:
438 case SLANG_OPER_NOTEQUAL
:
439 case SLANG_OPER_LESS
:
440 case SLANG_OPER_GREATER
:
441 case SLANG_OPER_LESSEQUAL
:
442 case SLANG_OPER_GREATEREQUAL
:
444 ti
->spec
.type
= SLANG_SPEC_BOOL
;
446 case SLANG_OPER_LITERAL_INT
:
447 if (op
->literal_size
== 1)
448 ti
->spec
.type
= SLANG_SPEC_INT
;
449 else if (op
->literal_size
== 2)
450 ti
->spec
.type
= SLANG_SPEC_IVEC2
;
451 else if (op
->literal_size
== 3)
452 ti
->spec
.type
= SLANG_SPEC_IVEC3
;
453 else if (op
->literal_size
== 4)
454 ti
->spec
.type
= SLANG_SPEC_IVEC4
;
457 "Unexpected int literal_size %d in _slang_typeof_operation()",
459 ti
->spec
.type
= SLANG_SPEC_INT
;
462 case SLANG_OPER_LITERAL_FLOAT
:
463 if (op
->literal_size
== 1)
464 ti
->spec
.type
= SLANG_SPEC_FLOAT
;
465 else if (op
->literal_size
== 2)
466 ti
->spec
.type
= SLANG_SPEC_VEC2
;
467 else if (op
->literal_size
== 3)
468 ti
->spec
.type
= SLANG_SPEC_VEC3
;
469 else if (op
->literal_size
== 4)
470 ti
->spec
.type
= SLANG_SPEC_VEC4
;
473 "Unexpected float literal_size %d in _slang_typeof_operation()",
475 ti
->spec
.type
= SLANG_SPEC_FLOAT
;
478 case SLANG_OPER_IDENTIFIER
:
479 case SLANG_OPER_VARIABLE_DECL
:
482 var
= _slang_locate_variable(op
->locals
, op
->a_id
, GL_TRUE
);
484 slang_info_log_error(log
, "undefined variable '%s'",
488 if (!slang_type_specifier_copy(&ti
->spec
, &var
->type
.specifier
)) {
489 slang_info_log_memory(log
);
492 ti
->can_be_referenced
= GL_TRUE
;
493 ti
->array_len
= var
->array_len
;
496 case SLANG_OPER_SEQUENCE
:
497 /* TODO: check [0] and [1] if they match */
498 if (!_slang_typeof_operation_(&op
->children
[1], space
, ti
, atoms
, log
)) {
501 ti
->can_be_referenced
= GL_FALSE
;
502 ti
->is_swizzled
= GL_FALSE
;
504 /*case SLANG_OPER_MODASSIGN: */
505 /*case SLANG_OPER_LSHASSIGN: */
506 /*case SLANG_OPER_RSHASSIGN: */
507 /*case SLANG_OPER_ORASSIGN: */
508 /*case SLANG_OPER_XORASSIGN: */
509 /*case SLANG_OPER_ANDASSIGN: */
510 case SLANG_OPER_SELECT
:
511 /* TODO: check [1] and [2] if they match */
512 if (!_slang_typeof_operation_(&op
->children
[1], space
, ti
, atoms
, log
)) {
515 ti
->can_be_referenced
= GL_FALSE
;
516 ti
->is_swizzled
= GL_FALSE
;
518 /*case SLANG_OPER_BITOR: */
519 /*case SLANG_OPER_BITXOR: */
520 /*case SLANG_OPER_BITAND: */
521 /*case SLANG_OPER_LSHIFT: */
522 /*case SLANG_OPER_RSHIFT: */
524 assert(op
->num_children
== 2);
525 if (!typeof_math_call("+", op
, space
, &ti
->spec
, atoms
, log
))
528 case SLANG_OPER_SUBTRACT
:
529 assert(op
->num_children
== 2);
530 if (!typeof_math_call("-", op
, space
, &ti
->spec
, atoms
, log
))
533 case SLANG_OPER_MULTIPLY
:
534 assert(op
->num_children
== 2);
535 if (!typeof_math_call("*", op
, space
, &ti
->spec
, atoms
, log
))
538 case SLANG_OPER_DIVIDE
:
539 assert(op
->num_children
== 2);
540 if (!typeof_math_call("/", op
, space
, &ti
->spec
, atoms
, log
))
543 /*case SLANG_OPER_MODULUS: */
544 case SLANG_OPER_PLUS
:
545 if (!_slang_typeof_operation_(op
->children
, space
, ti
, atoms
, log
))
547 ti
->can_be_referenced
= GL_FALSE
;
548 ti
->is_swizzled
= GL_FALSE
;
550 case SLANG_OPER_MINUS
:
551 assert(op
->num_children
== 1);
552 if (!typeof_math_call("-", op
, space
, &ti
->spec
, atoms
, log
))
555 /*case SLANG_OPER_COMPLEMENT: */
556 case SLANG_OPER_SUBSCRIPT
:
560 if (!slang_typeinfo_construct(&_ti
))
562 if (!_slang_typeof_operation_(op
->children
, space
, &_ti
, atoms
, log
)) {
563 slang_typeinfo_destruct(&_ti
);
566 ti
->can_be_referenced
= _ti
.can_be_referenced
;
567 if (_ti
.spec
.type
== SLANG_SPEC_ARRAY
) {
568 if (!slang_type_specifier_copy(&ti
->spec
, _ti
.spec
._array
)) {
569 slang_typeinfo_destruct(&_ti
);
574 if (!_slang_type_is_vector(_ti
.spec
.type
)
575 && !_slang_type_is_matrix(_ti
.spec
.type
)) {
576 slang_typeinfo_destruct(&_ti
);
577 slang_info_log_error(log
, "cannot index a non-array type");
580 ti
->spec
.type
= _slang_type_base(_ti
.spec
.type
);
582 slang_typeinfo_destruct(&_ti
);
585 case SLANG_OPER_CALL
:
587 /* we've resolved this call before */
588 slang_type_specifier_copy(&ti
->spec
, &op
->fun
->header
.type
.specifier
);
592 if (!_slang_typeof_function(op
->a_id
, op
->children
, op
->num_children
,
593 space
, &ti
->spec
, &fun
, atoms
, log
))
596 /* save result for future use */
601 slang_struct_scope_find(space
->structs
, op
->a_id
, GL_TRUE
);
603 /* struct initializer */
604 ti
->spec
.type
= SLANG_SPEC_STRUCT
;
606 (slang_struct
*) _slang_alloc(sizeof(slang_struct
));
607 if (ti
->spec
._struct
== NULL
)
609 if (!slang_struct_construct(ti
->spec
._struct
)) {
610 _slang_free(ti
->spec
._struct
);
611 ti
->spec
._struct
= NULL
;
614 if (!slang_struct_copy(ti
->spec
._struct
, s
))
618 /* float, int, vec4, mat3, etc. constructor? */
620 slang_type_specifier_type type
;
622 name
= slang_atom_pool_id(atoms
, op
->a_id
);
623 type
= slang_type_specifier_type_from_string(name
);
624 if (type
== SLANG_SPEC_VOID
) {
625 slang_info_log_error(log
, "undefined function '%s'", name
);
628 ti
->spec
.type
= type
;
633 case SLANG_OPER_FIELD
:
637 if (!slang_typeinfo_construct(&_ti
))
639 if (!_slang_typeof_operation_(op
->children
, space
, &_ti
, atoms
, log
)) {
640 slang_typeinfo_destruct(&_ti
);
643 if (_ti
.spec
.type
== SLANG_SPEC_STRUCT
) {
644 slang_variable
*field
;
646 field
= _slang_locate_variable(_ti
.spec
._struct
->fields
, op
->a_id
,
649 slang_typeinfo_destruct(&_ti
);
652 if (!slang_type_specifier_copy(&ti
->spec
, &field
->type
.specifier
)) {
653 slang_typeinfo_destruct(&_ti
);
656 ti
->can_be_referenced
= _ti
.can_be_referenced
;
661 slang_type_specifier_type base
;
663 /* determine the swizzle of the field expression */
664 if (!_slang_type_is_vector(_ti
.spec
.type
)) {
665 slang_typeinfo_destruct(&_ti
);
666 slang_info_log_error(log
, "Can't swizzle scalar expression");
669 rows
= _slang_type_dim(_ti
.spec
.type
);
670 swizzle
= slang_atom_pool_id(atoms
, op
->a_id
);
671 if (!_slang_is_swizzle(swizzle
, rows
, &ti
->swz
)) {
672 slang_typeinfo_destruct(&_ti
);
673 slang_info_log_error(log
, "bad swizzle '%s'", swizzle
);
676 ti
->is_swizzled
= GL_TRUE
;
677 ti
->can_be_referenced
= _ti
.can_be_referenced
678 && _slang_is_swizzle_mask(&ti
->swz
, rows
);
679 if (_ti
.is_swizzled
) {
682 /* swizzle the swizzle */
683 _slang_multiply_swizzles(&swz
, &_ti
.swz
, &ti
->swz
);
686 base
= _slang_type_base(_ti
.spec
.type
);
687 switch (ti
->swz
.num_components
) {
689 ti
->spec
.type
= base
;
693 case SLANG_SPEC_FLOAT
:
694 ti
->spec
.type
= SLANG_SPEC_VEC2
;
697 ti
->spec
.type
= SLANG_SPEC_IVEC2
;
699 case SLANG_SPEC_BOOL
:
700 ti
->spec
.type
= SLANG_SPEC_BVEC2
;
708 case SLANG_SPEC_FLOAT
:
709 ti
->spec
.type
= SLANG_SPEC_VEC3
;
712 ti
->spec
.type
= SLANG_SPEC_IVEC3
;
714 case SLANG_SPEC_BOOL
:
715 ti
->spec
.type
= SLANG_SPEC_BVEC3
;
723 case SLANG_SPEC_FLOAT
:
724 ti
->spec
.type
= SLANG_SPEC_VEC4
;
727 ti
->spec
.type
= SLANG_SPEC_IVEC4
;
729 case SLANG_SPEC_BOOL
:
730 ti
->spec
.type
= SLANG_SPEC_BVEC4
;
740 slang_typeinfo_destruct(&_ti
);
743 case SLANG_OPER_POSTINCREMENT
:
744 case SLANG_OPER_POSTDECREMENT
:
745 if (!_slang_typeof_operation_(op
->children
, space
, ti
, atoms
, log
))
747 ti
->can_be_referenced
= GL_FALSE
;
748 ti
->is_swizzled
= GL_FALSE
;
759 * Lookup a function according to name and parameter count/types.
762 _slang_locate_function(const slang_function_scope
* funcs
, slang_atom a_name
,
763 slang_operation
* args
, GLuint num_args
,
764 const slang_name_space
* space
, slang_atom_pool
* atoms
,
765 slang_info_log
*log
, GLboolean
*error
)
767 slang_typeinfo arg_ti
[100];
772 /* determine type of each argument */
773 assert(num_args
< 100);
774 for (i
= 0; i
< num_args
; i
++) {
775 if (!slang_typeinfo_construct(&arg_ti
[i
]))
777 if (!_slang_typeof_operation_(&args
[i
], space
, &arg_ti
[i
], atoms
, log
)) {
782 /* loop over function scopes */
785 /* look for function with matching name and argument/param types */
786 for (i
= 0; i
< funcs
->num_functions
; i
++) {
787 slang_function
*f
= &funcs
->functions
[i
];
788 const GLuint haveRetValue
= _slang_function_has_return_value(f
);
791 if (a_name
!= f
->header
.a_name
)
793 if (f
->param_count
- haveRetValue
!= num_args
)
796 /* compare parameter / argument types */
797 for (j
= 0; j
< num_args
; j
++) {
798 if (!slang_type_specifier_compatible(&arg_ti
[j
].spec
,
799 &f
->parameters
->variables
[j
]->type
.specifier
)) {
800 /* param/arg types don't match */
804 /* "out" and "inout" formal parameter requires the actual
805 * argument to be an l-value.
807 if (!arg_ti
[j
].can_be_referenced
&&
808 (f
->parameters
->variables
[j
]->type
.qualifier
== SLANG_QUAL_OUT
||
809 f
->parameters
->variables
[j
]->type
.qualifier
== SLANG_QUAL_INOUT
)) {
810 /* param is not an lvalue! */
817 /* name and args match! */
822 funcs
= funcs
->outer_scope
;
830 * Determine if a type is a matrix.
831 * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
834 _slang_type_is_matrix(slang_type_specifier_type ty
)
837 case SLANG_SPEC_MAT2
:
838 case SLANG_SPEC_MAT3
:
839 case SLANG_SPEC_MAT4
:
840 case SLANG_SPEC_MAT23
:
841 case SLANG_SPEC_MAT32
:
842 case SLANG_SPEC_MAT24
:
843 case SLANG_SPEC_MAT42
:
844 case SLANG_SPEC_MAT34
:
845 case SLANG_SPEC_MAT43
:
854 * Determine if a type is a vector.
855 * \return GL_TRUE if is a vector, GL_FALSE otherwise.
858 _slang_type_is_vector(slang_type_specifier_type ty
)
861 case SLANG_SPEC_VEC2
:
862 case SLANG_SPEC_VEC3
:
863 case SLANG_SPEC_VEC4
:
864 case SLANG_SPEC_IVEC2
:
865 case SLANG_SPEC_IVEC3
:
866 case SLANG_SPEC_IVEC4
:
867 case SLANG_SPEC_BVEC2
:
868 case SLANG_SPEC_BVEC3
:
869 case SLANG_SPEC_BVEC4
:
878 * Determine if a type is a float, float vector or float matrix.
879 * \return GL_TRUE if so, GL_FALSE otherwise
882 _slang_type_is_float_vec_mat(slang_type_specifier_type ty
)
885 case SLANG_SPEC_FLOAT
:
886 case SLANG_SPEC_VEC2
:
887 case SLANG_SPEC_VEC3
:
888 case SLANG_SPEC_VEC4
:
889 case SLANG_SPEC_MAT2
:
890 case SLANG_SPEC_MAT3
:
891 case SLANG_SPEC_MAT4
:
892 case SLANG_SPEC_MAT23
:
893 case SLANG_SPEC_MAT32
:
894 case SLANG_SPEC_MAT24
:
895 case SLANG_SPEC_MAT42
:
896 case SLANG_SPEC_MAT34
:
897 case SLANG_SPEC_MAT43
:
906 * Given a vector type, return the type of the vector's elements.
907 * For a matrix, return the type of the columns.
909 slang_type_specifier_type
910 _slang_type_base(slang_type_specifier_type ty
)
913 case SLANG_SPEC_FLOAT
:
914 case SLANG_SPEC_VEC2
:
915 case SLANG_SPEC_VEC3
:
916 case SLANG_SPEC_VEC4
:
917 return SLANG_SPEC_FLOAT
;
919 case SLANG_SPEC_IVEC2
:
920 case SLANG_SPEC_IVEC3
:
921 case SLANG_SPEC_IVEC4
:
922 return SLANG_SPEC_INT
;
923 case SLANG_SPEC_BOOL
:
924 case SLANG_SPEC_BVEC2
:
925 case SLANG_SPEC_BVEC3
:
926 case SLANG_SPEC_BVEC4
:
927 return SLANG_SPEC_BOOL
;
928 case SLANG_SPEC_MAT2
:
929 return SLANG_SPEC_VEC2
;
930 case SLANG_SPEC_MAT3
:
931 return SLANG_SPEC_VEC3
;
932 case SLANG_SPEC_MAT4
:
933 return SLANG_SPEC_VEC4
;
934 case SLANG_SPEC_MAT23
:
935 return SLANG_SPEC_VEC3
;
936 case SLANG_SPEC_MAT32
:
937 return SLANG_SPEC_VEC2
;
938 case SLANG_SPEC_MAT24
:
939 return SLANG_SPEC_VEC4
;
940 case SLANG_SPEC_MAT42
:
941 return SLANG_SPEC_VEC2
;
942 case SLANG_SPEC_MAT34
:
943 return SLANG_SPEC_VEC4
;
944 case SLANG_SPEC_MAT43
:
945 return SLANG_SPEC_VEC3
;
947 return SLANG_SPEC_VOID
;
953 * Return the dimensionality of a vector, or for a matrix, return number
957 _slang_type_dim(slang_type_specifier_type ty
)
960 case SLANG_SPEC_FLOAT
:
962 case SLANG_SPEC_BOOL
:
964 case SLANG_SPEC_VEC2
:
965 case SLANG_SPEC_IVEC2
:
966 case SLANG_SPEC_BVEC2
:
967 case SLANG_SPEC_MAT2
:
969 case SLANG_SPEC_VEC3
:
970 case SLANG_SPEC_IVEC3
:
971 case SLANG_SPEC_BVEC3
:
972 case SLANG_SPEC_MAT3
:
974 case SLANG_SPEC_VEC4
:
975 case SLANG_SPEC_IVEC4
:
976 case SLANG_SPEC_BVEC4
:
977 case SLANG_SPEC_MAT4
:
980 case SLANG_SPEC_MAT23
:
982 case SLANG_SPEC_MAT32
:
984 case SLANG_SPEC_MAT24
:
986 case SLANG_SPEC_MAT42
:
988 case SLANG_SPEC_MAT34
:
990 case SLANG_SPEC_MAT43
:
1000 * Return the GL_* type that corresponds to a SLANG_SPEC_* type.
1003 _slang_gltype_from_specifier(const slang_type_specifier
*type
)
1005 switch (type
->type
) {
1006 case SLANG_SPEC_BOOL
:
1008 case SLANG_SPEC_BVEC2
:
1009 return GL_BOOL_VEC2
;
1010 case SLANG_SPEC_BVEC3
:
1011 return GL_BOOL_VEC3
;
1012 case SLANG_SPEC_BVEC4
:
1013 return GL_BOOL_VEC4
;
1014 case SLANG_SPEC_INT
:
1016 case SLANG_SPEC_IVEC2
:
1018 case SLANG_SPEC_IVEC3
:
1020 case SLANG_SPEC_IVEC4
:
1022 case SLANG_SPEC_FLOAT
:
1024 case SLANG_SPEC_VEC2
:
1025 return GL_FLOAT_VEC2
;
1026 case SLANG_SPEC_VEC3
:
1027 return GL_FLOAT_VEC3
;
1028 case SLANG_SPEC_VEC4
:
1029 return GL_FLOAT_VEC4
;
1030 case SLANG_SPEC_MAT2
:
1031 return GL_FLOAT_MAT2
;
1032 case SLANG_SPEC_MAT3
:
1033 return GL_FLOAT_MAT3
;
1034 case SLANG_SPEC_MAT4
:
1035 return GL_FLOAT_MAT4
;
1036 case SLANG_SPEC_MAT23
:
1037 return GL_FLOAT_MAT2x3
;
1038 case SLANG_SPEC_MAT32
:
1039 return GL_FLOAT_MAT3x2
;
1040 case SLANG_SPEC_MAT24
:
1041 return GL_FLOAT_MAT2x4
;
1042 case SLANG_SPEC_MAT42
:
1043 return GL_FLOAT_MAT4x2
;
1044 case SLANG_SPEC_MAT34
:
1045 return GL_FLOAT_MAT3x4
;
1046 case SLANG_SPEC_MAT43
:
1047 return GL_FLOAT_MAT4x3
;
1048 case SLANG_SPEC_SAMPLER1D
:
1049 return GL_SAMPLER_1D
;
1050 case SLANG_SPEC_SAMPLER2D
:
1051 return GL_SAMPLER_2D
;
1052 case SLANG_SPEC_SAMPLER3D
:
1053 return GL_SAMPLER_3D
;
1054 case SLANG_SPEC_SAMPLERCUBE
:
1055 return GL_SAMPLER_CUBE
;
1056 case SLANG_SPEC_SAMPLER1DSHADOW
:
1057 return GL_SAMPLER_1D_SHADOW
;
1058 case SLANG_SPEC_SAMPLER2DSHADOW
:
1059 return GL_SAMPLER_2D_SHADOW
;
1060 case SLANG_SPEC_SAMPLER2DRECT
:
1061 return GL_SAMPLER_2D_RECT_ARB
;
1062 case SLANG_SPEC_SAMPLER2DRECTSHADOW
:
1063 return GL_SAMPLER_2D_RECT_SHADOW_ARB
;
1064 case SLANG_SPEC_ARRAY
:
1065 return _slang_gltype_from_specifier(type
->_array
);
1066 case SLANG_SPEC_STRUCT
: