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