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