Split slang_compile.c into several smaller files - it was just too big.
[mesa.git] / src / mesa / shader / slang / slang_storage.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file slang_storage.c
27 * slang variable storage
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_utility.h"
33 #include "slang_storage.h"
34 #include "slang_assemble.h"
35
36 /* slang_storage_array */
37
38 void slang_storage_array_construct (slang_storage_array *arr)
39 {
40 arr->type = slang_stor_aggregate;
41 arr->aggregate = NULL;
42 arr->length = 0;
43 }
44
45 void slang_storage_array_destruct (slang_storage_array *arr)
46 {
47 if (arr->aggregate != NULL)
48 {
49 slang_storage_aggregate_destruct (arr->aggregate);
50 slang_alloc_free (arr->aggregate);
51 }
52 }
53
54 /* slang_storage_aggregate */
55
56 void slang_storage_aggregate_construct (slang_storage_aggregate *agg)
57 {
58 agg->arrays = NULL;
59 agg->count = 0;
60 }
61
62 void slang_storage_aggregate_destruct (slang_storage_aggregate *agg)
63 {
64 unsigned int i;
65 for (i = 0; i < agg->count; i++)
66 slang_storage_array_destruct (agg->arrays + i);
67 slang_alloc_free (agg->arrays);
68 }
69
70 static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg)
71 {
72 slang_storage_array *arr = NULL;
73 agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof (
74 slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array));
75 if (agg->arrays != NULL)
76 {
77 arr = agg->arrays + agg->count;
78 slang_storage_array_construct (arr);
79 agg->count++;
80 }
81 return arr;
82 }
83
84 /* _slang_aggregate_variable() */
85
86 static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type,
87 unsigned int row_count)
88 {
89 slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
90 if (arr == NULL)
91 return 0;
92 arr->type = basic_type;
93 arr->length = row_count;
94 return 1;
95 }
96
97 static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type,
98 unsigned int dimension)
99 {
100 slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
101 if (arr == NULL)
102 return 0;
103 arr->type = slang_stor_aggregate;
104 arr->length = dimension;
105 arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (
106 slang_storage_aggregate));
107 if (arr->aggregate == NULL)
108 return 0;
109 slang_storage_aggregate_construct (arr->aggregate);
110 if (!aggregate_vector (arr->aggregate, basic_type, dimension))
111 return 0;
112 return 1;
113 }
114
115 static int aggregate_variables (slang_storage_aggregate *agg, slang_variable_scope *vars,
116 slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals)
117 {
118 unsigned int i;
119 for (i = 0; i < vars->num_variables; i++)
120 if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier,
121 vars->variables[i].array_size, funcs, structs, globals))
122 return 0;
123 return 1;
124 }
125
126 int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec,
127 slang_operation *array_size, slang_function_scope *funcs, slang_struct_scope *structs,
128 slang_variable_scope *vars)
129 {
130 switch (spec->type)
131 {
132 case slang_spec_bool:
133 return aggregate_vector (agg, slang_stor_bool, 1);
134 case slang_spec_bvec2:
135 return aggregate_vector (agg, slang_stor_bool, 2);
136 case slang_spec_bvec3:
137 return aggregate_vector (agg, slang_stor_bool, 3);
138 case slang_spec_bvec4:
139 return aggregate_vector (agg, slang_stor_bool, 4);
140 case slang_spec_int:
141 return aggregate_vector (agg, slang_stor_int, 1);
142 case slang_spec_ivec2:
143 return aggregate_vector (agg, slang_stor_int, 2);
144 case slang_spec_ivec3:
145 return aggregate_vector (agg, slang_stor_int, 3);
146 case slang_spec_ivec4:
147 return aggregate_vector (agg, slang_stor_int, 4);
148 case slang_spec_float:
149 return aggregate_vector (agg, slang_stor_float, 1);
150 case slang_spec_vec2:
151 return aggregate_vector (agg, slang_stor_float, 2);
152 case slang_spec_vec3:
153 return aggregate_vector (agg, slang_stor_float, 3);
154 case slang_spec_vec4:
155 return aggregate_vector (agg, slang_stor_float, 4);
156 case slang_spec_mat2:
157 return aggregate_matrix (agg, slang_stor_float, 2);
158 case slang_spec_mat3:
159 return aggregate_matrix (agg, slang_stor_float, 3);
160 case slang_spec_mat4:
161 return aggregate_matrix (agg, slang_stor_float, 4);
162 case slang_spec_sampler1D:
163 case slang_spec_sampler2D:
164 case slang_spec_sampler3D:
165 case slang_spec_samplerCube:
166 case slang_spec_sampler1DShadow:
167 case slang_spec_sampler2DShadow:
168 return aggregate_vector (agg, slang_stor_int, 1);
169 case slang_spec_struct:
170 return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars);
171 case slang_spec_array:
172 {
173 slang_storage_array *arr;
174 slang_assembly_file file;
175 slang_assembly_flow_control flow;
176 slang_assembly_name_space space;
177 slang_assembly_local_info info;
178 slang_assembly_stack_info stk;
179
180 arr = slang_storage_aggregate_push_new (agg);
181 if (arr == NULL)
182 return 0;
183 arr->type = slang_stor_aggregate;
184 arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (
185 slang_storage_aggregate));
186 if (arr->aggregate == NULL)
187 return 0;
188 slang_storage_aggregate_construct (arr->aggregate);
189 if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs, vars))
190 return 0;
191 slang_assembly_file_construct (&file);
192 space.funcs = funcs;
193 space.structs = structs;
194 space.vars = vars;
195 if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk))
196 {
197 slang_assembly_file_destruct (&file);
198 return 0;
199 }
200 /* TODO: evaluate array size */
201 slang_assembly_file_destruct (&file);
202 arr->length = 256;
203 }
204 return 1;
205 default:
206 return 0;
207 }
208 }
209
210 /* _slang_sizeof_aggregate() */
211
212 unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
213 {
214 unsigned int i, size = 0;
215 for (i = 0; i < agg->count; i++)
216 {
217 unsigned int element_size;
218 if (agg->arrays[i].type == slang_stor_aggregate)
219 element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);
220 else
221 element_size = sizeof (GLfloat);
222 size += element_size * agg->arrays[i].length;
223 }
224 return size;
225 }
226
227 /* _slang_flatten_aggregate () */
228
229 int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
230 {
231 unsigned int i;
232 for (i = 0; i < agg->count; i++)
233 {
234 unsigned int j;
235 for (j = 0; j < agg->arrays[i].length; j++)
236 {
237 if (agg->arrays[i].type == slang_stor_aggregate)
238 {
239 if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))
240 return 0;
241 }
242 else
243 {
244 slang_storage_array *arr;
245 arr = slang_storage_aggregate_push_new (flat);
246 if (arr == NULL)
247 return 0;
248 arr->type = agg->arrays[i].type;
249 arr->length = 1;
250 }
251 }
252 }
253 return 1;
254 }
255