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_utility.h"
33 #include "slang_storage.h"
34 #include "slang_assemble.h"
36 /* slang_storage_array */
38 void slang_storage_array_construct (slang_storage_array
*arr
)
40 arr
->type
= slang_stor_aggregate
;
41 arr
->aggregate
= NULL
;
45 void slang_storage_array_destruct (slang_storage_array
*arr
)
47 if (arr
->aggregate
!= NULL
)
49 slang_storage_aggregate_destruct (arr
->aggregate
);
50 slang_alloc_free (arr
->aggregate
);
54 /* slang_storage_aggregate */
56 void slang_storage_aggregate_construct (slang_storage_aggregate
*agg
)
62 void slang_storage_aggregate_destruct (slang_storage_aggregate
*agg
)
65 for (i
= 0; i
< agg
->count
; i
++)
66 slang_storage_array_destruct (agg
->arrays
+ i
);
67 slang_alloc_free (agg
->arrays
);
70 static slang_storage_array
*slang_storage_aggregate_push_new (slang_storage_aggregate
*agg
)
72 slang_storage_array
*arr
= NULL
;
73 agg
->arrays
= (slang_storage_array
*) slang_alloc_realloc (agg
->arrays
, agg
->count
* sizeof (
74 slang_storage_array
), (agg
->count
+ 1) * sizeof (slang_storage_array
));
75 if (agg
->arrays
!= NULL
)
77 arr
= agg
->arrays
+ agg
->count
;
78 slang_storage_array_construct (arr
);
84 /* _slang_aggregate_variable() */
86 static int aggregate_vector (slang_storage_aggregate
*agg
, slang_storage_type basic_type
,
87 unsigned int row_count
)
89 slang_storage_array
*arr
= slang_storage_aggregate_push_new (agg
);
92 arr
->type
= basic_type
;
93 arr
->length
= row_count
;
97 static int aggregate_matrix (slang_storage_aggregate
*agg
, slang_storage_type basic_type
,
98 unsigned int dimension
)
100 slang_storage_array
*arr
= slang_storage_aggregate_push_new (agg
);
103 arr
->type
= slang_stor_aggregate
;
104 arr
->length
= dimension
;
105 arr
->aggregate
= (slang_storage_aggregate
*) slang_alloc_malloc (sizeof (
106 slang_storage_aggregate
));
107 if (arr
->aggregate
== NULL
)
109 slang_storage_aggregate_construct (arr
->aggregate
);
110 if (!aggregate_vector (arr
->aggregate
, basic_type
, dimension
))
115 static int aggregate_variables (slang_storage_aggregate
*agg
, slang_variable_scope
*vars
,
116 slang_function_scope
*funcs
, slang_struct_scope
*structs
, slang_variable_scope
*globals
)
119 for (i
= 0; i
< vars
->num_variables
; i
++)
120 if (!_slang_aggregate_variable (agg
, &vars
->variables
[i
].type
.specifier
,
121 vars
->variables
[i
].array_size
, funcs
, structs
, globals
))
126 int _slang_aggregate_variable (slang_storage_aggregate
*agg
, slang_type_specifier
*spec
,
127 slang_operation
*array_size
, slang_function_scope
*funcs
, slang_struct_scope
*structs
,
128 slang_variable_scope
*vars
)
132 case slang_spec_bool
:
133 return aggregate_vector (agg
, slang_stor_bool
, 1);
134 case slang_spec_bvec2
:
135 return aggregate_vector (agg
, slang_stor_bool
, 2);
136 case slang_spec_bvec3
:
137 return aggregate_vector (agg
, slang_stor_bool
, 3);
138 case slang_spec_bvec4
:
139 return aggregate_vector (agg
, slang_stor_bool
, 4);
141 return aggregate_vector (agg
, slang_stor_int
, 1);
142 case slang_spec_ivec2
:
143 return aggregate_vector (agg
, slang_stor_int
, 2);
144 case slang_spec_ivec3
:
145 return aggregate_vector (agg
, slang_stor_int
, 3);
146 case slang_spec_ivec4
:
147 return aggregate_vector (agg
, slang_stor_int
, 4);
148 case slang_spec_float
:
149 return aggregate_vector (agg
, slang_stor_float
, 1);
150 case slang_spec_vec2
:
151 return aggregate_vector (agg
, slang_stor_float
, 2);
152 case slang_spec_vec3
:
153 return aggregate_vector (agg
, slang_stor_float
, 3);
154 case slang_spec_vec4
:
155 return aggregate_vector (agg
, slang_stor_float
, 4);
156 case slang_spec_mat2
:
157 return aggregate_matrix (agg
, slang_stor_float
, 2);
158 case slang_spec_mat3
:
159 return aggregate_matrix (agg
, slang_stor_float
, 3);
160 case slang_spec_mat4
:
161 return aggregate_matrix (agg
, slang_stor_float
, 4);
162 case slang_spec_sampler1D
:
163 case slang_spec_sampler2D
:
164 case slang_spec_sampler3D
:
165 case slang_spec_samplerCube
:
166 case slang_spec_sampler1DShadow
:
167 case slang_spec_sampler2DShadow
:
168 return aggregate_vector (agg
, slang_stor_int
, 1);
169 case slang_spec_struct
:
170 return aggregate_variables (agg
, spec
->_struct
->fields
, funcs
, structs
, vars
);
171 case slang_spec_array
:
173 slang_storage_array
*arr
;
174 slang_assembly_file file
;
175 slang_assembly_flow_control flow
;
176 slang_assembly_name_space space
;
177 slang_assembly_local_info info
;
178 slang_assembly_stack_info stk
;
180 arr
= slang_storage_aggregate_push_new (agg
);
183 arr
->type
= slang_stor_aggregate
;
184 arr
->aggregate
= (slang_storage_aggregate
*) slang_alloc_malloc (sizeof (
185 slang_storage_aggregate
));
186 if (arr
->aggregate
== NULL
)
188 slang_storage_aggregate_construct (arr
->aggregate
);
189 if (!_slang_aggregate_variable (arr
->aggregate
, spec
->_array
, NULL
, funcs
, structs
, vars
))
191 slang_assembly_file_construct (&file
);
193 space
.structs
= structs
;
195 if (!_slang_assemble_operation (&file
, array_size
, 0, &flow
, &space
, &info
, &stk
))
197 slang_assembly_file_destruct (&file
);
200 /* TODO: evaluate array size */
201 slang_assembly_file_destruct (&file
);
210 /* _slang_sizeof_aggregate() */
212 unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate
*agg
)
214 unsigned int i
, size
= 0;
215 for (i
= 0; i
< agg
->count
; i
++)
217 unsigned int element_size
;
218 if (agg
->arrays
[i
].type
== slang_stor_aggregate
)
219 element_size
= _slang_sizeof_aggregate (agg
->arrays
[i
].aggregate
);
221 element_size
= sizeof (GLfloat
);
222 size
+= element_size
* agg
->arrays
[i
].length
;
227 /* _slang_flatten_aggregate () */
229 int _slang_flatten_aggregate (slang_storage_aggregate
*flat
, const slang_storage_aggregate
*agg
)
232 for (i
= 0; i
< agg
->count
; i
++)
235 for (j
= 0; j
< agg
->arrays
[i
].length
; j
++)
237 if (agg
->arrays
[i
].type
== slang_stor_aggregate
)
239 if (!_slang_flatten_aggregate (flat
, agg
->arrays
[i
].aggregate
))
244 slang_storage_array
*arr
;
245 arr
= slang_storage_aggregate_push_new (flat
);
248 arr
->type
= agg
->arrays
[i
].type
;