2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * \file slang_storage.c
27 * slang variable storage
32 #include "slang_storage.h"
34 /* slang_storage_array */
36 GLboolean
slang_storage_array_construct (slang_storage_array
*arr
)
38 arr
->type
= slang_stor_aggregate
;
39 arr
->aggregate
= NULL
;
44 GLvoid
slang_storage_array_destruct (slang_storage_array
*arr
)
46 if (arr
->aggregate
!= NULL
)
48 slang_storage_aggregate_destruct (arr
->aggregate
);
49 slang_alloc_free (arr
->aggregate
);
53 /* slang_storage_aggregate */
55 GLboolean
slang_storage_aggregate_construct (slang_storage_aggregate
*agg
)
62 GLvoid
slang_storage_aggregate_destruct (slang_storage_aggregate
*agg
)
66 for (i
= 0; i
< agg
->count
; i
++)
67 slang_storage_array_destruct (agg
->arrays
+ i
);
68 slang_alloc_free (agg
->arrays
);
71 static slang_storage_array
*slang_storage_aggregate_push_new (slang_storage_aggregate
*agg
)
73 slang_storage_array
*arr
= NULL
;
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
)
79 arr
= agg
->arrays
+ agg
->count
;
80 if (!slang_storage_array_construct (arr
))
87 /* _slang_aggregate_variable() */
89 static GLboolean
aggregate_vector (slang_storage_aggregate
*agg
, slang_storage_type basic_type
,
92 slang_storage_array
*arr
= slang_storage_aggregate_push_new (agg
);
95 arr
->type
= basic_type
;
96 arr
->length
= row_count
;
100 static GLboolean
aggregate_matrix (slang_storage_aggregate
*agg
, slang_storage_type basic_type
,
103 slang_storage_array
*arr
= slang_storage_aggregate_push_new (agg
);
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
)
111 if (!slang_storage_aggregate_construct (arr
->aggregate
))
113 slang_alloc_free (arr
->aggregate
);
114 arr
->aggregate
= NULL
;
117 if (!aggregate_vector (arr
->aggregate
, basic_type
, dimension
))
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
)
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
))
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
)
139 slang_assembly_file_restore_point point
;
141 slang_assemble_ctx A
;
147 A
.local
.ret_size
= 0;
148 A
.local
.addr_tmp
= 0;
149 A
.local
.swizzle_tmp
= 4;
151 /* save the current assembly */
152 if (!slang_assembly_file_restore_point_save (file
, &point
))
155 /* setup the machine */
157 mach
.ip
= file
->count
;
159 /* allocate local storage for expression */
160 if (!slang_assembly_file_push_label (file
, slang_asm_local_alloc
, 20))
162 if (!slang_assembly_file_push_label (file
, slang_asm_enter
, 20))
165 /* insert the actual expression */
166 if (!_slang_assemble_operation (&A
, array_size
, slang_ref_forbid
))
168 if (!slang_assembly_file_push (file
, slang_asm_exit
))
171 /* execute the expression */
172 if (!_slang_execute2 (file
, &mach
))
175 /* the evaluated expression is on top of the stack */
176 *pint
= (GLuint
) mach
.mem
[mach
.sp
+ SLANG_MACHINE_GLOBAL_SIZE
]._float
;
178 /* restore the old assembly */
179 if (!slang_assembly_file_restore_point_load (file
, &point
))
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
)
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);
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
,
232 case slang_spec_array
:
234 slang_storage_array
*arr
;
236 arr
= slang_storage_aggregate_push_new (agg
);
239 arr
->type
= slang_stor_aggregate
;
240 arr
->aggregate
= (slang_storage_aggregate
*) slang_alloc_malloc (sizeof (slang_storage_aggregate
));
241 if (arr
->aggregate
== NULL
)
243 if (!slang_storage_aggregate_construct (arr
->aggregate
))
245 slang_alloc_free (arr
->aggregate
);
246 arr
->aggregate
= NULL
;
249 if (!_slang_aggregate_variable (arr
->aggregate
, spec
->_array
, 0, funcs
, structs
,
250 vars
, mach
, file
, atoms
))
252 arr
->length
= array_len
;
253 /* TODO: check if 0 < arr->length <= 65535 */
261 /* _slang_sizeof_aggregate() */
263 GLuint
_slang_sizeof_aggregate (const slang_storage_aggregate
*agg
)
267 for (i
= 0; i
< agg
->count
; i
++)
271 if (agg
->arrays
[i
].type
== slang_stor_aggregate
)
272 element_size
= _slang_sizeof_aggregate (agg
->arrays
[i
].aggregate
);
274 element_size
= sizeof (GLfloat
);
275 size
+= element_size
* agg
->arrays
[i
].length
;
280 /* _slang_flatten_aggregate () */
282 GLboolean
_slang_flatten_aggregate (slang_storage_aggregate
*flat
, const slang_storage_aggregate
*agg
)
286 for (i
= 0; i
< agg
->count
; i
++)
290 for (j
= 0; j
< agg
->arrays
[i
].length
; j
++)
292 if (agg
->arrays
[i
].type
== slang_stor_aggregate
)
294 if (!_slang_flatten_aggregate (flat
, agg
->arrays
[i
].aggregate
))
299 slang_storage_array
*arr
;
301 arr
= slang_storage_aggregate_push_new (flat
);
304 arr
->type
= agg
->arrays
[i
].type
;