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