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