diff options
-rw-r--r-- | src/mesa/shader/slang/slang_assemble_typeinfo.c | 117 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 52 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 13 |
3 files changed, 177 insertions, 5 deletions
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c index 21b31091ea7..6a87ef3340b 100644 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.c +++ b/src/mesa/shader/slang/slang_assemble_typeinfo.c @@ -32,6 +32,123 @@ #include "slang_assemble.h" #include "slang_compile.h" #include "slang_error.h" +#include "prog_instruction.h" + + + + +/** + * Checks if a field selector is a general swizzle (an r-value swizzle + * with replicated components or an l-value swizzle mask) for a + * vector. Returns GL_TRUE if this is the case, <swz> is filled with + * swizzle information. Returns GL_FALSE otherwise. + */ +GLboolean +_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz) +{ + GLuint i; + GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; + + /* init to undefined. + * We rely on undefined/nil values to distinguish between + * regular swizzles and writemasks. + * For example, the swizzle ".xNNN" is the writemask ".x". + * That's different than the swizzle ".xxxx". + */ + for (i = 0; i < 4; i++) + swz->swizzle[i] = SWIZZLE_NIL; + + /* the swizzle can be at most 4-component long */ + swz->num_components = slang_string_length(field); + if (swz->num_components > 4) + return GL_FALSE; + + for (i = 0; i < swz->num_components; i++) { + /* mark which swizzle group is used */ + switch (field[i]) { + case 'x': + case 'y': + case 'z': + case 'w': + xyzw = GL_TRUE; + break; + case 'r': + case 'g': + case 'b': + case 'a': + rgba = GL_TRUE; + break; + case 's': + case 't': + case 'p': + case 'q': + stpq = GL_TRUE; + break; + default: + return GL_FALSE; + } + + /* collect swizzle component */ + switch (field[i]) { + case 'x': + case 'r': + case 's': + swz->swizzle[i] = 0; + break; + case 'y': + case 'g': + case 't': + swz->swizzle[i] = 1; + break; + case 'z': + case 'b': + case 'p': + swz->swizzle[i] = 2; + break; + case 'w': + case 'a': + case 'q': + swz->swizzle[i] = 3; + break; + } + + /* check if the component is valid for given vector's row count */ + if (rows <= swz->swizzle[i]) + return GL_FALSE; + } + + /* only one swizzle group can be used */ + if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) + return GL_FALSE; + + return GL_TRUE; +} + + + +/** + * Checks if a general swizzle is an l-value swizzle - these swizzles + * do not have duplicated fields. Returns GL_TRUE if this is a + * swizzle mask. Returns GL_FALSE otherwise + */ +GLboolean +_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows) +{ + GLuint i, c = 0; + + /* the swizzle may not be longer than the vector dim */ + if (swz->num_components > rows) + return GL_FALSE; + + /* the swizzle components cannot be duplicated */ + for (i = 0; i < swz->num_components; i++) { + if ((c & (1 << swz->swizzle[i])) != 0) + return GL_FALSE; + c |= 1 << swz->swizzle[i]; + } + + return GL_TRUE; +} GLvoid diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 5ce3e465784..03562018cab 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1264,6 +1264,58 @@ _slang_first_function(struct slang_function_scope_ *scope, const char *name) +slang_function * +_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, + const slang_operation * args, GLuint num_args, + const slang_assembly_name_space * space, + slang_atom_pool * atoms) +{ + GLuint i; + + for (i = 0; i < funcs->num_functions; i++) { + slang_function *f = &funcs->functions[i]; + const GLuint haveRetValue = _slang_function_has_return_value(f); + GLuint j; + + if (a_name != f->header.a_name) + continue; + if (f->param_count - haveRetValue != num_args) + continue; + + /* compare parameter / argument types */ + for (j = 0; j < num_args; j++) { + slang_assembly_typeinfo ti; + + if (!slang_assembly_typeinfo_construct(&ti)) + return NULL; + if (!_slang_typeof_operation_(&args[j], space, &ti, atoms)) { + slang_assembly_typeinfo_destruct(&ti); + return NULL; + } + if (!slang_type_specifier_equal(&ti.spec, + &f->parameters->variables[j/* + haveRetValue*/]->type.specifier)) { + slang_assembly_typeinfo_destruct(&ti); + break; + } + slang_assembly_typeinfo_destruct(&ti); + + /* "out" and "inout" formal parameter requires the actual parameter to be l-value */ + if (!ti.can_be_referenced && + (f->parameters->variables[j/* + haveRetValue*/]->type.qualifier == slang_qual_out || + f->parameters->variables[j/* + haveRetValue*/]->type.qualifier == slang_qual_inout)) + break; + } + if (j == num_args) + return f; + } + if (funcs->outer_scope != NULL) + return _slang_locate_function(funcs->outer_scope, a_name, args, + num_args, space, atoms); + return NULL; +} + + + /** * Assemble a function call, given a particular function name. * \param name the function's name (operators like '*' are possible). diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 9f7f18167d8..67fcbaef92d 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -100,7 +100,7 @@ _slang_code_object_ctr(slang_code_object * self) for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) _slang_code_unit_ctr(&self->builtin[i], self); _slang_code_unit_ctr(&self->unit, self); -#if 01 +#if 0 _slang_assembly_file_ctr(&self->assembly); #endif self->varpool.next_addr = 0; @@ -115,7 +115,7 @@ _slang_code_object_dtr(slang_code_object * self) for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) _slang_code_unit_dtr(&self->builtin[i]); _slang_code_unit_dtr(&self->unit); -#if 01 +#if 0 slang_assembly_file_destruct(&self->assembly); #endif slang_atom_pool_destruct(&self->atompool); @@ -1551,7 +1551,7 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) slang_operation op_id, op_assign; GLboolean result; -#if 01 +#if 0 /* save the current assembly */ if (!slang_assembly_file_restore_point_save(A->file, &point)) return GL_FALSE; @@ -1561,10 +1561,12 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) A->local.ret_size = 0; A->local.addr_tmp = 0; A->local.swizzle_tmp = 4; +#if 0 if (!slang_assembly_file_push_label(A->file, slang_asm_local_alloc, 20)) return GL_FALSE; if (!slang_assembly_file_push_label(A->file, slang_asm_enter, 20)) return GL_FALSE; +#endif /* construct the left side of assignment */ if (!slang_operation_construct(&op_id)) @@ -1618,10 +1620,11 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) if (!result) return GL_FALSE; +#if 0 if (!slang_assembly_file_push(A->file, slang_asm_exit)) return GL_FALSE; - -#if 01 +#endif +#if 0 /* restore the old assembly */ if (!slang_assembly_file_restore_point_load(A->file, &point)) return GL_FALSE; |