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