new varnames in slang_operation_insert()
[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_storage.h"
33
34 /* slang_storage_array */
35
36 GLboolean
37 slang_storage_array_construct(slang_storage_array * arr)
38 {
39 arr->type = SLANG_STORE_AGGREGATE;
40 arr->aggregate = NULL;
41 arr->length = 0;
42 return GL_TRUE;
43 }
44
45 GLvoid
46 slang_storage_array_destruct(slang_storage_array * arr)
47 {
48 if (arr->aggregate != NULL) {
49 slang_storage_aggregate_destruct(arr->aggregate);
50 slang_alloc_free(arr->aggregate);
51 }
52 }
53
54 /* slang_storage_aggregate */
55
56 GLboolean
57 slang_storage_aggregate_construct(slang_storage_aggregate * agg)
58 {
59 agg->arrays = NULL;
60 agg->count = 0;
61 return GL_TRUE;
62 }
63
64 GLvoid
65 slang_storage_aggregate_destruct(slang_storage_aggregate * agg)
66 {
67 GLuint i;
68
69 for (i = 0; i < agg->count; i++)
70 slang_storage_array_destruct(agg->arrays + i);
71 slang_alloc_free(agg->arrays);
72 }
73
74 static slang_storage_array *
75 slang_storage_aggregate_push_new(slang_storage_aggregate * agg)
76 {
77 slang_storage_array *arr = NULL;
78
79 agg->arrays = (slang_storage_array *)
80 slang_alloc_realloc(agg->arrays,
81 agg->count * sizeof(slang_storage_array),
82 (agg->count + 1) * sizeof(slang_storage_array));
83 if (agg->arrays != NULL) {
84 arr = agg->arrays + agg->count;
85 if (!slang_storage_array_construct(arr))
86 return NULL;
87 agg->count++;
88 }
89 return arr;
90 }
91
92 /* _slang_aggregate_variable() */
93
94 static GLboolean
95 aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type,
96 GLuint row_count)
97 {
98 slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
99 if (arr == NULL)
100 return GL_FALSE;
101 arr->type = basic_type;
102 arr->length = row_count;
103 return GL_TRUE;
104 }
105
106 static GLboolean
107 aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type,
108 GLuint columns, GLuint rows)
109 {
110 slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
111 if (arr == NULL)
112 return GL_FALSE;
113 arr->type = SLANG_STORE_AGGREGATE;
114 arr->length = columns;
115 arr->aggregate =
116 (slang_storage_aggregate *)
117 slang_alloc_malloc(sizeof(slang_storage_aggregate));
118 if (arr->aggregate == NULL)
119 return GL_FALSE;
120 if (!slang_storage_aggregate_construct(arr->aggregate)) {
121 slang_alloc_free(arr->aggregate);
122 arr->aggregate = NULL;
123 return GL_FALSE;
124 }
125 if (!aggregate_vector(arr->aggregate, basic_type, rows))
126 return GL_FALSE;
127 return GL_TRUE;
128 }
129
130
131 static GLboolean
132 aggregate_variables(slang_storage_aggregate * agg,
133 slang_variable_scope * vars, slang_function_scope * funcs,
134 slang_struct_scope * structs,
135 slang_variable_scope * globals,
136 slang_atom_pool * atoms)
137 {
138 GLuint i;
139
140 for (i = 0; i < vars->num_variables; i++)
141 if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier,
142 vars->variables[i]->array_len, funcs,
143 structs, globals, atoms))
144 return GL_FALSE;
145 return GL_TRUE;
146 }
147
148
149 GLboolean
150 _slang_aggregate_variable(slang_storage_aggregate * agg,
151 slang_type_specifier * spec, GLuint array_len,
152 slang_function_scope * funcs,
153 slang_struct_scope * structs,
154 slang_variable_scope * vars,
155 slang_atom_pool * atoms)
156 {
157 switch (spec->type) {
158 case SLANG_SPEC_BOOL:
159 return aggregate_vector(agg, SLANG_STORE_BOOL, 1);
160 case SLANG_SPEC_BVEC2:
161 return aggregate_vector(agg, SLANG_STORE_BOOL, 2);
162 case SLANG_SPEC_BVEC3:
163 return aggregate_vector(agg, SLANG_STORE_BOOL, 3);
164 case SLANG_SPEC_BVEC4:
165 return aggregate_vector(agg, SLANG_STORE_BOOL, 4);
166 case SLANG_SPEC_INT:
167 return aggregate_vector(agg, SLANG_STORE_INT, 1);
168 case SLANG_SPEC_IVEC2:
169 return aggregate_vector(agg, SLANG_STORE_INT, 2);
170 case SLANG_SPEC_IVEC3:
171 return aggregate_vector(agg, SLANG_STORE_INT, 3);
172 case SLANG_SPEC_IVEC4:
173 return aggregate_vector(agg, SLANG_STORE_INT, 4);
174 case SLANG_SPEC_FLOAT:
175 return aggregate_vector(agg, SLANG_STORE_FLOAT, 1);
176 case SLANG_SPEC_VEC2:
177 return aggregate_vector(agg, SLANG_STORE_FLOAT, 2);
178 case SLANG_SPEC_VEC3:
179 return aggregate_vector(agg, SLANG_STORE_FLOAT, 3);
180 case SLANG_SPEC_VEC4:
181 return aggregate_vector(agg, SLANG_STORE_FLOAT, 4);
182 case SLANG_SPEC_MAT2:
183 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 2);
184 case SLANG_SPEC_MAT3:
185 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3);
186 case SLANG_SPEC_MAT4:
187 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4);
188
189 case SLANG_SPEC_MAT23:
190 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3);
191 case SLANG_SPEC_MAT32:
192 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2);
193 case SLANG_SPEC_MAT24:
194 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4);
195 case SLANG_SPEC_MAT42:
196 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2);
197 case SLANG_SPEC_MAT34:
198 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4);
199 case SLANG_SPEC_MAT43:
200 return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3);
201
202 case SLANG_SPEC_SAMPLER1D:
203 case SLANG_SPEC_SAMPLER2D:
204 case SLANG_SPEC_SAMPLER3D:
205 case SLANG_SPEC_SAMPLERCUBE:
206 case SLANG_SPEC_SAMPLER1DSHADOW:
207 case SLANG_SPEC_SAMPLER2DSHADOW:
208 case SLANG_SPEC_SAMPLER2DRECT:
209 case SLANG_SPEC_SAMPLER2DRECTSHADOW:
210 return aggregate_vector(agg, SLANG_STORE_INT, 1);
211 case SLANG_SPEC_STRUCT:
212 return aggregate_variables(agg, spec->_struct->fields, funcs, structs,
213 vars, atoms);
214 case SLANG_SPEC_ARRAY:
215 {
216 slang_storage_array *arr;
217
218 arr = slang_storage_aggregate_push_new(agg);
219 if (arr == NULL)
220 return GL_FALSE;
221 arr->type = SLANG_STORE_AGGREGATE;
222 arr->aggregate =
223 (slang_storage_aggregate *)
224 slang_alloc_malloc(sizeof(slang_storage_aggregate));
225 if (arr->aggregate == NULL)
226 return GL_FALSE;
227 if (!slang_storage_aggregate_construct(arr->aggregate)) {
228 slang_alloc_free(arr->aggregate);
229 arr->aggregate = NULL;
230 return GL_FALSE;
231 }
232 if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
233 funcs, structs, vars, atoms))
234 return GL_FALSE;
235 arr->length = array_len;
236 /* TODO: check if 0 < arr->length <= 65535 */
237 }
238 return GL_TRUE;
239 default:
240 return GL_FALSE;
241 }
242 }
243
244
245 GLuint
246 _slang_sizeof_type(slang_storage_type type)
247 {
248 if (type == SLANG_STORE_AGGREGATE)
249 return 0;
250 if (type == SLANG_STORE_VEC4)
251 return 4 * sizeof(GLfloat);
252 return sizeof(GLfloat);
253 }
254
255
256 GLuint
257 _slang_sizeof_aggregate(const slang_storage_aggregate * agg)
258 {
259 GLuint i, size = 0;
260
261 for (i = 0; i < agg->count; i++) {
262 slang_storage_array *arr = &agg->arrays[i];
263 GLuint element_size;
264
265 if (arr->type == SLANG_STORE_AGGREGATE)
266 element_size = _slang_sizeof_aggregate(arr->aggregate);
267 else
268 element_size = _slang_sizeof_type(arr->type);
269 size += element_size * arr->length;
270 }
271 return size;
272 }
273
274
275 #if 0
276 GLboolean
277 _slang_flatten_aggregate(slang_storage_aggregate * flat,
278 const slang_storage_aggregate * agg)
279 {
280 GLuint i;
281
282 for (i = 0; i < agg->count; i++) {
283 GLuint j;
284
285 for (j = 0; j < agg->arrays[i].length; j++) {
286 if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
287 if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
288 return GL_FALSE;
289 }
290 else {
291 GLuint k, count;
292 slang_storage_type type;
293
294 if (agg->arrays[i].type == SLANG_STORE_VEC4) {
295 count = 4;
296 type = SLANG_STORE_FLOAT;
297 }
298 else {
299 count = 1;
300 type = agg->arrays[i].type;
301 }
302
303 for (k = 0; k < count; k++) {
304 slang_storage_array *arr;
305
306 arr = slang_storage_aggregate_push_new(flat);
307 if (arr == NULL)
308 return GL_FALSE;
309 arr->type = type;
310 arr->length = 1;
311 }
312 }
313 }
314 }
315 return GL_TRUE;
316 }
317 #endif