updated some printfs, added comment about sched_yield
[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 slang_storage_array_construct (slang_storage_array *arr)
37 {
38 arr->type = slang_stor_aggregate;
39 arr->aggregate = NULL;
40 arr->length = 0;
41 return GL_TRUE;
42 }
43
44 GLvoid slang_storage_array_destruct (slang_storage_array *arr)
45 {
46 if (arr->aggregate != NULL)
47 {
48 slang_storage_aggregate_destruct (arr->aggregate);
49 slang_alloc_free (arr->aggregate);
50 }
51 }
52
53 /* slang_storage_aggregate */
54
55 GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *agg)
56 {
57 agg->arrays = NULL;
58 agg->count = 0;
59 return GL_TRUE;
60 }
61
62 GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *agg)
63 {
64 GLuint i;
65
66 for (i = 0; i < agg->count; i++)
67 slang_storage_array_destruct (agg->arrays + i);
68 slang_alloc_free (agg->arrays);
69 }
70
71 static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg)
72 {
73 slang_storage_array *arr = NULL;
74
75 agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof (
76 slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array));
77 if (agg->arrays != NULL)
78 {
79 arr = agg->arrays + agg->count;
80 if (!slang_storage_array_construct (arr))
81 return NULL;
82 agg->count++;
83 }
84 return arr;
85 }
86
87 /* _slang_aggregate_variable() */
88
89 static GLboolean aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type,
90 GLuint row_count)
91 {
92 slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
93 if (arr == NULL)
94 return GL_FALSE;
95 arr->type = basic_type;
96 arr->length = row_count;
97 return GL_TRUE;
98 }
99
100 static GLboolean aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type,
101 GLuint dimension)
102 {
103 slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
104 if (arr == NULL)
105 return GL_FALSE;
106 arr->type = slang_stor_aggregate;
107 arr->length = dimension;
108 arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (slang_storage_aggregate));
109 if (arr->aggregate == NULL)
110 return GL_FALSE;
111 if (!slang_storage_aggregate_construct (arr->aggregate))
112 {
113 slang_alloc_free (arr->aggregate);
114 arr->aggregate = NULL;
115 return GL_FALSE;
116 }
117 if (!aggregate_vector (arr->aggregate, basic_type, dimension))
118 return GL_FALSE;
119 return GL_TRUE;
120 }
121
122 static GLboolean aggregate_variables (slang_storage_aggregate *agg, slang_variable_scope *vars,
123 slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals,
124 slang_machine *mach, slang_assembly_file *file, slang_atom_pool *atoms)
125 {
126 GLuint i;
127
128 for (i = 0; i < vars->num_variables; i++)
129 if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier,
130 vars->variables[i].array_len, funcs, structs, globals, mach, file, atoms))
131 return GL_FALSE;
132 return GL_TRUE;
133 }
134
135 GLboolean _slang_evaluate_int (slang_assembly_file *file, slang_machine *pmach,
136 slang_assembly_name_space *space, slang_operation *array_size, GLuint *pint,
137 slang_atom_pool *atoms)
138 {
139 slang_assembly_file_restore_point point;
140 slang_machine mach;
141 slang_assemble_ctx A;
142
143 A.file = file;
144 A.mach = pmach;
145 A.atoms = atoms;
146 A.space = *space;
147 A.local.ret_size = 0;
148 A.local.addr_tmp = 0;
149 A.local.swizzle_tmp = 4;
150
151 /* save the current assembly */
152 if (!slang_assembly_file_restore_point_save (file, &point))
153 return GL_FALSE;
154
155 /* setup the machine */
156 mach = *pmach;
157 mach.ip = file->count;
158
159 /* allocate local storage for expression */
160 if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))
161 return GL_FALSE;
162 if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))
163 return GL_FALSE;
164
165 /* insert the actual expression */
166 if (!_slang_assemble_operation (&A, array_size, slang_ref_forbid))
167 return GL_FALSE;
168 if (!slang_assembly_file_push (file, slang_asm_exit))
169 return GL_FALSE;
170
171 /* execute the expression */
172 if (!_slang_execute2 (file, &mach))
173 return GL_FALSE;
174
175 /* the evaluated expression is on top of the stack */
176 *pint = (GLuint) mach.mem[mach.sp + SLANG_MACHINE_GLOBAL_SIZE]._float;
177
178 /* restore the old assembly */
179 if (!slang_assembly_file_restore_point_load (file, &point))
180 return GL_FALSE;
181
182 return GL_TRUE;
183 }
184
185 GLboolean _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec,
186 GLuint array_len, slang_function_scope *funcs, slang_struct_scope *structs,
187 slang_variable_scope *vars, slang_machine *mach, slang_assembly_file *file,
188 slang_atom_pool *atoms)
189 {
190 switch (spec->type)
191 {
192 case slang_spec_bool:
193 return aggregate_vector (agg, slang_stor_bool, 1);
194 case slang_spec_bvec2:
195 return aggregate_vector (agg, slang_stor_bool, 2);
196 case slang_spec_bvec3:
197 return aggregate_vector (agg, slang_stor_bool, 3);
198 case slang_spec_bvec4:
199 return aggregate_vector (agg, slang_stor_bool, 4);
200 case slang_spec_int:
201 return aggregate_vector (agg, slang_stor_int, 1);
202 case slang_spec_ivec2:
203 return aggregate_vector (agg, slang_stor_int, 2);
204 case slang_spec_ivec3:
205 return aggregate_vector (agg, slang_stor_int, 3);
206 case slang_spec_ivec4:
207 return aggregate_vector (agg, slang_stor_int, 4);
208 case slang_spec_float:
209 return aggregate_vector (agg, slang_stor_float, 1);
210 case slang_spec_vec2:
211 return aggregate_vector (agg, slang_stor_float, 2);
212 case slang_spec_vec3:
213 return aggregate_vector (agg, slang_stor_float, 3);
214 case slang_spec_vec4:
215 return aggregate_vector (agg, slang_stor_float, 4);
216 case slang_spec_mat2:
217 return aggregate_matrix (agg, slang_stor_float, 2);
218 case slang_spec_mat3:
219 return aggregate_matrix (agg, slang_stor_float, 3);
220 case slang_spec_mat4:
221 return aggregate_matrix (agg, slang_stor_float, 4);
222 case slang_spec_sampler1D:
223 case slang_spec_sampler2D:
224 case slang_spec_sampler3D:
225 case slang_spec_samplerCube:
226 case slang_spec_sampler1DShadow:
227 case slang_spec_sampler2DShadow:
228 return aggregate_vector (agg, slang_stor_int, 1);
229 case slang_spec_struct:
230 return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars, mach,
231 file, atoms);
232 case slang_spec_array:
233 {
234 slang_storage_array *arr;
235
236 arr = slang_storage_aggregate_push_new (agg);
237 if (arr == NULL)
238 return GL_FALSE;
239 arr->type = slang_stor_aggregate;
240 arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (slang_storage_aggregate));
241 if (arr->aggregate == NULL)
242 return GL_FALSE;
243 if (!slang_storage_aggregate_construct (arr->aggregate))
244 {
245 slang_alloc_free (arr->aggregate);
246 arr->aggregate = NULL;
247 return GL_FALSE;
248 }
249 if (!_slang_aggregate_variable (arr->aggregate, spec->_array, 0, funcs, structs,
250 vars, mach, file, atoms))
251 return GL_FALSE;
252 arr->length = array_len;
253 /* TODO: check if 0 < arr->length <= 65535 */
254 }
255 return GL_TRUE;
256 default:
257 return GL_FALSE;
258 }
259 }
260
261 /* _slang_sizeof_aggregate() */
262
263 GLuint _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
264 {
265 GLuint i, size = 0;
266
267 for (i = 0; i < agg->count; i++)
268 {
269 GLuint element_size;
270
271 if (agg->arrays[i].type == slang_stor_aggregate)
272 element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);
273 else
274 element_size = sizeof (GLfloat);
275 size += element_size * agg->arrays[i].length;
276 }
277 return size;
278 }
279
280 /* _slang_flatten_aggregate () */
281
282 GLboolean _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
283 {
284 GLuint i;
285
286 for (i = 0; i < agg->count; i++)
287 {
288 GLuint j;
289
290 for (j = 0; j < agg->arrays[i].length; j++)
291 {
292 if (agg->arrays[i].type == slang_stor_aggregate)
293 {
294 if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))
295 return GL_FALSE;
296 }
297 else
298 {
299 slang_storage_array *arr;
300
301 arr = slang_storage_aggregate_push_new (flat);
302 if (arr == NULL)
303 return GL_FALSE;
304 arr->type = agg->arrays[i].type;
305 arr->length = 1;
306 }
307 }
308 }
309 return GL_TRUE;
310 }
311