diff options
Diffstat (limited to 'src/mesa/slang/slang_storage.c')
-rw-r--r-- | src/mesa/slang/slang_storage.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/src/mesa/slang/slang_storage.c b/src/mesa/slang/slang_storage.c new file mode 100644 index 00000000000..656e15670d3 --- /dev/null +++ b/src/mesa/slang/slang_storage.c @@ -0,0 +1,321 @@ +/* + * 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_storage.c + * slang variable storage + * \author Michal Krol + */ + +#include "main/imports.h" +#include "slang_storage.h" +#include "slang_mem.h" + +/* slang_storage_array */ + +GLboolean +slang_storage_array_construct(slang_storage_array * arr) +{ + arr->type = SLANG_STORE_AGGREGATE; + arr->aggregate = NULL; + arr->length = 0; + return GL_TRUE; +} + +GLvoid +slang_storage_array_destruct(slang_storage_array * arr) +{ + if (arr->aggregate != NULL) { + slang_storage_aggregate_destruct(arr->aggregate); + _slang_free(arr->aggregate); + } +} + +/* slang_storage_aggregate */ + +GLboolean +slang_storage_aggregate_construct(slang_storage_aggregate * agg) +{ + agg->arrays = NULL; + agg->count = 0; + return GL_TRUE; +} + +GLvoid +slang_storage_aggregate_destruct(slang_storage_aggregate * agg) +{ + GLuint i; + + for (i = 0; i < agg->count; i++) + slang_storage_array_destruct(agg->arrays + i); + _slang_free(agg->arrays); +} + +static slang_storage_array * +slang_storage_aggregate_push_new(slang_storage_aggregate * agg) +{ + slang_storage_array *arr = NULL; + + agg->arrays = (slang_storage_array *) + _slang_realloc(agg->arrays, + agg->count * sizeof(slang_storage_array), + (agg->count + 1) * sizeof(slang_storage_array)); + if (agg->arrays != NULL) { + arr = agg->arrays + agg->count; + if (!slang_storage_array_construct(arr)) + return NULL; + agg->count++; + } + return arr; +} + +/* _slang_aggregate_variable() */ + +static GLboolean +aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type, + GLuint row_count) +{ + slang_storage_array *arr = slang_storage_aggregate_push_new(agg); + if (arr == NULL) + return GL_FALSE; + arr->type = basic_type; + arr->length = row_count; + return GL_TRUE; +} + +static GLboolean +aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type, + GLuint columns, GLuint rows) +{ + slang_storage_array *arr = slang_storage_aggregate_push_new(agg); + if (arr == NULL) + return GL_FALSE; + arr->type = SLANG_STORE_AGGREGATE; + arr->length = columns; + arr->aggregate = (slang_storage_aggregate *) + _slang_alloc(sizeof(slang_storage_aggregate)); + if (arr->aggregate == NULL) + return GL_FALSE; + if (!slang_storage_aggregate_construct(arr->aggregate)) { + _slang_free(arr->aggregate); + arr->aggregate = NULL; + return GL_FALSE; + } + if (!aggregate_vector(arr->aggregate, basic_type, rows)) + return GL_FALSE; + return GL_TRUE; +} + + +static GLboolean +aggregate_variables(slang_storage_aggregate * agg, + slang_variable_scope * vars, slang_function_scope * funcs, + slang_struct_scope * structs, + slang_variable_scope * globals, + slang_atom_pool * atoms) +{ + GLuint i; + + for (i = 0; i < vars->num_variables; i++) + if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier, + vars->variables[i]->array_len, funcs, + structs, globals, atoms)) + return GL_FALSE; + return GL_TRUE; +} + + +GLboolean +_slang_aggregate_variable(slang_storage_aggregate * agg, + slang_type_specifier * spec, GLuint array_len, + slang_function_scope * funcs, + slang_struct_scope * structs, + slang_variable_scope * vars, + slang_atom_pool * atoms) +{ + switch (spec->type) { + case SLANG_SPEC_BOOL: + return aggregate_vector(agg, SLANG_STORE_BOOL, 1); + case SLANG_SPEC_BVEC2: + return aggregate_vector(agg, SLANG_STORE_BOOL, 2); + case SLANG_SPEC_BVEC3: + return aggregate_vector(agg, SLANG_STORE_BOOL, 3); + case SLANG_SPEC_BVEC4: + return aggregate_vector(agg, SLANG_STORE_BOOL, 4); + case SLANG_SPEC_INT: + return aggregate_vector(agg, SLANG_STORE_INT, 1); + case SLANG_SPEC_IVEC2: + return aggregate_vector(agg, SLANG_STORE_INT, 2); + case SLANG_SPEC_IVEC3: + return aggregate_vector(agg, SLANG_STORE_INT, 3); + case SLANG_SPEC_IVEC4: + return aggregate_vector(agg, SLANG_STORE_INT, 4); + case SLANG_SPEC_FLOAT: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 1); + case SLANG_SPEC_VEC2: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 2); + case SLANG_SPEC_VEC3: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 3); + case SLANG_SPEC_VEC4: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 4); + case SLANG_SPEC_MAT2: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 2); + case SLANG_SPEC_MAT3: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3); + case SLANG_SPEC_MAT4: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4); + + case SLANG_SPEC_MAT23: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3); + case SLANG_SPEC_MAT32: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2); + case SLANG_SPEC_MAT24: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4); + case SLANG_SPEC_MAT42: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2); + case SLANG_SPEC_MAT34: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4); + case SLANG_SPEC_MAT43: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3); + + case SLANG_SPEC_SAMPLER_1D: + case SLANG_SPEC_SAMPLER_2D: + case SLANG_SPEC_SAMPLER_3D: + case SLANG_SPEC_SAMPLER_CUBE: + case SLANG_SPEC_SAMPLER_1D_SHADOW: + case SLANG_SPEC_SAMPLER_2D_SHADOW: + case SLANG_SPEC_SAMPLER_RECT: + case SLANG_SPEC_SAMPLER_RECT_SHADOW: + case SLANG_SPEC_SAMPLER_1D_ARRAY: + case SLANG_SPEC_SAMPLER_2D_ARRAY: + case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW: + case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW: + + return aggregate_vector(agg, SLANG_STORE_INT, 1); + case SLANG_SPEC_STRUCT: + return aggregate_variables(agg, spec->_struct->fields, funcs, structs, + vars, atoms); + case SLANG_SPEC_ARRAY: + { + slang_storage_array *arr; + + arr = slang_storage_aggregate_push_new(agg); + if (arr == NULL) + return GL_FALSE; + arr->type = SLANG_STORE_AGGREGATE; + arr->aggregate = (slang_storage_aggregate *) + _slang_alloc(sizeof(slang_storage_aggregate)); + if (arr->aggregate == NULL) + return GL_FALSE; + if (!slang_storage_aggregate_construct(arr->aggregate)) { + _slang_free(arr->aggregate); + arr->aggregate = NULL; + return GL_FALSE; + } + if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0, + funcs, structs, vars, atoms)) + return GL_FALSE; + arr->length = array_len; + /* TODO: check if 0 < arr->length <= 65535 */ + } + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +GLuint +_slang_sizeof_type(slang_storage_type type) +{ + if (type == SLANG_STORE_AGGREGATE) + return 0; + if (type == SLANG_STORE_VEC4) + return 4 * sizeof(GLfloat); + return sizeof(GLfloat); +} + + +GLuint +_slang_sizeof_aggregate(const slang_storage_aggregate * agg) +{ + GLuint i, size = 0; + + for (i = 0; i < agg->count; i++) { + slang_storage_array *arr = &agg->arrays[i]; + GLuint element_size; + + if (arr->type == SLANG_STORE_AGGREGATE) + element_size = _slang_sizeof_aggregate(arr->aggregate); + else + element_size = _slang_sizeof_type(arr->type); + size += element_size * arr->length; + } + return size; +} + + +#if 0 +GLboolean +_slang_flatten_aggregate(slang_storage_aggregate * flat, + const slang_storage_aggregate * agg) +{ + GLuint i; + + for (i = 0; i < agg->count; i++) { + GLuint j; + + for (j = 0; j < agg->arrays[i].length; j++) { + if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) { + if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate)) + return GL_FALSE; + } + else { + GLuint k, count; + slang_storage_type type; + + if (agg->arrays[i].type == SLANG_STORE_VEC4) { + count = 4; + type = SLANG_STORE_FLOAT; + } + else { + count = 1; + type = agg->arrays[i].type; + } + + for (k = 0; k < count; k++) { + slang_storage_array *arr; + + arr = slang_storage_aggregate_push_new(flat); + if (arr == NULL) + return GL_FALSE; + arr->type = type; + arr->length = 1; + } + } + } + } + return GL_TRUE; +} +#endif |