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 if (!state->ctx->Extensions.EXT_point_parameters) { 1283 yyerror(& @1, state, "GL_ARB_point_parameters not supported"); 1284 YYERROR; 1285 } 1286 1287 $$ = STATE_ATTENUATION; 1288 } 1289 | SPOT stateSpotProperty 1290 { 1291 $$ = $2; 1292 } 1293 | HALF 1294 { 1295 $$ = STATE_HALF_VECTOR; 1296 } 1297 ; 1298 1299 stateSpotProperty: DIRECTION 1300 { 1301 $$ = STATE_SPOT_DIRECTION; 1302 } 1303 ; 1304 1305 stateLightModelItem: LIGHTMODEL stateLModProperty 1306 { 1307 $$[0] = $2[0]; 1308 $$[1] = $2[1]; 1309 } 1310 ; 1311 1312 stateLModProperty: AMBIENT 1313 { 1314 memset($$, 0, sizeof($$)); 1315 $$[0] = STATE_LIGHTMODEL_AMBIENT; 1316 } 1317 | optFaceType SCENECOLOR 1318 { 1319 memset($$, 0, sizeof($$)); 1320 $$[0] = STATE_LIGHTMODEL_SCENECOLOR; 1321 $$[1] = $1; 1322 } 1323 ; 1324 1325 stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty 1326 { 1327 memset($$, 0, sizeof($$)); 1328 $$[0] = STATE_LIGHTPROD; 1329 $$[1] = $3; 1330 $$[2] = $6 + $5; 1331 $$[3] = 0; 1332 } 1333 ; 1334 1335 stateLProdProperty: ambDiffSpecPropertyMaterial; 1336 1337 stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty 1338 { 1339 memset($$, 0, sizeof($$)); 1340 $$[0] = $3; 1341 $$[1] = $2; 1342 } 1343 ; 1344 1345 stateTexEnvProperty: COLOR 1346 { 1347 $$ = STATE_TEXENV_COLOR; 1348 } 1349 ; 1350 1351 ambDiffSpecPropertyMaterial: AMBIENT 1352 { 1353 $$ = MAT_ATTRIB_FRONT_AMBIENT; 1354 } 1355 | DIFFUSE 1356 { 1357 $$ = MAT_ATTRIB_FRONT_DIFFUSE; 1358 } 1359 | SPECULAR 1360 { 1361 $$ = MAT_ATTRIB_FRONT_SPECULAR; 1362 } 1363 ; 1364 1365 ambDiffSpecPropertyLight: AMBIENT 1366 { 1367 $$ = STATE_AMBIENT; 1368 } 1369 | DIFFUSE 1370 { 1371 $$ = STATE_DIFFUSE; 1372 } 1373 | SPECULAR 1374 { 1375 $$ = STATE_SPECULAR; 1376 } 1377 ; 1378 1379 stateLightNumber: INTEGER 1380 { 1381 if ((unsigned) $1 >= state->MaxLights) { 1382 yyerror(& @1, state, "invalid light selector"); 1383 YYERROR; 1384 } 1385 1386 $$ = $1; 1387 } 1388 ; 1389 1390 stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord 1391 { 1392 memset($$, 0, sizeof($$)); 1393 $$[0] = STATE_TEXGEN; 1394 $$[1] = $2; 1395 $$[2] = $3 + $4; 1396 } 1397 ; 1398 1399 stateTexGenType: EYE 1400 { 1401 $$ = STATE_TEXGEN_EYE_S; 1402 } 1403 | OBJECT 1404 { 1405 $$ = STATE_TEXGEN_OBJECT_S; 1406 } 1407 ; 1408 stateTexGenCoord: TEXGEN_S 1409 { 1410 $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; 1411 } 1412 | TEXGEN_T 1413 { 1414 $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; 1415 } 1416 | TEXGEN_R 1417 { 1418 $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; 1419 } 1420 | TEXGEN_Q 1421 { 1422 $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; 1423 } 1424 ; 1425 1426 stateFogItem: FOG stateFogProperty 1427 { 1428 memset($$, 0, sizeof($$)); 1429 $$[0] = $2; 1430 } 1431 ; 1432 1433 stateFogProperty: COLOR 1434 { 1435 $$ = STATE_FOG_COLOR; 1436 } 1437 | PARAMS 1438 { 1439 $$ = STATE_FOG_PARAMS; 1440 } 1441 ; 1442 1443 stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE 1444 { 1445 memset($$, 0, sizeof($$)); 1446 $$[0] = STATE_CLIPPLANE; 1447 $$[1] = $3; 1448 } 1449 ; 1450 1451 stateClipPlaneNum: INTEGER 1452 { 1453 if ((unsigned) $1 >= state->MaxClipPlanes) { 1454 yyerror(& @1, state, "invalid clip plane selector"); 1455 YYERROR; 1456 } 1457 1458 $$ = $1; 1459 } 1460 ; 1461 1462 statePointItem: POINT_TOK statePointProperty 1463 { 1464 memset($$, 0, sizeof($$)); 1465 $$[0] = $2; 1466 } 1467 ; 1468 1469 statePointProperty: SIZE_TOK 1470 { 1471 $$ = STATE_POINT_SIZE; 1472 } 1473 | ATTENUATION 1474 { 1475 $$ = STATE_POINT_ATTENUATION; 1476 } 1477 ; 1478 1479 stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']' 1480 { 1481 $$[0] = $1[0] + $1[2]; 1482 $$[1] = $1[1]; 1483 $$[2] = $4; 1484 $$[3] = $4; 1485 } 1486 ; 1487 1488 stateMatrixRows: stateMatrixItem optMatrixRows 1489 { 1490 $$[0] = $1[0] + $1[2]; 1491 $$[1] = $1[1]; 1492 $$[2] = $2[2]; 1493 $$[3] = $2[3]; 1494 } 1495 ; 1496 1497 optMatrixRows: 1498 { 1499 $$[2] = 0; 1500 $$[3] = 3; 1501 } 1502 | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']' 1503 { 1504 /* It seems logical that the matrix row range specifier would have 1505 * to specify a range or more than one row (i.e., $5 > $3). 1506 * However, the ARB_vertex_program spec says "a program will fail 1507 * to load if <a> is greater than <b>." This means that $3 == $5 1508 * is valid. 1509 */ 1510 if ($3 > $5) { 1511 yyerror(& @3, state, "invalid matrix row range"); 1512 YYERROR; 1513 } 1514 1515 $$[2] = $3; 1516 $$[3] = $5; 1517 } 1518 ; 1519 1520 stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier 1521 { 1522 $$[0] = $2[0]; 1523 $$[1] = $2[1]; 1524 $$[2] = $3; 1525 } 1526 ; 1527 1528 stateOptMatModifier: 1529 { 1530 $$ = STATE_MATRIX_NO_MODIFIER; 1531 } 1532 | stateMatModifier 1533 { 1534 $$ = $1; 1535 } 1536 ; 1537 1538 stateMatModifier: INVERSE 1539 { 1540 $$ = STATE_MATRIX_INVERSE; 1541 } 1542 | TRANSPOSE 1543 { 1544 $$ = STATE_MATRIX_TRANSPOSE; 1545 } 1546 | INVTRANS 1547 { 1548 $$ = STATE_MATRIX_INVTRANS; 1549 } 1550 ; 1551 1552 stateMatrixRowNum: INTEGER 1553 { 1554 if ($1 > 3) { 1555 yyerror(& @1, state, "invalid matrix row reference"); 1556 YYERROR; 1557 } 1558 1559 $$ = $1; 1560 } 1561 ; 1562 1563 stateMatrixName: MODELVIEW stateOptModMatNum 1564 { 1565 $$[0] = STATE_MODELVIEW_MATRIX; 1566 $$[1] = $2; 1567 } 1568 | PROJECTION 1569 { 1570 $$[0] = STATE_PROJECTION_MATRIX; 1571 $$[1] = 0; 1572 } 1573 | MVP 1574 { 1575 $$[0] = STATE_MVP_MATRIX; 1576 $$[1] = 0; 1577 } 1578 | TEXTURE optTexCoordUnitNum 1579 { 1580 $$[0] = STATE_TEXTURE_MATRIX; 1581 $$[1] = $2; 1582 } 1583 | PALETTE '[' statePaletteMatNum ']' 1584 { 1585 yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); 1586 YYERROR; 1587 } 1588 | MAT_PROGRAM '[' stateProgramMatNum ']' 1589 { 1590 $$[0] = STATE_PROGRAM_MATRIX; 1591 $$[1] = $3; 1592 } 1593 ; 1594 1595 stateOptModMatNum: 1596 { 1597 $$ = 0; 1598 } 1599 | '[' stateModMatNum ']' 1600 { 1601 $$ = $2; 1602 } 1603 ; 1604 stateModMatNum: INTEGER 1605 { 1606 /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix 1607 * zero is valid. 1608 */ 1609 if ($1 != 0) { 1610 yyerror(& @1, state, "invalid modelview matrix index"); 1611 YYERROR; 1612 } 1613 1614 $$ = $1; 1615 } 1616 ; 1617 statePaletteMatNum: INTEGER 1618 { 1619 /* Since GL_ARB_matrix_palette isn't supported, just let any value 1620 * through here. The error will be generated later. 1621 */ 1622 $$ = $1; 1623 } 1624 ; 1625 stateProgramMatNum: INTEGER 1626 { 1627 if ((unsigned) $1 >= state->MaxProgramMatrices) { 1628 yyerror(& @1, state, "invalid program matrix selector"); 1629 YYERROR; 1630 } 1631 1632 $$ = $1; 1633 } 1634 ; 1635 1636 stateDepthItem: DEPTH RANGE 1637 { 1638 memset($$, 0, sizeof($$)); 1639 $$[0] = STATE_DEPTH_RANGE; 1640 } 1641 ; 1642 1643 1644 programSingleItem: progEnvParam | progLocalParam; 1645 1646 programMultipleItem: progEnvParams | progLocalParams; 1647 1648 progEnvParams: PROGRAM ENV '[' progEnvParamNums ']' 1649 { 1650 memset($$, 0, sizeof($$)); 1651 $$[0] = state->state_param_enum_env; 1652 $$[1] = $4[0]; 1653 $$[2] = $4[1]; 1654 $$[3] = 0; 1655 } 1656 ; 1657 1658 progEnvParamNums: progEnvParamNum 1659 { 1660 $$[0] = $1; 1661 $$[1] = $1; 1662 } 1663 | progEnvParamNum DOT_DOT progEnvParamNum 1664 { 1665 $$[0] = $1; 1666 $$[1] = $3; 1667 } 1668 ; 1669 1670 progEnvParam: PROGRAM ENV '[' progEnvParamNum ']' 1671 { 1672 memset($$, 0, sizeof($$)); 1673 $$[0] = state->state_param_enum_env; 1674 $$[1] = $4; 1675 $$[2] = $4; 1676 $$[3] = 0; 1677 } 1678 ; 1679 1680 progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']' 1681 { 1682 memset($$, 0, sizeof($$)); 1683 $$[0] = state->state_param_enum_local; 1684 $$[1] = $4[0]; 1685 $$[2] = $4[1]; 1686 $$[3] = 0; 1687 } 1688 1689 progLocalParamNums: progLocalParamNum 1690 { 1691 $$[0] = $1; 1692 $$[1] = $1; 1693 } 1694 | progLocalParamNum DOT_DOT progLocalParamNum 1695 { 1696 $$[0] = $1; 1697 $$[1] = $3; 1698 } 1699 ; 1700 1701 progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']' 1702 { 1703 memset($$, 0, sizeof($$)); 1704 $$[0] = state->state_param_enum_local; 1705 $$[1] = $4; 1706 $$[2] = $4; 1707 $$[3] = 0; 1708 } 1709 ; 1710 1711 progEnvParamNum: INTEGER 1712 { 1713 if ((unsigned) $1 >= state->limits->MaxEnvParams) { 1714 yyerror(& @1, state, "invalid environment parameter reference"); 1715 YYERROR; 1716 } 1717 $$ = $1; 1718 } 1719 ; 1720 1721 progLocalParamNum: INTEGER 1722 { 1723 if ((unsigned) $1 >= state->limits->MaxLocalParams) { 1724 yyerror(& @1, state, "invalid local parameter reference"); 1725 YYERROR; 1726 } 1727 $$ = $1; 1728 } 1729 ; 1730 1731 1732 1733 paramConstDecl: paramConstScalarDecl | paramConstVector; 1734 paramConstUse: paramConstScalarUse | paramConstVector; 1735 1736 paramConstScalarDecl: signedFloatConstant 1737 { 1738 $$.count = 4; 1739 $$.data[0].f = $1; 1740 $$.data[1].f = $1; 1741 $$.data[2].f = $1; 1742 $$.data[3].f = $1; 1743 } 1744 ; 1745 1746 paramConstScalarUse: REAL 1747 { 1748 $$.count = 1; 1749 $$.data[0].f = $1; 1750 $$.data[1].f = $1; 1751 $$.data[2].f = $1; 1752 $$.data[3].f = $1; 1753 } 1754 | INTEGER 1755 { 1756 $$.count = 1; 1757 $$.data[0].f = (float) $1; 1758 $$.data[1].f = (float) $1; 1759 $$.data[2].f = (float) $1; 1760 $$.data[3].f = (float) $1; 1761 } 1762 ; 1763 1764 paramConstVector: '{' signedFloatConstant '}' 1765 { 1766 $$.count = 4; 1767 $$.data[0].f = $2; 1768 $$.data[1].f = 0.0f; 1769 $$.data[2].f = 0.0f; 1770 $$.data[3].f = 1.0f; 1771 } 1772 | '{' signedFloatConstant ',' signedFloatConstant '}' 1773 { 1774 $$.count = 4; 1775 $$.data[0].f = $2; 1776 $$.data[1].f = $4; 1777 $$.data[2].f = 0.0f; 1778 $$.data[3].f = 1.0f; 1779 } 1780 | '{' signedFloatConstant ',' signedFloatConstant ',' 1781 signedFloatConstant '}' 1782 { 1783 $$.count = 4; 1784 $$.data[0].f = $2; 1785 $$.data[1].f = $4; 1786 $$.data[2].f = $6; 1787 $$.data[3].f = 1.0f; 1788 } 1789 | '{' signedFloatConstant ',' signedFloatConstant ',' 1790 signedFloatConstant ',' signedFloatConstant '}' 1791 { 1792 $$.count = 4; 1793 $$.data[0].f = $2; 1794 $$.data[1].f = $4; 1795 $$.data[2].f = $6; 1796 $$.data[3].f = $8; 1797 } 1798 ; 1799 1800 signedFloatConstant: optionalSign REAL 1801 { 1802 $$ = ($1) ? -$2 : $2; 1803 } 1804 | optionalSign INTEGER 1805 { 1806 $$ = (float)(($1) ? -$2 : $2); 1807 } 1808 ; 1809 1810 optionalSign: '+' { $$ = FALSE; } 1811 | '-' { $$ = TRUE; } 1812 | { $$ = FALSE; } 1813 ; 1814 1815 TEMP_statement: TEMP { $<integer>$ = $1; } varNameList 1816 ; 1817 1818 ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList 1819 ; 1820 1821 varNameList: varNameList ',' IDENTIFIER 1822 { 1823 if (!declare_variable(state, $3, $<integer>0, & @3)) { 1824 free($3); 1825 YYERROR; 1826 } 1827 } 1828 | IDENTIFIER 1829 { 1830 if (!declare_variable(state, $1, $<integer>0, & @1)) { 1831 free($1); 1832 YYERROR; 1833 } 1834 } 1835 ; 1836 1837 OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding 1838 { 1839 struct asm_symbol *const s = 1840 declare_variable(state, $2, at_output, & @2); 1841 1842 if (s == NULL) { 1843 free($2); 1844 YYERROR; 1845 } else { 1846 s->output_binding = $4; 1847 } 1848 } 1849 ; 1850 1851 resultBinding: RESULT POSITION 1852 { 1853 if (state->mode == ARB_vertex) { 1854 $$ = VARYING_SLOT_POS; 1855 } else { 1856 yyerror(& @2, state, "invalid program result name"); 1857 YYERROR; 1858 } 1859 } 1860 | RESULT FOGCOORD 1861 { 1862 if (state->mode == ARB_vertex) { 1863 $$ = VARYING_SLOT_FOGC; 1864 } else { 1865 yyerror(& @2, state, "invalid program result name"); 1866 YYERROR; 1867 } 1868 } 1869 | RESULT resultColBinding 1870 { 1871 $$ = $2; 1872 } 1873 | RESULT POINTSIZE 1874 { 1875 if (state->mode == ARB_vertex) { 1876 $$ = VARYING_SLOT_PSIZ; 1877 } else { 1878 yyerror(& @2, state, "invalid program result name"); 1879 YYERROR; 1880 } 1881 } 1882 | RESULT TEXCOORD optTexCoordUnitNum 1883 { 1884 if (state->mode == ARB_vertex) { 1885 $$ = VARYING_SLOT_TEX0 + $3; 1886 } else { 1887 yyerror(& @2, state, "invalid program result name"); 1888 YYERROR; 1889 } 1890 } 1891 | RESULT DEPTH 1892 { 1893 if (state->mode == ARB_fragment) { 1894 $$ = FRAG_RESULT_DEPTH; 1895 } else { 1896 yyerror(& @2, state, "invalid program result name"); 1897 YYERROR; 1898 } 1899 } 1900 ; 1901 1902 resultColBinding: COLOR optResultFaceType optResultColorType 1903 { 1904 $$ = $2 + $3; 1905 } 1906 ; 1907 1908 optResultFaceType: 1909 { 1910 if (state->mode == ARB_vertex) { 1911 $$ = VARYING_SLOT_COL0; 1912 } else { 1913 if (state->option.DrawBuffers) 1914 $$ = FRAG_RESULT_DATA0; 1915 else 1916 $$ = FRAG_RESULT_COLOR; 1917 } 1918 } 1919 | '[' INTEGER ']' 1920 { 1921 if (state->mode == ARB_vertex) { 1922 yyerror(& @1, state, "invalid program result name"); 1923 YYERROR; 1924 } else { 1925 if (!state->option.DrawBuffers) { 1926 /* From the ARB_draw_buffers spec (same text exists 1927 * for ATI_draw_buffers): 1928 * 1929 * If this option is not specified, a fragment 1930 * program that attempts to bind 1931 * "result.color[n]" will fail to load, and only 1932 * "result.color" will be allowed. 1933 */ 1934 yyerror(& @1, state, 1935 "result.color[] used without " 1936 "`OPTION ARB_draw_buffers' or " 1937 "`OPTION ATI_draw_buffers'"); 1938 YYERROR; 1939 } else if ($2 >= state->MaxDrawBuffers) { 1940 yyerror(& @1, state, 1941 "result.color[] exceeds MAX_DRAW_BUFFERS_ARB"); 1942 YYERROR; 1943 } 1944 $$ = FRAG_RESULT_DATA0 + $2; 1945 } 1946 } 1947 | FRONT 1948 { 1949 if (state->mode == ARB_vertex) { 1950 $$ = VARYING_SLOT_COL0; 1951 } else { 1952 yyerror(& @1, state, "invalid program result name"); 1953 YYERROR; 1954 } 1955 } 1956 | BACK 1957 { 1958 if (state->mode == ARB_vertex) { 1959 $$ = VARYING_SLOT_BFC0; 1960 } else { 1961 yyerror(& @1, state, "invalid program result name"); 1962 YYERROR; 1963 } 1964 } 1965 ; 1966 1967 optResultColorType: 1968 { 1969 $$ = 0; 1970 } 1971 | PRIMARY 1972 { 1973 if (state->mode == ARB_vertex) { 1974 $$ = 0; 1975 } else { 1976 yyerror(& @1, state, "invalid program result name"); 1977 YYERROR; 1978 } 1979 } 1980 | SECONDARY 1981 { 1982 if (state->mode == ARB_vertex) { 1983 $$ = 1; 1984 } else { 1985 yyerror(& @1, state, "invalid program result name"); 1986 YYERROR; 1987 } 1988 } 1989 ; 1990 1991 optFaceType: { $$ = 0; } 1992 | FRONT { $$ = 0; } 1993 | BACK { $$ = 1; } 1994 ; 1995 1996 optColorType: { $$ = 0; } 1997 | PRIMARY { $$ = 0; } 1998 | SECONDARY { $$ = 1; } 1999 ; 2000 2001 optTexCoordUnitNum: { $$ = 0; } 2002 | '[' texCoordUnitNum ']' { $$ = $2; } 2003 ; 2004 2005 optTexImageUnitNum: { $$ = 0; } 2006 | '[' texImageUnitNum ']' { $$ = $2; } 2007 ; 2008 2009 optLegacyTexUnitNum: { $$ = 0; } 2010 | '[' legacyTexUnitNum ']' { $$ = $2; } 2011 ; 2012 2013 texCoordUnitNum: INTEGER 2014 { 2015 if ((unsigned) $1 >= state->MaxTextureCoordUnits) { 2016 yyerror(& @1, state, "invalid texture coordinate unit selector"); 2017 YYERROR; 2018 } 2019 2020 $$ = $1; 2021 } 2022 ; 2023 2024 texImageUnitNum: INTEGER 2025 { 2026 if ((unsigned) $1 >= state->MaxTextureImageUnits) { 2027 yyerror(& @1, state, "invalid texture image unit selector"); 2028 YYERROR; 2029 } 2030 2031 $$ = $1; 2032 } 2033 ; 2034 2035 legacyTexUnitNum: INTEGER 2036 { 2037 if ((unsigned) $1 >= state->MaxTextureUnits) { 2038 yyerror(& @1, state, "invalid texture unit selector"); 2039 YYERROR; 2040 } 2041 2042 $$ = $1; 2043 } 2044 ; 2045 2046 ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER 2047 { 2048 struct asm_symbol *exist = (struct asm_symbol *) 2049 _mesa_symbol_table_find_symbol(state->st, $2); 2050 struct asm_symbol *target = (struct asm_symbol *) 2051 _mesa_symbol_table_find_symbol(state->st, $4); 2052 2053 free($4); 2054 2055 if (exist != NULL) { 2056 char m[1000]; 2057 snprintf(m, sizeof(m), "redeclared identifier: %s", $2); 2058 free($2); 2059 yyerror(& @2, state, m); 2060 YYERROR; 2061 } else if (target == NULL) { 2062 free($2); 2063 yyerror(& @4, state, 2064 "undefined variable binding in ALIAS statement"); 2065 YYERROR; 2066 } else { 2067 _mesa_symbol_table_add_symbol(state->st, $2, target); 2068 } 2069 } 2070 ; 2071 2072 string: IDENTIFIER 2073 | USED_IDENTIFIER 2074 ; 2075 2076 %% 2077 2078 void 2079 asm_instruction_set_operands(struct asm_instruction *inst, 2080 const struct prog_dst_register *dst, 2081 const struct asm_src_register *src0, 2082 const struct asm_src_register *src1, 2083 const struct asm_src_register *src2) 2084 { 2085 /* In the core ARB extensions only the KIL instruction doesn't have a 2086 * destination register. 2087 */ 2088 if (dst == NULL) { 2089 init_dst_reg(& inst->Base.DstReg); 2090 } else { 2091 inst->Base.DstReg = *dst; 2092 } 2093 2094 if (src0 != NULL) { 2095 inst->Base.SrcReg[0] = src0->Base; 2096 inst->SrcReg[0] = *src0; 2097 } else { 2098 init_src_reg(& inst->SrcReg[0]); 2099 } 2100 2101 if (src1 != NULL) { 2102 inst->Base.SrcReg[1] = src1->Base; 2103 inst->SrcReg[1] = *src1; 2104 } else { 2105 init_src_reg(& inst->SrcReg[1]); 2106 } 2107 2108 if (src2 != NULL) { 2109 inst->Base.SrcReg[2] = src2->Base; 2110 inst->SrcReg[2] = *src2; 2111 } else { 2112 init_src_reg(& inst->SrcReg[2]); 2113 } 2114 } 2115 2116 2117 struct asm_instruction * 2118 asm_instruction_ctor(enum prog_opcode op, 2119 const struct prog_dst_register *dst, 2120 const struct asm_src_register *src0, 2121 const struct asm_src_register *src1, 2122 const struct asm_src_register *src2) 2123 { 2124 struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); 2125 2126 if (inst) { 2127 _mesa_init_instructions(& inst->Base, 1); 2128 inst->Base.Opcode = op; 2129 2130 asm_instruction_set_operands(inst, dst, src0, src1, src2); 2131 } 2132 2133 return inst; 2134 } 2135 2136 2137 struct asm_instruction * 2138 asm_instruction_copy_ctor(const struct prog_instruction *base, 2139 const struct prog_dst_register *dst, 2140 const struct asm_src_register *src0, 2141 const struct asm_src_register *src1, 2142 const struct asm_src_register *src2) 2143 { 2144 struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); 2145 2146 if (inst) { 2147 _mesa_init_instructions(& inst->Base, 1); 2148 inst->Base.Opcode = base->Opcode; 2149 inst->Base.Saturate = base->Saturate; 2150 2151 asm_instruction_set_operands(inst, dst, src0, src1, src2); 2152 } 2153 2154 return inst; 2155 } 2156 2157 2158 void 2159 init_dst_reg(struct prog_dst_register *r) 2160 { 2161 memset(r, 0, sizeof(*r)); 2162 r->File = PROGRAM_UNDEFINED; 2163 r->WriteMask = WRITEMASK_XYZW; 2164 } 2165 2166 2167 /** Like init_dst_reg() but set the File and Index fields. */ 2168 void 2169 set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index) 2170 { 2171 const GLint maxIndex = 1 << INST_INDEX_BITS; 2172 const GLint minIndex = 0; 2173 assert(index >= minIndex); 2174 (void) minIndex; 2175 assert(index <= maxIndex); 2176 (void) maxIndex; 2177 assert(file == PROGRAM_TEMPORARY || 2178 file == PROGRAM_ADDRESS || 2179 file == PROGRAM_OUTPUT); 2180 memset(r, 0, sizeof(*r)); 2181 r->File = file; 2182 r->Index = index; 2183 r->WriteMask = WRITEMASK_XYZW; 2184 } 2185 2186 2187 void 2188 init_src_reg(struct asm_src_register *r) 2189 { 2190 memset(r, 0, sizeof(*r)); 2191 r->Base.File = PROGRAM_UNDEFINED; 2192 r->Base.Swizzle = SWIZZLE_NOOP; 2193 r->Symbol = NULL; 2194 } 2195 2196 2197 /** Like init_src_reg() but set the File and Index fields. 2198 * \return GL_TRUE if a valid src register, GL_FALSE otherwise 2199 */ 2200 void 2201 set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) 2202 { 2203 set_src_reg_swz(r, file, index, SWIZZLE_XYZW); 2204 } 2205 2206 2207 void 2208 set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index, 2209 GLuint swizzle) 2210 { 2211 const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; 2212 const GLint minIndex = -(1 << INST_INDEX_BITS); 2213 assert(file < PROGRAM_FILE_MAX); 2214 assert(index >= minIndex); 2215 (void) minIndex; 2216 assert(index <= maxIndex); 2217 (void) maxIndex; 2218 memset(r, 0, sizeof(*r)); 2219 r->Base.File = file; 2220 r->Base.Index = index; 2221 r->Base.Swizzle = swizzle; 2222 r->Symbol = NULL; 2223 } 2224 2225 2226 /** 2227 * Validate the set of inputs used by a program 2228 * 2229 * Validates that legal sets of inputs are used by the program. In this case 2230 * "used" included both reading the input or binding the input to a name using 2231 * the \c ATTRIB command. 2232 * 2233 * \return 2234 * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. 2235 */ 2236 int 2237 validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) 2238 { 2239 const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound; 2240 GLbitfield ff_inputs = 0; 2241 2242 /* Since Mesa internal attribute indices are different from 2243 * how NV_vertex_program defines attribute aliasing, we have to construct 2244 * a separate usage mask based on how the aliasing is defined. 2245 * 2246 * Note that attribute aliasing is optional if NV_vertex_program is 2247 * unsupported. 2248 */ 2249 if (inputs & VERT_BIT_POS) 2250 ff_inputs |= 1 << 0; 2251 if (inputs & VERT_BIT_NORMAL) 2252 ff_inputs |= 1 << 2; 2253 if (inputs & VERT_BIT_COLOR0) 2254 ff_inputs |= 1 << 3; 2255 if (inputs & VERT_BIT_COLOR1) 2256 ff_inputs |= 1 << 4; 2257 if (inputs & VERT_BIT_FOG) 2258 ff_inputs |= 1 << 5; 2259 2260 ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8; 2261 2262 if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) { 2263 yyerror(locp, state, "illegal use of generic attribute and name attribute"); 2264 return 0; 2265 } 2266 2267 return 1; 2268 } 2269 2270 2271 struct asm_symbol * 2272 declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, 2273 struct YYLTYPE *locp) 2274 { 2275 struct asm_symbol *s = NULL; 2276 struct asm_symbol *exist = (struct asm_symbol *) 2277 _mesa_symbol_table_find_symbol(state->st, name); 2278 2279 2280 if (exist != NULL) { 2281 yyerror(locp, state, "redeclared identifier"); 2282 } else { 2283 s = calloc(1, sizeof(struct asm_symbol)); 2284 s->name = name; 2285 s->type = t; 2286 2287 switch (t) { 2288 case at_temp: 2289 if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) { 2290 yyerror(locp, state, "too many temporaries declared"); 2291 free(s); 2292 return NULL; 2293 } 2294 2295 s->temp_binding = state->prog->arb.NumTemporaries; 2296 state->prog->arb.NumTemporaries++; 2297 break; 2298 2299 case at_address: 2300 if (state->prog->arb.NumAddressRegs >= 2301 state->limits->MaxAddressRegs) { 2302 yyerror(locp, state, "too many address registers declared"); 2303 free(s); 2304 return NULL; 2305 } 2306 2307 /* FINISHME: Add support for multiple address registers. 2308 */ 2309 state->prog->arb.NumAddressRegs++; 2310 break; 2311 2312 default: 2313 break; 2314 } 2315 2316 _mesa_symbol_table_add_symbol(state->st, s->name, s); 2317 s->next = state->sym; 2318 state->sym = s; 2319 } 2320 2321 return s; 2322 } 2323 2324 2325 int add_state_reference(struct gl_program_parameter_list *param_list, 2326 const gl_state_index16 tokens[STATE_LENGTH]) 2327 { 2328 const GLuint size = 4; /* XXX fix */ 2329 char *name; 2330 GLint index; 2331 2332 name = _mesa_program_state_string(tokens); 2333 index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, 2334 size, GL_NONE, NULL, tokens, true); 2335 param_list->StateFlags |= _mesa_program_state_flags(tokens); 2336 2337 /* free name string here since we duplicated it in add_parameter() */ 2338 free(name); 2339 2340 return index; 2341 } 2342 2343 2344 int 2345 initialize_symbol_from_state(struct gl_program *prog, 2346 struct asm_symbol *param_var, 2347 const gl_state_index16 tokens[STATE_LENGTH]) 2348 { 2349 int idx = -1; 2350 gl_state_index16 state_tokens[STATE_LENGTH]; 2351 2352 2353 memcpy(state_tokens, tokens, sizeof(state_tokens)); 2354 2355 param_var->type = at_param; 2356 param_var->param_binding_type = PROGRAM_STATE_VAR; 2357 2358 /* If we are adding a STATE_MATRIX that has multiple rows, we need to 2359 * unroll it and call add_state_reference() for each row 2360 */ 2361 if (state_tokens[0] >= STATE_MODELVIEW_MATRIX && 2362 state_tokens[0] <= STATE_PROGRAM_MATRIX_INVTRANS 2363 && (state_tokens[2] != state_tokens[3])) { 2364 int row; 2365 const int first_row = state_tokens[2]; 2366 const int last_row = state_tokens[3]; 2367 2368 for (row = first_row; row <= last_row; row++) { 2369 state_tokens[2] = state_tokens[3] = row; 2370 2371 idx = add_state_reference(prog->Parameters, state_tokens); 2372 if (param_var->param_binding_begin == ~0U) { 2373 param_var->param_binding_begin = idx; 2374 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2375 } 2376 2377 param_var->param_binding_length++; 2378 } 2379 } 2380 else { 2381 idx = add_state_reference(prog->Parameters, state_tokens); 2382 if (param_var->param_binding_begin == ~0U) { 2383 param_var->param_binding_begin = idx; 2384 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2385 } 2386 param_var->param_binding_length++; 2387 } 2388 2389 return idx; 2390 } 2391 2392 2393 int 2394 initialize_symbol_from_param(struct gl_program *prog, 2395 struct asm_symbol *param_var, 2396 const gl_state_index16 tokens[STATE_LENGTH]) 2397 { 2398 int idx = -1; 2399 gl_state_index16 state_tokens[STATE_LENGTH]; 2400 2401 2402 memcpy(state_tokens, tokens, sizeof(state_tokens)); 2403 2404 assert(state_tokens[0] == STATE_VERTEX_PROGRAM_ENV || 2405 state_tokens[0] == STATE_VERTEX_PROGRAM_LOCAL || 2406 state_tokens[0] == STATE_FRAGMENT_PROGRAM_ENV || 2407 state_tokens[0] == STATE_FRAGMENT_PROGRAM_LOCAL); 2408 2409 /* 2410 * The param type is STATE_VAR. The program parameter entry will 2411 * effectively be a pointer into the LOCAL or ENV parameter array. 2412 */ 2413 param_var->type = at_param; 2414 param_var->param_binding_type = PROGRAM_STATE_VAR; 2415 2416 /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, 2417 * we need to unroll it and call add_state_reference() for each row 2418 */ 2419 if (state_tokens[1] != state_tokens[2]) { 2420 int row; 2421 const int first_row = state_tokens[1]; 2422 const int last_row = state_tokens[2]; 2423 2424 for (row = first_row; row <= last_row; row++) { 2425 state_tokens[1] = state_tokens[2] = row; 2426 2427 idx = add_state_reference(prog->Parameters, state_tokens); 2428 if (param_var->param_binding_begin == ~0U) { 2429 param_var->param_binding_begin = idx; 2430 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2431 } 2432 param_var->param_binding_length++; 2433 } 2434 } 2435 else { 2436 idx = add_state_reference(prog->Parameters, state_tokens); 2437 if (param_var->param_binding_begin == ~0U) { 2438 param_var->param_binding_begin = idx; 2439 param_var->param_binding_swizzle = SWIZZLE_XYZW; 2440 } 2441 param_var->param_binding_length++; 2442 } 2443 2444 return idx; 2445 } 2446 2447 2448 /** 2449 * Put a float/vector constant/literal into the parameter list. 2450 * \param param_var returns info about the parameter/constant's location, 2451 * binding, type, etc. 2452 * \param vec the vector/constant to add 2453 * \param allowSwizzle if true, try to consolidate constants which only differ 2454 * by a swizzle. We don't want to do this when building 2455 * arrays of constants that may be indexed indirectly. 2456 * \return index of the constant in the parameter list. 2457 */ 2458 int 2459 initialize_symbol_from_const(struct gl_program *prog, 2460 struct asm_symbol *param_var, 2461 const struct asm_vector *vec, 2462 GLboolean allowSwizzle) 2463 { 2464 unsigned swizzle; 2465 const int idx = _mesa_add_unnamed_constant(prog->Parameters, 2466 vec->data, vec->count, 2467 allowSwizzle ? &swizzle : NULL); 2468 2469 param_var->type = at_param; 2470 param_var->param_binding_type = PROGRAM_CONSTANT; 2471 2472 if (param_var->param_binding_begin == ~0U) { 2473 param_var->param_binding_begin = idx; 2474 param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW; 2475 } 2476 param_var->param_binding_length++; 2477 2478 return idx; 2479 } 2480 2481 2482 char * 2483 make_error_string(const char *fmt, ...) 2484 { 2485 int length; 2486 char *str; 2487 va_list args; 2488 2489 2490 /* Call vsnprintf once to determine how large the final string is. Call it 2491 * again to do the actual formatting. from the vsnprintf manual page: 2492 * 2493 * Upon successful return, these functions return the number of 2494 * characters printed (not including the trailing '\0' used to end 2495 * output to strings). 2496 */ 2497 va_start(args, fmt); 2498 length = 1 + vsnprintf(NULL, 0, fmt, args); 2499 va_end(args); 2500 2501 str = malloc(length); 2502 if (str) { 2503 va_start(args, fmt); 2504 vsnprintf(str, length, fmt, args); 2505 va_end(args); 2506 } 2507 2508 return str; 2509 } 2510 2511 2512 void 2513 yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) 2514 { 2515 char *err_str; 2516 2517 2518 err_str = make_error_string("glProgramStringARB(%s)\n", s); 2519 if (err_str) { 2520 _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str); 2521 free(err_str); 2522 } 2523 2524 err_str = make_error_string("line %u, char %u: error: %s\n", 2525 locp->first_line, locp->first_column, s); 2526 _mesa_set_program_error(state->ctx, locp->position, err_str); 2527 2528 if (err_str) { 2529 free(err_str); 2530 } 2531 } 2532 2533 2534 GLboolean 2535 _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str, 2536 GLsizei len, struct asm_parser_state *state) 2537 { 2538 struct asm_instruction *inst; 2539 unsigned i; 2540 GLubyte *strz; 2541 GLboolean result = GL_FALSE; 2542 void *temp; 2543 struct asm_symbol *sym; 2544 2545 state->ctx = ctx; 2546 state->prog->Target = target; 2547 state->prog->Parameters = _mesa_new_parameter_list(); 2548 2549 /* Make a copy of the program string and force it to be NUL-terminated. 2550 */ 2551 strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 1); 2552 if (strz == NULL) { 2553 if (state->prog->Parameters) { 2554 _mesa_free_parameter_list(state->prog->Parameters); 2555 state->prog->Parameters = NULL; 2556 } 2557 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); 2558 return GL_FALSE; 2559 } 2560 memcpy (strz, str, len); 2561 strz[len] = '\0'; 2562 2563 state->prog->String = strz; 2564 2565 state->st = _mesa_symbol_table_ctor(); 2566 2567 state->limits = (target == GL_VERTEX_PROGRAM_ARB) 2568 ? & ctx->Const.Program[MESA_SHADER_VERTEX] 2569 : & ctx->Const.Program[MESA_SHADER_FRAGMENT]; 2570 2571 state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; 2572 state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; 2573 state->MaxTextureUnits = ctx->Const.MaxTextureUnits; 2574 state->MaxClipPlanes = ctx->Const.MaxClipPlanes; 2575 state->MaxLights = ctx->Const.MaxLights; 2576 state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; 2577 state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers; 2578 2579 state->state_param_enum_env = (target == GL_VERTEX_PROGRAM_ARB) 2580 ? STATE_VERTEX_PROGRAM_ENV : STATE_FRAGMENT_PROGRAM_ENV; 2581 state->state_param_enum_local = (target == GL_VERTEX_PROGRAM_ARB) 2582 ? STATE_VERTEX_PROGRAM_LOCAL : STATE_FRAGMENT_PROGRAM_LOCAL; 2583 2584 _mesa_set_program_error(ctx, -1, NULL); 2585 2586 _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len); 2587 yyparse(state); 2588 _mesa_program_lexer_dtor(state->scanner); 2589 2590 2591 if (ctx->Program.ErrorPos != -1) { 2592 goto error; 2593 } 2594 2595 if (! _mesa_layout_parameters(state)) { 2596 struct YYLTYPE loc; 2597 2598 loc.first_line = 0; 2599 loc.first_column = 0; 2600 loc.position = len; 2601 2602 yyerror(& loc, state, "invalid PARAM usage"); 2603 goto error; 2604 } 2605 2606 2607 2608 /* Add one instruction to store the "END" instruction. 2609 */ 2610 state->prog->arb.Instructions = 2611 rzalloc_array(state->mem_ctx, struct prog_instruction, 2612 state->prog->arb.NumInstructions + 1); 2613 2614 if (state->prog->arb.Instructions == NULL) { 2615 goto error; 2616 } 2617 2618 inst = state->inst_head; 2619 for (i = 0; i < state->prog->arb.NumInstructions; i++) { 2620 struct asm_instruction *const temp = inst->next; 2621 2622 state->prog->arb.Instructions[i] = inst->Base; 2623 inst = temp; 2624 } 2625 2626 /* Finally, tag on an OPCODE_END instruction */ 2627 { 2628 const GLuint numInst = state->prog->arb.NumInstructions; 2629 _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1); 2630 state->prog->arb.Instructions[numInst].Opcode = OPCODE_END; 2631 } 2632 state->prog->arb.NumInstructions++; 2633 2634 state->prog->arb.NumParameters = state->prog->Parameters->NumParameters; 2635 state->prog->arb.NumAttributes = 2636 util_bitcount64(state->prog->info.inputs_read); 2637 2638 /* 2639 * Initialize native counts to logical counts. The device driver may 2640 * change them if program is translated into a hardware program. 2641 */ 2642 state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions; 2643 state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries; 2644 state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters; 2645 state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes; 2646 state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs; 2647 2648 result = GL_TRUE; 2649 2650 error: 2651 for (inst = state->inst_head; inst != NULL; inst = temp) { 2652 temp = inst->next; 2653 free(inst); 2654 } 2655 2656 state->inst_head = NULL; 2657 state->inst_tail = NULL; 2658 2659 for (sym = state->sym; sym != NULL; sym = temp) { 2660 temp = sym->next; 2661 2662 free((void *) sym->name); 2663 free(sym); 2664 } 2665 state->sym = NULL; 2666 2667 _mesa_symbol_table_dtor(state->st); 2668 state->st = NULL; 2669 2670 if (result != GL_TRUE) { 2671 if (state->prog->Parameters) { 2672 _mesa_free_parameter_list(state->prog->Parameters); 2673 state->prog->Parameters = NULL; 2674 } 2675 ralloc_free(state->prog->String); 2676 state->prog->String = NULL; 2677 } 2678 2679 return result; 2680 } 2681