1 /* 2 * Copyright 2010 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 24 #include "ast.h" 25 26 void 27 ast_type_specifier::print(void) const 28 { 29 if (structure) { 30 structure->print(); 31 } else { 32 printf("%s ", type_name); 33 } 34 35 if (array_specifier) { 36 array_specifier->print(); 37 } 38 } 39 40 bool 41 ast_fully_specified_type::has_qualifiers(_mesa_glsl_parse_state *state) const 42 { 43 /* 'subroutine' isnt a real qualifier. */ 44 ast_type_qualifier subroutine_only; 45 subroutine_only.flags.i = 0; 46 subroutine_only.flags.q.subroutine = 1; 47 subroutine_only.flags.q.subroutine_def = 1; 48 if (state->has_explicit_uniform_location()) { 49 subroutine_only.flags.q.explicit_index = 1; 50 } 51 return (this->qualifier.flags.i & ~subroutine_only.flags.i) != 0; 52 } 53 54 bool ast_type_qualifier::has_interpolation() const 55 { 56 return this->flags.q.smooth 57 || this->flags.q.flat 58 || this->flags.q.noperspective; 59 } 60 61 bool 62 ast_type_qualifier::has_layout() const 63 { 64 return this->flags.q.origin_upper_left 65 || this->flags.q.pixel_center_integer 66 || this->flags.q.depth_any 67 || this->flags.q.depth_greater 68 || this->flags.q.depth_less 69 || this->flags.q.depth_unchanged 70 || this->flags.q.std140 71 || this->flags.q.std430 72 || this->flags.q.shared 73 || this->flags.q.column_major 74 || this->flags.q.row_major 75 || this->flags.q.packed 76 || this->flags.q.explicit_align 77 || this->flags.q.explicit_component 78 || this->flags.q.explicit_location 79 || this->flags.q.explicit_image_format 80 || this->flags.q.explicit_index 81 || this->flags.q.explicit_binding 82 || this->flags.q.explicit_offset 83 || this->flags.q.explicit_stream 84 || this->flags.q.explicit_xfb_buffer 85 || this->flags.q.explicit_xfb_offset 86 || this->flags.q.explicit_xfb_stride; 87 } 88 89 bool 90 ast_type_qualifier::has_storage() const 91 { 92 return this->flags.q.constant 93 || this->flags.q.attribute 94 || this->flags.q.varying 95 || this->flags.q.in 96 || this->flags.q.out 97 || this->flags.q.uniform 98 || this->flags.q.buffer 99 || this->flags.q.shared_storage; 100 } 101 102 bool 103 ast_type_qualifier::has_auxiliary_storage() const 104 { 105 return this->flags.q.centroid 106 || this->flags.q.sample 107 || this->flags.q.patch; 108 } 109 110 bool ast_type_qualifier::has_memory() const 111 { 112 return this->flags.q.coherent 113 || this->flags.q._volatile 114 || this->flags.q.restrict_flag 115 || this->flags.q.read_only 116 || this->flags.q.write_only; 117 } 118 119 static bool 120 validate_prim_type(YYLTYPE *loc, 121 _mesa_glsl_parse_state *state, 122 const ast_type_qualifier &qualifier, 123 const ast_type_qualifier &new_qualifier) 124 { 125 /* Input layout qualifiers can be specified multiple 126 * times in separate declarations, as long as they match. 127 */ 128 if (qualifier.flags.q.prim_type && new_qualifier.flags.q.prim_type 129 && qualifier.prim_type != new_qualifier.prim_type) { 130 _mesa_glsl_error(loc, state, 131 "conflicting input primitive %s specified", 132 state->stage == MESA_SHADER_GEOMETRY ? 133 "type" : "mode"); 134 return false; 135 } 136 137 return true; 138 } 139 140 static bool 141 validate_vertex_spacing(YYLTYPE *loc, 142 _mesa_glsl_parse_state *state, 143 const ast_type_qualifier &qualifier, 144 const ast_type_qualifier &new_qualifier) 145 { 146 if (qualifier.flags.q.vertex_spacing && new_qualifier.flags.q.vertex_spacing 147 && qualifier.vertex_spacing != new_qualifier.vertex_spacing) { 148 _mesa_glsl_error(loc, state, 149 "conflicting vertex spacing specified"); 150 return false; 151 } 152 153 return true; 154 } 155 156 static bool 157 validate_ordering(YYLTYPE *loc, 158 _mesa_glsl_parse_state *state, 159 const ast_type_qualifier &qualifier, 160 const ast_type_qualifier &new_qualifier) 161 { 162 if (qualifier.flags.q.ordering && new_qualifier.flags.q.ordering 163 && qualifier.ordering != new_qualifier.ordering) { 164 _mesa_glsl_error(loc, state, 165 "conflicting ordering specified"); 166 return false; 167 } 168 169 return true; 170 } 171 172 static bool 173 validate_point_mode(MAYBE_UNUSED const ast_type_qualifier &qualifier, 174 MAYBE_UNUSED const ast_type_qualifier &new_qualifier) 175 { 176 /* Point mode can only be true if the flag is set. */ 177 assert (!qualifier.flags.q.point_mode || !new_qualifier.flags.q.point_mode 178 || (qualifier.point_mode && new_qualifier.point_mode)); 179 180 return true; 181 } 182 183 /** 184 * This function merges duplicate layout identifiers. 185 * 186 * It deals with duplicates within a single layout qualifier, among multiple 187 * layout qualifiers on a single declaration and on several declarations for 188 * the same variable. 189 * 190 * The is_single_layout_merge and is_multiple_layouts_merge parameters are 191 * used to differentiate among them. 192 */ 193 bool 194 ast_type_qualifier::merge_qualifier(YYLTYPE *loc, 195 _mesa_glsl_parse_state *state, 196 const ast_type_qualifier &q, 197 bool is_single_layout_merge, 198 bool is_multiple_layouts_merge) 199 { 200 bool r = true; 201 ast_type_qualifier ubo_mat_mask; 202 ubo_mat_mask.flags.i = 0; 203 ubo_mat_mask.flags.q.row_major = 1; 204 ubo_mat_mask.flags.q.column_major = 1; 205 206 ast_type_qualifier ubo_layout_mask; 207 ubo_layout_mask.flags.i = 0; 208 ubo_layout_mask.flags.q.std140 = 1; 209 ubo_layout_mask.flags.q.packed = 1; 210 ubo_layout_mask.flags.q.shared = 1; 211 ubo_layout_mask.flags.q.std430 = 1; 212 213 ast_type_qualifier ubo_binding_mask; 214 ubo_binding_mask.flags.i = 0; 215 ubo_binding_mask.flags.q.explicit_binding = 1; 216 ubo_binding_mask.flags.q.explicit_offset = 1; 217 218 ast_type_qualifier stream_layout_mask; 219 stream_layout_mask.flags.i = 0; 220 stream_layout_mask.flags.q.stream = 1; 221 222 /* FIXME: We should probably do interface and function param validation 223 * separately. 224 */ 225 ast_type_qualifier input_layout_mask; 226 input_layout_mask.flags.i = 0; 227 input_layout_mask.flags.q.centroid = 1; 228 /* Function params can have constant */ 229 input_layout_mask.flags.q.constant = 1; 230 input_layout_mask.flags.q.explicit_component = 1; 231 input_layout_mask.flags.q.explicit_location = 1; 232 input_layout_mask.flags.q.flat = 1; 233 input_layout_mask.flags.q.in = 1; 234 input_layout_mask.flags.q.invariant = 1; 235 input_layout_mask.flags.q.noperspective = 1; 236 input_layout_mask.flags.q.origin_upper_left = 1; 237 /* Function params 'inout' will set this */ 238 input_layout_mask.flags.q.out = 1; 239 input_layout_mask.flags.q.patch = 1; 240 input_layout_mask.flags.q.pixel_center_integer = 1; 241 input_layout_mask.flags.q.precise = 1; 242 input_layout_mask.flags.q.sample = 1; 243 input_layout_mask.flags.q.smooth = 1; 244 245 /* Uniform block layout qualifiers get to overwrite each 246 * other (rightmost having priority), while all other 247 * qualifiers currently don't allow duplicates. 248 */ 249 ast_type_qualifier allowed_duplicates_mask; 250 allowed_duplicates_mask.flags.i = 251 ubo_mat_mask.flags.i | 252 ubo_layout_mask.flags.i | 253 ubo_binding_mask.flags.i; 254 255 /* Geometry shaders can have several layout qualifiers 256 * assigning different stream values. 257 */ 258 if (state->stage == MESA_SHADER_GEOMETRY) { 259 allowed_duplicates_mask.flags.i |= 260 stream_layout_mask.flags.i; 261 } 262 263 if (is_single_layout_merge && !state->has_enhanced_layouts() && 264 (this->flags.i & q.flags.i & ~allowed_duplicates_mask.flags.i) != 0) { 265 _mesa_glsl_error(loc, state, "duplicate layout qualifiers used"); 266 return false; 267 } 268 269 if (is_multiple_layouts_merge && !state->has_420pack_or_es31()) { 270 _mesa_glsl_error(loc, state, 271 "duplicate layout(...) qualifiers"); 272 return false; 273 } 274 275 if (q.flags.q.prim_type) { 276 r &= validate_prim_type(loc, state, *this, q); 277 this->flags.q.prim_type = 1; 278 this->prim_type = q.prim_type; 279 } 280 281 if (q.flags.q.max_vertices) { 282 if (this->flags.q.max_vertices 283 && !is_single_layout_merge && !is_multiple_layouts_merge) { 284 this->max_vertices->merge_qualifier(q.max_vertices); 285 } else { 286 this->flags.q.max_vertices = 1; 287 this->max_vertices = q.max_vertices; 288 } 289 } 290 291 if (q.flags.q.subroutine_def) { 292 if (this->flags.q.subroutine_def) { 293 _mesa_glsl_error(loc, state, 294 "conflicting subroutine qualifiers used"); 295 } else { 296 this->subroutine_list = q.subroutine_list; 297 } 298 } 299 300 if (q.flags.q.invocations) { 301 if (this->flags.q.invocations 302 && !is_single_layout_merge && !is_multiple_layouts_merge) { 303 this->invocations->merge_qualifier(q.invocations); 304 } else { 305 this->flags.q.invocations = 1; 306 this->invocations = q.invocations; 307 } 308 } 309 310 if (state->stage == MESA_SHADER_GEOMETRY && 311 state->has_explicit_attrib_stream()) { 312 if (!this->flags.q.explicit_stream) { 313 if (q.flags.q.stream) { 314 this->flags.q.stream = 1; 315 this->stream = q.stream; 316 } else if (!this->flags.q.stream && this->flags.q.out && 317 !this->flags.q.in) { 318 /* Assign default global stream value */ 319 this->flags.q.stream = 1; 320 this->stream = state->out_qualifier->stream; 321 } 322 } 323 } 324 325 if (state->has_enhanced_layouts()) { 326 if (!this->flags.q.explicit_xfb_buffer) { 327 if (q.flags.q.xfb_buffer) { 328 this->flags.q.xfb_buffer = 1; 329 this->xfb_buffer = q.xfb_buffer; 330 } else if (!this->flags.q.xfb_buffer && this->flags.q.out && 331 !this->flags.q.in) { 332 /* Assign global xfb_buffer value */ 333 this->flags.q.xfb_buffer = 1; 334 this->xfb_buffer = state->out_qualifier->xfb_buffer; 335 } 336 } 337 338 if (q.flags.q.explicit_xfb_stride) { 339 this->flags.q.xfb_stride = 1; 340 this->flags.q.explicit_xfb_stride = 1; 341 this->xfb_stride = q.xfb_stride; 342 } 343 } 344 345 if (q.flags.q.vertices) { 346 if (this->flags.q.vertices 347 && !is_single_layout_merge && !is_multiple_layouts_merge) { 348 this->vertices->merge_qualifier(q.vertices); 349 } else { 350 this->flags.q.vertices = 1; 351 this->vertices = q.vertices; 352 } 353 } 354 355 if (q.flags.q.vertex_spacing) { 356 r &= validate_vertex_spacing(loc, state, *this, q); 357 this->flags.q.vertex_spacing = 1; 358 this->vertex_spacing = q.vertex_spacing; 359 } 360 361 if (q.flags.q.ordering) { 362 r &= validate_ordering(loc, state, *this, q); 363 this->flags.q.ordering = 1; 364 this->ordering = q.ordering; 365 } 366 367 if (q.flags.q.point_mode) { 368 r &= validate_point_mode(*this, q); 369 this->flags.q.point_mode = 1; 370 this->point_mode = q.point_mode; 371 } 372 373 if (q.flags.q.early_fragment_tests) 374 this->flags.q.early_fragment_tests = true; 375 376 if ((q.flags.i & ubo_mat_mask.flags.i) != 0) 377 this->flags.i &= ~ubo_mat_mask.flags.i; 378 if ((q.flags.i & ubo_layout_mask.flags.i) != 0) 379 this->flags.i &= ~ubo_layout_mask.flags.i; 380 381 for (int i = 0; i < 3; i++) { 382 if (q.flags.q.local_size & (1 << i)) { 383 if (this->local_size[i] 384 && !is_single_layout_merge && !is_multiple_layouts_merge) { 385 this->local_size[i]->merge_qualifier(q.local_size[i]); 386 } else { 387 this->local_size[i] = q.local_size[i]; 388 } 389 } 390 } 391 392 if (q.flags.q.local_size_variable) 393 this->flags.q.local_size_variable = true; 394 395 this->flags.i |= q.flags.i; 396 397 if (this->flags.q.in && 398 (this->flags.i & ~input_layout_mask.flags.i) != 0) { 399 _mesa_glsl_error(loc, state, "invalid input layout qualifier used"); 400 return false; 401 } 402 403 if (q.flags.q.explicit_align) 404 this->align = q.align; 405 406 if (q.flags.q.explicit_location) 407 this->location = q.location; 408 409 if (q.flags.q.explicit_index) 410 this->index = q.index; 411 412 if (q.flags.q.explicit_component) 413 this->component = q.component; 414 415 if (q.flags.q.explicit_binding) 416 this->binding = q.binding; 417 418 if (q.flags.q.explicit_offset || q.flags.q.explicit_xfb_offset) 419 this->offset = q.offset; 420 421 if (q.precision != ast_precision_none) 422 this->precision = q.precision; 423 424 if (q.flags.q.explicit_image_format) { 425 this->image_format = q.image_format; 426 this->image_base_type = q.image_base_type; 427 } 428 429 return r; 430 } 431 432 bool 433 ast_type_qualifier::validate_out_qualifier(YYLTYPE *loc, 434 _mesa_glsl_parse_state *state) 435 { 436 bool r = true; 437 ast_type_qualifier valid_out_mask; 438 valid_out_mask.flags.i = 0; 439 440 switch (state->stage) { 441 case MESA_SHADER_GEOMETRY: 442 if (this->flags.q.prim_type) { 443 /* Make sure this is a valid output primitive type. */ 444 switch (this->prim_type) { 445 case GL_POINTS: 446 case GL_LINE_STRIP: 447 case GL_TRIANGLE_STRIP: 448 break; 449 default: 450 r = false; 451 _mesa_glsl_error(loc, state, "invalid geometry shader output " 452 "primitive type"); 453 break; 454 } 455 } 456 457 valid_out_mask.flags.q.stream = 1; 458 valid_out_mask.flags.q.explicit_stream = 1; 459 valid_out_mask.flags.q.explicit_xfb_buffer = 1; 460 valid_out_mask.flags.q.xfb_buffer = 1; 461 valid_out_mask.flags.q.explicit_xfb_stride = 1; 462 valid_out_mask.flags.q.xfb_stride = 1; 463 valid_out_mask.flags.q.max_vertices = 1; 464 valid_out_mask.flags.q.prim_type = 1; 465 break; 466 case MESA_SHADER_TESS_CTRL: 467 valid_out_mask.flags.q.vertices = 1; 468 valid_out_mask.flags.q.explicit_xfb_buffer = 1; 469 valid_out_mask.flags.q.xfb_buffer = 1; 470 valid_out_mask.flags.q.explicit_xfb_stride = 1; 471 valid_out_mask.flags.q.xfb_stride = 1; 472 break; 473 case MESA_SHADER_TESS_EVAL: 474 case MESA_SHADER_VERTEX: 475 valid_out_mask.flags.q.explicit_xfb_buffer = 1; 476 valid_out_mask.flags.q.xfb_buffer = 1; 477 valid_out_mask.flags.q.explicit_xfb_stride = 1; 478 valid_out_mask.flags.q.xfb_stride = 1; 479 break; 480 case MESA_SHADER_FRAGMENT: 481 valid_out_mask.flags.q.blend_support = 1; 482 break; 483 default: 484 r = false; 485 _mesa_glsl_error(loc, state, 486 "out layout qualifiers only valid in " 487 "geometry, tessellation, vertex and fragment shaders"); 488 } 489 490 /* Generate an error when invalid output layout qualifiers are used. */ 491 if ((this->flags.i & ~valid_out_mask.flags.i) != 0) { 492 r = false; 493 _mesa_glsl_error(loc, state, "invalid output layout qualifiers used"); 494 } 495 496 return r; 497 } 498 499 bool 500 ast_type_qualifier::merge_into_out_qualifier(YYLTYPE *loc, 501 _mesa_glsl_parse_state *state, 502 ast_node* &node) 503 { 504 const bool r = state->out_qualifier->merge_qualifier(loc, state, 505 *this, false); 506 507 switch (state->stage) { 508 case MESA_SHADER_GEOMETRY: 509 /* Allow future assignments of global out's stream id value */ 510 state->out_qualifier->flags.q.explicit_stream = 0; 511 break; 512 case MESA_SHADER_TESS_CTRL: 513 node = new(state->linalloc) ast_tcs_output_layout(*loc); 514 break; 515 default: 516 break; 517 } 518 519 /* Allow future assignments of global out's */ 520 state->out_qualifier->flags.q.explicit_xfb_buffer = 0; 521 state->out_qualifier->flags.q.explicit_xfb_stride = 0; 522 523 return r; 524 } 525 526 bool 527 ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc, 528 _mesa_glsl_parse_state *state) 529 { 530 bool r = true; 531 ast_type_qualifier valid_in_mask; 532 valid_in_mask.flags.i = 0; 533 534 switch (state->stage) { 535 case MESA_SHADER_TESS_EVAL: 536 if (this->flags.q.prim_type) { 537 /* Make sure this is a valid input primitive type. */ 538 switch (this->prim_type) { 539 case GL_TRIANGLES: 540 case GL_QUADS: 541 case GL_ISOLINES: 542 break; 543 default: 544 r = false; 545 _mesa_glsl_error(loc, state, 546 "invalid tessellation evaluation " 547 "shader input primitive type"); 548 break; 549 } 550 } 551 552 valid_in_mask.flags.q.prim_type = 1; 553 valid_in_mask.flags.q.vertex_spacing = 1; 554 valid_in_mask.flags.q.ordering = 1; 555 valid_in_mask.flags.q.point_mode = 1; 556 break; 557 case MESA_SHADER_GEOMETRY: 558 if (this->flags.q.prim_type) { 559 /* Make sure this is a valid input primitive type. */ 560 switch (this->prim_type) { 561 case GL_POINTS: 562 case GL_LINES: 563 case GL_LINES_ADJACENCY: 564 case GL_TRIANGLES: 565 case GL_TRIANGLES_ADJACENCY: 566 break; 567 default: 568 r = false; 569 _mesa_glsl_error(loc, state, 570 "invalid geometry shader input primitive type"); 571 break; 572 } 573 } 574 575 valid_in_mask.flags.q.prim_type = 1; 576 valid_in_mask.flags.q.invocations = 1; 577 break; 578 case MESA_SHADER_FRAGMENT: 579 valid_in_mask.flags.q.early_fragment_tests = 1; 580 valid_in_mask.flags.q.inner_coverage = 1; 581 valid_in_mask.flags.q.post_depth_coverage = 1; 582 break; 583 case MESA_SHADER_COMPUTE: 584 valid_in_mask.flags.q.local_size = 7; 585 valid_in_mask.flags.q.local_size_variable = 1; 586 break; 587 default: 588 r = false; 589 _mesa_glsl_error(loc, state, 590 "input layout qualifiers only valid in " 591 "geometry, tessellation, fragment and compute shaders"); 592 break; 593 } 594 595 /* Generate an error when invalid input layout qualifiers are used. */ 596 if ((this->flags.i & ~valid_in_mask.flags.i) != 0) { 597 r = false; 598 _mesa_glsl_error(loc, state, "invalid input layout qualifiers used"); 599 } 600 601 /* The checks below are also performed when merging but we want to spit an 602 * error against the default global input qualifier as soon as we can, with 603 * the closest error location in the shader. 604 */ 605 r &= validate_prim_type(loc, state, *state->in_qualifier, *this); 606 r &= validate_vertex_spacing(loc, state, *state->in_qualifier, *this); 607 r &= validate_ordering(loc, state, *state->in_qualifier, *this); 608 r &= validate_point_mode(*state->in_qualifier, *this); 609 610 return r; 611 } 612 613 bool 614 ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc, 615 _mesa_glsl_parse_state *state, 616 ast_node* &node) 617 { 618 bool r = true; 619 void *lin_ctx = state->linalloc; 620 621 /* We create the gs_input_layout node before merging so, in the future, no 622 * more repeated nodes will be created as we will have the flag set. 623 */ 624 if (state->stage == MESA_SHADER_GEOMETRY 625 && this->flags.q.prim_type && !state->in_qualifier->flags.q.prim_type) { 626 node = new(lin_ctx) ast_gs_input_layout(*loc, this->prim_type); 627 } 628 629 r = state->in_qualifier->merge_qualifier(loc, state, *this, false); 630 631 if (state->in_qualifier->flags.q.early_fragment_tests) { 632 state->fs_early_fragment_tests = true; 633 state->in_qualifier->flags.q.early_fragment_tests = false; 634 } 635 636 if (state->in_qualifier->flags.q.inner_coverage) { 637 state->fs_inner_coverage = true; 638 state->in_qualifier->flags.q.inner_coverage = false; 639 } 640 641 if (state->in_qualifier->flags.q.post_depth_coverage) { 642 state->fs_post_depth_coverage = true; 643 state->in_qualifier->flags.q.post_depth_coverage = false; 644 } 645 646 if (state->fs_inner_coverage && state->fs_post_depth_coverage) { 647 _mesa_glsl_error(loc, state, 648 "inner_coverage & post_depth_coverage layout qualifiers " 649 "are mutally exclusives"); 650 r = false; 651 } 652 653 /* We allow the creation of multiple cs_input_layout nodes. Coherence among 654 * all existing nodes is checked later, when the AST node is transformed 655 * into HIR. 656 */ 657 if (state->in_qualifier->flags.q.local_size) { 658 node = new(lin_ctx) ast_cs_input_layout(*loc, 659 state->in_qualifier->local_size); 660 state->in_qualifier->flags.q.local_size = 0; 661 for (int i = 0; i < 3; i++) 662 state->in_qualifier->local_size[i] = NULL; 663 } 664 665 if (state->in_qualifier->flags.q.local_size_variable) { 666 state->cs_input_local_size_variable_specified = true; 667 state->in_qualifier->flags.q.local_size_variable = false; 668 } 669 670 return r; 671 } 672 673 bool 674 ast_type_qualifier::push_to_global(YYLTYPE *loc, 675 _mesa_glsl_parse_state *state) 676 { 677 if (this->flags.q.xfb_stride) { 678 this->flags.q.xfb_stride = 0; 679 680 unsigned buff_idx; 681 if (process_qualifier_constant(state, loc, "xfb_buffer", 682 this->xfb_buffer, &buff_idx)) { 683 if (state->out_qualifier->out_xfb_stride[buff_idx]) { 684 state->out_qualifier->out_xfb_stride[buff_idx]->merge_qualifier( 685 new(state->linalloc) ast_layout_expression(*loc, 686 this->xfb_stride)); 687 } else { 688 state->out_qualifier->out_xfb_stride[buff_idx] = 689 new(state->linalloc) ast_layout_expression(*loc, 690 this->xfb_stride); 691 } 692 } 693 } 694 695 return true; 696 } 697 698 /** 699 * Check if the current type qualifier has any illegal flags. 700 * 701 * If so, print an error message, followed by a list of illegal flags. 702 * 703 * \param message The error message to print. 704 * \param allowed_flags A list of valid flags. 705 */ 706 bool 707 ast_type_qualifier::validate_flags(YYLTYPE *loc, 708 _mesa_glsl_parse_state *state, 709 const ast_type_qualifier &allowed_flags, 710 const char *message, const char *name) 711 { 712 ast_type_qualifier bad; 713 bad.flags.i = this->flags.i & ~allowed_flags.flags.i; 714 if (bad.flags.i == 0) 715 return true; 716 717 _mesa_glsl_error(loc, state, 718 "%s '%s':" 719 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" 720 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" 721 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", 722 message, name, 723 bad.flags.q.invariant ? " invariant" : "", 724 bad.flags.q.precise ? " precise" : "", 725 bad.flags.q.constant ? " constant" : "", 726 bad.flags.q.attribute ? " attribute" : "", 727 bad.flags.q.varying ? " varying" : "", 728 bad.flags.q.in ? " in" : "", 729 bad.flags.q.out ? " out" : "", 730 bad.flags.q.centroid ? " centroid" : "", 731 bad.flags.q.sample ? " sample" : "", 732 bad.flags.q.patch ? " patch" : "", 733 bad.flags.q.uniform ? " uniform" : "", 734 bad.flags.q.buffer ? " buffer" : "", 735 bad.flags.q.shared_storage ? " shared_storage" : "", 736 bad.flags.q.smooth ? " smooth" : "", 737 bad.flags.q.flat ? " flat" : "", 738 bad.flags.q.noperspective ? " noperspective" : "", 739 bad.flags.q.origin_upper_left ? " origin_upper_left" : "", 740 bad.flags.q.pixel_center_integer ? " pixel_center_integer" : "", 741 bad.flags.q.explicit_align ? " align" : "", 742 bad.flags.q.explicit_component ? " component" : "", 743 bad.flags.q.explicit_location ? " location" : "", 744 bad.flags.q.explicit_index ? " index" : "", 745 bad.flags.q.explicit_binding ? " binding" : "", 746 bad.flags.q.explicit_offset ? " offset" : "", 747 bad.flags.q.depth_any ? " depth_any" : "", 748 bad.flags.q.depth_greater ? " depth_greater" : "", 749 bad.flags.q.depth_less ? " depth_less" : "", 750 bad.flags.q.depth_unchanged ? " depth_unchanged" : "", 751 bad.flags.q.std140 ? " std140" : "", 752 bad.flags.q.std430 ? " std430" : "", 753 bad.flags.q.shared ? " shared" : "", 754 bad.flags.q.packed ? " packed" : "", 755 bad.flags.q.column_major ? " column_major" : "", 756 bad.flags.q.row_major ? " row_major" : "", 757 bad.flags.q.prim_type ? " prim_type" : "", 758 bad.flags.q.max_vertices ? " max_vertices" : "", 759 bad.flags.q.local_size ? " local_size" : "", 760 bad.flags.q.local_size_variable ? " local_size_variable" : "", 761 bad.flags.q.early_fragment_tests ? " early_fragment_tests" : "", 762 bad.flags.q.explicit_image_format ? " image_format" : "", 763 bad.flags.q.coherent ? " coherent" : "", 764 bad.flags.q._volatile ? " _volatile" : "", 765 bad.flags.q.restrict_flag ? " restrict_flag" : "", 766 bad.flags.q.read_only ? " read_only" : "", 767 bad.flags.q.write_only ? " write_only" : "", 768 bad.flags.q.invocations ? " invocations" : "", 769 bad.flags.q.stream ? " stream" : "", 770 bad.flags.q.explicit_stream ? " stream" : "", 771 bad.flags.q.explicit_xfb_offset ? " xfb_offset" : "", 772 bad.flags.q.xfb_buffer ? " xfb_buffer" : "", 773 bad.flags.q.explicit_xfb_buffer ? " xfb_buffer" : "", 774 bad.flags.q.xfb_stride ? " xfb_stride" : "", 775 bad.flags.q.explicit_xfb_stride ? " xfb_stride" : "", 776 bad.flags.q.vertex_spacing ? " vertex_spacing" : "", 777 bad.flags.q.ordering ? " ordering" : "", 778 bad.flags.q.point_mode ? " point_mode" : "", 779 bad.flags.q.vertices ? " vertices" : "", 780 bad.flags.q.subroutine ? " subroutine" : "", 781 bad.flags.q.subroutine_def ? " subroutine_def" : "", 782 bad.flags.q.inner_coverage ? " inner_coverage" : "", 783 bad.flags.q.post_depth_coverage ? " post_depth_coverage" : ""); 784 return false; 785 } 786 787 bool 788 ast_layout_expression::process_qualifier_constant(struct _mesa_glsl_parse_state *state, 789 const char *qual_indentifier, 790 unsigned *value, 791 bool can_be_zero) 792 { 793 int min_value = 0; 794 bool first_pass = true; 795 *value = 0; 796 797 if (!can_be_zero) 798 min_value = 1; 799 800 for (exec_node *node = layout_const_expressions.get_head_raw(); 801 !node->is_tail_sentinel(); node = node->next) { 802 803 exec_list dummy_instructions; 804 ast_node *const_expression = exec_node_data(ast_node, node, link); 805 806 ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state); 807 808 ir_constant *const const_int = ir->constant_expression_value(); 809 if (const_int == NULL || !const_int->type->is_integer()) { 810 YYLTYPE loc = const_expression->get_location(); 811 _mesa_glsl_error(&loc, state, "%s must be an integral constant " 812 "expression", qual_indentifier); 813 return false; 814 } 815 816 if (const_int->value.i[0] < min_value) { 817 YYLTYPE loc = const_expression->get_location(); 818 _mesa_glsl_error(&loc, state, "%s layout qualifier is invalid " 819 "(%d < %d)", qual_indentifier, 820 const_int->value.i[0], min_value); 821 return false; 822 } 823 824 if (!first_pass && *value != const_int->value.u[0]) { 825 YYLTYPE loc = const_expression->get_location(); 826 _mesa_glsl_error(&loc, state, "%s layout qualifier does not " 827 "match previous declaration (%d vs %d)", 828 qual_indentifier, *value, const_int->value.i[0]); 829 return false; 830 } else { 831 first_pass = false; 832 *value = const_int->value.u[0]; 833 } 834 835 /* If the location is const (and we've verified that 836 * it is) then no instructions should have been emitted 837 * when we converted it to HIR. If they were emitted, 838 * then either the location isn't const after all, or 839 * we are emitting unnecessary instructions. 840 */ 841 assert(dummy_instructions.is_empty()); 842 } 843 844 return true; 845 } 846 847 bool 848 process_qualifier_constant(struct _mesa_glsl_parse_state *state, 849 YYLTYPE *loc, 850 const char *qual_indentifier, 851 ast_expression *const_expression, 852 unsigned *value) 853 { 854 exec_list dummy_instructions; 855 856 if (const_expression == NULL) { 857 *value = 0; 858 return true; 859 } 860 861 ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state); 862 863 ir_constant *const const_int = ir->constant_expression_value(); 864 if (const_int == NULL || !const_int->type->is_integer()) { 865 _mesa_glsl_error(loc, state, "%s must be an integral constant " 866 "expression", qual_indentifier); 867 return false; 868 } 869 870 if (const_int->value.i[0] < 0) { 871 _mesa_glsl_error(loc, state, "%s layout qualifier is invalid (%d < 0)", 872 qual_indentifier, const_int->value.u[0]); 873 return false; 874 } 875 876 /* If the location is const (and we've verified that 877 * it is) then no instructions should have been emitted 878 * when we converted it to HIR. If they were emitted, 879 * then either the location isn't const after all, or 880 * we are emitting unnecessary instructions. 881 */ 882 assert(dummy_instructions.is_empty()); 883 884 *value = const_int->value.u[0]; 885 return true; 886 } 887