bc32aa4b0220bbb52ec746e729fe09c5ece3a50b
[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 #include "slang_mem.h"
34
35 /* slang_storage_array */
36
37 GLboolean
38 slang_storage_array_construct(slang_storage_array * arr)
39 {
40 arr->type = SLANG_STORE_AGGREGATE;
41 arr->aggregate = NULL;
42 arr->length = 0;
43 return GL_TRUE;
44 }
45
46 GLvoid
47 slang_storage_array_destruct(slang_storage_array * arr)
48 {
49 if (arr->aggregate != NULL) {
50 slang_storage_aggregate_destruct(arr->aggregate);
51 _slang_free(arr->aggregate);
52 }
53 }
54
55 /* slang_storage_aggregate */
56
57 GLboolean
58 slang_storage_aggregate_construct(slang_storage_aggregate * agg)
59 {
60 agg->arrays = NULL;
61 agg->count = 0;
62 return GL_TRUE;
63 }
64
65 GLvoid
66 slang_storage_aggregate_destruct(slang_storage_aggregate * agg)
67 {
68 GLuint i;
69
70 for (i = 0; i < agg->count; i++)
71 slang_storage_array_destruct(agg->arrays + i);
72 _slang_free(agg->arrays);
73 }
74
75 static slang_storage_array *
76 slang_storage_aggregate_push_new(slang_storage_aggregate * agg)
77 {
78 slang_storage_array *arr = NULL;
79
80 agg->arrays = (slang_storage_array *)
81 _slang_realloc(agg->arrays,
82 agg->count * sizeof(slang_storage_array),
83 (agg->count + 1) * sizeof(slang_storage_array));
84 if (agg->arrays != NULL) {
85 arr = agg->arrays + agg->count;
86 if (!slang_storage_array_construct(arr))
87 return NULL;
88 agg->count++;
89 }
90 return arr;
91 }
92
93 /* _slang_aggregate_variable() */
94
95 static GLboolean
96 aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type,
97 GLuint row_count)
98 {
99 slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
100 if (arr == NULL)
101 return GL_FALSE;
102 arr->type = basic_type;
103 arr->length = row_count;
104 return GL_TRUE;
105 }
106
107 static GLboolean
108 aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type,
109 GLuint columns, GLuint rows)
110 {
111 slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
112 if (arr == NULL)
113 return GL_FALSE;
114 arr->type = SLANG_STORE_AGGREGATE;
115 arr->length = columns;
116 arr->aggregate = (slang_storage_aggregate *)
117 _slang_alloc(sizeof(slang_storage_aggregate));
118 if (arr->aggregate == NULL)
119 return GL_FALSE;
120 if (!slang_storage_aggregate_construct(arr->aggregate)) {
121 _slang_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 = (slang_storage_aggregate *)
223 _slang_alloc(sizeof(slang_storage_aggregate));
224 if (arr->aggregate == NULL)
225 return GL_FALSE;
226 if (!slang_storage_aggregate_construct(arr->aggregate)) {
227 _slang_free(arr->aggregate);
228 arr->aggregate = NULL;
229 return GL_FALSE;
230 }
231 if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
232 funcs, structs, vars, atoms))
233 return GL_FALSE;
234 arr->length = array_len;
235 /* TODO: check if 0 < arr->length <= 65535 */
236 }
237 return GL_TRUE;
238 default:
239 return GL_FALSE;
240 }
241 }
242
243
244 GLuint
245 _slang_sizeof_type(slang_storage_type type)
246 {
247 if (type == SLANG_STORE_AGGREGATE)
248 return 0;
249 if (type == SLANG_STORE_VEC4)
250 return 4 * sizeof(GLfloat);
251 return sizeof(GLfloat);
252 }
253
254
255 GLuint
256 _slang_sizeof_aggregate(const slang_storage_aggregate * agg)
257 {
258 GLuint i, size = 0;
259
260 for (i = 0; i < agg->count; i++) {
261 slang_storage_array *arr = &agg->arrays[i];
262 GLuint element_size;
263
264 if (arr->type == SLANG_STORE_AGGREGATE)
265 element_size = _slang_sizeof_aggregate(arr->aggregate);
266 else
267 element_size = _slang_sizeof_type(arr->type);
268 size += element_size * arr->length;
269 }
270 return size;
271 }
272
273
274 #if 0
275 GLboolean
276 _slang_flatten_aggregate(slang_storage_aggregate * flat,
277 const slang_storage_aggregate * agg)
278 {
279 GLuint i;
280
281 for (i = 0; i < agg->count; i++) {
282 GLuint j;
283
284 for (j = 0; j < agg->arrays[i].length; j++) {
285 if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
286 if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
287 return GL_FALSE;
288 }
289 else {
290 GLuint k, count;
291 slang_storage_type type;
292
293 if (agg->arrays[i].type == SLANG_STORE_VEC4) {
294 count = 4;
295 type = SLANG_STORE_FLOAT;
296 }
297 else {
298 count = 1;
299 type = agg->arrays[i].type;
300 }
301
302 for (k = 0; k < count; k++) {
303 slang_storage_array *arr;
304
305 arr = slang_storage_aggregate_push_new(flat);
306 if (arr == NULL)
307 return GL_FALSE;
308 arr->type = type;
309 arr->length = 1;
310 }
311 }
312 }
313 }
314 return GL_TRUE;
315 }
316 #endif