1 %{ 2 /* 3 * Copyright © 2009 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <stdarg.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include "main/errors.h" 31 #include "main/mtypes.h" 32 33 #include "program/program.h" 34 #include "program/prog_parameter.h" 35 #include "program/prog_parameter_layout.h" 36 #include "program/prog_statevars.h" 37 #include "program/prog_instruction.h" 38 39 #include "program/symbol_table.h" 40 #include "program/program_parser.h" 41 42 #include "util/u_math.h" 43 #include "util/u_memory.h" 44 45 enum { 46 STATE_MATRIX_NO_MODIFIER, 47 STATE_MATRIX_INVERSE, 48 STATE_MATRIX_TRANSPOSE, 49 STATE_MATRIX_INVTRANS, 50 }; 51 52 extern void *yy_scan_string(char *); 53 extern void yy_delete_buffer(void *); 54 55 static struct asm_symbol *declare_variable(struct asm_parser_state *state, 56 char *name, enum asm_type t, struct YYLTYPE *locp); 57 58 static int add_state_reference(struct gl_program_parameter_list *param_list, 59 const gl_state_index16 tokens[STATE_LENGTH]); 60 61 static int initialize_symbol_from_state(struct gl_program *prog, 62 struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]); 63 64 static int initialize_symbol_from_param(struct gl_program *prog, 65 struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]); 66 67 static int initialize_symbol_from_const(struct gl_program *prog, 68 struct asm_symbol *param_var, const struct asm_vector *vec, 69 GLboolean allowSwizzle); 70 71 static int yyparse(struct asm_parser_state *state); 72 73 static char *make_error_string(const char *fmt, ...); 74 75 static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state, 76 const char *s); 77 78 static int validate_inputs(struct YYLTYPE *locp, 79 struct asm_parser_state *state); 80 81 static void init_dst_reg(struct prog_dst_register *r); 82 83 static void set_dst_reg(struct prog_dst_register *r, 84 gl_register_file file, GLint index); 85 86 static void init_src_reg(struct asm_src_register *r); 87 88 static void set_src_reg(struct asm_src_register *r, 89 gl_register_file file, GLint index); 90 91 static void set_src_reg_swz(struct asm_src_register *r, 92 gl_register_file file, GLint index, GLuint swizzle); 93 94 static void asm_instruction_set_operands(struct asm_instruction *inst, 95 const struct prog_dst_register *dst, const struct asm_src_register *src0, 96 const struct asm_src_register *src1, const struct asm_src_register *src2); 97 98 static struct asm_instruction *asm_instruction_ctor(enum prog_opcode op, 99 const struct prog_dst_register *dst, const struct asm_src_register *src0, 100 const struct asm_src_register *src1, const struct asm_src_register *src2); 101 102 static struct asm_instruction *asm_instruction_copy_ctor( 103 const struct prog_instruction *base, const struct prog_dst_register *dst, 104 const struct asm_src_register *src0, const struct asm_src_register *src1, 105 const struct asm_src_register *src2); 106 107 #ifndef FALSE 108 #define FALSE 0 109 #define TRUE (!FALSE) 110 #endif 111 112 #define YYLLOC_DEFAULT(Current, Rhs, N) \ 113 do { \ 114 if (N) { \ 115 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ 116 (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ 117 (Current).position = YYRHSLOC(Rhs, 1).position; \ 118 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ 119 (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ 120 } else { \ 121 (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ 122 (Current).last_line = (Current).first_line; \ 123 (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ 124 (Current).last_column = (Current).first_column; \ 125 (Current).position = YYRHSLOC(Rhs, 0).position \ 126 + (Current).first_column; \ 127 } \ 128 } while(0) 129 %} 130 131 %pure-parser 132 %locations 133 %lex-param { struct asm_parser_state *state } 134 %parse-param { struct asm_parser_state *state } 135 %error-verbose 136 137 %union { 138 struct asm_instruction *inst; 139 struct asm_symbol *sym; 140 struct asm_symbol temp_sym; 141 struct asm_swizzle_mask swiz_mask; 142 struct asm_src_register src_reg; 143 struct prog_dst_register dst_reg; 144 struct prog_instruction temp_inst; 145 char *string; 146 unsigned result; 147 unsigned attrib; 148 int integer; 149 float real; 150 gl_state_index16 state[STATE_LENGTH]; 151 int negate; 152 struct asm_vector vector; 153 enum prog_opcode opcode; 154 155 struct { 156 unsigned swz; 157 unsigned rgba_valid:1; 158 unsigned xyzw_valid:1; 159 unsigned negate:1; 160 } ext_swizzle; 161 } 162 163 %token ARBvp_10 ARBfp_10 164 165 /* Tokens for assembler pseudo-ops */ 166 %token <integer> ADDRESS 167 %token ALIAS ATTRIB 168 %token OPTION OUTPUT 169 %token PARAM 170 %token <integer> TEMP 171 %token END 172 173 /* Tokens for instructions */ 174 %token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP 175 %token <temp_inst> ARL KIL SWZ TXD_OP 176 177 %token <integer> INTEGER 178 %token <real> REAL 179 180 %token AMBIENT ATTENUATION 181 %token BACK 182 %token CLIP COLOR 183 %token DEPTH DIFFUSE DIRECTION 184 %token EMISSION ENV EYE 185 %token FOG FOGCOORD FRAGMENT FRONT 186 %token HALF 187 %token INVERSE INVTRANS 188 %token LIGHT LIGHTMODEL LIGHTPROD LOCAL 189 %token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP 190 %token NORMAL 191 %token OBJECT 192 %token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION 193 %token RANGE RESULT ROW 194 %token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE 195 %token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE 196 %token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT 197 %token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT 198 %token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D 199 %token VERTEX VTXATTRIB 200 201 %token <string> IDENTIFIER USED_IDENTIFIER 202 %type <string> string 203 %token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE 204 %token DOT_DOT 205 %token DOT 206 207 %type <inst> instruction ALU_instruction TexInstruction 208 %type <inst> ARL_instruction VECTORop_instruction 209 %type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction 210 %type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction 211 %type <inst> KIL_instruction 212 213 %type <dst_reg> dstReg maskedDstReg maskedAddrReg 214 %type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg 215 %type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle 216 %type <ext_swizzle> extSwizComp extSwizSel 217 %type <swiz_mask> optionalMask 218 219 %type <sym> progParamArray 220 %type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset 221 %type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel 222 %type <sym> addrReg 223 %type <swiz_mask> addrComponent addrWriteMask 224 225 %type <result> resultBinding resultColBinding 226 %type <integer> optFaceType optColorType 227 %type <integer> optResultFaceType optResultColorType 228 229 %type <integer> optTexImageUnitNum texImageUnitNum 230 %type <integer> optTexCoordUnitNum texCoordUnitNum 231 %type <integer> optLegacyTexUnitNum legacyTexUnitNum 232 %type <integer> texImageUnit texTarget 233 %type <integer> vtxAttribNum 234 235 %type <attrib> attribBinding vtxAttribItem fragAttribItem 236 237 %type <temp_sym> paramSingleInit paramSingleItemDecl 238 %type <integer> optArraySize 239 240 %type <state> stateSingleItem stateMultipleItem 241 %type <state> stateMaterialItem 242 %type <state> stateLightItem stateLightModelItem stateLightProdItem 243 %type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem 244 %type <state> stateMatrixItem stateMatrixRow stateMatrixRows 245 %type <state> stateTexEnvItem stateDepthItem 246 247 %type <state> stateLModProperty 248 %type <state> stateMatrixName optMatrixRows 249 250 %type <integer> stateMatProperty 251 %type <integer> stateLightProperty stateSpotProperty 252 %type <integer> stateLightNumber stateLProdProperty 253 %type <integer> stateTexGenType stateTexGenCoord 254 %type <integer> stateTexEnvProperty 255 %type <integer> stateFogProperty 256 %type <integer> stateClipPlaneNum 257 %type <integer> statePointProperty 258 259 %type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum 260 %type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum 261 %type <integer> stateProgramMatNum 262 263 %type <integer> ambDiffSpecPropertyMaterial 264 %type <integer> ambDiffSpecPropertyLight 265 266 %type <state> programSingleItem progEnvParam progLocalParam 267 %type <state> programMultipleItem progEnvParams progLocalParams 268 269 %type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem 270 %type <temp_sym> paramSingleItemUse 271 272 %type <integer> progEnvParamNum progLocalParamNum 273 %type <state> progEnvParamNums progLocalParamNums 274 275 %type <vector> paramConstDecl paramConstUse 276 %type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector 277 %type <real> signedFloatConstant 278 %type <negate> optionalSign 279 280 %{ 281 extern int 282 _mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, 283 void *yyscanner); 284 285 static int 286 yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, 287 struct asm_parser_state *state) 288 { 289 return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner); 290 } 291 %} 292 293 %% 294 295 program: language optionSequence statementSequence END 296 ; 297 298 language: ARBvp_10 299 { 300 if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) { 301 yyerror(& @1, state, "invalid fragment program header"); 302 303 } 304 state->mode = ARB_vertex; 305 } 306 | ARBfp_10 307 { 308 if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) { 309 yyerror(& @1, state, "invalid vertex program header"); 310 } 311 state->mode = ARB_fragment; 312 313 state->option.TexRect = 314 (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE); 315 } 316 ; 317 318 optionSequence: optionSequence option 319 | 320 ; 321 322 option: OPTION string ';' 323 { 324 int valid = 0; 325 326 if (state->mode == ARB_vertex) { 327 valid = _mesa_ARBvp_parse_option(state, $2); 328 } else if (state->mode == ARB_fragment) { 329 valid = _mesa_ARBfp_parse_option(state, $2); 330 } 331 332 333 free($2); 334 335 if (!valid) { 336 const char *const err_str = (state->mode == ARB_vertex) 337 ? "invalid ARB vertex program option" 338 : "invalid ARB fragment program option"; 339 340 yyerror(& @2, state, err_str); 341 YYERROR; 342 } 343 } 344 ; 345 346 statementSequence: statementSequence statement 347 | 348 ; 349 350 statement: instruction ';' 351 { 352 if ($1 != NULL) { 353 if (state->inst_tail == NULL) { 354 state->inst_head = $1; 355 } else { 356 state->inst_tail->next = $1; 357 } 358 359 state->inst_tail = $1; 360 $1->next = NULL; 361 362 state->prog->arb.NumInstructions++; 363 } 364 } 365 | namingStatement ';' 366 ; 367 368 instruction: ALU_instruction 369 { 370 $$ = $1; 371 state->prog->arb.NumAluInstructions++; 372 } 373 | TexInstruction 374 { 375 $$ = $1; 376 state->prog->arb.NumTexInstructions++; 377 } 378 ; 379 380 ALU_instruction: ARL_instruction 381 | VECTORop_instruction 382 | SCALARop_instruction 383 | BINSCop_instruction 384 | BINop_instruction 385 | TRIop_instruction 386 | SWZ_instruction 387 ; 388 389 TexInstruction: SAMPLE_instruction 390 | KIL_instruction 391 | TXD_instruction 392 ; 393 394 ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg 395 { 396 $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL); 397 } 398 ; 399 400 VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg 401 { 402 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 403 } 404 ; 405 406 SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg 407 { 408 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 409 } 410 ; 411 412 BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg 413 { 414 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL); 415 } 416 ; 417 418 419 BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg 420 { 421 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL); 422 } 423 ; 424 425 TRIop_instruction: TRI_OP maskedDstReg ',' 426 swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg 427 { 428 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8); 429 } 430 ; 431 432 SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget 433 { 434 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 435 if ($$ != NULL) { 436 const GLbitfield tex_mask = (1U << $6); 437 GLbitfield shadow_tex = 0; 438 GLbitfield target_mask = 0; 439 440 441 $$->Base.TexSrcUnit = $6; 442 443 if ($8 < 0) { 444 shadow_tex = tex_mask; 445 446 $$->Base.TexSrcTarget = -$8; 447 $$->Base.TexShadow = 1; 448 } else { 449 $$->Base.TexSrcTarget = $8; 450 } 451 452 target_mask = (1U << $$->Base.TexSrcTarget); 453 454 /* If this texture unit was previously accessed and that access 455 * had a different texture target, generate an error. 456 * 457 * If this texture unit was previously accessed and that access 458 * had a different shadow mode, generate an error. 459 */ 460 if ((state->prog->TexturesUsed[$6] != 0) 461 && ((state->prog->TexturesUsed[$6] != target_mask) 462 || ((state->prog->ShadowSamplers & tex_mask) 463 != shadow_tex))) { 464 yyerror(& @8, state, 465 "multiple targets used on one texture image unit"); 466 YYERROR; 467 } 468 469 470 state->prog->TexturesUsed[$6] |= target_mask; 471 state->prog->ShadowSamplers |= shadow_tex; 472 } 473 } 474 ; 475 476 KIL_instruction: KIL swizzleSrcReg 477 { 478 $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL); 479 state->fragment.UsesKill = 1; 480 } 481 ; 482 483 TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget 484 { 485 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8); 486 if ($$ != NULL) { 487 const GLbitfield tex_mask = (1U << $10); 488 GLbitfield shadow_tex = 0; 489 GLbitfield target_mask = 0; 490 491 492 $$->Base.TexSrcUnit = $10; 493 494 if ($12 < 0) { 495 shadow_tex = tex_mask; 496 497 $$->Base.TexSrcTarget = -$12; 498 $$->Base.TexShadow = 1; 499 } else { 500 $$->Base.TexSrcTarget = $12; 501 } 502 503 target_mask = (1U << $$->Base.TexSrcTarget); 504 505 /* If this texture unit was previously accessed and that access 506 * had a different texture target, generate an error. 507 * 508 * If this texture unit was previously accessed and that access 509 * had a different shadow mode, generate an error. 510 */ 511 if ((state->prog->TexturesUsed[$10] != 0) 512 && ((state->prog->TexturesUsed[$10] != target_mask) 513 || ((state->prog->ShadowSamplers & tex_mask) 514 != shadow_tex))) { 515 yyerror(& @12, state, 516 "multiple targets used on one texture image unit"); 517 YYERROR; 518 } 519 520 521 state->prog->TexturesUsed[$10] |= target_mask; 522 state->prog->ShadowSamplers |= shadow_tex; 523 } 524 } 525 ; 526 527 texImageUnit: TEXTURE_UNIT optTexImageUnitNum 528 { 529 $$ = $2; 530 } 531 ; 532 533 texTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; } 534 | TEX_2D { $$ = TEXTURE_2D_INDEX; } 535 | TEX_3D { $$ = TEXTURE_3D_INDEX; } 536 | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; } 537 | TEX_RECT { $$ = TEXTURE_RECT_INDEX; } 538 | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; } 539 | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; } 540 | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; } 541 | TEX_ARRAY1D { $$ = TEXTURE_1D_ARRAY_INDEX; } 542 | TEX_ARRAY2D { $$ = TEXTURE_2D_ARRAY_INDEX; } 543 | TEX_ARRAYSHADOW1D { $$ = -TEXTURE_1D_ARRAY_INDEX; } 544 | TEX_ARRAYSHADOW2D { $$ = -TEXTURE_2D_ARRAY_INDEX; } 545 ; 546 547 SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle 548 { 549 /* FIXME: Is this correct? Should the extenedSwizzle be applied 550 * FIXME: to the existing swizzle? 551 */ 552 $4.Base.Swizzle = $6.swizzle; 553 $4.Base.Negate = $6.mask; 554 555 $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 556 } 557 ; 558 559 scalarSrcReg: optionalSign scalarUse 560 { 561 $$ = $2; 562 563 if ($1) { 564 $$.Base.Negate = ~$$.Base.Negate; 565 } 566 } 567 ; 568 569 scalarUse: srcReg scalarSuffix 570 { 571 $$ = $1; 572 573 $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, 574 $2.swizzle); 575 } 576 ; 577 578 swizzleSrcReg: optionalSign srcReg swizzleSuffix 579 { 580 $$ = $2; 581 582 if ($1) { 583 $$.Base.Negate = ~$$.Base.Negate; 584 } 585 586 $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, 587 $3.swizzle); 588 } 589 ; 590 591 maskedDstReg: dstReg optionalMask 592 { 593 $$ = $1; 594 $$.WriteMask = $2.mask; 595 596 if ($$.File == PROGRAM_OUTPUT) { 597 /* Technically speaking, this should check that it is in 598 * vertex program mode. However, PositionInvariant can never be 599 * set in fragment program mode, so it is somewhat irrelevant. 600 */ 601 if (state->option.PositionInvariant 602 && ($$.Index == VARYING_SLOT_POS)) { 603 yyerror(& @1, state, "position-invariant programs cannot " 604 "write position"); 605 YYERROR; 606 } 607 608 state->prog->info.outputs_written |= BITFIELD64_BIT($$.Index); 609 } 610 } 611 ; 612 613 maskedAddrReg: addrReg addrWriteMask 614 { 615 set_dst_reg(& $$, PROGRAM_ADDRESS, 0); 616 $$.WriteMask = $2.mask; 617 } 618 ; 619 620 extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp 621 { 622 const unsigned xyzw_valid = 623 ($1.xyzw_valid << 0) 624 | ($3.xyzw_valid << 1) 625 | ($5.xyzw_valid << 2) 626 | ($7.xyzw_valid << 3); 627 const unsigned rgba_valid = 628 ($1.rgba_valid << 0) 629 | ($3.rgba_valid << 1) 630 | ($5.rgba_valid << 2) 631 | ($7.rgba_valid << 3); 632 633 /* All of the swizzle components have to be valid in either RGBA 634 * or XYZW. Note that 0 and 1 are valid in both, so both masks 635 * can have some bits set. 636 * 637 * We somewhat deviate from the spec here. It would be really hard 638 * to figure out which component is the error, and there probably 639 * isn't a lot of benefit. 640 */ 641 if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) { 642 yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle " 643 "components"); 644 YYERROR; 645 } 646 647 $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz); 648 $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2) 649 | ($7.negate << 3); 650 } 651 ; 652 653 extSwizComp: optionalSign extSwizSel 654 { 655 $$ = $2; 656 $$.negate = ($1) ? 1 : 0; 657 } 658 ; 659 660 extSwizSel: INTEGER 661 { 662 if (($1 != 0) && ($1 != 1)) { 663 yyerror(& @1, state, "invalid extended swizzle selector"); 664 YYERROR; 665 } 666 667 $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE; 668 $$.negate = 0; 669 670 /* 0 and 1 are valid for both RGBA swizzle names and XYZW 671 * swizzle names. 672 */ 673 $$.xyzw_valid = 1; 674 $$.rgba_valid = 1; 675 } 676 | string 677 { 678 char s; 679 680 if (strlen($1) > 1) { 681 yyerror(& @1, state, "invalid extended swizzle selector"); 682 YYERROR; 683 } 684 685 s = $1[0]; 686 free($1); 687 688 $$.rgba_valid = 0; 689 $$.xyzw_valid = 0; 690 $$.negate = 0; 691 692 switch (s) { 693 case 'x': 694 $$.swz = SWIZZLE_X; 695 $$.xyzw_valid = 1; 696 break; 697 case 'y': 698 $$.swz = SWIZZLE_Y; 699 $$.xyzw_valid = 1; 700 break; 701 case 'z': 702 $$.swz = SWIZZLE_Z; 703 $$.xyzw_valid = 1; 704 break; 705 case 'w': 706 $$.swz = SWIZZLE_W; 707 $$.xyzw_valid = 1; 708 break; 709 710 case 'r': 711 $$.swz = SWIZZLE_X; 712 $$.rgba_valid = 1; 713 break; 714 case 'g': 715 $$.swz = SWIZZLE_Y; 716 $$.rgba_valid = 1; 717 break; 718 case 'b': 719 $$.swz = SWIZZLE_Z; 720 $$.rgba_valid = 1; 721 break; 722 case 'a': 723 $$.swz = SWIZZLE_W; 724 $$.rgba_valid = 1; 725 break; 726 727 default: 728 yyerror(& @1, state, "invalid extended swizzle selector"); 729 YYERROR; 730 break; 731 } 732 } 733 ; 734 735 srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ 736 { 737 struct asm_symbol *const s = (struct asm_symbol *) 738 _mesa_symbol_table_find_symbol(state->st, $1); 739 740 free($1); 741 742 if (s == NULL) { 743 yyerror(& @1, state, "invalid operand variable"); 744 YYERROR; 745 } else if ((s->type != at_param) && (s->type != at_temp) 746 && (s->type != at_attrib)) { 747 yyerror(& @1, state, "invalid operand variable"); 748 YYERROR; 749 } else if ((s->type == at_param) && s->param_is_array) { 750 yyerror(& @1, state, "non-array access to array PARAM"); 751 YYERROR; 752 } 753 754 init_src_reg(& $$); 755 switch (s->type) { 756 case at_temp: 757 set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); 758 break; 759 case at_param: 760 set_src_reg_swz(& $$, s->param_binding_type, 761 s->param_binding_begin, 762 s->param_binding_swizzle); 763 break; 764 case at_attrib: 765 set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding); 766 state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index); 767 768 if (!validate_inputs(& @1, state)) { 769 YYERROR; 770 } 771 break; 772 773 default: 774 YYERROR; 775 break; 776 } 777 } 778 | attribBinding 779 { 780 set_src_reg(& $$, PROGRAM_INPUT, $1); 781 state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index); 782 783 if (!validate_inputs(& @1, state)) { 784 YYERROR; 785 } 786 } 787 | progParamArray '[' progParamArrayMem ']' 788 { 789 if (! $3.Base.RelAddr 790 && ((unsigned) $3.Base.Index >= $1->param_binding_length)) { 791 yyerror(& @3, state, "out of bounds array access"); 792 YYERROR; 793 } 794 795 init_src_reg(& $$); 796 $$.Base.File = $1->param_binding_type; 797 798 if ($3.Base.RelAddr) { 799 state->prog->arb.IndirectRegisterFiles |= (1 << $$.Base.File); 800 $1->param_accessed_indirectly = 1; 801 802 $$.Base.RelAddr = 1; 803 $$.Base.Index = $3.Base.Index; 804 $$.Symbol = $1; 805 } else { 806 $$.Base.Index = $1->param_binding_begin + $3.Base.Index; 807 } 808 } 809 | paramSingleItemUse 810 { 811 gl_register_file file = ($1.name != NULL) 812 ? $1.param_binding_type 813 : PROGRAM_CONSTANT; 814 set_src_reg_swz(& $$, file, $1.param_binding_begin, 815 $1.param_binding_swizzle); 816 } 817 ; 818 819 dstReg: resultBinding 820 { 821 set_dst_reg(& $$, PROGRAM_OUTPUT, $1); 822 } 823 | USED_IDENTIFIER /* temporaryReg | vertexResultReg */ 824 { 825 struct asm_symbol *const s = (struct asm_symbol *) 826 _mesa_symbol_table_find_symbol(state->st, $1); 827 828 free($1); 829 830 if (s == NULL) { 831 yyerror(& @1, state, "invalid operand variable"); 832 YYERROR; 833 } else if ((s->type != at_output) && (s->type != at_temp)) { 834 yyerror(& @1, state, "invalid operand variable"); 835 YYERROR; 836 } 837 838 switch (s->type) { 839 case at_temp: 840 set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); 841 break; 842 case at_output: 843 set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding); 844 break; 845 default: 846 set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin); 847 break; 848 } 849 } 850 ; 851 852 progParamArray: USED_IDENTIFIER 853 { 854 struct asm_symbol *const s = (struct asm_symbol *) 855 _mesa_symbol_table_find_symbol(state->st, $1); 856 857 free($1); 858 859 if (s == NULL) { 860 yyerror(& @1, state, "invalid operand variable"); 861 YYERROR; 862 } else if ((s->type != at_param) || !s->param_is_array) { 863 yyerror(& @1, state, "array access to non-PARAM variable"); 864 YYERROR; 865 } else { 866 $$ = s; 867 } 868 } 869 ; 870 871 progParamArrayMem: progParamArrayAbs | progParamArrayRel; 872 873 progParamArrayAbs: INTEGER 874 { 875 init_src_reg(& $$); 876 $$.Base.Index = $1; 877 } 878 ; 879 880 progParamArrayRel: addrReg addrComponent addrRegRelOffset 881 { 882 /* FINISHME: Add support for multiple address registers. 883 */ 884 /* FINISHME: Add support for 4-component address registers. 885 */ 886 init_src_reg(& $$); 887 $$.Base.RelAddr = 1; 888 $$.Base.Index = $3; 889 } 890 ; 891 892 addrRegRelOffset: { $$ = 0; } 893 | '+' addrRegPosOffset { $$ = $2; } 894 | '-' addrRegNegOffset { $$ = -$2; } 895 ; 896 897 addrRegPosOffset: INTEGER 898 { 899 if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) { 900 char s[100]; 901 snprintf(s, sizeof(s), 902 "relative address offset too large (%d)", $1); 903 yyerror(& @1, state, s); 904 YYERROR; 905 } else { 906 $$ = $1; 907 } 908 } 909 ; 910 911 addrRegNegOffset: INTEGER 912 { 913 if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) { 914 char s[100]; 915 snprintf(s, sizeof(s), 916 "relative address offset too large (%d)", $1); 917 yyerror(& @1, state, s); 918 YYERROR; 919 } else { 920 $$ = $1; 921 } 922 } 923 ; 924 925 addrReg: USED_IDENTIFIER 926 { 927 struct asm_symbol *const s = (struct asm_symbol *) 928 _mesa_symbol_table_find_symbol(state->st, $1); 929 930 free($1); 931 932 if (s == NULL) { 933 yyerror(& @1, state, "invalid array member"); 934 YYERROR; 935 } else if (s->type != at_address) { 936 yyerror(& @1, state, 937 "invalid variable for indexed array access"); 938 YYERROR; 939 } else { 940 $$ = s; 941 } 942 } 943 ; 944 945 addrComponent: MASK1 946 { 947 if ($1.mask != WRITEMASK_X) { 948 yyerror(& @1, state, "invalid address component selector"); 949 YYERROR; 950 } else { 951 $$ = $1; 952 } 953 } 954 ; 955 956 addrWriteMask: MASK1 957 { 958 if ($1.mask != WRITEMASK_X) { 959 yyerror(& @1, state, 960 "address register write mask must be \".x\""); 961 YYERROR; 962 } else { 963 $$ = $1; 964 } 965 } 966 ; 967 968 scalarSuffix: MASK1; 969 970 swizzleSuffix: MASK1 971 | MASK4 972 | SWIZZLE 973 | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } 974 ; 975 976 optionalMask: MASK4 | MASK3 | MASK2 | MASK1 977 | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } 978 ; 979 980 namingStatement: ATTRIB_statement 981 | PARAM_statement 982 | TEMP_statement 983 | ADDRESS_statement 984 | OUTPUT_statement 985 | ALIAS_statement 986 ; 987 988 ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding 989 { 990 struct asm_symbol *const s = 991 declare_variable(state, $2, at_attrib, & @2); 992 993 if (s == NULL) { 994 free($2); 995 YYERROR; 996 } else { 997 s->attrib_binding = $4; 998 state->InputsBound |= BITFIELD64_BIT(s->attrib_binding); 999 1000 if (!validate_inputs(& @4, state)) { 1001 YYERROR; 1002 } 1003 } 1004 } 1005 ; 1006 1007 attribBinding: VERTEX vtxAttribItem 1008 { 1009 $$ = $2; 1010 } 1011 | FRAGMENT fragAttribItem 1012 { 1013 $$ = $2; 1014 } 1015 ; 1016 1017 vtxAttribItem: POSITION 1018 { 1019 $$ = VERT_ATTRIB_POS; 1020 } 1021 | NORMAL 1022 { 1023 $$ = VERT_ATTRIB_NORMAL; 1024 } 1025 | COLOR optColorType 1026 { 1027 $$ = VERT_ATTRIB_COLOR0 + $2; 1028 } 1029 | FOGCOORD 1030 { 1031 $$ = VERT_ATTRIB_FOG; 1032 } 1033 | TEXCOORD optTexCoordUnitNum 1034 { 1035 $$ = VERT_ATTRIB_TEX0 + $2; 1036 } 1037 | MATRIXINDEX '[' vtxWeightNum ']' 1038 { 1039 yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); 1040 YYERROR; 1041 } 1042 | VTXATTRIB '[' vtxAttribNum ']' 1043 { 1044 $$ = VERT_ATTRIB_GENERIC0 + $3; 1045 } 1046 ; 1047 1048 vtxAttribNum: INTEGER 1049 { 1050 if ((unsigned) $1 >= state->limits->MaxAttribs) { 1051 yyerror(& @1, state, "invalid vertex attribute reference"); 1052 YYERROR; 1053 } 1054 1055 $$ = $1; 1056 } 1057 ; 1058 1059 vtxWeightNum: INTEGER; 1060 1061 fragAttribItem: POSITION 1062 { 1063 $$ = VARYING_SLOT_POS; 1064 } 1065 | COLOR optColorType 1066 { 1067 $$ = VARYING_SLOT_COL0 + $2; 1068 } 1069 | FOGCOORD 1070 { 1071 $$ = VARYING_SLOT_FOGC; 1072 } 1073 | TEXCOORD optTexCoordUnitNum 1074 { 1075 $$ = VARYING_SLOT_TEX0 + $2; 1076 } 1077 ; 1078 1079 PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt; 1080 1081 PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit 1082 { 1083 struct asm_symbol *const s = 1084 declare_variable(state, $2, at_param, & @2); 1085 1086 if (s == NULL) { 1087 free($2); 1088 YYERROR; 1089 } else { 1090 s->param_binding_type = $3.param_binding_type; 1091 s->param_binding_begin = $3.param_binding_begin; 1092 s->param_binding_length = $3.param_binding_length; 1093 s->param_binding_swizzle = $3.param_binding_swizzle; 1094 s->param_is_array = 0; 1095 } 1096 } 1097 ; 1098 1099 PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit 1100 { 1101 if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) { 1102 free($2); 1103 yyerror(& @4, state, 1104 "parameter array size and number of bindings must match"); 1105 YYERROR; 1106 } else { 1107 struct asm_symbol *const s = 1108 declare_variable(state, $2, $6.type, & @2); 1109 1110 if (s == NULL) { 1111 free($2); 1112 YYERROR; 1113 } else { 1114 s->param_binding_type = $6.param_binding_type; 1115 s->param_binding_begin = $6.param_binding_begin; 1116 s->param_binding_length = $6.param_binding_length; 1117 s->param_binding_swizzle = SWIZZLE_XYZW; 1118 s->param_is_array = 1; 1119 } 1120 } 1121 } 1122 ; 1123 1124 optArraySize: 1125 { 1126 $$ = 0; 1127 } 1128 | INTEGER 1129 { 1130 if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) { 1131 char msg[100]; 1132 snprintf(msg, sizeof(msg), 1133 "invalid parameter array size (size=%d max=%u)", 1134 $1, state->limits->MaxParameters); 1135 yyerror(& @1, state, msg); 1136 YYERROR; 1137 } else { 1138 $$ = $1; 1139 } 1140 } 1141 ; 1142 1143 paramSingleInit: '=' paramSingleItemDecl 1144 { 1145 $$ = $2; 1146 } 1147 ; 1148 1149 paramMultipleInit: '=' '{' paramMultInitList '}' 1150 { 1151 $$ = $3; 1152 } 1153 ; 1154 1155 paramMultInitList: paramMultipleItem 1156 | paramMultInitList ',' paramMultipleItem 1157 { 1158 $1.param_binding_length += $3.param_binding_length; 1159 $$ = $1; 1160 } 1161 ; 1162 1163 paramSingleItemDecl: stateSingleItem 1164 { 1165 memset(& $$, 0, sizeof($$)); 1166 $$.param_binding_begin = ~0; 1167 initialize_symbol_from_state(state->prog, & $$, $1); 1168 } 1169 | programSingleItem 1170 { 1171 memset(& $$, 0, sizeof($$)); 1172 $$.param_binding_begin = ~0; 1173 initialize_symbol_from_param(state->prog, & $$, $1); 1174 } 1175 | paramConstDecl 1176 { 1177 memset(& $$, 0, sizeof($$)); 1178 $$.param_binding_begin = ~0; 1179 initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); 1180 } 1181 ; 1182 1183 paramSingleItemUse: stateSingleItem 1184 { 1185 memset(& $$, 0, sizeof($$)); 1186 $$.param_binding_begin = ~0; 1187 initialize_symbol_from_state(state->prog, & $$, $1); 1188 } 1189 | programSingleItem 1190 { 1191 memset(& $$, 0, sizeof($$)); 1192 $$.param_binding_begin = ~0; 1193 initialize_symbol_from_param(state->prog, & $$, $1); 1194 } 1195 | paramConstUse 1196 { 1197 memset(& $$, 0, sizeof($$)); 1198 $$.param_binding_begin = ~0; 1199 initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); 1200 } 1201 ; 1202 1203 paramMultipleItem: stateMultipleItem 1204 { 1205 memset(& $$, 0, sizeof($$)); 1206 $$.param_binding_begin = ~0; 1207 initialize_symbol_from_state(state->prog, & $$, $1); 1208 } 1209 | programMultipleItem 1210 { 1211 memset(& $$, 0, sizeof($$)); 1212 $$.param_binding_begin = ~0; 1213 initialize_symbol_from_param(state->prog, & $$, $1); 1214 } 1215 | paramConstDecl 1216 { 1217 memset(& $$, 0, sizeof($$)); 1218 $$.param_binding_begin = ~0; 1219 initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE); 1220 } 1221 ; 1222 1223 stateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); } 1224 | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); } 1225 ; 1226 1227 stateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); } 1228 | STATE stateLightItem { memcpy($$, $2, sizeof($$)); } 1229 | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); } 1230 | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); } 1231 | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); } 1232 | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); } 1233 | STATE stateFogItem { memcpy($$, $2, sizeof($$)); } 1234 | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); } 1235 | STATE statePointItem { memcpy($$, $2, sizeof($$)); } 1236 | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); } 1237 | STATE stateDepthItem { memcpy($$, $2, sizeof($$)); } 1238 ; 1239 1240 stateMaterialItem: MATERIAL optFaceType stateMatProperty 1241 { 1242 memset($$, 0, sizeof($$)); 1243 $$[0] = STATE_MATERIAL; 1244 $$[1] = $3 + $2; 1245 $$[2] = 0; 1246 } 1247 ; 1248 1249 stateMatProperty: ambDiffSpecPropertyMaterial 1250 { 1251 $$ = $1; 1252 } 1253 | EMISSION 1254 { 1255 $$ = MAT_ATTRIB_FRONT_EMISSION; 1256 } 1257 | SHININESS 1258 { 1259 $$ = MAT_ATTRIB_FRONT_SHININESS; 1260 } 1261 ; 1262 1263 stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty 1264 { 1265 memset($$, 0, sizeof($$)); 1266 $$[0] = STATE_LIGHT; 1267 $$[1] = $3; 1268 $$[2] = $5; 1269 } 1270 ; 1271 1272 stateLightProperty: ambDiffSpecPropertyLight 1273 { 1274 $$ = $1; 1275 } 1276 | POSITION 1277 { 1278 $$ = STATE_POSITION; 1279 } 1280 | ATTENUATION 1281 { 1282 $$ = STATE_ATTENUATION; 1283 } 1284 | SPOT stateSpotProperty 1285 { 1286 $$ = $2; 1287 } 1288 | HALF 1289 { 1290 $$ = STATE_HALF_VECTOR; 1291 } 1292 ; 1293 1294 stateSpotProperty: DIRECTION 1295 { 1296 $$ = STATE_SPOT_DIRECTION; 1297 } 1298 ; 1299 1300 stateLightModelItem: LIGHTMODEL stateLModProperty 1301 { 1302 $$[0] = $2[0]; 1303 $$[1] = $2[1]; 1304 } 1305 ; 1306 1307 stateLModProperty: AMBIENT 1308 { 1309 memset($$, 0, sizeof($$)); 1310 $$[0] = STATE_LIGHTMODEL_AMBIENT; 1311 } 1312 | optFaceType SCENECOLOR 1313 { 1314 memset($$, 0, sizeof($$)); 1315 $$[0] = STATE_LIGHTMODEL_SCENECOLOR; 1316 $$[1] = $1; 1317 } 1318 ; 1319 1320 stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty 1321 { 1322 memset($$, 0, sizeof($$)); 1323 $$[0] = STATE_LIGHTPROD; 1324 $$[1] = $3; 1325 $$[2] = $6 + $5; 1326 $$[3] = 0; 1327 } 1328 ; 1329 1330 stateLProdProperty: ambDiffSpecPropertyMaterial; 1331 1332 stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty 1333 { 1334 memset($$, 0, sizeof($$)); 1335 $$[0] = $3; 1336 $$[1] = $2; 1337 } 1338 ; 1339 1340 stateTexEnvProperty: COLOR 1341 { 1342 $$ = STATE_TEXENV_COLOR; 1343 } 1344 ; 1345 1346 ambDiffSpecPropertyMaterial: AMBIENT 1347 { 1348 $$ = MAT_ATTRIB_FRONT_AMBIENT; 1349 } 1350 | DIFFUSE 1351 { 1352 $$ = MAT_ATTRIB_FRONT_DIFFUSE; 1353 } 1354 | SPECULAR 1355 { 1356 $$ = MAT_ATTRIB_FRONT_SPECULAR; 1357 } 1358 ; 1359 1360 ambDiffSpecPropertyLight: AMBIENT 1361 { 1362 $$ = STATE_AMBIENT; 1363 } 1364 | DIFFUSE 1365 { 1366 $$ = STATE_DIFFUSE; 1367 } 1368 | SPECULAR 1369 { 1370 $$ = STATE_SPECULAR; 1371 } 1372 ; 1373 1374 stateLightNumber: INTEGER 1375 { 1376 if ((unsigned) $1 >= state->MaxLights) { 1377 yyerror(& @1, state, "invalid light selector"); 1378 YYERROR; 1379 } 1380 1381 $$ = $1; 1382 } 1383 ; 1384 1385 stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord 1386 { 1387 memset($$, 0, sizeof($$)); 1388 $$[0] = STATE_TEXGEN; 1389 $$[1] = $2; 1390 $$[2] = $3 + $4; 1391 } 1392 ; 1393 1394 stateTexGenType: EYE 1395 { 1396 $$ = STATE_TEXGEN_EYE_S; 1397 } 1398 | OBJECT 1399 { 1400 $$ = STATE_TEXGEN_OBJECT_S; 1401 } 1402 ; 1403 stateTexGenCoord: TEXGEN_S 1404 { 1405 $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; 1406 } 1407 | TEXGEN_T 1408 { 1409 $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; 1410 } 1411 | TEXGEN_R 1412 { 1413 $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; 1414 } 1415 | TEXGEN_Q 1416 { 1417 $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; 1418 } 1419 ; 1420 1421 stateFogItem: FOG stateFogProperty 1422 { 1423 memset($$, 0, sizeof($$)); 1424 $$[0] = $2; 1425 } 1426 ; 1427 1428 stateFogProperty: COLOR 1429 { 1430 $$ = STATE_FOG_COLOR; 1431 } 1432 | PARAMS 1433 { 1434 $$ = STATE_FOG_PARAMS; 1435 } 1436 ; 1437 1438 stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE 1439 { 1440 memset($$, 0, sizeof($$)); 1441 $$[0] = STATE_CLIPPLANE; 1442 $$[1] = $3; 1443 } 1444 ; 1445 1446 stateClipPlaneNum: INTEGER 1447 { 1448 if ((unsigned) $1 >= state->MaxClipPlanes) { 1449 yyerror(& @1, state, "invalid clip plane selector"); 1450 YYERROR; 1451 } 1452 1453 $$ = $1; 1454 } 1455 ; 1456 1457 statePointItem: POINT_TOK statePointProperty 1458 { 1459 memset($$, 0, sizeof($$)); 1460 $$[0] = $2; 1461 } 1462 ; 1463 1464 statePointProperty: SIZE_TOK 1465 { 1466 $$ = STATE_POINT_SIZE; 1467 } 1468 | ATTENUATION 1469 { 1470 $$ = STATE_POINT_ATTENUATION; 1471 } 1472 ; 1473 1474 stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']' 1475 { 1476 $$[0] = $1[0] + $1[2]; 1477 $$[1] = $1[1]; 1478 $$[2] = $4; 1479 $$[3] = $4; 1480 } 1481 ; 1482 1483 stateMatrixRows: stateMatrixItem optMatrixRows 1484 { 1485 $$[0] = $1[0] + $1[2]; 1486 $$[1] = $1[1]; 1487 $$[2] = $2[2]; 1488 $$[3] = $2[3]; 1489 } 1490 ; 1491 1492 optMatrixRows: 1493 { 1494 $$[2] = 0; 1495 $$[3] = 3; 1496 } 1497 | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']' 1498 { 1499 /* It seems logical that the matrix row range specifier would have 1500 * to specify a range or more than one row (i.e., $5 > $3). 1501 * However, the ARB_vertex_program spec says "a program will fail 1502 * to load if <a> is greater than <b>." This means that $3 == $5 1503 * is valid. 1504 */ 1505 if ($3 > $5) { 1506 yyerror(& @3, state, "invalid matrix row range"); 1507 YYERROR; 1508 } 1509 1510 $$[2] = $3; 1511 $$[3] = $5; 1512 } 1513 ; 1514 1515 stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier 1516 { 1517 $$[0] = $2[0]; 1518 $$[1] = $2[1]; 1519 $$[2] = $3; 1520 } 1521 ; 1522 1523 stateOptMatModifier: 1524 { 1525 $$ = STATE_MATRIX_NO_MODIFIER; 1526 } 1527 | stateMatModifier 1528 { 1529 $$ = $1; 1530 } 1531 ; 1532 1533 stateMatModifier: INVERSE 1534 { 1535 $$ = STATE_MATRIX_INVERSE; 1536 } 1537 | TRANSPOSE 1538 { 1539 $$ = STATE_MATRIX_TRANSPOSE; 1540 } 1541 | INVTRANS 1542 { 1543 $$ = STATE_MATRIX_INVTRANS; 1544 } 1545 ; 1546 1547 stateMatrixRowNum: INTEGER 1548 { 1549 if ($1 > 3) { 1550 yyerror(& @1, state, "invalid matrix row reference"); 1551 YYERROR; 1552 } 1553 1554 $$ = $1; 1555 } 1556 ; 1557 1558 stateMatrixName: MODELVIEW stateOptModMatNum 1559 { 1560 $$[0] = STATE_MODELVIEW_MATRIX; 1561 $$[1] = $2; 1562 } 1563 | PROJECTION 1564 { 1565 $$[0] = STATE_PROJECTION_MATRIX; 1566 $$[1] = 0; 1567 } 1568 | MVP 1569 { 1570 $$[0] = STATE_MVP_MATRIX; 1571 $$[1] = 0; 1572 } 1573 | TEXTURE optTexCoordUnitNum 1574 { 1575 $$[0] = STATE_TEXTURE_MATRIX; 1576 $$[1] = $2; 1577 } 1578 | PALETTE '[' statePaletteMatNum ']' 1579 { 1580 yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); 1581 YYERROR; 1582 } 1583 | MAT_PROGRAM '[' stateProgramMatNum ']' 1584 { 1585 $$[0] = STATE_PROGRAM_MATRIX; 1586 $$[1] = $3; 1587 } 1588 ; 1589 1590 stateOptModMatNum: 1591 { 1592 $$ = 0; 1593 } 1594 | '[' stateModMatNum ']' 1595 { 1596 $$ = $2; 1597 } 1598 ; 1599 stateModMatNum: INTEGER 1600 { 1601 /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix 1602 * zero is valid. 1603 */ 1604 if ($1 != 0) { 1605 yyerror(& @1, state, "invalid modelview matrix index"); 1606 YYERROR; 1607 } 1608 1609 $$ = $1; 1610 } 1611 ; 1612 statePaletteMatNum: INTEGER 1613 { 1614 /* Since GL_ARB_matrix_palette isn't supported, just let any value 1615 * through here. The error will be generated later. 1616 */ 1617 $$ = $1; 1618 } 1619 ; 1620 stateProgramMatNum: INTEGER 1621 { 1622 if ((unsigned) $1 >= state->MaxProgramMatrices) { 1623 yyerror(& @1, state, "invalid program matrix selector"); 1624 YYERROR; 1625 } 1626 1627 $$ = $1; 1628 } 1629 ; 1630 1631 stateDepthItem: DEPTH RANGE 1632 { 1633 memset($$, 0, sizeof($$)); 1634 $$[0] = STATE_DEPTH_RANGE; 1635 } 1636 ; 1637 1638 1639 programSingleItem: progEnvParam | progLocalParam; 1640 1641 programMultipleItem: progEnvParams | progLocalParams; 1642 1643 progEnvParams: PROGRAM ENV '[' progEnvParamNums ']' 1644 { 1645 memset($$, 0, sizeof($$)); 1646 $$[0] = state->state_param_enum_env; 1647 $$[1] = $4[0]; 1648 $$[2] = $4[1]; 1649 $$[3] = 0; 1650 } 1651 ; 1652 1653 progEnvParamNums: progEnvParamNum 1654 { 1655 $$[0] = $1; 1656 $$[1] = $1; 1657 } 1658 | progEnvParamNum DOT_DOT progEnvParamNum 1659 { 1660 $$[0] = $1; 1661 $$[1] = $3; 1662 } 1663 ; 1664 1665 progEnvParam: PROGRAM ENV '[' progEnvParamNum ']' 1666 { 1667 memset($$, 0, sizeof($$)); 1668 $$[0] = state->state_param_enum_env; 1669 $$[1] = $4; 1670 $$[2] = $4; 1671 $$[3] = 0; 1672 } 1673 ; 1674 1675 progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']' 1676 { 1677 memset($$, 0, sizeof($$)); 1678 $$[0] = state->state_param_enum_local; 1679 $$[1] = $4[0]; 1680 $$[2] = $4[1]; 1681 $$[3] = 0; 1682 } 1683 1684 progLocalParamNums: progLocalParamNum 1685 { 1686 $$[0] = $1; 1687 $$[1] = $1; 1688 } 1689 | progLocalParamNum DOT_DOT progLocalParamNum 1690 { 1691 $$[0] = $1; 1692 $$[1] = $3; 1693 } 1694 ; 1695 1696 progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']' 1697 { 1698 memset($$, 0, sizeof($$)); 1699 $$[0] = state->state_param_enum_local; 1700 $$[1] = $4; 1701 $$[2] = $4; 1702 $$[3] = 0; 1703 } 1704 ; 1705 1706 progEnvParamNum: INTEGER 1707 { 1708 if ((unsigned) $1 >= state->limits->MaxEnvParams) { 1709 yyerror(& @1, state, "invalid environment parameter reference"); 1710 YYERROR; 1711 } 1712 $$ = $1; 1713 } 1714 ; 1715 1716 progLocalParamNum: INTEGER 1717 { 1718 if ((unsigned) $1 >= state->limits->MaxLocalParams) { 1719 yyerror(& @1, state, "invalid local parameter reference"); 1720 YYERROR; 1721 } 1722 $$ = $1; 1723 } 1724 ; 1725 1726 1727 1728 paramConstDecl: paramConstScalarDecl | paramConstVector; 1729 paramConstUse: paramConstScalarUse | paramConstVector; 1730 1731 paramConstScalarDecl: signedFloatConstant 1732 { 1733 $$.count = 4; 1734 $$.data[0].f = $1; 1735 $$.data[1].f = $1; 1736 $$.data[2].f = $1; 1737 $$.data[3].f = $1; 1738 } 1739 ; 1740 1741 paramConstScalarUse: REAL 1742 { 1743 $$.count = 1; 1744 $$.data[0].f = $1; 1745 $$.data[1].f = $1; 1746 $$.data[2].f = $1; 1747 $$.data[3].f = $1; 1748 } 1749 | INTEGER 1750 { 1751 $$.count = 1; 1752 $$.data[0].f = (float) $1; 1753 $$.data[1].f = (float) $1; 1754 $$.data[2].f = (float) $1; 1755 $$.data[3].f = (float) $1; 1756 } 1757 ; 1758 1759 paramConstVector: '{' signedFloatConstant '}' 1760 { 1761 $$.count = 4; 1762 $$.data[0].f = $2; 1763 $$.data[1].f = 0.0f; 1764 $$.data[2].f = 0.0f; 1765 $$.data[3].f = 1.0f; 1766 } 1767 | '{' signedFloatConstant ',' signedFloatConstant '}' 1768 { 1769 $$.count = 4; 1770 $$.data[0].f = $2; 1771 $$.data[1].f = $4; 1772 $$.data[2].f = 0.0f; 1773 $$.data[3].f = 1.0f; 1774 } 1775 | '{' signedFloatConstant ',' signedFloatConstant ',' 1776 signedFloatConstant '}' 1777 { 1778 $$.count = 4; 1779 $$.data[0].f = $2; 1780 $$.data[1].f = $4; 1781 $$.data[2].f = $6; 1782 $$.data[3].f = 1.0f; 1783 } 1784 | '{' signedFloatConstant ',' signedFloatConstant ',' 1785 signedFloatConstant ',' signedFloatConstant '}' 1786 { 1787 $$.count = 4; 1788 $$.data[0].f = $2; 1789 $$.data[1].f = $4; 1790 $$.data[2].f = $6; 1791 $$.data[3].f = $8; 1792 } 1793 ; 1794 1795 signedFloatConstant: optionalSign REAL 1796 { 1797 $$ = ($1) ? -$2 : $2; 1798 } 1799 | optionalSign INTEGER 1800 { 1801 $$ = (float)(($1) ? -$2 : $2); 1802 } 1803 ; 1804 1805 optionalSign: '+' { $$ = FALSE; } 1806 | '-' { $$ = TRUE; } 1807 | { $$ = FALSE; } 1808 ; 1809 1810 TEMP_statement: TEMP { $<integer>$ = $1; } varNameList 1811 ; 1812 1813 ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList 1814 ; 1815 1816 varNameList: varNameList ',' IDENTIFIER 1817 { 1818 if (!declare_variable(state, $3, $<integer>0, & @3)) { 1819 free($3); 1820 YYERROR; 1821 } 1822 } 1823 | IDENTIFIER 1824 { 1825 if (!declare_variable(state, $1, $<integer>0, & @1)) { 1826 free($1); 1827 YYERROR; 1828 } 1829 } 1830 ; 1831 1832 OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding 1833 { 1834 struct asm_symbol *const s = 1835 declare_variable(state, $2, at_output, & @2); 1836 1837 if (s == NULL) { 1838 free($2); 1839 YYERROR; 1840 } else { 1841 s->output_binding = $4; 1842 } 1843 } 1844 ; 1845 1846 resultBinding: RESULT POSITION 1847 { 1848 if (state->mode == ARB_vertex) { 1849 $$ = VARYING_SLOT_POS; 1850 } else { 1851 yyerror(& @2, state, "invalid program result name"); 1852 YYERROR; 1853 } 1854 } 1855 | RESULT FOGCOORD 1856 { 1857 if (state->mode == ARB_vertex) { 1858 $$ = VARYING_SLOT_FOGC; 1859 } else { 1860 yyerror(& @2, state, "invalid program result name"); 1861 YYERROR; 1862 } 1863 } 1864 | RESULT resultColBinding 1865 { 1866 $$ = $2; 1867 } 1868 | RESULT POINTSIZE 1869 { 1870 if (state->mode == ARB_vertex) { 1871 $$ = VARYING_SLOT_PSIZ; 1872 } else { 1873 yyerror(& @2, state, "invalid program result name"); 1874 YYERROR; 1875 } 1876 } 1877 | RESULT TEXCOORD optTexCoordUnitNum 1878 { 1879 if (state->mode == ARB_vertex) { 1880 $$ = VARYING_SLOT_TEX0 + $3; 1881 } else { 1882 yyerror(& @2, state, "invalid program result name"); 1883 YYERROR; 1884 } 1885 } 1886 | RESULT DEPTH 1887 { 1888 if (state->mode == ARB_fragment) { 1889 $$ = FRAG_RESULT_DEPTH; 1890 } else { 1891 yyerror(& @2, state, "invalid program result name"); 1892 YYERROR; 1893 } 1894 } 1895 ; 1896 1897 resultColBinding: COLOR optResultFaceType optResultColorType 1898 { 1899 $$ = $2 + $3; 1900 } 1901 ; 1902 1903 optResultFaceType: 1904 { 1905 if (state->mode == ARB_vertex) { 1906 $$ = VARYING_SLOT_COL0; 1907 } else { 1908 if (state->option.DrawBuffers) 1909 $$ = FRAG_RESULT_DATA0; 1910 else 1911 $$ = FRAG_RESULT_COLOR; 1912 } 1913 } 1914 | '[' INTEGER ']' 1915 { 1916 if (state->mode == ARB_vertex) { 1917 yyerror(& @1, state, "invalid program result name"); 1918 YYERROR; 1919 } else { 1920 if (!state->option.DrawBuffers) { 1921 /* From the ARB_draw_buffers spec (same text exists 1922 * for ATI_draw_buffers): 1923 * 1924 * If this option is not specified, a fragment 1925 * program that attempts to bind 1926 * "result.color[n]" will fail to load, and only 1927 * "result.color" will be allowed. 1928 */ 1929 yyerror(& @1, state, 1930 "result.color[] used without " 1931 "`OPTION ARB_draw_buffers' or " 1932 "`OPTION ATI_draw_buffers'"); 1933 YYERROR; 1934 } else if ($2 >= state->MaxDrawBuffers) { 1935 yyerror(& @1, state, 1936 "result.color[] exceeds MAX_DRAW_BUFFERS_ARB"); 1937 YYERROR; 1938 } 1939 $$ = FRAG_RESULT_DATA0 + $2; 1940 } 1941 } 1942 | FRONT 1943 { 1944 if (state->mode == ARB_vertex) { 1945 $$ = VARYING_SLOT_COL0; 1946 } else { 1947 yyerror(& @1, state, "invalid program result name"); 1948 YYERROR; 1949 } 1950 } 1951 | BACK 1952 { 1953 if (state->mode == ARB_vertex) { 1954 $$ = VARYING_SLOT_BFC0; 1955 } else { 1956 yyerror(& @1, state, "invalid program result name"); 1957 YYERROR; 1958 } 1959 } 1960 ; 1961 1962 optResultColorType: 1963 { 1964 $$ = 0; 1965 } 1966 | PRIMARY 1967 { 1968 if (state->mode == ARB_vertex) { 1969 $$ = 0; 1970 } else { 1971 yyerror(& @1, state, "invalid program result name"); 1972 YYERROR; 1973 } 1974 } 1975 | SECONDARY 1976 { 1977 if (state->mode == ARB_vertex) { 1978 $$ = 1; 1979 } else { 1980 yyerror(& @1, state, "invalid program result name"); 1981 YYERROR; 1982 } 1983 } 1984 ; 1985 1986 optFaceType: { $$ = 0; } 1987 | FRONT { $$ = 0; } 1988 | BACK { $$ = 1; } 1989 ; 1990 1991 optColorType: { $$ = 0; } 1992 | PRIMARY { $$ = 0; } 1993 | SECONDARY { $$ = 1; } 1994 ; 1995 1996 optTexCoordUnitNum: { $$ = 0; } 1997 | '[' texCoordUnitNum ']' { $$ = $2; } 1998 ; 1999 2000 optTexImageUnitNum: { $$ = 0; } 2001 | '[' texImageUnitNum ']' { $$ = $2; } 2002 ; 2003 2004 optLegacyTexUnitNum: { $$ = 0; } 2005 | '[' legacyTexUnitNum ']' { $$ = $2; } 2006 ; 2007 2008 texCoordUnitNum: INTEGER 2009 { 2010 if ((unsigned) $1 >= state->MaxTextureCoordUnits) { 2011 yyerror(& @1, state, "invalid texture coordinate unit selector"); 2012 YYERROR; 2013 } 2014 2015 $$ = $1; 2016 } 2017 ; 2018 2019 texImageUnitNum: INTEGER 2020 { 2021 if ((unsigned) $1 >= state->MaxTextureImageUnits) { 2022 yyerror(& @1, state, "invalid texture image unit selector"); 2023 YYERROR; 2024 } 2025 2026 $$ = $1; 2027 } 2028 ; 2029 2030 legacyTexUnitNum: INTEGER 2031 { 2032 if ((unsigned) $1 >= state->MaxTextureUnits) { 2033 yyerror(& @1, state, "invalid texture unit selector"); 2034 YYERROR; 2035 } 2036 2037 $$ = $1; 2038 } 2039 ; 2040 2041 ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER 2042 { 2043 struct asm_symbol *exist = (struct asm_symbol *) 2044 _mesa_symbol_table_find_symbol(state->st, $2); 2045 struct asm_symbol *target = (struct asm_symbol *) 2046 _mesa_symbol_table_find_symbol(state->st, $4); 2047 2048 free($4); 2049 2050 if (exist != NULL) { 2051 char m[1000]; 2052 snprintf(m, sizeof(m), "redeclared identifier: %s", $2); 2053 free($2); 2054 yyerror(& @2, state, m); 2055 YYERROR; 2056 } else if (target == NULL) { 2057 free($2); 2058 yyerror(& @4, state, 2059 "undefined variable binding in ALIAS statement"); 2060 YYERROR; 2061 } else { 2062 _mesa_symbol_table_add_symbol(state->st, $2, target); 2063 } 2064 } 2065 ; 2066 2067 string: IDENTIFIER 2068 | USED_IDENTIFIER 2069 ; 2070 2071 %% 2072 2073 void 2074 asm_instruction_set_operands(struct asm_instruction *inst, 2075 const struct prog_dst_register *dst, 2076 const struct asm_src_register *src0, 2077 const struct asm_src_register *src1, 2078 const struct asm_src_register *src2) 2079 { 2080 /* In the core ARB extensions only the KIL instruction doesn't have a 2081 * destination register. 2082 */ 2083 if (dst == NULL) { 2084 init_dst_reg(& inst->Base.DstReg); 2085 } else { 2086 inst->Base.DstReg = *dst; 2087 } 2088 2089 if (src0 != NULL) { 2090 inst->Base.SrcReg[0] = src0->Base; 2091 inst->SrcReg[0] = *src0; 2092 } else { 2093 init_src_reg(& inst->SrcReg[0]); 2094 } 2095 2096 if (src1 != NULL) { 2097 inst->Base.SrcReg[1] = src1->Base; 2098 inst->SrcReg[1] = *src1; 2099 } else { 2100 init_src_reg(& inst->SrcReg[1]); 2101 } 2102 2103 if (src2 != NULL) { 2104 inst->Base.SrcReg[2] = src2->Base; 2105 inst->SrcReg[2] = *src2; 2106 } else { 2107 init_src_reg(& inst->SrcReg[2]); 2108 } 2109 } 2110 2111 2112 struct asm_instruction * 2113 asm_instruction_ctor(enum prog_opcode op, 2114 const struct prog_dst_register *dst, 2115 const struct asm_src_register *src0, 2116 const struct asm_src_register *src1, 2117 const struct asm_src_register *src2) 2118 { 2119 struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction)); 2120 2121 if (inst) { 2122 _mesa_init_instructions(& inst->Base, 1); 2123 inst->Base.Opcode = op; 2124 2125 asm_instruction_set_operands(inst, dst, src0, src1, src2); 2126 } 2127 2128 return inst; 2129 } 2130 2131 2132 struct asm_instruction * 2133 asm_instruction_copy_ctor(const struct prog_instruction *base, 2134 const struct prog_dst_register *dst, 2135 const struct asm_src_register *src0, 2136 const struct asm_src_register *src1, 2137 const struct asm_src_register *src2) 2138 { 2139 struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); 2140 2141 if (inst) { 2142 _mesa_init_instructions(& inst->Base, 1); 2143 inst->Base.Opcode = base->Opcode; 2144 inst->Base.Saturate = base->Saturate; 2145 2146 asm_instruction_set_operands(inst, dst, src0, src1, src2); 2147 } 2148 2149 return inst; 2150 } 2151 2152 2153 void 2154 init_dst_reg(struct prog_dst_register *r) 2155 { 2156 memset(r, 0, sizeof(*r)); 2157 r->File = PROGRAM_UNDEFINED; 2158 r->WriteMask = WRITEMASK_XYZW; 2159 } 2160 2161 2162 /** Like init_dst_reg() but set the File and Index fields. */ 2163 void 2164 set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index) 2165 { 2166 const GLint maxIndex = 1 << INST_INDEX_BITS; 2167 const GLint minIndex = 0; 2168 assert(index >= minIndex); 2169 (void) minIndex; 2170 assert(index <= maxIndex); 2171 (void) maxIndex; 2172 assert(file == PROGRAM_TEMPORARY || 2173 file == PROGRAM_ADDRESS || 2174 file == PROGRAM_OUTPUT); 2175 memset(r, 0, sizeof(*r)); 2176 r->File = file; 2177 r->Index = index; 2178 r->WriteMask = WRITEMASK_XYZW; 2179 } 2180 2181 2182 void 2183 init_src_reg(struct asm_src_register *r) 2184 { 2185 memset(r, 0, sizeof(*r)); 2186 r->Base.File = PROGRAM_UNDEFINED; 2187 r->Base.Swizzle = SWIZZLE_NOOP; 2188 r->Symbol = NULL; 2189 } 2190 2191 2192 /** Like init_src_reg() but set the File and Index fields. 2193 * \return GL_TRUE if a valid src register, GL_FALSE otherwise 2194 */ 2195 void 2196 set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) 2197 { 2198 set_src_reg_swz(r, file, index, SWIZZLE_XYZW); 2199 } 2200 2201 2202 void 2203 set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index, 2204 GLuint swizzle) 2205 { 2206 const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; 2207 const GLint minIndex = -(1 << INST_INDEX_BITS); 2208 assert(file < PROGRAM_FILE_MAX); 2209 assert(index >= minIndex); 2210 (void) minIndex; 2211 assert(index <= maxIndex); 2212 (void) maxIndex; 2213 memset(r, 0, sizeof(*r)); 2214 r->Base.File = file; 2215 r->Base.Index = index; 2216 r->Base.Swizzle = swizzle; 2217 r->Symbol = NULL; 2218 } 2219 2220 2221 /** 2222 * Validate the set of inputs used by a program 2223 * 2224 * Validates that legal sets of inputs are used by the program. In this case 2225 * "used" included both reading the input or binding the input to a name using 2226 * the \c ATTRIB command. 2227 * 2228 * \return 2229 * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. 2230 */ 2231 int 2232 validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) 2233 { 2234 const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound; 2235 GLbitfield ff_inputs = 0; 2236 2237 /* Since Mesa internal attribute indices are different from 2238 * how NV_vertex_program defines attribute aliasing, we have to construct 2239 * a separate usage mask based on how the aliasing is defined. 2240 * 2241 * Note that attribute aliasing is optional if NV_vertex_program is 2242 * unsupported. 2243 */ 2244 if (inputs & VERT_BIT_POS) 2245 ff_inputs |= 1 << 0; 2246 if (inputs & VERT_BIT_NORMAL) 2247 ff_inputs |= 1 << 2; 2248 if (inputs & VERT_BIT_COLOR0) 2249 ff_inputs |= 1 << 3; 2250 if (inputs & VERT_BIT_COLOR1) 2251 ff_inputs |= 1 << 4; 2252 if (inputs & VERT_BIT_FOG) 2253 ff_inputs |= 1 << 5; 2254 2255 ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8; 2256 2257 if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) { 2258 yyerror(locp, state, "illegal use of generic attribute and name attribute"); 2259 return 0; 2260 } 2261 2262 return 1; 2263 } 2264 2265 2266 struct asm_symbol * 2267 declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, 2268 struct YYLTYPE *locp) 2269 { 2270 struct asm_symbol *s = NULL; 2271 struct asm_symbol *exist = (struct asm_symbol *) 2272 _mesa_symbol_table_find_symbol(state->st, name); 2273 2274 2275 if (exist != NULL) { 2276 yyerror(locp, state, "redeclared identifier"); 2277 } else { 2278 s = calloc(1, sizeof(struct asm_symbol)); 2279 s->name = name; 2280 s->type = t; 2281 2282 switch (t) { 2283 case at_temp: 2284 if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) { 2285 yyerror(locp, state, "too many temporaries declared"); 2286 free(s); 2287 return NULL; 2288 } 2289 2290 s->temp_binding = state->prog->arb.NumTemporaries; 2291 state->prog->arb.NumTemporaries++; 2292 break; 2293 2294 case at_address: 2295 if (state->prog->arb.NumAddressRegs >= 2296 state->limits->MaxAddressRegs) { 2297 yyerror(locp, state, "too many address registers declared"); 2298 free(s); 2299 return NULL; 2300 } 2301 2302 /* FINISHME: Add support for multiple address registers. 2303 */ 2304 state->prog->arb.NumAddressRegs++; 2305 break; 2306 2307 default: 2308 break; 2309 } 2310 2311 _mesa_symbol_table_add_symbol(state->st, s->name, s); 2312 s->next = state->sym; 2313 state->sym = s; 2314 } 2315 2316 return s; 2317 } 2318 2319 2320 int add_state_reference(struct gl_program_parameter_list *param_list, 2321 const gl_state_index16 tokens[STATE_LENGTH]) 2322 { 2323 const GLuint size = 4; /* XXX fix */ 2324 char *name; 2325 GLint index; 2326 2327 name = _mesa_program_state_string(tokens); 2328 index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, 2329 size, GL_NONE, NULL, tokens, true); 2330 param_list->StateFlags |= _mesa_program_state_flags(tokens); 2331 2332 /* free name string here since we duplicated it in add_parameter() */ 2333 free(name); 2334 2335 return index; 2336 } 2337 2338 2339 int 2340 initialize_symbol_from_state(struct gl_program *prog, 2341 struct asm_symbol *param_var, 2342 const gl_state_index16 tokens[STATE_LENGTH]) 2343 { 2344 int idx = -1; 2345 gl_state_index16 state_tokens[STATE_LENGTH]; 2346 2347 2348 memcpy(state_tokens, tokens, sizeof(state_tokens)); 2349 2350 param_var->type = at_param; 2351 param_var->param_binding_type = PROGRAM_STATE_VAR; 2352 2353 /* If we are adding a STATE_MATRIX that has multiple rows, we need to 2354 * unroll it and call add_state_reference() for each row 2355 */ 2356 if (state_tokens[0] >= STATE_MODELVIEW_MATRIX && 2357 state_tokens[0] <= STATE_PROGRAM_MATRIX_INVTRANS 2358 && (state_tokens[2] != state_tokens[3])) { 2359 int row; 2360 const int first_row = state_tokens[2]; 2361 const int last_row = state_tokens[3]; 2362 2363 for (row = first_row; row <= last_row; row++) { 2364 state_tokens[2] = state_tokens[3] = row; 2365 2366 idx = add_state_reference(prog->Parameters, state_tokens); 2367 if (param_var->param_binding_begin == ~0U) { 2368 param_var->param_binding_begin = idx; 2369 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2370 } 2371 2372 param_var->param_binding_length++; 2373 } 2374 } 2375 else { 2376 idx = add_state_reference(prog->Parameters, state_tokens); 2377 if (param_var->param_binding_begin == ~0U) { 2378 param_var->param_binding_begin = idx; 2379 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2380 } 2381 param_var->param_binding_length++; 2382 } 2383 2384 return idx; 2385 } 2386 2387 2388 int 2389 initialize_symbol_from_param(struct gl_program *prog, 2390 struct asm_symbol *param_var, 2391 const gl_state_index16 tokens[STATE_LENGTH]) 2392 { 2393 int idx = -1; 2394 gl_state_index16 state_tokens[STATE_LENGTH]; 2395 2396 2397 memcpy(state_tokens, tokens, sizeof(state_tokens)); 2398 2399 assert(state_tokens[0] == STATE_VERTEX_PROGRAM_ENV || 2400 state_tokens[0] == STATE_VERTEX_PROGRAM_LOCAL || 2401 state_tokens[0] == STATE_FRAGMENT_PROGRAM_ENV || 2402 state_tokens[0] == STATE_FRAGMENT_PROGRAM_LOCAL); 2403 2404 /* 2405 * The param type is STATE_VAR. The program parameter entry will 2406 * effectively be a pointer into the LOCAL or ENV parameter array. 2407 */ 2408 param_var->type = at_param; 2409 param_var->param_binding_type = PROGRAM_STATE_VAR; 2410 2411 /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, 2412 * we need to unroll it and call add_state_reference() for each row 2413 */ 2414 if (state_tokens[1] != state_tokens[2]) { 2415 int row; 2416 const int first_row = state_tokens[1]; 2417 const int last_row = state_tokens[2]; 2418 2419 for (row = first_row; row <= last_row; row++) { 2420 state_tokens[1] = state_tokens[2] = row; 2421 2422 idx = add_state_reference(prog->Parameters, state_tokens); 2423 if (param_var->param_binding_begin == ~0U) { 2424 param_var->param_binding_begin = idx; 2425 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2426 } 2427 param_var->param_binding_length++; 2428 } 2429 } 2430 else { 2431 idx = add_state_reference(prog->Parameters, state_tokens); 2432 if (param_var->param_binding_begin == ~0U) { 2433 param_var->param_binding_begin = idx; 2434 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2435 } 2436 param_var->param_binding_length++; 2437 } 2438 2439 return idx; 2440 } 2441 2442 2443 /** 2444 * Put a float/vector constant/literal into the parameter list. 2445 * \param param_var returns info about the parameter/constant's location, 2446 * binding, type, etc. 2447 * \param vec the vector/constant to add 2448 * \param allowSwizzle if true, try to consolidate constants which only differ 2449 * by a swizzle. We don't want to do this when building 2450 * arrays of constants that may be indexed indirectly. 2451 * \return index of the constant in the parameter list. 2452 */ 2453 int 2454 initialize_symbol_from_const(struct gl_program *prog, 2455 struct asm_symbol *param_var, 2456 const struct asm_vector *vec, 2457 GLboolean allowSwizzle) 2458 { 2459 unsigned swizzle; 2460 const int idx = _mesa_add_unnamed_constant(prog->Parameters, 2461 vec->data, vec->count, 2462 allowSwizzle ? &swizzle : NULL); 2463 2464 param_var->type = at_param; 2465 param_var->param_binding_type = PROGRAM_CONSTANT; 2466 2467 if (param_var->param_binding_begin == ~0U) { 2468 param_var->param_binding_begin = idx; 2469 param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW; 2470 } 2471 param_var->param_binding_length++; 2472 2473 return idx; 2474 } 2475 2476 2477 char * 2478 make_error_string(const char *fmt, ...) 2479 { 2480 int length; 2481 char *str; 2482 va_list args; 2483 2484 2485 /* Call vsnprintf once to determine how large the final string is. Call it 2486 * again to do the actual formatting. from the vsnprintf manual page: 2487 * 2488 * Upon successful return, these functions return the number of 2489 * characters printed (not including the trailing '\0' used to end 2490 * output to strings). 2491 */ 2492 va_start(args, fmt); 2493 length = 1 + vsnprintf(NULL, 0, fmt, args); 2494 va_end(args); 2495 2496 str = malloc(length); 2497 if (str) { 2498 va_start(args, fmt); 2499 vsnprintf(str, length, fmt, args); 2500 va_end(args); 2501 } 2502 2503 return str; 2504 } 2505 2506 2507 void 2508 yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) 2509 { 2510 char *err_str; 2511 2512 2513 err_str = make_error_string("glProgramStringARB(%s)\n", s); 2514 if (err_str) { 2515 _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str); 2516 free(err_str); 2517 } 2518 2519 err_str = make_error_string("line %u, char %u: error: %s\n", 2520 locp->first_line, locp->first_column, s); 2521 _mesa_set_program_error(state->ctx, locp->position, err_str); 2522 2523 if (err_str) { 2524 free(err_str); 2525 } 2526 } 2527 2528 2529 GLboolean 2530 _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str, 2531 GLsizei len, struct asm_parser_state *state) 2532 { 2533 struct asm_instruction *inst; 2534 unsigned i; 2535 GLubyte *strz; 2536 GLboolean result = GL_FALSE; 2537 void *temp; 2538 struct asm_symbol *sym; 2539 2540 state->ctx = ctx; 2541 state->prog->Target = target; 2542 state->prog->Parameters = _mesa_new_parameter_list(); 2543 2544 /* Make a copy of the program string and force it to be newline and NUL-terminated. 2545 */ 2546 strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 2); 2547 if (strz == NULL) { 2548 if (state->prog->Parameters) { 2549 _mesa_free_parameter_list(state->prog->Parameters); 2550 state->prog->Parameters = NULL; 2551 } 2552 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); 2553 return GL_FALSE; 2554 } 2555 memcpy (strz, str, len); 2556 strz[len] = '\n'; 2557 strz[len + 1] = '\0'; 2558 2559 state->prog->String = strz; 2560 2561 state->st = _mesa_symbol_table_ctor(); 2562 2563 state->limits = (target == GL_VERTEX_PROGRAM_ARB) 2564 ? & ctx->Const.Program[MESA_SHADER_VERTEX] 2565 : & ctx->Const.Program[MESA_SHADER_FRAGMENT]; 2566 2567 state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; 2568 state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; 2569 state->MaxTextureUnits = ctx->Const.MaxTextureUnits; 2570 state->MaxClipPlanes = ctx->Const.MaxClipPlanes; 2571 state->MaxLights = ctx->Const.MaxLights; 2572 state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; 2573 state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers; 2574 2575 state->state_param_enum_env = (target == GL_VERTEX_PROGRAM_ARB) 2576 ? STATE_VERTEX_PROGRAM_ENV : STATE_FRAGMENT_PROGRAM_ENV; 2577 state->state_param_enum_local = (target == GL_VERTEX_PROGRAM_ARB) 2578 ? STATE_VERTEX_PROGRAM_LOCAL : STATE_FRAGMENT_PROGRAM_LOCAL; 2579 2580 _mesa_set_program_error(ctx, -1, NULL); 2581 2582 _mesa_program_lexer_ctor(& state->scanner, state, (const char *) strz, len + 1); 2583 yyparse(state); 2584 _mesa_program_lexer_dtor(state->scanner); 2585 2586 /* Remove the newline we added so reflection returns the original string */ 2587 strz[len] = '\0'; 2588 2589 if (ctx->Program.ErrorPos != -1) { 2590 goto error; 2591 } 2592 2593 if (! _mesa_layout_parameters(state)) { 2594 struct YYLTYPE loc; 2595 2596 loc.first_line = 0; 2597 loc.first_column = 0; 2598 loc.position = len; 2599 2600 yyerror(& loc, state, "invalid PARAM usage"); 2601 goto error; 2602 } 2603 2604 2605 2606 /* Add one instruction to store the "END" instruction. 2607 */ 2608 state->prog->arb.Instructions = 2609 rzalloc_array(state->mem_ctx, struct prog_instruction, 2610 state->prog->arb.NumInstructions + 1); 2611 2612 if (state->prog->arb.Instructions == NULL) { 2613 goto error; 2614 } 2615 2616 inst = state->inst_head; 2617 for (i = 0; i < state->prog->arb.NumInstructions; i++) { 2618 struct asm_instruction *const temp = inst->next; 2619 2620 state->prog->arb.Instructions[i] = inst->Base; 2621 inst = temp; 2622 } 2623 2624 /* Finally, tag on an OPCODE_END instruction */ 2625 { 2626 const GLuint numInst = state->prog->arb.NumInstructions; 2627 _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1); 2628 state->prog->arb.Instructions[numInst].Opcode = OPCODE_END; 2629 } 2630 state->prog->arb.NumInstructions++; 2631 2632 state->prog->arb.NumParameters = state->prog->Parameters->NumParameters; 2633 state->prog->arb.NumAttributes = 2634 util_bitcount64(state->prog->info.inputs_read); 2635 2636 /* 2637 * Initialize native counts to logical counts. The device driver may 2638 * change them if program is translated into a hardware program. 2639 */ 2640 state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions; 2641 state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries; 2642 state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters; 2643 state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes; 2644 state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs; 2645 2646 result = GL_TRUE; 2647 2648 error: 2649 for (inst = state->inst_head; inst != NULL; inst = temp) { 2650 temp = inst->next; 2651 free(inst); 2652 } 2653 2654 state->inst_head = NULL; 2655 state->inst_tail = NULL; 2656 2657 for (sym = state->sym; sym != NULL; sym = temp) { 2658 temp = sym->next; 2659 2660 free((void *) sym->name); 2661 free(sym); 2662 } 2663 state->sym = NULL; 2664 2665 _mesa_symbol_table_dtor(state->st); 2666 state->st = NULL; 2667 2668 if (result != GL_TRUE) { 2669 if (state->prog->Parameters) { 2670 _mesa_free_parameter_list(state->prog->Parameters); 2671 state->prog->Parameters = NULL; 2672 } 2673 ralloc_free(state->prog->String); 2674 state->prog->String = NULL; 2675 } 2676 2677 return result; 2678 } 2679