diff options
Diffstat (limited to 'src/mesa/shader/slang/slang_assemble_constructor.c')
-rw-r--r-- | src/mesa/shader/slang/slang_assemble_constructor.c | 770 |
1 files changed, 385 insertions, 385 deletions
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c index ea82e85342..6f02772bcd 100644 --- a/src/mesa/shader/slang/slang_assemble_constructor.c +++ b/src/mesa/shader/slang/slang_assemble_constructor.c @@ -1,385 +1,385 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file slang_assemble_constructor.c
- * slang constructor and vector swizzle assembler
- * \author Michal Krol
- */
-
-#include "imports.h"
-#include "slang_assemble.h"
-#include "slang_storage.h"
-
-/* _slang_is_swizzle() */
-
-GLboolean _slang_is_swizzle (const char *field, GLuint rows, slang_swizzle *swz)
-{
- GLuint i;
- GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
-
- /* 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;
-}
-
-/* _slang_is_swizzle_mask() */
-
-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;
-}
-
-/* _slang_multiply_swizzles() */
-
-GLvoid _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
- const slang_swizzle *right)
-{
- GLuint i;
-
- dst->num_components = right->num_components;
- for (i = 0; i < right->num_components; i++)
- dst->swizzle[i] = left->swizzle[right->swizzle[i]];
-}
-
-/* _slang_assemble_constructor() */
-
-static GLboolean sizeof_argument (slang_assemble_ctx *A, GLuint *size, slang_operation *op)
-{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg, flat_agg;
-
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end2;
-
- if (!slang_storage_aggregate_construct (&flat_agg))
- goto end2;
- if (!_slang_flatten_aggregate (&flat_agg, &agg))
- goto end;
-
- *size = flat_agg.count * 4;
-
- result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&flat_agg);
-end2:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
-}
-
-static GLboolean constructor_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *flat,
- slang_operation *op, GLuint garbage_size)
-{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg, flat_agg;
-
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end2;
-
- if (!slang_storage_aggregate_construct (&flat_agg))
- goto end2;
- if (!_slang_flatten_aggregate (&flat_agg, &agg))
- goto end;
-
- if (!_slang_assemble_operation (A, op, slang_ref_forbid))
- goto end;
-
- /* TODO: convert (generic) elements */
-
- /* free the garbage */
- if (garbage_size != 0)
- {
- GLuint i;
-
- /* move the non-garbage part to the end of the argument */
- if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, 0))
- goto end;
- for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4)
- {
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_move,
- garbage_size + i, i))
- {
- goto end;
- }
- }
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, garbage_size + 4))
- goto end;
- }
-
- result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&flat_agg);
-end2:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
-}
-
-GLboolean _slang_assemble_constructor (slang_assemble_ctx *A, slang_operation *op)
-{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg, flat;
- GLuint size, i;
- GLuint arg_sums[2];
-
- /* get typeinfo of the constructor (the result of constructor expression) */
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- /* create an aggregate of the constructor */
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end2;
-
- /* calculate size of the constructor */
- size = _slang_sizeof_aggregate (&agg);
-
- /* flatten the constructor */
- if (!slang_storage_aggregate_construct (&flat))
- goto end2;
- if (!_slang_flatten_aggregate (&flat, &agg))
- goto end;
-
- /* collect the last two constructor's argument size sums */
- arg_sums[0] = 0; /* will hold all but the last argument's size sum */
- arg_sums[1] = 0; /* will hold all argument's size sum */
- for (i = 0; i < op->num_children; i++)
- {
- GLuint arg_size;
-
- if (!sizeof_argument (A, &arg_size, &op->children[i]))
- goto end;
- if (i > 0)
- arg_sums[0] = arg_sums[1];
- arg_sums[1] += arg_size;
- }
-
- /* check if there are too many arguments */
- if (arg_sums[0] >= size)
- {
- /* TODO: info log: too many arguments in constructor list */
- goto end;
- }
-
- /* check if there are too few arguments */
- if (arg_sums[1] < size)
- {
- /* TODO: info log: too few arguments in constructor list */
- goto end;
- }
-
- /* traverse the children that form the constructor expression */
- for (i = op->num_children; i > 0; i--)
- {
- GLuint garbage_size;
-
- /* the last argument may be too big - calculate the unnecessary data size */
- if (i == op->num_children)
- garbage_size = arg_sums[1] - size;
- else
- garbage_size = 0;
-
- if (!constructor_aggregate (A, &flat, &op->children[i - 1], garbage_size))
- goto end;
- }
-
- result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&flat);
-end2:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
-}
-
-/* _slang_assemble_constructor_from_swizzle() */
-
-GLboolean _slang_assemble_constructor_from_swizzle (slang_assemble_ctx *A, const slang_swizzle *swz,
- slang_type_specifier *spec, slang_type_specifier *master_spec)
-{
- GLuint master_rows, i;
-
- master_rows = _slang_type_dim (master_spec->type);
- for (i = 0; i < master_rows; i++)
- {
- switch (_slang_type_base (master_spec->type))
- {
- case slang_spec_bool:
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_bool_copy,
- (master_rows - i) * 4, i * 4))
- return GL_FALSE;
- break;
- case slang_spec_int:
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_int_copy,
- (master_rows - i) * 4, i * 4))
- return GL_FALSE;
- break;
- case slang_spec_float:
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_copy,
- (master_rows - i) * 4, i * 4))
- return GL_FALSE;
- break;
- default:
- break;
- }
- }
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- for (i = swz->num_components; i > 0; i--)
- {
- GLuint n = i - 1;
-
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
- return GL_FALSE;
- if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, swz->swizzle[n] * 4))
- return GL_FALSE;
- if (!slang_assembly_file_push (A->file, slang_asm_addr_add))
- return GL_FALSE;
- switch (_slang_type_base (master_spec->type))
- {
- case slang_spec_bool:
- if (!slang_assembly_file_push (A->file, slang_asm_bool_deref))
- return GL_FALSE;
- break;
- case slang_spec_int:
- if (!slang_assembly_file_push (A->file, slang_asm_int_deref))
- return GL_FALSE;
- break;
- case slang_spec_float:
- if (!slang_assembly_file_push (A->file, slang_asm_float_deref))
- return GL_FALSE;
- break;
- default:
- break;
- }
- }
-
- return GL_TRUE;
-}
-
+/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble_constructor.c + * slang constructor and vector swizzle assembler + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_assemble.h" +#include "slang_storage.h" + +/* _slang_is_swizzle() */ + +GLboolean _slang_is_swizzle (const char *field, GLuint rows, slang_swizzle *swz) +{ + GLuint i; + GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; + + /* 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; +} + +/* _slang_is_swizzle_mask() */ + +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; +} + +/* _slang_multiply_swizzles() */ + +GLvoid _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left, + const slang_swizzle *right) +{ + GLuint i; + + dst->num_components = right->num_components; + for (i = 0; i < right->num_components; i++) + dst->swizzle[i] = left->swizzle[right->swizzle[i]]; +} + +/* _slang_assemble_constructor() */ + +static GLboolean sizeof_argument (slang_assemble_ctx *A, GLuint *size, slang_operation *op) +{ + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg, flat_agg; + + if (!slang_assembly_typeinfo_construct (&ti)) + return GL_FALSE; + if (!_slang_typeof_operation (A, op, &ti)) + goto end1; + + if (!slang_storage_aggregate_construct (&agg)) + goto end1; + if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, + A->space.vars, A->mach, A->file, A->atoms)) + goto end2; + + if (!slang_storage_aggregate_construct (&flat_agg)) + goto end2; + if (!_slang_flatten_aggregate (&flat_agg, &agg)) + goto end; + + *size = flat_agg.count * 4; + + result = GL_TRUE; +end: + slang_storage_aggregate_destruct (&flat_agg); +end2: + slang_storage_aggregate_destruct (&agg); +end1: + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +static GLboolean constructor_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *flat, + slang_operation *op, GLuint garbage_size) +{ + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg, flat_agg; + + if (!slang_assembly_typeinfo_construct (&ti)) + return GL_FALSE; + if (!_slang_typeof_operation (A, op, &ti)) + goto end1; + + if (!slang_storage_aggregate_construct (&agg)) + goto end1; + if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, + A->space.vars, A->mach, A->file, A->atoms)) + goto end2; + + if (!slang_storage_aggregate_construct (&flat_agg)) + goto end2; + if (!_slang_flatten_aggregate (&flat_agg, &agg)) + goto end; + + if (!_slang_assemble_operation (A, op, slang_ref_forbid)) + goto end; + + /* TODO: convert (generic) elements */ + + /* free the garbage */ + if (garbage_size != 0) + { + GLuint i; + + /* move the non-garbage part to the end of the argument */ + if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, 0)) + goto end; + for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4) + { + if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_move, + garbage_size + i, i)) + { + goto end; + } + } + if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, garbage_size + 4)) + goto end; + } + + result = GL_TRUE; +end: + slang_storage_aggregate_destruct (&flat_agg); +end2: + slang_storage_aggregate_destruct (&agg); +end1: + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +GLboolean _slang_assemble_constructor (slang_assemble_ctx *A, slang_operation *op) +{ + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg, flat; + GLuint size, i; + GLuint arg_sums[2]; + + /* get typeinfo of the constructor (the result of constructor expression) */ + if (!slang_assembly_typeinfo_construct (&ti)) + return GL_FALSE; + if (!_slang_typeof_operation (A, op, &ti)) + goto end1; + + /* create an aggregate of the constructor */ + if (!slang_storage_aggregate_construct (&agg)) + goto end1; + if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, + A->space.vars, A->mach, A->file, A->atoms)) + goto end2; + + /* calculate size of the constructor */ + size = _slang_sizeof_aggregate (&agg); + + /* flatten the constructor */ + if (!slang_storage_aggregate_construct (&flat)) + goto end2; + if (!_slang_flatten_aggregate (&flat, &agg)) + goto end; + + /* collect the last two constructor's argument size sums */ + arg_sums[0] = 0; /* will hold all but the last argument's size sum */ + arg_sums[1] = 0; /* will hold all argument's size sum */ + for (i = 0; i < op->num_children; i++) + { + GLuint arg_size; + + if (!sizeof_argument (A, &arg_size, &op->children[i])) + goto end; + if (i > 0) + arg_sums[0] = arg_sums[1]; + arg_sums[1] += arg_size; + } + + /* check if there are too many arguments */ + if (arg_sums[0] >= size) + { + /* TODO: info log: too many arguments in constructor list */ + goto end; + } + + /* check if there are too few arguments */ + if (arg_sums[1] < size) + { + /* TODO: info log: too few arguments in constructor list */ + goto end; + } + + /* traverse the children that form the constructor expression */ + for (i = op->num_children; i > 0; i--) + { + GLuint garbage_size; + + /* the last argument may be too big - calculate the unnecessary data size */ + if (i == op->num_children) + garbage_size = arg_sums[1] - size; + else + garbage_size = 0; + + if (!constructor_aggregate (A, &flat, &op->children[i - 1], garbage_size)) + goto end; + } + + result = GL_TRUE; +end: + slang_storage_aggregate_destruct (&flat); +end2: + slang_storage_aggregate_destruct (&agg); +end1: + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +/* _slang_assemble_constructor_from_swizzle() */ + +GLboolean _slang_assemble_constructor_from_swizzle (slang_assemble_ctx *A, const slang_swizzle *swz, + slang_type_specifier *spec, slang_type_specifier *master_spec) +{ + GLuint master_rows, i; + + master_rows = _slang_type_dim (master_spec->type); + for (i = 0; i < master_rows; i++) + { + switch (_slang_type_base (master_spec->type)) + { + case slang_spec_bool: + if (!slang_assembly_file_push_label2 (A->file, slang_asm_bool_copy, + (master_rows - i) * 4, i * 4)) + return GL_FALSE; + break; + case slang_spec_int: + if (!slang_assembly_file_push_label2 (A->file, slang_asm_int_copy, + (master_rows - i) * 4, i * 4)) + return GL_FALSE; + break; + case slang_spec_float: + if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_copy, + (master_rows - i) * 4, i * 4)) + return GL_FALSE; + break; + default: + break; + } + } + if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4)) + return GL_FALSE; + for (i = swz->num_components; i > 0; i--) + { + GLuint n = i - 1; + + if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) + return GL_FALSE; + if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, swz->swizzle[n] * 4)) + return GL_FALSE; + if (!slang_assembly_file_push (A->file, slang_asm_addr_add)) + return GL_FALSE; + switch (_slang_type_base (master_spec->type)) + { + case slang_spec_bool: + if (!slang_assembly_file_push (A->file, slang_asm_bool_deref)) + return GL_FALSE; + break; + case slang_spec_int: + if (!slang_assembly_file_push (A->file, slang_asm_int_deref)) + return GL_FALSE; + break; + case slang_spec_float: + if (!slang_assembly_file_push (A->file, slang_asm_float_deref)) + return GL_FALSE; + break; + default: + break; + } + } + + return GL_TRUE; +} + |