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