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_compile_variable.c
27 * slang front-end compiler
32 #include "slang_utility.h"
33 #include "slang_compile_variable.h"
34 #include "slang_compile_struct.h"
35 #include "slang_compile_operation.h"
37 /* slang_type_specifier_type */
42 slang_type_specifier_type type
;
43 } type_specifier_type_name
;
45 static type_specifier_type_name type_specifier_type_names
[] = {
46 { "void", slang_spec_void
},
47 { "bool", slang_spec_bool
},
48 { "bvec2", slang_spec_bvec2
},
49 { "bvec3", slang_spec_bvec3
},
50 { "bvec4", slang_spec_bvec4
},
51 { "int", slang_spec_int
},
52 { "ivec2", slang_spec_ivec2
},
53 { "ivec3", slang_spec_ivec3
},
54 { "ivec4", slang_spec_ivec4
},
55 { "float", slang_spec_float
},
56 { "vec2", slang_spec_vec2
},
57 { "vec3", slang_spec_vec3
},
58 { "vec4", slang_spec_vec4
},
59 { "mat2", slang_spec_mat2
},
60 { "mat3", slang_spec_mat3
},
61 { "mat4", slang_spec_mat4
},
62 { "sampler1D", slang_spec_sampler1D
},
63 { "sampler2D", slang_spec_sampler2D
},
64 { "sampler3D", slang_spec_sampler3D
},
65 { "samplerCube", slang_spec_samplerCube
},
66 { "sampler1DShadow", slang_spec_sampler1DShadow
},
67 { "sampler2DShadow", slang_spec_sampler2DShadow
},
68 { NULL
, slang_spec_void
}
71 slang_type_specifier_type
slang_type_specifier_type_from_string (const char *name
)
73 type_specifier_type_name
*p
= type_specifier_type_names
;
74 while (p
->name
!= NULL
)
76 if (slang_string_compare (p
->name
, name
) == 0)
83 const char *slang_type_specifier_type_to_string (slang_type_specifier_type type
)
85 type_specifier_type_name
*p
= type_specifier_type_names
;
86 while (p
->name
!= NULL
)
95 /* slang_type_specifier */
97 int slang_type_specifier_construct (slang_type_specifier
*spec
)
99 spec
->type
= slang_spec_void
;
100 spec
->_struct
= NULL
;
105 void slang_type_specifier_destruct (slang_type_specifier
*spec
)
107 if (spec
->_struct
!= NULL
)
109 slang_struct_destruct (spec
->_struct
);
110 slang_alloc_free (spec
->_struct
);
112 if (spec
->_array
!= NULL
)
114 slang_type_specifier_destruct (spec
->_array
);
115 slang_alloc_free (spec
->_array
);
119 int slang_type_specifier_copy (slang_type_specifier
*x
, const slang_type_specifier
*y
)
121 slang_type_specifier z
;
123 if (!slang_type_specifier_construct (&z
))
126 if (z
.type
== slang_spec_struct
)
128 z
._struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
129 if (z
._struct
== NULL
)
131 slang_type_specifier_destruct (&z
);
134 if (!slang_struct_construct (z
._struct
))
136 slang_alloc_free (z
._struct
);
137 slang_type_specifier_destruct (&z
);
140 if (!slang_struct_copy (z
._struct
, y
->_struct
))
142 slang_type_specifier_destruct (&z
);
146 else if (z
.type
== slang_spec_array
)
148 z
._array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (slang_type_specifier
));
149 if (z
._array
== NULL
)
151 slang_type_specifier_destruct (&z
);
154 if (!slang_type_specifier_construct (z
._array
))
156 slang_alloc_free (z
._array
);
157 slang_type_specifier_destruct (&z
);
160 if (!slang_type_specifier_copy (z
._array
, y
->_array
))
162 slang_type_specifier_destruct (&z
);
166 slang_type_specifier_destruct (x
);
171 int slang_type_specifier_equal (const slang_type_specifier
*x
, const slang_type_specifier
*y
)
173 if (x
->type
!= y
->type
)
175 if (x
->type
== slang_spec_struct
)
176 return slang_struct_equal (x
->_struct
, y
->_struct
);
177 if (x
->type
== slang_spec_array
)
178 return slang_type_specifier_equal (x
->_array
, y
->_array
);
182 /* slang_fully_specified_type */
184 int slang_fully_specified_type_construct (slang_fully_specified_type
*type
)
186 type
->qualifier
= slang_qual_none
;
187 if (!slang_type_specifier_construct (&type
->specifier
))
192 void slang_fully_specified_type_destruct (slang_fully_specified_type
*type
)
194 slang_type_specifier_destruct (&type
->specifier
);
197 int slang_fully_specified_type_copy (slang_fully_specified_type
*x
, const slang_fully_specified_type
*y
)
199 slang_fully_specified_type z
;
201 if (!slang_fully_specified_type_construct (&z
))
203 z
.qualifier
= y
->qualifier
;
204 if (!slang_type_specifier_copy (&z
.specifier
, &y
->specifier
))
206 slang_fully_specified_type_destruct (&z
);
209 slang_fully_specified_type_destruct (x
);
214 /* slang_variable_scope */
216 int slang_variable_scope_construct (slang_variable_scope
*scope
)
218 scope
->variables
= NULL
;
219 scope
->num_variables
= 0;
220 scope
->outer_scope
= NULL
;
224 void slang_variable_scope_destruct (slang_variable_scope
*scope
)
228 for (i
= 0; i
< scope
->num_variables
; i
++)
229 slang_variable_destruct (scope
->variables
+ i
);
230 slang_alloc_free (scope
->variables
);
231 /* do not free scope->outer_scope */
234 int slang_variable_scope_copy (slang_variable_scope
*x
, const slang_variable_scope
*y
)
236 slang_variable_scope z
;
239 if (!slang_variable_scope_construct (&z
))
241 z
.variables
= (slang_variable
*) slang_alloc_malloc (y
->num_variables
* sizeof (slang_variable
));
242 if (z
.variables
== NULL
)
244 slang_variable_scope_destruct (&z
);
247 for (z
.num_variables
= 0; z
.num_variables
< y
->num_variables
; z
.num_variables
++)
248 if (!slang_variable_construct (&z
.variables
[z
.num_variables
]))
250 slang_variable_scope_destruct (&z
);
253 for (i
= 0; i
< z
.num_variables
; i
++)
254 if (!slang_variable_copy (&z
.variables
[i
], &y
->variables
[i
]))
256 slang_variable_scope_destruct (&z
);
259 z
.outer_scope
= y
->outer_scope
;
260 slang_variable_scope_destruct (x
);
267 int slang_variable_construct (slang_variable
*var
)
269 if (!slang_fully_specified_type_construct (&var
->type
))
271 var
->a_name
= SLANG_ATOM_NULL
;
273 var
->initializer
= NULL
;
280 void slang_variable_destruct (slang_variable
*var
)
282 slang_fully_specified_type_destruct (&var
->type
);
283 if (var
->initializer
!= NULL
)
285 slang_operation_destruct (var
->initializer
);
286 slang_alloc_free (var
->initializer
);
290 int slang_variable_copy (slang_variable
*x
, const slang_variable
*y
)
294 if (!slang_variable_construct (&z
))
296 if (!slang_fully_specified_type_copy (&z
.type
, &y
->type
))
298 slang_variable_destruct (&z
);
301 z
.a_name
= y
->a_name
;
302 z
.array_len
= y
->array_len
;
303 if (y
->initializer
!= NULL
)
305 z
.initializer
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
306 if (z
.initializer
== NULL
)
308 slang_variable_destruct (&z
);
311 if (!slang_operation_construct (z
.initializer
))
313 slang_alloc_free (z
.initializer
);
314 slang_variable_destruct (&z
);
317 if (!slang_operation_copy (z
.initializer
, y
->initializer
))
319 slang_variable_destruct (&z
);
323 z
.address
= y
->address
;
325 z
.global
= y
->global
;
326 slang_variable_destruct (x
);
331 slang_variable
*_slang_locate_variable (slang_variable_scope
*scope
, slang_atom a_name
, GLboolean all
)
335 for (i
= 0; i
< scope
->num_variables
; i
++)
336 if (a_name
== scope
->variables
[i
].a_name
)
337 return &scope
->variables
[i
];
338 if (all
&& scope
->outer_scope
!= NULL
)
339 return _slang_locate_variable (scope
->outer_scope
, a_name
, 1);
344 * slang_active_uniforms
347 GLvoid
slang_active_uniforms_ctr (slang_active_uniforms
*self
)
353 GLvoid
slang_active_uniforms_dtr (slang_active_uniforms
*self
)
357 for (i
= 0; i
< self
->count
; i
++)
358 slang_alloc_free (self
->table
[i
].name
);
359 slang_alloc_free (self
->table
);
362 GLboolean
slang_active_uniforms_add (slang_active_uniforms
*self
, slang_export_data_quant
*q
,
365 const GLuint n
= self
->count
;
367 self
->table
= (slang_active_uniform
*) slang_alloc_realloc (self
->table
,
368 n
* sizeof (slang_active_uniform
), (n
+ 1) * sizeof (slang_active_uniform
));
369 if (self
->table
== NULL
)
371 self
->table
[n
].quant
= q
;
372 self
->table
[n
].name
= slang_string_duplicate (name
);
373 if (self
->table
[n
].name
== NULL
)
379 static GLenum
gl_type_from_specifier (const slang_type_specifier
*type
)
383 case slang_spec_bool
:
385 case slang_spec_bvec2
:
386 return GL_BOOL_VEC2_ARB
;
387 case slang_spec_bvec3
:
388 return GL_BOOL_VEC3_ARB
;
389 case slang_spec_bvec4
:
390 return GL_BOOL_VEC4_ARB
;
393 case slang_spec_ivec2
:
394 return GL_INT_VEC2_ARB
;
395 case slang_spec_ivec3
:
396 return GL_INT_VEC3_ARB
;
397 case slang_spec_ivec4
:
398 return GL_INT_VEC4_ARB
;
399 case slang_spec_float
:
401 case slang_spec_vec2
:
402 return GL_FLOAT_VEC2_ARB
;
403 case slang_spec_vec3
:
404 return GL_FLOAT_VEC3_ARB
;
405 case slang_spec_vec4
:
406 return GL_FLOAT_VEC4_ARB
;
407 case slang_spec_mat2
:
408 return GL_FLOAT_MAT2_ARB
;
409 case slang_spec_mat3
:
410 return GL_FLOAT_MAT3_ARB
;
411 case slang_spec_mat4
:
412 return GL_FLOAT_MAT4_ARB
;
413 case slang_spec_sampler1D
:
414 return GL_SAMPLER_1D_ARB
;
415 case slang_spec_sampler2D
:
416 return GL_SAMPLER_2D_ARB
;
417 case slang_spec_sampler3D
:
418 return GL_SAMPLER_3D_ARB
;
419 case slang_spec_samplerCube
:
420 return GL_SAMPLER_CUBE_ARB
;
421 case slang_spec_sampler1DShadow
:
422 return GL_SAMPLER_1D_SHADOW_ARB
;
423 case slang_spec_sampler2DShadow
:
424 return GL_SAMPLER_2D_SHADOW_ARB
;
425 case slang_spec_array
:
426 return gl_type_from_specifier (type
->_array
);
432 static GLboolean
build_quant (slang_export_data_quant
*q
, slang_variable
*var
)
434 slang_type_specifier
*spec
= &var
->type
.specifier
;
436 q
->name
= var
->a_name
;
438 if (spec
->type
== slang_spec_array
)
440 q
->array_len
= var
->array_len
;
441 q
->size
/= var
->array_len
;
444 if (spec
->type
== slang_spec_struct
)
448 q
->u
.field_count
= spec
->_struct
->fields
->num_variables
;
449 q
->structure
= (slang_export_data_quant
*) slang_alloc_malloc (
450 q
->u
.field_count
* sizeof (slang_export_data_quant
));
451 if (q
->structure
== NULL
)
454 for (i
= 0; i
< q
->u
.field_count
; i
++)
455 slang_export_data_quant_ctr (&q
->structure
[i
]);
456 for (i
= 0; i
< q
->u
.field_count
; i
++)
457 if (!build_quant (&q
->structure
[i
], &spec
->_struct
->fields
->variables
[i
]))
461 q
->u
.basic_type
= gl_type_from_specifier (spec
);
465 GLboolean
_slang_build_export_data_table (slang_export_data_table
*tbl
, slang_variable_scope
*vars
)
469 for (i
= 0; i
< vars
->num_variables
; i
++)
471 slang_variable
*var
= &vars
->variables
[i
];
473 if (var
->type
.qualifier
== slang_qual_uniform
)
475 slang_export_data_entry
*e
= slang_export_data_table_add (tbl
);
478 if (!build_quant (&e
->quant
, var
))
480 e
->access
= slang_exp_uniform
;
481 e
->address
= var
->address
;
485 if (vars
->outer_scope
!= NULL
)
486 return _slang_build_export_data_table (tbl
, vars
->outer_scope
);
490 static GLboolean
insert_uniform (slang_active_uniforms
*u
, slang_export_data_quant
*q
, char *name
,
491 slang_atom_pool
*atoms
)
493 slang_string_concat (name
, slang_atom_pool_id (atoms
, q
->name
));
494 if (q
->array_len
!= 0)
495 slang_string_concat (name
, "[0]");
497 if (q
->structure
!= NULL
)
501 slang_string_concat (name
, ".");
502 save
= slang_string_length (name
);
504 for (i
= 0; i
< q
->u
.field_count
; i
++)
506 if (!insert_uniform (u
, &q
->structure
[i
], name
, atoms
))
514 return slang_active_uniforms_add (u
, q
, name
);
517 GLboolean
_slang_gather_active_uniforms (slang_active_uniforms
*u
, slang_export_data_table
*tbl
)
521 for (i
= 0; i
< tbl
->count
; i
++)
523 char name
[1024] = "";
525 if (!insert_uniform (u
, &tbl
->entries
[i
].quant
, name
, tbl
->atoms
))