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