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