mesa: set up gl_vert_result and gl_frag_attrib values for gl_ClipDistance.
[mesa.git] / src / glsl / glsl_parser_extras.cpp
1 /*
2 * Copyright © 2008, 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <assert.h>
27
28 extern "C" {
29 #include "main/core.h" /* for struct gl_context */
30 }
31
32 #include "ralloc.h"
33 #include "ast.h"
34 #include "glsl_parser_extras.h"
35 #include "glsl_parser.h"
36 #include "ir_optimization.h"
37 #include "loop_analysis.h"
38
39 _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
40 GLenum target, void *mem_ctx)
41 {
42 switch (target) {
43 case GL_VERTEX_SHADER: this->target = vertex_shader; break;
44 case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
45 case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
46 }
47
48 this->scanner = NULL;
49 this->translation_unit.make_empty();
50 this->symbols = new(mem_ctx) glsl_symbol_table;
51 this->info_log = ralloc_strdup(mem_ctx, "");
52 this->error = false;
53 this->loop_or_switch_nesting = NULL;
54
55 /* Set default language version and extensions */
56 this->language_version = 110;
57 this->es_shader = false;
58 this->ARB_texture_rectangle_enable = true;
59
60 /* OpenGL ES 2.0 has different defaults from desktop GL. */
61 if (ctx->API == API_OPENGLES2) {
62 this->language_version = 100;
63 this->es_shader = true;
64 this->ARB_texture_rectangle_enable = false;
65 }
66
67 this->extensions = &ctx->Extensions;
68
69 this->Const.MaxLights = ctx->Const.MaxLights;
70 this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
71 this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
72 this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
73 this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
74 this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
75 this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
76 this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
77 this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
78 this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
79 this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
80
81 this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
82
83 /* Note: Once the OpenGL 3.0 'forward compatible' context or the OpenGL 3.2
84 * Core context is supported, this logic will need change. Older versions of
85 * GLSL are no longer supported outside the compatibility contexts of 3.x.
86 */
87 this->Const.GLSL_100ES = (ctx->API == API_OPENGLES2)
88 || ctx->Extensions.ARB_ES2_compatibility;
89 this->Const.GLSL_110 = (ctx->API == API_OPENGL);
90 this->Const.GLSL_120 = (ctx->API == API_OPENGL)
91 && (ctx->Const.GLSLVersion >= 120);
92 this->Const.GLSL_130 = (ctx->API == API_OPENGL)
93 && (ctx->Const.GLSLVersion >= 130);
94
95 const unsigned lowest_version =
96 (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility
97 ? 100 : 110;
98 const unsigned highest_version =
99 (ctx->API == API_OPENGL) ? ctx->Const.GLSLVersion : 100;
100 char *supported = ralloc_strdup(this, "");
101
102 for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) {
103 const char *const prefix = (ver == lowest_version)
104 ? ""
105 : ((ver == highest_version) ? ", and " : ", ");
106
107 ralloc_asprintf_append(& supported, "%s%d.%02d%s",
108 prefix,
109 ver / 100, ver % 100,
110 (ver == 100) ? " ES" : "");
111 }
112
113 this->supported_version_string = supported;
114 }
115
116 const char *
117 _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
118 {
119 switch (target) {
120 case vertex_shader: return "vertex";
121 case fragment_shader: return "fragment";
122 case geometry_shader: return "geometry";
123 }
124
125 assert(!"Should not get here.");
126 return "unknown";
127 }
128
129
130 void
131 _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
132 const char *fmt, ...)
133 {
134 va_list ap;
135
136 state->error = true;
137
138 assert(state->info_log != NULL);
139 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): error: ",
140 locp->source,
141 locp->first_line,
142 locp->first_column);
143 va_start(ap, fmt);
144 ralloc_vasprintf_append(&state->info_log, fmt, ap);
145 va_end(ap);
146 ralloc_strcat(&state->info_log, "\n");
147 }
148
149
150 void
151 _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
152 const char *fmt, ...)
153 {
154 va_list ap;
155
156 assert(state->info_log != NULL);
157 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): warning: ",
158 locp->source,
159 locp->first_line,
160 locp->first_column);
161 va_start(ap, fmt);
162 ralloc_vasprintf_append(&state->info_log, fmt, ap);
163 va_end(ap);
164 ralloc_strcat(&state->info_log, "\n");
165 }
166
167
168 /**
169 * Enum representing the possible behaviors that can be specified in
170 * an #extension directive.
171 */
172 enum ext_behavior {
173 extension_disable,
174 extension_enable,
175 extension_require,
176 extension_warn
177 };
178
179 /**
180 * Element type for _mesa_glsl_supported_extensions
181 */
182 struct _mesa_glsl_extension {
183 /**
184 * Name of the extension when referred to in a GLSL extension
185 * statement
186 */
187 const char *name;
188
189 /** True if this extension is available to vertex shaders */
190 bool avail_in_VS;
191
192 /** True if this extension is available to geometry shaders */
193 bool avail_in_GS;
194
195 /** True if this extension is available to fragment shaders */
196 bool avail_in_FS;
197
198 /** True if this extension is available to desktop GL shaders */
199 bool avail_in_GL;
200
201 /** True if this extension is available to GLES shaders */
202 bool avail_in_ES;
203
204 /**
205 * Flag in the gl_extensions struct indicating whether this
206 * extension is supported by the driver, or
207 * &gl_extensions::dummy_true if supported by all drivers.
208 *
209 * Note: the type (GLboolean gl_extensions::*) is a "pointer to
210 * member" type, the type-safe alternative to the "offsetof" macro.
211 * In a nutshell:
212 *
213 * - foo bar::* p declares p to be an "offset" to a field of type
214 * foo that exists within struct bar
215 * - &bar::baz computes the "offset" of field baz within struct bar
216 * - x.*p accesses the field of x that exists at "offset" p
217 * - x->*p is equivalent to (*x).*p
218 */
219 const GLboolean gl_extensions::* supported_flag;
220
221 /**
222 * Flag in the _mesa_glsl_parse_state struct that should be set
223 * when this extension is enabled.
224 *
225 * See note in _mesa_glsl_extension::supported_flag about "pointer
226 * to member" types.
227 */
228 bool _mesa_glsl_parse_state::* enable_flag;
229
230 /**
231 * Flag in the _mesa_glsl_parse_state struct that should be set
232 * when the shader requests "warn" behavior for this extension.
233 *
234 * See note in _mesa_glsl_extension::supported_flag about "pointer
235 * to member" types.
236 */
237 bool _mesa_glsl_parse_state::* warn_flag;
238
239
240 bool compatible_with_state(const _mesa_glsl_parse_state *state) const;
241 void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
242 };
243
244 #define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \
245 { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \
246 &_mesa_glsl_parse_state::NAME##_enable, \
247 &_mesa_glsl_parse_state::NAME##_warn }
248
249 /**
250 * Table of extensions that can be enabled/disabled within a shader,
251 * and the conditions under which they are supported.
252 */
253 static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
254 /* target availability API availability */
255 /* name VS GS FS GL ES supported flag */
256 EXT(ARB_conservative_depth, true, false, true, true, false, AMD_conservative_depth),
257 EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true),
258 EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced),
259 EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location),
260 EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions),
261 EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true),
262 EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array),
263 EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod),
264 EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
265 EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth),
266 EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
267 EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D),
268 };
269
270 #undef EXT
271
272
273 /**
274 * Determine whether a given extension is compatible with the target,
275 * API, and extension information in the current parser state.
276 */
277 bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
278 state) const
279 {
280 /* Check that this extension matches the type of shader we are
281 * compiling to.
282 */
283 switch (state->target) {
284 case vertex_shader:
285 if (!this->avail_in_VS) {
286 return false;
287 }
288 break;
289 case geometry_shader:
290 if (!this->avail_in_GS) {
291 return false;
292 }
293 break;
294 case fragment_shader:
295 if (!this->avail_in_FS) {
296 return false;
297 }
298 break;
299 default:
300 assert (!"Unrecognized shader target");
301 return false;
302 }
303
304 /* Check that this extension matches whether we are compiling
305 * for desktop GL or GLES.
306 */
307 if (state->es_shader) {
308 if (!this->avail_in_ES) return false;
309 } else {
310 if (!this->avail_in_GL) return false;
311 }
312
313 /* Check that this extension is supported by the OpenGL
314 * implementation.
315 *
316 * Note: the ->* operator indexes into state->extensions by the
317 * offset this->supported_flag. See
318 * _mesa_glsl_extension::supported_flag for more info.
319 */
320 return state->extensions->*(this->supported_flag);
321 }
322
323 /**
324 * Set the appropriate flags in the parser state to establish the
325 * given behavior for this extension.
326 */
327 void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state,
328 ext_behavior behavior) const
329 {
330 /* Note: the ->* operator indexes into state by the
331 * offsets this->enable_flag and this->warn_flag. See
332 * _mesa_glsl_extension::supported_flag for more info.
333 */
334 state->*(this->enable_flag) = (behavior != extension_disable);
335 state->*(this->warn_flag) = (behavior == extension_warn);
336 }
337
338 /**
339 * Find an extension by name in _mesa_glsl_supported_extensions. If
340 * the name is not found, return NULL.
341 */
342 static const _mesa_glsl_extension *find_extension(const char *name)
343 {
344 for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) {
345 if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) {
346 return &_mesa_glsl_supported_extensions[i];
347 }
348 }
349 return NULL;
350 }
351
352
353 bool
354 _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
355 const char *behavior_string, YYLTYPE *behavior_locp,
356 _mesa_glsl_parse_state *state)
357 {
358 ext_behavior behavior;
359 if (strcmp(behavior_string, "warn") == 0) {
360 behavior = extension_warn;
361 } else if (strcmp(behavior_string, "require") == 0) {
362 behavior = extension_require;
363 } else if (strcmp(behavior_string, "enable") == 0) {
364 behavior = extension_enable;
365 } else if (strcmp(behavior_string, "disable") == 0) {
366 behavior = extension_disable;
367 } else {
368 _mesa_glsl_error(behavior_locp, state,
369 "Unknown extension behavior `%s'",
370 behavior_string);
371 return false;
372 }
373
374 if (strcmp(name, "all") == 0) {
375 if ((behavior == extension_enable) || (behavior == extension_require)) {
376 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
377 (behavior == extension_enable)
378 ? "enable" : "require");
379 return false;
380 } else {
381 for (unsigned i = 0;
382 i < Elements(_mesa_glsl_supported_extensions); ++i) {
383 const _mesa_glsl_extension *extension
384 = &_mesa_glsl_supported_extensions[i];
385 if (extension->compatible_with_state(state)) {
386 _mesa_glsl_supported_extensions[i].set_flags(state, behavior);
387 }
388 }
389 }
390 } else {
391 const _mesa_glsl_extension *extension = find_extension(name);
392 if (extension && extension->compatible_with_state(state)) {
393 extension->set_flags(state, behavior);
394 } else {
395 static const char *const fmt = "extension `%s' unsupported in %s shader";
396
397 if (behavior == extension_require) {
398 _mesa_glsl_error(name_locp, state, fmt,
399 name, _mesa_glsl_shader_target_name(state->target));
400 return false;
401 } else {
402 _mesa_glsl_warning(name_locp, state, fmt,
403 name, _mesa_glsl_shader_target_name(state->target));
404 }
405 }
406 }
407
408 return true;
409 }
410
411 void
412 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
413 {
414 if (q->flags.q.constant)
415 printf("const ");
416
417 if (q->flags.q.invariant)
418 printf("invariant ");
419
420 if (q->flags.q.attribute)
421 printf("attribute ");
422
423 if (q->flags.q.varying)
424 printf("varying ");
425
426 if (q->flags.q.in && q->flags.q.out)
427 printf("inout ");
428 else {
429 if (q->flags.q.in)
430 printf("in ");
431
432 if (q->flags.q.out)
433 printf("out ");
434 }
435
436 if (q->flags.q.centroid)
437 printf("centroid ");
438 if (q->flags.q.uniform)
439 printf("uniform ");
440 if (q->flags.q.smooth)
441 printf("smooth ");
442 if (q->flags.q.flat)
443 printf("flat ");
444 if (q->flags.q.noperspective)
445 printf("noperspective ");
446 }
447
448
449 void
450 ast_node::print(void) const
451 {
452 printf("unhandled node ");
453 }
454
455
456 ast_node::ast_node(void)
457 {
458 this->location.source = 0;
459 this->location.line = 0;
460 this->location.column = 0;
461 }
462
463
464 static void
465 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
466 {
467 if (is_array) {
468 printf("[ ");
469
470 if (array_size)
471 array_size->print();
472
473 printf("] ");
474 }
475 }
476
477
478 void
479 ast_compound_statement::print(void) const
480 {
481 printf("{\n");
482
483 foreach_list_const(n, &this->statements) {
484 ast_node *ast = exec_node_data(ast_node, n, link);
485 ast->print();
486 }
487
488 printf("}\n");
489 }
490
491
492 ast_compound_statement::ast_compound_statement(int new_scope,
493 ast_node *statements)
494 {
495 this->new_scope = new_scope;
496
497 if (statements != NULL) {
498 this->statements.push_degenerate_list_at_head(&statements->link);
499 }
500 }
501
502
503 void
504 ast_expression::print(void) const
505 {
506 switch (oper) {
507 case ast_assign:
508 case ast_mul_assign:
509 case ast_div_assign:
510 case ast_mod_assign:
511 case ast_add_assign:
512 case ast_sub_assign:
513 case ast_ls_assign:
514 case ast_rs_assign:
515 case ast_and_assign:
516 case ast_xor_assign:
517 case ast_or_assign:
518 subexpressions[0]->print();
519 printf("%s ", operator_string(oper));
520 subexpressions[1]->print();
521 break;
522
523 case ast_field_selection:
524 subexpressions[0]->print();
525 printf(". %s ", primary_expression.identifier);
526 break;
527
528 case ast_plus:
529 case ast_neg:
530 case ast_bit_not:
531 case ast_logic_not:
532 case ast_pre_inc:
533 case ast_pre_dec:
534 printf("%s ", operator_string(oper));
535 subexpressions[0]->print();
536 break;
537
538 case ast_post_inc:
539 case ast_post_dec:
540 subexpressions[0]->print();
541 printf("%s ", operator_string(oper));
542 break;
543
544 case ast_conditional:
545 subexpressions[0]->print();
546 printf("? ");
547 subexpressions[1]->print();
548 printf(": ");
549 subexpressions[2]->print();
550 break;
551
552 case ast_array_index:
553 subexpressions[0]->print();
554 printf("[ ");
555 subexpressions[1]->print();
556 printf("] ");
557 break;
558
559 case ast_function_call: {
560 subexpressions[0]->print();
561 printf("( ");
562
563 foreach_list_const (n, &this->expressions) {
564 if (n != this->expressions.get_head())
565 printf(", ");
566
567 ast_node *ast = exec_node_data(ast_node, n, link);
568 ast->print();
569 }
570
571 printf(") ");
572 break;
573 }
574
575 case ast_identifier:
576 printf("%s ", primary_expression.identifier);
577 break;
578
579 case ast_int_constant:
580 printf("%d ", primary_expression.int_constant);
581 break;
582
583 case ast_uint_constant:
584 printf("%u ", primary_expression.uint_constant);
585 break;
586
587 case ast_float_constant:
588 printf("%f ", primary_expression.float_constant);
589 break;
590
591 case ast_bool_constant:
592 printf("%s ",
593 primary_expression.bool_constant
594 ? "true" : "false");
595 break;
596
597 case ast_sequence: {
598 printf("( ");
599 foreach_list_const(n, & this->expressions) {
600 if (n != this->expressions.get_head())
601 printf(", ");
602
603 ast_node *ast = exec_node_data(ast_node, n, link);
604 ast->print();
605 }
606 printf(") ");
607 break;
608 }
609
610 default:
611 assert(0);
612 break;
613 }
614 }
615
616 ast_expression::ast_expression(int oper,
617 ast_expression *ex0,
618 ast_expression *ex1,
619 ast_expression *ex2)
620 {
621 this->oper = ast_operators(oper);
622 this->subexpressions[0] = ex0;
623 this->subexpressions[1] = ex1;
624 this->subexpressions[2] = ex2;
625 }
626
627
628 void
629 ast_expression_statement::print(void) const
630 {
631 if (expression)
632 expression->print();
633
634 printf("; ");
635 }
636
637
638 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
639 expression(ex)
640 {
641 /* empty */
642 }
643
644
645 void
646 ast_function::print(void) const
647 {
648 return_type->print();
649 printf(" %s (", identifier);
650
651 foreach_list_const(n, & this->parameters) {
652 ast_node *ast = exec_node_data(ast_node, n, link);
653 ast->print();
654 }
655
656 printf(")");
657 }
658
659
660 ast_function::ast_function(void)
661 : is_definition(false), signature(NULL)
662 {
663 /* empty */
664 }
665
666
667 void
668 ast_fully_specified_type::print(void) const
669 {
670 _mesa_ast_type_qualifier_print(& qualifier);
671 specifier->print();
672 }
673
674
675 void
676 ast_parameter_declarator::print(void) const
677 {
678 type->print();
679 if (identifier)
680 printf("%s ", identifier);
681 ast_opt_array_size_print(is_array, array_size);
682 }
683
684
685 void
686 ast_function_definition::print(void) const
687 {
688 prototype->print();
689 body->print();
690 }
691
692
693 void
694 ast_declaration::print(void) const
695 {
696 printf("%s ", identifier);
697 ast_opt_array_size_print(is_array, array_size);
698
699 if (initializer) {
700 printf("= ");
701 initializer->print();
702 }
703 }
704
705
706 ast_declaration::ast_declaration(char *identifier, int is_array,
707 ast_expression *array_size,
708 ast_expression *initializer)
709 {
710 this->identifier = identifier;
711 this->is_array = is_array;
712 this->array_size = array_size;
713 this->initializer = initializer;
714 }
715
716
717 void
718 ast_declarator_list::print(void) const
719 {
720 assert(type || invariant);
721
722 if (type)
723 type->print();
724 else
725 printf("invariant ");
726
727 foreach_list_const (ptr, & this->declarations) {
728 if (ptr != this->declarations.get_head())
729 printf(", ");
730
731 ast_node *ast = exec_node_data(ast_node, ptr, link);
732 ast->print();
733 }
734
735 printf("; ");
736 }
737
738
739 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
740 {
741 this->type = type;
742 this->invariant = false;
743 }
744
745 void
746 ast_jump_statement::print(void) const
747 {
748 switch (mode) {
749 case ast_continue:
750 printf("continue; ");
751 break;
752 case ast_break:
753 printf("break; ");
754 break;
755 case ast_return:
756 printf("return ");
757 if (opt_return_value)
758 opt_return_value->print();
759
760 printf("; ");
761 break;
762 case ast_discard:
763 printf("discard; ");
764 break;
765 }
766 }
767
768
769 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
770 {
771 this->mode = ast_jump_modes(mode);
772
773 if (mode == ast_return)
774 opt_return_value = return_value;
775 }
776
777
778 void
779 ast_selection_statement::print(void) const
780 {
781 printf("if ( ");
782 condition->print();
783 printf(") ");
784
785 then_statement->print();
786
787 if (else_statement) {
788 printf("else ");
789 else_statement->print();
790 }
791
792 }
793
794
795 ast_selection_statement::ast_selection_statement(ast_expression *condition,
796 ast_node *then_statement,
797 ast_node *else_statement)
798 {
799 this->condition = condition;
800 this->then_statement = then_statement;
801 this->else_statement = else_statement;
802 }
803
804
805 void
806 ast_iteration_statement::print(void) const
807 {
808 switch (mode) {
809 case ast_for:
810 printf("for( ");
811 if (init_statement)
812 init_statement->print();
813 printf("; ");
814
815 if (condition)
816 condition->print();
817 printf("; ");
818
819 if (rest_expression)
820 rest_expression->print();
821 printf(") ");
822
823 body->print();
824 break;
825
826 case ast_while:
827 printf("while ( ");
828 if (condition)
829 condition->print();
830 printf(") ");
831 body->print();
832 break;
833
834 case ast_do_while:
835 printf("do ");
836 body->print();
837 printf("while ( ");
838 if (condition)
839 condition->print();
840 printf("); ");
841 break;
842 }
843 }
844
845
846 ast_iteration_statement::ast_iteration_statement(int mode,
847 ast_node *init,
848 ast_node *condition,
849 ast_expression *rest_expression,
850 ast_node *body)
851 {
852 this->mode = ast_iteration_modes(mode);
853 this->init_statement = init;
854 this->condition = condition;
855 this->rest_expression = rest_expression;
856 this->body = body;
857 }
858
859
860 void
861 ast_struct_specifier::print(void) const
862 {
863 printf("struct %s { ", name);
864 foreach_list_const(n, &this->declarations) {
865 ast_node *ast = exec_node_data(ast_node, n, link);
866 ast->print();
867 }
868 printf("} ");
869 }
870
871
872 ast_struct_specifier::ast_struct_specifier(char *identifier,
873 ast_node *declarator_list)
874 {
875 if (identifier == NULL) {
876 static unsigned anon_count = 1;
877 identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count);
878 anon_count++;
879 }
880 name = identifier;
881 this->declarations.push_degenerate_list_at_head(&declarator_list->link);
882 }
883
884 bool
885 do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
886 {
887 GLboolean progress = GL_FALSE;
888
889 progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
890
891 if (linked) {
892 progress = do_function_inlining(ir) || progress;
893 progress = do_dead_functions(ir) || progress;
894 progress = do_structure_splitting(ir) || progress;
895 }
896 progress = do_if_simplification(ir) || progress;
897 progress = do_discard_simplification(ir) || progress;
898 progress = do_copy_propagation(ir) || progress;
899 progress = do_copy_propagation_elements(ir) || progress;
900 if (linked)
901 progress = do_dead_code(ir) || progress;
902 else
903 progress = do_dead_code_unlinked(ir) || progress;
904 progress = do_dead_code_local(ir) || progress;
905 progress = do_tree_grafting(ir) || progress;
906 progress = do_constant_propagation(ir) || progress;
907 if (linked)
908 progress = do_constant_variable(ir) || progress;
909 else
910 progress = do_constant_variable_unlinked(ir) || progress;
911 progress = do_constant_folding(ir) || progress;
912 progress = do_algebraic(ir) || progress;
913 progress = do_lower_jumps(ir) || progress;
914 progress = do_vec_index_to_swizzle(ir) || progress;
915 progress = do_swizzle_swizzle(ir) || progress;
916 progress = do_noop_swizzle(ir) || progress;
917
918 progress = optimize_redundant_jumps(ir) || progress;
919
920 loop_state *ls = analyze_loop_variables(ir);
921 if (ls->loop_found) {
922 progress = set_loop_controls(ir, ls) || progress;
923 progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
924 }
925 delete ls;
926
927 return progress;
928 }
929
930 extern "C" {
931
932 /**
933 * To be called at GL teardown time, this frees compiler datastructures.
934 *
935 * After calling this, any previously compiled shaders and shader
936 * programs would be invalid. So this should happen at approximately
937 * program exit.
938 */
939 void
940 _mesa_destroy_shader_compiler(void)
941 {
942 _mesa_destroy_shader_compiler_caches();
943
944 _mesa_glsl_release_types();
945 }
946
947 /**
948 * Releases compiler caches to trade off performance for memory.
949 *
950 * Intended to be used with glReleaseShaderCompiler().
951 */
952 void
953 _mesa_destroy_shader_compiler_caches(void)
954 {
955 _mesa_glsl_release_functions();
956 }
957
958 }