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"
33 #include "slang_mem.h"
35 /* slang_storage_array */
38 slang_storage_array_construct(slang_storage_array
* arr
)
40 arr
->type
= SLANG_STORE_AGGREGATE
;
41 arr
->aggregate
= NULL
;
47 slang_storage_array_destruct(slang_storage_array
* arr
)
49 if (arr
->aggregate
!= NULL
) {
50 slang_storage_aggregate_destruct(arr
->aggregate
);
51 _slang_free(arr
->aggregate
);
55 /* slang_storage_aggregate */
58 slang_storage_aggregate_construct(slang_storage_aggregate
* agg
)
66 slang_storage_aggregate_destruct(slang_storage_aggregate
* agg
)
70 for (i
= 0; i
< agg
->count
; i
++)
71 slang_storage_array_destruct(agg
->arrays
+ i
);
72 _slang_free(agg
->arrays
);
75 static slang_storage_array
*
76 slang_storage_aggregate_push_new(slang_storage_aggregate
* agg
)
78 slang_storage_array
*arr
= NULL
;
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
))
93 /* _slang_aggregate_variable() */
96 aggregate_vector(slang_storage_aggregate
* agg
, slang_storage_type basic_type
,
99 slang_storage_array
*arr
= slang_storage_aggregate_push_new(agg
);
102 arr
->type
= basic_type
;
103 arr
->length
= row_count
;
108 aggregate_matrix(slang_storage_aggregate
* agg
, slang_storage_type basic_type
,
109 GLuint columns
, GLuint rows
)
111 slang_storage_array
*arr
= slang_storage_aggregate_push_new(agg
);
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
)
120 if (!slang_storage_aggregate_construct(arr
->aggregate
)) {
121 _slang_free(arr
->aggregate
);
122 arr
->aggregate
= NULL
;
125 if (!aggregate_vector(arr
->aggregate
, basic_type
, rows
))
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
)
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
))
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
)
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);
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);
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);
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
,
214 case SLANG_SPEC_ARRAY
:
216 slang_storage_array
*arr
;
218 arr
= slang_storage_aggregate_push_new(agg
);
221 arr
->type
= SLANG_STORE_AGGREGATE
;
222 arr
->aggregate
= (slang_storage_aggregate
*)
223 _slang_alloc(sizeof(slang_storage_aggregate
));
224 if (arr
->aggregate
== NULL
)
226 if (!slang_storage_aggregate_construct(arr
->aggregate
)) {
227 _slang_free(arr
->aggregate
);
228 arr
->aggregate
= NULL
;
231 if (!_slang_aggregate_variable(arr
->aggregate
, spec
->_array
, 0,
232 funcs
, structs
, vars
, atoms
))
234 arr
->length
= array_len
;
235 /* TODO: check if 0 < arr->length <= 65535 */
245 _slang_sizeof_type(slang_storage_type type
)
247 if (type
== SLANG_STORE_AGGREGATE
)
249 if (type
== SLANG_STORE_VEC4
)
250 return 4 * sizeof(GLfloat
);
251 return sizeof(GLfloat
);
256 _slang_sizeof_aggregate(const slang_storage_aggregate
* agg
)
260 for (i
= 0; i
< agg
->count
; i
++) {
261 slang_storage_array
*arr
= &agg
->arrays
[i
];
264 if (arr
->type
== SLANG_STORE_AGGREGATE
)
265 element_size
= _slang_sizeof_aggregate(arr
->aggregate
);
267 element_size
= _slang_sizeof_type(arr
->type
);
268 size
+= element_size
* arr
->length
;
276 _slang_flatten_aggregate(slang_storage_aggregate
* flat
,
277 const slang_storage_aggregate
* agg
)
281 for (i
= 0; i
< agg
->count
; i
++) {
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
))
291 slang_storage_type type
;
293 if (agg
->arrays
[i
].type
== SLANG_STORE_VEC4
) {
295 type
= SLANG_STORE_FLOAT
;
299 type
= agg
->arrays
[i
].type
;
302 for (k
= 0; k
< count
; k
++) {
303 slang_storage_array
*arr
;
305 arr
= slang_storage_aggregate_push_new(flat
);