e099ecb067e27957ab85dc905c573bbc3f8a729f
[mesa.git] / src / mesa / shader / slang / slang_compile_variable.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 2005-2007 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_compile_variable.c
27 * slang front-end compiler
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_compile.h"
33
34 /* slang_type_specifier_type */
35
36 typedef struct
37 {
38 const char *name;
39 slang_type_specifier_type type;
40 } type_specifier_type_name;
41
42 static const type_specifier_type_name type_specifier_type_names[] = {
43 {"void", SLANG_SPEC_VOID},
44 {"bool", SLANG_SPEC_BOOL},
45 {"bvec2", SLANG_SPEC_BVEC2},
46 {"bvec3", SLANG_SPEC_BVEC3},
47 {"bvec4", SLANG_SPEC_BVEC4},
48 {"int", SLANG_SPEC_INT},
49 {"ivec2", SLANG_SPEC_IVEC2},
50 {"ivec3", SLANG_SPEC_IVEC3},
51 {"ivec4", SLANG_SPEC_IVEC4},
52 {"float", SLANG_SPEC_FLOAT},
53 {"vec2", SLANG_SPEC_VEC2},
54 {"vec3", SLANG_SPEC_VEC3},
55 {"vec4", SLANG_SPEC_VEC4},
56 {"mat2", SLANG_SPEC_MAT2},
57 {"mat3", SLANG_SPEC_MAT3},
58 {"mat4", SLANG_SPEC_MAT4},
59 {"sampler1D", SLANG_SPEC_SAMPLER1D},
60 {"sampler2D", SLANG_SPEC_SAMPLER2D},
61 {"sampler3D", SLANG_SPEC_SAMPLER3D},
62 {"samplerCube", SLANG_SPEC_SAMPLERCUBE},
63 {"sampler1DShadow", SLANG_SPEC_SAMPLER1DSHADOW},
64 {"sampler2DShadow", SLANG_SPEC_SAMPLER2DSHADOW},
65 {"sampler2DRect", SLANG_SPEC_SAMPLER2DRECT},
66 {"sampler2DRectShadow", SLANG_SPEC_SAMPLER2DRECTSHADOW},
67 {NULL, SLANG_SPEC_VOID}
68 };
69
70 slang_type_specifier_type
71 slang_type_specifier_type_from_string(const char *name)
72 {
73 const type_specifier_type_name *p = type_specifier_type_names;
74 while (p->name != NULL) {
75 if (slang_string_compare(p->name, name) == 0)
76 break;
77 p++;
78 }
79 return p->type;
80 }
81
82 const char *
83 slang_type_specifier_type_to_string(slang_type_specifier_type type)
84 {
85 const type_specifier_type_name *p = type_specifier_type_names;
86 while (p->name != NULL) {
87 if (p->type == type)
88 break;
89 p++;
90 }
91 return p->name;
92 }
93
94 /* slang_fully_specified_type */
95
96 int
97 slang_fully_specified_type_construct(slang_fully_specified_type * type)
98 {
99 type->qualifier = SLANG_QUAL_NONE;
100 slang_type_specifier_ctr(&type->specifier);
101 return 1;
102 }
103
104 void
105 slang_fully_specified_type_destruct(slang_fully_specified_type * type)
106 {
107 slang_type_specifier_dtr(&type->specifier);
108 }
109
110 int
111 slang_fully_specified_type_copy(slang_fully_specified_type * x,
112 const slang_fully_specified_type * y)
113 {
114 slang_fully_specified_type z;
115
116 if (!slang_fully_specified_type_construct(&z))
117 return 0;
118 z.qualifier = y->qualifier;
119 if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
120 slang_fully_specified_type_destruct(&z);
121 return 0;
122 }
123 slang_fully_specified_type_destruct(x);
124 *x = z;
125 return 1;
126 }
127
128
129 static slang_variable *
130 slang_variable_new(void)
131 {
132 slang_variable *v = (slang_variable *) malloc(sizeof(slang_variable));
133 if (v) {
134 if (!slang_variable_construct(v)) {
135 free(v);
136 v = NULL;
137 }
138 }
139 return v;
140 }
141
142
143 static void
144 slang_variable_delete(slang_variable * var)
145 {
146 slang_variable_destruct(var);
147 free(var);
148 }
149
150
151 /*
152 * slang_variable_scope
153 */
154
155 slang_variable_scope *
156 _slang_variable_scope_new(slang_variable_scope *parent)
157 {
158 slang_variable_scope *s;
159 s = (slang_variable_scope *) _mesa_calloc(sizeof(slang_variable_scope));
160 s->outer_scope = parent;
161 return s;
162 }
163
164
165 GLvoid
166 _slang_variable_scope_ctr(slang_variable_scope * self)
167 {
168 self->variables = NULL;
169 self->num_variables = 0;
170 self->outer_scope = NULL;
171 }
172
173 void
174 slang_variable_scope_destruct(slang_variable_scope * scope)
175 {
176 unsigned int i;
177
178 if (!scope)
179 return;
180 for (i = 0; i < scope->num_variables; i++) {
181 if (scope->variables[i])
182 slang_variable_delete(scope->variables[i]);
183 }
184 slang_alloc_free(scope->variables);
185 /* do not free scope->outer_scope */
186 }
187
188 int
189 slang_variable_scope_copy(slang_variable_scope * x,
190 const slang_variable_scope * y)
191 {
192 slang_variable_scope z;
193 unsigned int i;
194
195 _slang_variable_scope_ctr(&z);
196 z.variables = (slang_variable **)
197 _mesa_calloc(y->num_variables * sizeof(slang_variable *));
198 if (z.variables == NULL) {
199 slang_variable_scope_destruct(&z);
200 return 0;
201 }
202 for (z.num_variables = 0; z.num_variables < y->num_variables;
203 z.num_variables++) {
204 z.variables[z.num_variables] = slang_variable_new();
205 if (!z.variables[z.num_variables]) {
206 slang_variable_scope_destruct(&z);
207 return 0;
208 }
209 }
210 for (i = 0; i < z.num_variables; i++) {
211 if (!slang_variable_copy(z.variables[i], y->variables[i])) {
212 slang_variable_scope_destruct(&z);
213 return 0;
214 }
215 }
216 z.outer_scope = y->outer_scope;
217 slang_variable_scope_destruct(x);
218 *x = z;
219 return 1;
220 }
221
222
223 /**
224 * Grow the variable list by one.
225 * \return pointer to space for the new variable (will be initialized)
226 */
227 slang_variable *
228 slang_variable_scope_grow(slang_variable_scope *scope)
229 {
230 const int n = scope->num_variables;
231 scope->variables = (slang_variable **)
232 slang_alloc_realloc(scope->variables,
233 n * sizeof(slang_variable *),
234 (n + 1) * sizeof(slang_variable *));
235 if (!scope->variables)
236 return NULL;
237
238 scope->num_variables++;
239
240 scope->variables[n] = slang_variable_new();
241 if (!scope->variables[n])
242 return NULL;
243
244 return scope->variables[n];
245 }
246
247
248
249 /* slang_variable */
250
251 int
252 slang_variable_construct(slang_variable * var)
253 {
254 if (!slang_fully_specified_type_construct(&var->type))
255 return 0;
256 var->a_name = SLANG_ATOM_NULL;
257 var->array_len = 0;
258 var->initializer = NULL;
259 var->address = ~0;
260 var->size = 0;
261 var->isTemp = GL_FALSE;
262 var->aux = NULL;
263 return 1;
264 }
265
266
267 void
268 slang_variable_destruct(slang_variable * var)
269 {
270 slang_fully_specified_type_destruct(&var->type);
271 if (var->initializer != NULL) {
272 slang_operation_destruct(var->initializer);
273 slang_alloc_free(var->initializer);
274 }
275 if (var->aux) {
276 _mesa_free(var->aux);
277 }
278 }
279
280
281 int
282 slang_variable_copy(slang_variable * x, const slang_variable * y)
283 {
284 slang_variable z;
285
286 if (!slang_variable_construct(&z))
287 return 0;
288 if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
289 slang_variable_destruct(&z);
290 return 0;
291 }
292 z.a_name = y->a_name;
293 z.array_len = y->array_len;
294 if (y->initializer != NULL) {
295 z.initializer
296 = (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
297 if (z.initializer == NULL) {
298 slang_variable_destruct(&z);
299 return 0;
300 }
301 if (!slang_operation_construct(z.initializer)) {
302 slang_alloc_free(z.initializer);
303 slang_variable_destruct(&z);
304 return 0;
305 }
306 if (!slang_operation_copy(z.initializer, y->initializer)) {
307 slang_variable_destruct(&z);
308 return 0;
309 }
310 }
311 z.address = y->address;
312 z.size = y->size;
313 slang_variable_destruct(x);
314 *x = z;
315 return 1;
316 }
317
318
319 slang_variable *
320 _slang_locate_variable(const slang_variable_scope * scope,
321 const slang_atom a_name, GLboolean all)
322 {
323 GLuint i;
324
325 for (i = 0; i < scope->num_variables; i++)
326 if (a_name == scope->variables[i]->a_name)
327 return scope->variables[i];
328 if (all && scope->outer_scope != NULL)
329 return _slang_locate_variable(scope->outer_scope, a_name, 1);
330 return NULL;
331 }
332
333 #if 0
334 static GLenum
335 gl_type_from_specifier(const slang_type_specifier * type)
336 {
337 switch (type->type) {
338 case SLANG_SPEC_BOOL:
339 return GL_BOOL_ARB;
340 case SLANG_SPEC_BVEC2:
341 return GL_BOOL_VEC2_ARB;
342 case SLANG_SPEC_BVEC3:
343 return GL_BOOL_VEC3_ARB;
344 case SLANG_SPEC_BVEC4:
345 return GL_BOOL_VEC4_ARB;
346 case SLANG_SPEC_INT:
347 return GL_INT;
348 case SLANG_SPEC_IVEC2:
349 return GL_INT_VEC2_ARB;
350 case SLANG_SPEC_IVEC3:
351 return GL_INT_VEC3_ARB;
352 case SLANG_SPEC_IVEC4:
353 return GL_INT_VEC4_ARB;
354 case SLANG_SPEC_FLOAT:
355 return GL_FLOAT;
356 case SLANG_SPEC_VEC2:
357 return GL_FLOAT_VEC2_ARB;
358 case SLANG_SPEC_VEC3:
359 return GL_FLOAT_VEC3_ARB;
360 case SLANG_SPEC_VEC4:
361 return GL_FLOAT_VEC4_ARB;
362 case SLANG_SPEC_MAT2:
363 return GL_FLOAT_MAT2_ARB;
364 case SLANG_SPEC_MAT3:
365 return GL_FLOAT_MAT3_ARB;
366 case SLANG_SPEC_MAT4:
367 return GL_FLOAT_MAT4_ARB;
368 case SLANG_SPEC_SAMPLER1D:
369 return GL_SAMPLER_1D_ARB;
370 case SLANG_SPEC_SAMPLER2D:
371 return GL_SAMPLER_2D_ARB;
372 case SLANG_SPEC_SAMPLER3D:
373 return GL_SAMPLER_3D_ARB;
374 case SLANG_SPEC_SAMPLERCUBE:
375 return GL_SAMPLER_CUBE_ARB;
376 case SLANG_SPEC_SAMPLER1DShadow:
377 return GL_SAMPLER_1D_SHADOW_ARB;
378 case SLANG_SPEC_SAMPLER2DShadow:
379 return GL_SAMPLER_2D_SHADOW_ARB;
380 case SLANG_SPEC_ARRAy:
381 return gl_type_from_specifier(type->_array);
382 default:
383 return GL_FLOAT;
384 }
385 }
386 #endif
387