nv50: fix build-predicate function
[mesa.git] / src / mesa / 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 "main/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_SAMPLER_1D:
203 case SLANG_SPEC_SAMPLER_2D:
204 case SLANG_SPEC_SAMPLER_3D:
205 case SLANG_SPEC_SAMPLER_CUBE:
206 case SLANG_SPEC_SAMPLER_1D_SHADOW:
207 case SLANG_SPEC_SAMPLER_2D_SHADOW:
208 case SLANG_SPEC_SAMPLER_RECT:
209 case SLANG_SPEC_SAMPLER_RECT_SHADOW:
210 case SLANG_SPEC_SAMPLER_1D_ARRAY:
211 case SLANG_SPEC_SAMPLER_2D_ARRAY:
212 case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
213 case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
214
215 return aggregate_vector(agg, SLANG_STORE_INT, 1);
216 case SLANG_SPEC_STRUCT:
217 return aggregate_variables(agg, spec->_struct->fields, funcs, structs,
218 vars, atoms);
219 case SLANG_SPEC_ARRAY:
220 {
221 slang_storage_array *arr;
222
223 arr = slang_storage_aggregate_push_new(agg);
224 if (arr == NULL)
225 return GL_FALSE;
226 arr->type = SLANG_STORE_AGGREGATE;
227 arr->aggregate = (slang_storage_aggregate *)
228 _slang_alloc(sizeof(slang_storage_aggregate));
229 if (arr->aggregate == NULL)
230 return GL_FALSE;
231 if (!slang_storage_aggregate_construct(arr->aggregate)) {
232 _slang_free(arr->aggregate);
233 arr->aggregate = NULL;
234 return GL_FALSE;
235 }
236 if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
237 funcs, structs, vars, atoms))
238 return GL_FALSE;
239 arr->length = array_len;
240 /* TODO: check if 0 < arr->length <= 65535 */
241 }
242 return GL_TRUE;
243 default:
244 return GL_FALSE;
245 }
246 }
247
248
249 GLuint
250 _slang_sizeof_type(slang_storage_type type)
251 {
252 if (type == SLANG_STORE_AGGREGATE)
253 return 0;
254 if (type == SLANG_STORE_VEC4)
255 return 4 * sizeof(GLfloat);
256 return sizeof(GLfloat);
257 }
258
259
260 GLuint
261 _slang_sizeof_aggregate(const slang_storage_aggregate * agg)
262 {
263 GLuint i, size = 0;
264
265 for (i = 0; i < agg->count; i++) {
266 slang_storage_array *arr = &agg->arrays[i];
267 GLuint element_size;
268
269 if (arr->type == SLANG_STORE_AGGREGATE)
270 element_size = _slang_sizeof_aggregate(arr->aggregate);
271 else
272 element_size = _slang_sizeof_type(arr->type);
273 size += element_size * arr->length;
274 }
275 return size;
276 }
277
278
279 #if 0
280 GLboolean
281 _slang_flatten_aggregate(slang_storage_aggregate * flat,
282 const slang_storage_aggregate * agg)
283 {
284 GLuint i;
285
286 for (i = 0; i < agg->count; i++) {
287 GLuint j;
288
289 for (j = 0; j < agg->arrays[i].length; j++) {
290 if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
291 if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
292 return GL_FALSE;
293 }
294 else {
295 GLuint k, count;
296 slang_storage_type type;
297
298 if (agg->arrays[i].type == SLANG_STORE_VEC4) {
299 count = 4;
300 type = SLANG_STORE_FLOAT;
301 }
302 else {
303 count = 1;
304 type = agg->arrays[i].type;
305 }
306
307 for (k = 0; k < count; k++) {
308 slang_storage_array *arr;
309
310 arr = slang_storage_aggregate_push_new(flat);
311 if (arr == NULL)
312 return GL_FALSE;
313 arr->type = type;
314 arr->length = 1;
315 }
316 }
317 }
318 }
319 return GL_TRUE;
320 }
321 #endif