X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fshader%2Fslang%2Fslang_typeinfo.c;h=8a1c3abf4807df21510511cf62f0af37fa05e808;hb=09900df42967a0ba61e78038304fd6c54934ad0d;hp=bbcc1c740c11e2c1a386835a06905fc446871c83;hpb=1c1a0a23d32f889971de61c2c25fa1eebb9889a3;p=mesa.git diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c index bbcc1c740c1..8a1c3abf480 100644 --- a/src/mesa/shader/slang/slang_typeinfo.c +++ b/src/mesa/shader/slang/slang_typeinfo.c @@ -28,13 +28,12 @@ * \author Michal Krol */ -#include "imports.h" +#include "main/imports.h" +#include "shader/prog_instruction.h" #include "slang_typeinfo.h" #include "slang_compile.h" -#include "slang_error.h" -#include "prog_instruction.h" - - +#include "slang_log.h" +#include "slang_mem.h" /** @@ -180,11 +179,11 @@ slang_type_specifier_dtr(slang_type_specifier * self) { if (self->_struct != NULL) { slang_struct_destruct(self->_struct); - slang_alloc_free(self->_struct); + _slang_free(self->_struct); } if (self->_array != NULL) { slang_type_specifier_dtr(self->_array); - slang_alloc_free(self->_array); + _slang_free(self->_array); } } @@ -197,13 +196,13 @@ slang_type_specifier_copy(slang_type_specifier * x, slang_type_specifier_ctr(&z); z.type = y->type; if (z.type == SLANG_SPEC_STRUCT) { - z._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct)); if (z._struct == NULL) { slang_type_specifier_dtr(&z); return GL_FALSE; } if (!slang_struct_construct(z._struct)) { - slang_alloc_free(z._struct); + _slang_free(z._struct); slang_type_specifier_dtr(&z); return GL_FALSE; } @@ -213,9 +212,8 @@ slang_type_specifier_copy(slang_type_specifier * x, } } else if (z.type == SLANG_SPEC_ARRAY) { - z._array = - (slang_type_specifier *) - slang_alloc_malloc(sizeof(slang_type_specifier)); + z._array = (slang_type_specifier *) + _slang_alloc(sizeof(slang_type_specifier)); if (z._array == NULL) { slang_type_specifier_dtr(&z); return GL_FALSE; @@ -287,9 +285,36 @@ slang_typeinfo_destruct(slang_typeinfo * ti) } + /** * Determine the return type of a function. - * \param name name of the function + * \param a_name the function name + * \param param function parameters (overloading) + * \param num_params number of parameters to function + * \param space namespace to search + * \param spec returns the type + * \param funFound returns pointer to the function, or NULL if not found. + * \return GL_TRUE for success, GL_FALSE if failure (bad function name) + */ +static GLboolean +_slang_typeof_function(slang_atom a_name, + slang_operation * params, GLuint num_params, + const slang_name_space * space, + slang_type_specifier * spec, + slang_function **funFound, + slang_atom_pool *atoms, slang_info_log *log) +{ + *funFound = _slang_locate_function(space->funcs, a_name, params, + num_params, space, atoms, log); + if (!*funFound) + return GL_TRUE; /* yes, not false */ + return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier); +} + + +/** + * Determine the type of a math function. + * \param name name of the operator, one of +,-,*,/ or unary - * \param params array of function parameters * \param num_params number of parameters * \param space namespace to use @@ -298,28 +323,44 @@ slang_typeinfo_destruct(slang_typeinfo * ti) * \return GL_TRUE for success, GL_FALSE if failure */ static GLboolean -typeof_existing_function(const char *name, const slang_operation * params, - GLuint num_params, - const slang_name_space * space, - slang_type_specifier * spec, - slang_atom_pool * atoms) +typeof_math_call(const char *name, slang_operation *call, + const slang_name_space * space, + slang_type_specifier * spec, + slang_atom_pool * atoms, + slang_info_log *log) { - slang_atom atom; - GLboolean exists; + if (call->fun) { + /* we've previously resolved this function call */ + slang_type_specifier_copy(spec, &call->fun->header.type.specifier); + return GL_TRUE; + } + else { + slang_atom atom; + slang_function *fun; - atom = slang_atom_pool_atom(atoms, name); - if (!_slang_typeof_function(atom, params, num_params, space, spec, - &exists, atoms)) + /* number of params: */ + assert(call->num_children == 1 || call->num_children == 2); + + atom = slang_atom_pool_atom(atoms, name); + if (!_slang_typeof_function(atom, call->children, call->num_children, + space, spec, &fun, atoms, log)) + return GL_FALSE; + + if (fun) { + /* Save pointer to save time in future */ + call->fun = fun; + return GL_TRUE; + } return GL_FALSE; - return exists; + } } GLboolean _slang_typeof_operation(const slang_assemble_ctx * A, - const slang_operation * op, + slang_operation * op, slang_typeinfo * ti) { - return _slang_typeof_operation_(op, &A->space, ti, A->atoms); + return _slang_typeof_operation_(op, &A->space, ti, A->atoms, A->log); } @@ -332,10 +373,11 @@ _slang_typeof_operation(const slang_assemble_ctx * A, * \return GL_TRUE for success, GL_FALSE if failure */ GLboolean -_slang_typeof_operation_(const slang_operation * op, +_slang_typeof_operation_(slang_operation * op, const slang_name_space * space, slang_typeinfo * ti, - slang_atom_pool * atoms) + slang_atom_pool * atoms, + slang_info_log *log) { ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; @@ -364,7 +406,7 @@ _slang_typeof_operation_(const slang_operation * op, case SLANG_OPER_DIVASSIGN: case SLANG_OPER_PREINCREMENT: case SLANG_OPER_PREDECREMENT: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) return GL_FALSE; break; case SLANG_OPER_LITERAL_BOOL: @@ -390,8 +432,8 @@ _slang_typeof_operation_(const slang_operation * op, case SLANG_OPER_NOTEQUAL: case SLANG_OPER_LESS: case SLANG_OPER_GREATER: - case SLANG_OPER_LESSequal: - case SLANG_OPER_GREATERequal: + case SLANG_OPER_LESSEQUAL: + case SLANG_OPER_GREATEREQUAL: case SLANG_OPER_NOT: ti->spec.type = SLANG_SPEC_BOOL; break; @@ -431,18 +473,24 @@ _slang_typeof_operation_(const slang_operation * op, { slang_variable *var; var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); - if (var == NULL) - RETURN_ERROR2("undefined variable", (char *) op->a_id, 0); - if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) - RETURN_OUT_OF_MEMORY(); + if (!var) { + slang_info_log_error(log, "undefined variable '%s'", + (char *) op->a_id); + return GL_FALSE; + } + if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) { + slang_info_log_memory(log); + return GL_FALSE; + } ti->can_be_referenced = GL_TRUE; ti->array_len = var->array_len; } break; case SLANG_OPER_SEQUENCE: /* TODO: check [0] and [1] if they match */ - if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms, log)) { + return GL_FALSE; + } ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; @@ -454,8 +502,9 @@ _slang_typeof_operation_(const slang_operation * op, /*case SLANG_OPER_ANDASSIGN: */ case SLANG_OPER_SELECT: /* TODO: check [1] and [2] if they match */ - if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms, log)) { + return GL_FALSE; + } ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; @@ -465,36 +514,36 @@ _slang_typeof_operation_(const slang_operation * op, /*case SLANG_OPER_LSHIFT: */ /*case SLANG_OPER_RSHIFT: */ case SLANG_OPER_ADD: - if (!typeof_existing_function("+", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + assert(op->num_children == 2); + if (!typeof_math_call("+", op, space, &ti->spec, atoms, log)) + return GL_FALSE; break; case SLANG_OPER_SUBTRACT: - if (!typeof_existing_function("-", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + assert(op->num_children == 2); + if (!typeof_math_call("-", op, space, &ti->spec, atoms, log)) + return GL_FALSE; break; case SLANG_OPER_MULTIPLY: - if (!typeof_existing_function("*", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + assert(op->num_children == 2); + if (!typeof_math_call("*", op, space, &ti->spec, atoms, log)) + return GL_FALSE; break; case SLANG_OPER_DIVIDE: - if (!typeof_existing_function("/", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + assert(op->num_children == 2); + if (!typeof_math_call("/", op, space, &ti->spec, atoms, log)) + return GL_FALSE; break; - /*case SLANG_OPER_MODULUS: */ + /*case SLANG_OPER_MODULUS: */ case SLANG_OPER_PLUS: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; case SLANG_OPER_MINUS: - if (!typeof_existing_function("-", op->children, 1, space, - &ti->spec, atoms)) - RETURN_NIL(); + assert(op->num_children == 1); + if (!typeof_math_call("-", op, space, &ti->spec, atoms, log)) + return GL_FALSE; break; /*case SLANG_OPER_COMPLEMENT: */ case SLANG_OPER_SUBSCRIPT: @@ -502,23 +551,24 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo _ti; if (!slang_typeinfo_construct(&_ti)) - RETURN_NIL(); - if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } ti->can_be_referenced = _ti.can_be_referenced; if (_ti.spec.type == SLANG_SPEC_ARRAY) { if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } } else { if (!_slang_type_is_vector(_ti.spec.type) && !_slang_type_is_matrix(_ti.spec.type)) { slang_typeinfo_destruct(&_ti); - RETURN_ERROR("cannot index a non-array type", 0); + slang_info_log_error(log, "cannot index a non-array type"); + return GL_FALSE; } ti->spec.type = _slang_type_base(_ti.spec.type); } @@ -526,37 +576,48 @@ _slang_typeof_operation_(const slang_operation * op, } break; case SLANG_OPER_CALL: - { - GLboolean exists; - + if (op->fun) { + /* we've resolved this call before */ + slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier); + } + else { + slang_function *fun; if (!_slang_typeof_function(op->a_id, op->children, op->num_children, - space, &ti->spec, &exists, atoms)) - RETURN_NIL(); - if (!exists) { + space, &ti->spec, &fun, atoms, log)) + return GL_FALSE; + if (fun) { + /* save result for future use */ + op->fun = fun; + } + else { slang_struct *s = slang_struct_scope_find(space->structs, op->a_id, GL_TRUE); - if (s != NULL) { + if (s) { + /* struct initializer */ ti->spec.type = SLANG_SPEC_STRUCT; ti->spec._struct = - (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + (slang_struct *) _slang_alloc(sizeof(slang_struct)); if (ti->spec._struct == NULL) - RETURN_NIL(); + return GL_FALSE; if (!slang_struct_construct(ti->spec._struct)) { - slang_alloc_free(ti->spec._struct); + _slang_free(ti->spec._struct); ti->spec._struct = NULL; - RETURN_NIL(); + return GL_FALSE; } if (!slang_struct_copy(ti->spec._struct, s)) - RETURN_NIL(); + return GL_FALSE; } else { + /* float, int, vec4, mat3, etc. constructor? */ const char *name; slang_type_specifier_type type; name = slang_atom_pool_id(atoms, op->a_id); type = slang_type_specifier_type_from_string(name); - if (type == SLANG_SPEC_VOID) - RETURN_ERROR2("function not found", name, 0); + if (type == SLANG_SPEC_VOID) { + slang_info_log_error(log, "undefined function '%s'", name); + return GL_FALSE; + } ti->spec.type = type; } } @@ -567,10 +628,10 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo _ti; if (!slang_typeinfo_construct(&_ti)) - RETURN_NIL(); - if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } if (_ti.spec.type == SLANG_SPEC_STRUCT) { slang_variable *field; @@ -579,11 +640,11 @@ _slang_typeof_operation_(const slang_operation * op, GL_FALSE); if (field == NULL) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } ti->can_be_referenced = _ti.can_be_referenced; } @@ -593,17 +654,17 @@ _slang_typeof_operation_(const slang_operation * op, slang_type_specifier_type base; /* determine the swizzle of the field expression */ -#if 000 if (!_slang_type_is_vector(_ti.spec.type)) { slang_typeinfo_destruct(&_ti); - RETURN_ERROR("Can't swizzle scalar expression", 0); + slang_info_log_error(log, "Can't swizzle scalar expression"); + return GL_FALSE; } -#endif rows = _slang_type_dim(_ti.spec.type); swizzle = slang_atom_pool_id(atoms, op->a_id); if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) { slang_typeinfo_destruct(&_ti); - RETURN_ERROR("Bad swizzle", 0); + slang_info_log_error(log, "bad swizzle '%s'", swizzle); + return GL_FALSE; } ti->is_swizzled = GL_TRUE; ti->can_be_referenced = _ti.can_be_referenced @@ -674,13 +735,13 @@ _slang_typeof_operation_(const slang_operation * op, break; case SLANG_OPER_POSTINCREMENT: case SLANG_OPER_POSTDECREMENT: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; default: - RETURN_NIL(); + return GL_FALSE; } return GL_TRUE; @@ -692,8 +753,9 @@ _slang_typeof_operation_(const slang_operation * op, */ slang_function * _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, - const slang_operation * args, GLuint num_args, - const slang_name_space * space, slang_atom_pool * atoms) + slang_operation * args, GLuint num_args, + const slang_name_space * space, slang_atom_pool * atoms, + slang_info_log *log) { GLuint i; @@ -713,7 +775,7 @@ _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, if (!slang_typeinfo_construct(&ti)) return NULL; - if (!_slang_typeof_operation_(&args[j], space, &ti, atoms)) { + if (!_slang_typeof_operation_(&args[j], space, &ti, atoms, log)) { slang_typeinfo_destruct(&ti); return NULL; } @@ -737,38 +799,11 @@ _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, } if (funcs->outer_scope != NULL) return _slang_locate_function(funcs->outer_scope, a_name, args, - num_args, space, atoms); + num_args, space, atoms, log); return NULL; } - -/** - * Determine the return type of a function. - * \param a_name the function name - * \param param function parameters (overloading) - * \param num_params number of parameters to function - * \param space namespace to search - * \param exists returns GL_TRUE or GL_FALSE to indicate existance of function - * \return GL_TRUE for success, GL_FALSE if failure (bad function name) - */ -GLboolean -_slang_typeof_function(slang_atom a_name, const slang_operation * params, - GLuint num_params, - const slang_name_space * space, - slang_type_specifier * spec, GLboolean * exists, - slang_atom_pool * atoms) -{ - slang_function *fun = _slang_locate_function(space->funcs, a_name, params, - num_params, space, atoms); - *exists = fun != NULL; - if (!fun) - return GL_TRUE; /* yes, not false */ - return slang_type_specifier_copy(spec, &fun->header.type.specifier); -} - - - /** * Determine if a type is a matrix. * \return GL_TRUE if is a matrix, GL_FALSE otherwise. @@ -780,6 +815,12 @@ _slang_type_is_matrix(slang_type_specifier_type ty) case SLANG_SPEC_MAT2: case SLANG_SPEC_MAT3: case SLANG_SPEC_MAT4: + case SLANG_SPEC_MAT23: + case SLANG_SPEC_MAT32: + case SLANG_SPEC_MAT24: + case SLANG_SPEC_MAT42: + case SLANG_SPEC_MAT34: + case SLANG_SPEC_MAT43: return GL_TRUE; default: return GL_FALSE; @@ -812,7 +853,8 @@ _slang_type_is_vector(slang_type_specifier_type ty) /** - * Given a vector type, return the type of the vector's elements + * Given a vector type, return the type of the vector's elements. + * For a matrix, return the type of the columns. */ slang_type_specifier_type _slang_type_base(slang_type_specifier_type ty) @@ -839,6 +881,18 @@ _slang_type_base(slang_type_specifier_type ty) return SLANG_SPEC_VEC3; case SLANG_SPEC_MAT4: return SLANG_SPEC_VEC4; + case SLANG_SPEC_MAT23: + return SLANG_SPEC_VEC3; + case SLANG_SPEC_MAT32: + return SLANG_SPEC_VEC2; + case SLANG_SPEC_MAT24: + return SLANG_SPEC_VEC4; + case SLANG_SPEC_MAT42: + return SLANG_SPEC_VEC2; + case SLANG_SPEC_MAT34: + return SLANG_SPEC_VEC4; + case SLANG_SPEC_MAT43: + return SLANG_SPEC_VEC3; default: return SLANG_SPEC_VOID; } @@ -846,7 +900,8 @@ _slang_type_base(slang_type_specifier_type ty) /** - * Return the dimensionality of a vector or matrix type. + * Return the dimensionality of a vector, or for a matrix, return number + * of columns. */ GLuint _slang_type_dim(slang_type_specifier_type ty) @@ -871,7 +926,97 @@ _slang_type_dim(slang_type_specifier_type ty) case SLANG_SPEC_BVEC4: case SLANG_SPEC_MAT4: return 4; + + case SLANG_SPEC_MAT23: + return 2; + case SLANG_SPEC_MAT32: + return 3; + case SLANG_SPEC_MAT24: + return 2; + case SLANG_SPEC_MAT42: + return 4; + case SLANG_SPEC_MAT34: + return 3; + case SLANG_SPEC_MAT43: + return 4; + default: return 0; } } + + +/** + * Return the GL_* type that corresponds to a SLANG_SPEC_* type. + */ +GLenum +_slang_gltype_from_specifier(const slang_type_specifier *type) +{ + switch (type->type) { + case SLANG_SPEC_BOOL: + return GL_BOOL; + case SLANG_SPEC_BVEC2: + return GL_BOOL_VEC2; + case SLANG_SPEC_BVEC3: + return GL_BOOL_VEC3; + case SLANG_SPEC_BVEC4: + return GL_BOOL_VEC4; + case SLANG_SPEC_INT: + return GL_INT; + case SLANG_SPEC_IVEC2: + return GL_INT_VEC2; + case SLANG_SPEC_IVEC3: + return GL_INT_VEC3; + case SLANG_SPEC_IVEC4: + return GL_INT_VEC4; + case SLANG_SPEC_FLOAT: + return GL_FLOAT; + case SLANG_SPEC_VEC2: + return GL_FLOAT_VEC2; + case SLANG_SPEC_VEC3: + return GL_FLOAT_VEC3; + case SLANG_SPEC_VEC4: + return GL_FLOAT_VEC4; + case SLANG_SPEC_MAT2: + return GL_FLOAT_MAT2; + case SLANG_SPEC_MAT3: + return GL_FLOAT_MAT3; + case SLANG_SPEC_MAT4: + return GL_FLOAT_MAT4; + case SLANG_SPEC_MAT23: + return GL_FLOAT_MAT2x3; + case SLANG_SPEC_MAT32: + return GL_FLOAT_MAT3x2; + case SLANG_SPEC_MAT24: + return GL_FLOAT_MAT2x4; + case SLANG_SPEC_MAT42: + return GL_FLOAT_MAT4x2; + case SLANG_SPEC_MAT34: + return GL_FLOAT_MAT3x4; + case SLANG_SPEC_MAT43: + return GL_FLOAT_MAT4x3; + case SLANG_SPEC_SAMPLER1D: + return GL_SAMPLER_1D; + case SLANG_SPEC_SAMPLER2D: + return GL_SAMPLER_2D; + case SLANG_SPEC_SAMPLER3D: + return GL_SAMPLER_3D; + case SLANG_SPEC_SAMPLERCUBE: + return GL_SAMPLER_CUBE; + case SLANG_SPEC_SAMPLER1DSHADOW: + return GL_SAMPLER_1D_SHADOW; + case SLANG_SPEC_SAMPLER2DSHADOW: + return GL_SAMPLER_2D_SHADOW; + case SLANG_SPEC_SAMPLER2DRECT: + return GL_SAMPLER_2D_RECT_ARB; + case SLANG_SPEC_SAMPLER2DRECTSHADOW: + return GL_SAMPLER_2D_RECT_SHADOW_ARB; + case SLANG_SPEC_ARRAY: + return _slang_gltype_from_specifier(type->_array); + case SLANG_SPEC_STRUCT: + /* fall-through */ + default: + return GL_NONE; + } +} +