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
31 #include "main/imports.h"
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_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
:
215 return aggregate_vector(agg
, SLANG_STORE_INT
, 1);
216 case SLANG_SPEC_STRUCT
:
217 return aggregate_variables(agg
, spec
->_struct
->fields
, funcs
, structs
,
219 case SLANG_SPEC_ARRAY
:
221 slang_storage_array
*arr
;
223 arr
= slang_storage_aggregate_push_new(agg
);
226 arr
->type
= SLANG_STORE_AGGREGATE
;
227 arr
->aggregate
= (slang_storage_aggregate
*)
228 _slang_alloc(sizeof(slang_storage_aggregate
));
229 if (arr
->aggregate
== NULL
)
231 if (!slang_storage_aggregate_construct(arr
->aggregate
)) {
232 _slang_free(arr
->aggregate
);
233 arr
->aggregate
= NULL
;
236 if (!_slang_aggregate_variable(arr
->aggregate
, spec
->_array
, 0,
237 funcs
, structs
, vars
, atoms
))
239 arr
->length
= array_len
;
240 /* TODO: check if 0 < arr->length <= 65535 */
250 _slang_sizeof_type(slang_storage_type type
)
252 if (type
== SLANG_STORE_AGGREGATE
)
254 if (type
== SLANG_STORE_VEC4
)
255 return 4 * sizeof(GLfloat
);
256 return sizeof(GLfloat
);
261 _slang_sizeof_aggregate(const slang_storage_aggregate
* agg
)
265 for (i
= 0; i
< agg
->count
; i
++) {
266 slang_storage_array
*arr
= &agg
->arrays
[i
];
269 if (arr
->type
== SLANG_STORE_AGGREGATE
)
270 element_size
= _slang_sizeof_aggregate(arr
->aggregate
);
272 element_size
= _slang_sizeof_type(arr
->type
);
273 size
+= element_size
* arr
->length
;
281 _slang_flatten_aggregate(slang_storage_aggregate
* flat
,
282 const slang_storage_aggregate
* agg
)
286 for (i
= 0; i
< agg
->count
; i
++) {
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
))
296 slang_storage_type type
;
298 if (agg
->arrays
[i
].type
== SLANG_STORE_VEC4
) {
300 type
= SLANG_STORE_FLOAT
;
304 type
= agg
->arrays
[i
].type
;
307 for (k
= 0; k
< count
; k
++) {
308 slang_storage_array
*arr
;
310 arr
= slang_storage_aggregate_push_new(flat
);