summaryrefslogtreecommitdiff
path: root/src/mesa/slang/slang_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/slang/slang_storage.c')
-rw-r--r--src/mesa/slang/slang_storage.c321
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 0000000000..656e15670d
--- /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