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