13464ebd5Sriastradh%{ 23464ebd5Sriastradh/* 33464ebd5Sriastradh * Copyright © 2009 Intel Corporation 43464ebd5Sriastradh * 53464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 63464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"), 73464ebd5Sriastradh * to deal in the Software without restriction, including without limitation 83464ebd5Sriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 93464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the 103464ebd5Sriastradh * Software is furnished to do so, subject to the following conditions: 113464ebd5Sriastradh * 123464ebd5Sriastradh * The above copyright notice and this permission notice (including the next 133464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the 143464ebd5Sriastradh * Software. 153464ebd5Sriastradh * 163464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 173464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 183464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 193464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 203464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 213464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 223464ebd5Sriastradh * DEALINGS IN THE SOFTWARE. 233464ebd5Sriastradh */ 2401e04c3fSmrg 2501e04c3fSmrg#include <stdarg.h> 263464ebd5Sriastradh#include <stdio.h> 273464ebd5Sriastradh#include <stdlib.h> 283464ebd5Sriastradh#include <string.h> 293464ebd5Sriastradh 3001e04c3fSmrg#include "main/errors.h" 313464ebd5Sriastradh#include "main/mtypes.h" 327ec681f3Smrg 333464ebd5Sriastradh#include "program/program.h" 343464ebd5Sriastradh#include "program/prog_parameter.h" 353464ebd5Sriastradh#include "program/prog_parameter_layout.h" 363464ebd5Sriastradh#include "program/prog_statevars.h" 373464ebd5Sriastradh#include "program/prog_instruction.h" 383464ebd5Sriastradh 393464ebd5Sriastradh#include "program/symbol_table.h" 403464ebd5Sriastradh#include "program/program_parser.h" 413464ebd5Sriastradh 4201e04c3fSmrg#include "util/u_math.h" 437ec681f3Smrg#include "util/u_memory.h" 447ec681f3Smrg 457ec681f3Smrgenum { 467ec681f3Smrg STATE_MATRIX_NO_MODIFIER, 477ec681f3Smrg STATE_MATRIX_INVERSE, 487ec681f3Smrg STATE_MATRIX_TRANSPOSE, 497ec681f3Smrg STATE_MATRIX_INVTRANS, 507ec681f3Smrg}; 5101e04c3fSmrg 523464ebd5Sriastradhextern void *yy_scan_string(char *); 533464ebd5Sriastradhextern void yy_delete_buffer(void *); 543464ebd5Sriastradh 553464ebd5Sriastradhstatic struct asm_symbol *declare_variable(struct asm_parser_state *state, 563464ebd5Sriastradh char *name, enum asm_type t, struct YYLTYPE *locp); 573464ebd5Sriastradh 583464ebd5Sriastradhstatic int add_state_reference(struct gl_program_parameter_list *param_list, 5901e04c3fSmrg const gl_state_index16 tokens[STATE_LENGTH]); 603464ebd5Sriastradh 613464ebd5Sriastradhstatic int initialize_symbol_from_state(struct gl_program *prog, 6201e04c3fSmrg struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]); 633464ebd5Sriastradh 643464ebd5Sriastradhstatic int initialize_symbol_from_param(struct gl_program *prog, 6501e04c3fSmrg struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]); 663464ebd5Sriastradh 673464ebd5Sriastradhstatic int initialize_symbol_from_const(struct gl_program *prog, 683464ebd5Sriastradh struct asm_symbol *param_var, const struct asm_vector *vec, 693464ebd5Sriastradh GLboolean allowSwizzle); 703464ebd5Sriastradh 713464ebd5Sriastradhstatic int yyparse(struct asm_parser_state *state); 723464ebd5Sriastradh 733464ebd5Sriastradhstatic char *make_error_string(const char *fmt, ...); 743464ebd5Sriastradh 753464ebd5Sriastradhstatic void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state, 763464ebd5Sriastradh const char *s); 773464ebd5Sriastradh 783464ebd5Sriastradhstatic int validate_inputs(struct YYLTYPE *locp, 793464ebd5Sriastradh struct asm_parser_state *state); 803464ebd5Sriastradh 813464ebd5Sriastradhstatic void init_dst_reg(struct prog_dst_register *r); 823464ebd5Sriastradh 833464ebd5Sriastradhstatic void set_dst_reg(struct prog_dst_register *r, 843464ebd5Sriastradh gl_register_file file, GLint index); 853464ebd5Sriastradh 863464ebd5Sriastradhstatic void init_src_reg(struct asm_src_register *r); 873464ebd5Sriastradh 883464ebd5Sriastradhstatic void set_src_reg(struct asm_src_register *r, 893464ebd5Sriastradh gl_register_file file, GLint index); 903464ebd5Sriastradh 913464ebd5Sriastradhstatic void set_src_reg_swz(struct asm_src_register *r, 923464ebd5Sriastradh gl_register_file file, GLint index, GLuint swizzle); 933464ebd5Sriastradh 943464ebd5Sriastradhstatic void asm_instruction_set_operands(struct asm_instruction *inst, 953464ebd5Sriastradh const struct prog_dst_register *dst, const struct asm_src_register *src0, 963464ebd5Sriastradh const struct asm_src_register *src1, const struct asm_src_register *src2); 973464ebd5Sriastradh 9801e04c3fSmrgstatic struct asm_instruction *asm_instruction_ctor(enum prog_opcode op, 993464ebd5Sriastradh const struct prog_dst_register *dst, const struct asm_src_register *src0, 1003464ebd5Sriastradh const struct asm_src_register *src1, const struct asm_src_register *src2); 1013464ebd5Sriastradh 1023464ebd5Sriastradhstatic struct asm_instruction *asm_instruction_copy_ctor( 1033464ebd5Sriastradh const struct prog_instruction *base, const struct prog_dst_register *dst, 1043464ebd5Sriastradh const struct asm_src_register *src0, const struct asm_src_register *src1, 1053464ebd5Sriastradh const struct asm_src_register *src2); 1063464ebd5Sriastradh 1073464ebd5Sriastradh#ifndef FALSE 1083464ebd5Sriastradh#define FALSE 0 1093464ebd5Sriastradh#define TRUE (!FALSE) 1103464ebd5Sriastradh#endif 1113464ebd5Sriastradh 1123464ebd5Sriastradh#define YYLLOC_DEFAULT(Current, Rhs, N) \ 1133464ebd5Sriastradh do { \ 114af69d88dSmrg if (N) { \ 1153464ebd5Sriastradh (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ 1163464ebd5Sriastradh (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ 1173464ebd5Sriastradh (Current).position = YYRHSLOC(Rhs, 1).position; \ 1183464ebd5Sriastradh (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ 1193464ebd5Sriastradh (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ 1203464ebd5Sriastradh } else { \ 1213464ebd5Sriastradh (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ 1223464ebd5Sriastradh (Current).last_line = (Current).first_line; \ 1233464ebd5Sriastradh (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ 1243464ebd5Sriastradh (Current).last_column = (Current).first_column; \ 1253464ebd5Sriastradh (Current).position = YYRHSLOC(Rhs, 0).position \ 1263464ebd5Sriastradh + (Current).first_column; \ 1273464ebd5Sriastradh } \ 128af69d88dSmrg } while(0) 1293464ebd5Sriastradh%} 1303464ebd5Sriastradh 1313464ebd5Sriastradh%pure-parser 1323464ebd5Sriastradh%locations 133af69d88dSmrg%lex-param { struct asm_parser_state *state } 1343464ebd5Sriastradh%parse-param { struct asm_parser_state *state } 1353464ebd5Sriastradh%error-verbose 1363464ebd5Sriastradh 1373464ebd5Sriastradh%union { 1383464ebd5Sriastradh struct asm_instruction *inst; 1393464ebd5Sriastradh struct asm_symbol *sym; 1403464ebd5Sriastradh struct asm_symbol temp_sym; 1413464ebd5Sriastradh struct asm_swizzle_mask swiz_mask; 1423464ebd5Sriastradh struct asm_src_register src_reg; 1433464ebd5Sriastradh struct prog_dst_register dst_reg; 1443464ebd5Sriastradh struct prog_instruction temp_inst; 1453464ebd5Sriastradh char *string; 1463464ebd5Sriastradh unsigned result; 1473464ebd5Sriastradh unsigned attrib; 1483464ebd5Sriastradh int integer; 1493464ebd5Sriastradh float real; 15001e04c3fSmrg gl_state_index16 state[STATE_LENGTH]; 1513464ebd5Sriastradh int negate; 1523464ebd5Sriastradh struct asm_vector vector; 15301e04c3fSmrg enum prog_opcode opcode; 1543464ebd5Sriastradh 1553464ebd5Sriastradh struct { 1563464ebd5Sriastradh unsigned swz; 1573464ebd5Sriastradh unsigned rgba_valid:1; 1583464ebd5Sriastradh unsigned xyzw_valid:1; 1593464ebd5Sriastradh unsigned negate:1; 1603464ebd5Sriastradh } ext_swizzle; 1613464ebd5Sriastradh} 1623464ebd5Sriastradh 1633464ebd5Sriastradh%token ARBvp_10 ARBfp_10 1643464ebd5Sriastradh 1653464ebd5Sriastradh/* Tokens for assembler pseudo-ops */ 1663464ebd5Sriastradh%token <integer> ADDRESS 1673464ebd5Sriastradh%token ALIAS ATTRIB 1683464ebd5Sriastradh%token OPTION OUTPUT 1693464ebd5Sriastradh%token PARAM 1703464ebd5Sriastradh%token <integer> TEMP 1713464ebd5Sriastradh%token END 1723464ebd5Sriastradh 1733464ebd5Sriastradh /* Tokens for instructions */ 1743464ebd5Sriastradh%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP 1753464ebd5Sriastradh%token <temp_inst> ARL KIL SWZ TXD_OP 1763464ebd5Sriastradh 1773464ebd5Sriastradh%token <integer> INTEGER 1783464ebd5Sriastradh%token <real> REAL 1793464ebd5Sriastradh 1803464ebd5Sriastradh%token AMBIENT ATTENUATION 1813464ebd5Sriastradh%token BACK 1823464ebd5Sriastradh%token CLIP COLOR 1833464ebd5Sriastradh%token DEPTH DIFFUSE DIRECTION 1843464ebd5Sriastradh%token EMISSION ENV EYE 1853464ebd5Sriastradh%token FOG FOGCOORD FRAGMENT FRONT 1863464ebd5Sriastradh%token HALF 1873464ebd5Sriastradh%token INVERSE INVTRANS 1883464ebd5Sriastradh%token LIGHT LIGHTMODEL LIGHTPROD LOCAL 1893464ebd5Sriastradh%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP 1903464ebd5Sriastradh%token NORMAL 1913464ebd5Sriastradh%token OBJECT 1923464ebd5Sriastradh%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION 1933464ebd5Sriastradh%token RANGE RESULT ROW 1943464ebd5Sriastradh%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE 1953464ebd5Sriastradh%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE 1963464ebd5Sriastradh%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT 1973464ebd5Sriastradh%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT 1987ec681f3Smrg%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D 1993464ebd5Sriastradh%token VERTEX VTXATTRIB 2003464ebd5Sriastradh 2013464ebd5Sriastradh%token <string> IDENTIFIER USED_IDENTIFIER 2023464ebd5Sriastradh%type <string> string 2033464ebd5Sriastradh%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE 2043464ebd5Sriastradh%token DOT_DOT 2053464ebd5Sriastradh%token DOT 2063464ebd5Sriastradh 2073464ebd5Sriastradh%type <inst> instruction ALU_instruction TexInstruction 2083464ebd5Sriastradh%type <inst> ARL_instruction VECTORop_instruction 2093464ebd5Sriastradh%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction 2103464ebd5Sriastradh%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction 2113464ebd5Sriastradh%type <inst> KIL_instruction 2123464ebd5Sriastradh 2133464ebd5Sriastradh%type <dst_reg> dstReg maskedDstReg maskedAddrReg 2143464ebd5Sriastradh%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg 2153464ebd5Sriastradh%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle 2163464ebd5Sriastradh%type <ext_swizzle> extSwizComp extSwizSel 2173464ebd5Sriastradh%type <swiz_mask> optionalMask 2183464ebd5Sriastradh 2193464ebd5Sriastradh%type <sym> progParamArray 2203464ebd5Sriastradh%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset 2213464ebd5Sriastradh%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel 2223464ebd5Sriastradh%type <sym> addrReg 2233464ebd5Sriastradh%type <swiz_mask> addrComponent addrWriteMask 2243464ebd5Sriastradh 2253464ebd5Sriastradh%type <result> resultBinding resultColBinding 2263464ebd5Sriastradh%type <integer> optFaceType optColorType 2273464ebd5Sriastradh%type <integer> optResultFaceType optResultColorType 2283464ebd5Sriastradh 2293464ebd5Sriastradh%type <integer> optTexImageUnitNum texImageUnitNum 2303464ebd5Sriastradh%type <integer> optTexCoordUnitNum texCoordUnitNum 2313464ebd5Sriastradh%type <integer> optLegacyTexUnitNum legacyTexUnitNum 2323464ebd5Sriastradh%type <integer> texImageUnit texTarget 2333464ebd5Sriastradh%type <integer> vtxAttribNum 2343464ebd5Sriastradh 2353464ebd5Sriastradh%type <attrib> attribBinding vtxAttribItem fragAttribItem 2363464ebd5Sriastradh 2373464ebd5Sriastradh%type <temp_sym> paramSingleInit paramSingleItemDecl 2383464ebd5Sriastradh%type <integer> optArraySize 2393464ebd5Sriastradh 2403464ebd5Sriastradh%type <state> stateSingleItem stateMultipleItem 2413464ebd5Sriastradh%type <state> stateMaterialItem 2423464ebd5Sriastradh%type <state> stateLightItem stateLightModelItem stateLightProdItem 2433464ebd5Sriastradh%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem 2443464ebd5Sriastradh%type <state> stateMatrixItem stateMatrixRow stateMatrixRows 2453464ebd5Sriastradh%type <state> stateTexEnvItem stateDepthItem 2463464ebd5Sriastradh 2473464ebd5Sriastradh%type <state> stateLModProperty 2483464ebd5Sriastradh%type <state> stateMatrixName optMatrixRows 2493464ebd5Sriastradh 2503464ebd5Sriastradh%type <integer> stateMatProperty 2513464ebd5Sriastradh%type <integer> stateLightProperty stateSpotProperty 2523464ebd5Sriastradh%type <integer> stateLightNumber stateLProdProperty 2533464ebd5Sriastradh%type <integer> stateTexGenType stateTexGenCoord 2543464ebd5Sriastradh%type <integer> stateTexEnvProperty 2553464ebd5Sriastradh%type <integer> stateFogProperty 2563464ebd5Sriastradh%type <integer> stateClipPlaneNum 2573464ebd5Sriastradh%type <integer> statePointProperty 2583464ebd5Sriastradh 2593464ebd5Sriastradh%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum 2607ec681f3Smrg%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum 2613464ebd5Sriastradh%type <integer> stateProgramMatNum 2623464ebd5Sriastradh 2637ec681f3Smrg%type <integer> ambDiffSpecPropertyMaterial 2647ec681f3Smrg%type <integer> ambDiffSpecPropertyLight 2653464ebd5Sriastradh 2663464ebd5Sriastradh%type <state> programSingleItem progEnvParam progLocalParam 2673464ebd5Sriastradh%type <state> programMultipleItem progEnvParams progLocalParams 2683464ebd5Sriastradh 2693464ebd5Sriastradh%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem 2703464ebd5Sriastradh%type <temp_sym> paramSingleItemUse 2713464ebd5Sriastradh 2723464ebd5Sriastradh%type <integer> progEnvParamNum progLocalParamNum 2733464ebd5Sriastradh%type <state> progEnvParamNums progLocalParamNums 2743464ebd5Sriastradh 2753464ebd5Sriastradh%type <vector> paramConstDecl paramConstUse 2763464ebd5Sriastradh%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector 2773464ebd5Sriastradh%type <real> signedFloatConstant 2783464ebd5Sriastradh%type <negate> optionalSign 2793464ebd5Sriastradh 2803464ebd5Sriastradh%{ 281af69d88dSmrgextern int 282af69d88dSmrg_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, 283af69d88dSmrg void *yyscanner); 284af69d88dSmrg 285af69d88dSmrgstatic int 286af69d88dSmrgyylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, 287af69d88dSmrg struct asm_parser_state *state) 288af69d88dSmrg{ 289af69d88dSmrg return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner); 290af69d88dSmrg} 2913464ebd5Sriastradh%} 2923464ebd5Sriastradh 2933464ebd5Sriastradh%% 2943464ebd5Sriastradh 2953464ebd5Sriastradhprogram: language optionSequence statementSequence END 2963464ebd5Sriastradh ; 2973464ebd5Sriastradh 2983464ebd5Sriastradhlanguage: ARBvp_10 2993464ebd5Sriastradh { 3003464ebd5Sriastradh if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) { 3013464ebd5Sriastradh yyerror(& @1, state, "invalid fragment program header"); 3023464ebd5Sriastradh 3033464ebd5Sriastradh } 3043464ebd5Sriastradh state->mode = ARB_vertex; 3053464ebd5Sriastradh } 3063464ebd5Sriastradh | ARBfp_10 3073464ebd5Sriastradh { 3083464ebd5Sriastradh if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) { 3093464ebd5Sriastradh yyerror(& @1, state, "invalid vertex program header"); 3103464ebd5Sriastradh } 3113464ebd5Sriastradh state->mode = ARB_fragment; 3123464ebd5Sriastradh 3133464ebd5Sriastradh state->option.TexRect = 3143464ebd5Sriastradh (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE); 3153464ebd5Sriastradh } 3163464ebd5Sriastradh ; 3173464ebd5Sriastradh 3183464ebd5SriastradhoptionSequence: optionSequence option 3193464ebd5Sriastradh | 3203464ebd5Sriastradh ; 3213464ebd5Sriastradh 3223464ebd5Sriastradhoption: OPTION string ';' 3233464ebd5Sriastradh { 3243464ebd5Sriastradh int valid = 0; 3253464ebd5Sriastradh 3263464ebd5Sriastradh if (state->mode == ARB_vertex) { 3273464ebd5Sriastradh valid = _mesa_ARBvp_parse_option(state, $2); 3283464ebd5Sriastradh } else if (state->mode == ARB_fragment) { 3293464ebd5Sriastradh valid = _mesa_ARBfp_parse_option(state, $2); 3303464ebd5Sriastradh } 3313464ebd5Sriastradh 3323464ebd5Sriastradh 3333464ebd5Sriastradh free($2); 3343464ebd5Sriastradh 3353464ebd5Sriastradh if (!valid) { 3363464ebd5Sriastradh const char *const err_str = (state->mode == ARB_vertex) 3373464ebd5Sriastradh ? "invalid ARB vertex program option" 3383464ebd5Sriastradh : "invalid ARB fragment program option"; 3393464ebd5Sriastradh 3403464ebd5Sriastradh yyerror(& @2, state, err_str); 3413464ebd5Sriastradh YYERROR; 3423464ebd5Sriastradh } 3433464ebd5Sriastradh } 3443464ebd5Sriastradh ; 3453464ebd5Sriastradh 3463464ebd5SriastradhstatementSequence: statementSequence statement 3473464ebd5Sriastradh | 3483464ebd5Sriastradh ; 3493464ebd5Sriastradh 3503464ebd5Sriastradhstatement: instruction ';' 3513464ebd5Sriastradh { 3523464ebd5Sriastradh if ($1 != NULL) { 3533464ebd5Sriastradh if (state->inst_tail == NULL) { 3543464ebd5Sriastradh state->inst_head = $1; 3553464ebd5Sriastradh } else { 3563464ebd5Sriastradh state->inst_tail->next = $1; 3573464ebd5Sriastradh } 3583464ebd5Sriastradh 3593464ebd5Sriastradh state->inst_tail = $1; 3603464ebd5Sriastradh $1->next = NULL; 3613464ebd5Sriastradh 36201e04c3fSmrg state->prog->arb.NumInstructions++; 3633464ebd5Sriastradh } 3643464ebd5Sriastradh } 3653464ebd5Sriastradh | namingStatement ';' 3663464ebd5Sriastradh ; 3673464ebd5Sriastradh 3683464ebd5Sriastradhinstruction: ALU_instruction 3693464ebd5Sriastradh { 3703464ebd5Sriastradh $$ = $1; 37101e04c3fSmrg state->prog->arb.NumAluInstructions++; 3723464ebd5Sriastradh } 3733464ebd5Sriastradh | TexInstruction 3743464ebd5Sriastradh { 3753464ebd5Sriastradh $$ = $1; 37601e04c3fSmrg state->prog->arb.NumTexInstructions++; 3773464ebd5Sriastradh } 3783464ebd5Sriastradh ; 3793464ebd5Sriastradh 3803464ebd5SriastradhALU_instruction: ARL_instruction 3813464ebd5Sriastradh | VECTORop_instruction 3823464ebd5Sriastradh | SCALARop_instruction 3833464ebd5Sriastradh | BINSCop_instruction 3843464ebd5Sriastradh | BINop_instruction 3853464ebd5Sriastradh | TRIop_instruction 3863464ebd5Sriastradh | SWZ_instruction 3873464ebd5Sriastradh ; 3883464ebd5Sriastradh 3893464ebd5SriastradhTexInstruction: SAMPLE_instruction 3903464ebd5Sriastradh | KIL_instruction 3913464ebd5Sriastradh | TXD_instruction 3923464ebd5Sriastradh ; 3933464ebd5Sriastradh 3943464ebd5SriastradhARL_instruction: ARL maskedAddrReg ',' scalarSrcReg 3953464ebd5Sriastradh { 3963464ebd5Sriastradh $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL); 3973464ebd5Sriastradh } 3983464ebd5Sriastradh ; 3993464ebd5Sriastradh 4003464ebd5SriastradhVECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg 4013464ebd5Sriastradh { 4023464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 4033464ebd5Sriastradh } 4043464ebd5Sriastradh ; 4053464ebd5Sriastradh 4063464ebd5SriastradhSCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg 4073464ebd5Sriastradh { 4083464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 4093464ebd5Sriastradh } 4103464ebd5Sriastradh ; 4113464ebd5Sriastradh 4123464ebd5SriastradhBINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg 4133464ebd5Sriastradh { 4143464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL); 4153464ebd5Sriastradh } 4163464ebd5Sriastradh ; 4173464ebd5Sriastradh 4183464ebd5Sriastradh 4193464ebd5SriastradhBINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg 4203464ebd5Sriastradh { 4213464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL); 4223464ebd5Sriastradh } 4233464ebd5Sriastradh ; 4243464ebd5Sriastradh 4253464ebd5SriastradhTRIop_instruction: TRI_OP maskedDstReg ',' 4263464ebd5Sriastradh swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg 4273464ebd5Sriastradh { 4283464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8); 4293464ebd5Sriastradh } 4303464ebd5Sriastradh ; 4313464ebd5Sriastradh 4323464ebd5SriastradhSAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget 4333464ebd5Sriastradh { 4343464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 4353464ebd5Sriastradh if ($$ != NULL) { 4363464ebd5Sriastradh const GLbitfield tex_mask = (1U << $6); 4373464ebd5Sriastradh GLbitfield shadow_tex = 0; 4383464ebd5Sriastradh GLbitfield target_mask = 0; 4393464ebd5Sriastradh 4403464ebd5Sriastradh 4413464ebd5Sriastradh $$->Base.TexSrcUnit = $6; 4423464ebd5Sriastradh 4433464ebd5Sriastradh if ($8 < 0) { 4443464ebd5Sriastradh shadow_tex = tex_mask; 4453464ebd5Sriastradh 4463464ebd5Sriastradh $$->Base.TexSrcTarget = -$8; 4473464ebd5Sriastradh $$->Base.TexShadow = 1; 4483464ebd5Sriastradh } else { 4493464ebd5Sriastradh $$->Base.TexSrcTarget = $8; 4503464ebd5Sriastradh } 4513464ebd5Sriastradh 4523464ebd5Sriastradh target_mask = (1U << $$->Base.TexSrcTarget); 4533464ebd5Sriastradh 4543464ebd5Sriastradh /* If this texture unit was previously accessed and that access 4553464ebd5Sriastradh * had a different texture target, generate an error. 4563464ebd5Sriastradh * 4573464ebd5Sriastradh * If this texture unit was previously accessed and that access 4583464ebd5Sriastradh * had a different shadow mode, generate an error. 4593464ebd5Sriastradh */ 4603464ebd5Sriastradh if ((state->prog->TexturesUsed[$6] != 0) 4613464ebd5Sriastradh && ((state->prog->TexturesUsed[$6] != target_mask) 4623464ebd5Sriastradh || ((state->prog->ShadowSamplers & tex_mask) 4633464ebd5Sriastradh != shadow_tex))) { 4643464ebd5Sriastradh yyerror(& @8, state, 4653464ebd5Sriastradh "multiple targets used on one texture image unit"); 4663464ebd5Sriastradh YYERROR; 4673464ebd5Sriastradh } 4683464ebd5Sriastradh 4693464ebd5Sriastradh 4703464ebd5Sriastradh state->prog->TexturesUsed[$6] |= target_mask; 4713464ebd5Sriastradh state->prog->ShadowSamplers |= shadow_tex; 4723464ebd5Sriastradh } 4733464ebd5Sriastradh } 4743464ebd5Sriastradh ; 4753464ebd5Sriastradh 4763464ebd5SriastradhKIL_instruction: KIL swizzleSrcReg 4773464ebd5Sriastradh { 4783464ebd5Sriastradh $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL); 4793464ebd5Sriastradh state->fragment.UsesKill = 1; 4803464ebd5Sriastradh } 4813464ebd5Sriastradh ; 4823464ebd5Sriastradh 4833464ebd5SriastradhTXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget 4843464ebd5Sriastradh { 4853464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8); 4863464ebd5Sriastradh if ($$ != NULL) { 4873464ebd5Sriastradh const GLbitfield tex_mask = (1U << $10); 4883464ebd5Sriastradh GLbitfield shadow_tex = 0; 4893464ebd5Sriastradh GLbitfield target_mask = 0; 4903464ebd5Sriastradh 4913464ebd5Sriastradh 4923464ebd5Sriastradh $$->Base.TexSrcUnit = $10; 4933464ebd5Sriastradh 4943464ebd5Sriastradh if ($12 < 0) { 4953464ebd5Sriastradh shadow_tex = tex_mask; 4963464ebd5Sriastradh 4973464ebd5Sriastradh $$->Base.TexSrcTarget = -$12; 4983464ebd5Sriastradh $$->Base.TexShadow = 1; 4993464ebd5Sriastradh } else { 5003464ebd5Sriastradh $$->Base.TexSrcTarget = $12; 5013464ebd5Sriastradh } 5023464ebd5Sriastradh 5033464ebd5Sriastradh target_mask = (1U << $$->Base.TexSrcTarget); 5043464ebd5Sriastradh 5053464ebd5Sriastradh /* If this texture unit was previously accessed and that access 5063464ebd5Sriastradh * had a different texture target, generate an error. 5073464ebd5Sriastradh * 5083464ebd5Sriastradh * If this texture unit was previously accessed and that access 5093464ebd5Sriastradh * had a different shadow mode, generate an error. 5103464ebd5Sriastradh */ 5113464ebd5Sriastradh if ((state->prog->TexturesUsed[$10] != 0) 5123464ebd5Sriastradh && ((state->prog->TexturesUsed[$10] != target_mask) 5133464ebd5Sriastradh || ((state->prog->ShadowSamplers & tex_mask) 5143464ebd5Sriastradh != shadow_tex))) { 5153464ebd5Sriastradh yyerror(& @12, state, 5163464ebd5Sriastradh "multiple targets used on one texture image unit"); 5173464ebd5Sriastradh YYERROR; 5183464ebd5Sriastradh } 5193464ebd5Sriastradh 5203464ebd5Sriastradh 5213464ebd5Sriastradh state->prog->TexturesUsed[$10] |= target_mask; 5223464ebd5Sriastradh state->prog->ShadowSamplers |= shadow_tex; 5233464ebd5Sriastradh } 5243464ebd5Sriastradh } 5253464ebd5Sriastradh ; 5263464ebd5Sriastradh 5273464ebd5SriastradhtexImageUnit: TEXTURE_UNIT optTexImageUnitNum 5283464ebd5Sriastradh { 5293464ebd5Sriastradh $$ = $2; 5303464ebd5Sriastradh } 5313464ebd5Sriastradh ; 5323464ebd5Sriastradh 5333464ebd5SriastradhtexTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; } 5343464ebd5Sriastradh | TEX_2D { $$ = TEXTURE_2D_INDEX; } 5353464ebd5Sriastradh | TEX_3D { $$ = TEXTURE_3D_INDEX; } 5363464ebd5Sriastradh | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; } 5373464ebd5Sriastradh | TEX_RECT { $$ = TEXTURE_RECT_INDEX; } 5383464ebd5Sriastradh | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; } 5393464ebd5Sriastradh | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; } 5403464ebd5Sriastradh | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; } 5413464ebd5Sriastradh | TEX_ARRAY1D { $$ = TEXTURE_1D_ARRAY_INDEX; } 5423464ebd5Sriastradh | TEX_ARRAY2D { $$ = TEXTURE_2D_ARRAY_INDEX; } 5433464ebd5Sriastradh | TEX_ARRAYSHADOW1D { $$ = -TEXTURE_1D_ARRAY_INDEX; } 5443464ebd5Sriastradh | TEX_ARRAYSHADOW2D { $$ = -TEXTURE_2D_ARRAY_INDEX; } 5453464ebd5Sriastradh ; 5463464ebd5Sriastradh 5473464ebd5SriastradhSWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle 5483464ebd5Sriastradh { 5493464ebd5Sriastradh /* FIXME: Is this correct? Should the extenedSwizzle be applied 5503464ebd5Sriastradh * FIXME: to the existing swizzle? 5513464ebd5Sriastradh */ 5523464ebd5Sriastradh $4.Base.Swizzle = $6.swizzle; 5533464ebd5Sriastradh $4.Base.Negate = $6.mask; 5543464ebd5Sriastradh 5553464ebd5Sriastradh $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); 5563464ebd5Sriastradh } 5573464ebd5Sriastradh ; 5583464ebd5Sriastradh 5593464ebd5SriastradhscalarSrcReg: optionalSign scalarUse 5603464ebd5Sriastradh { 5613464ebd5Sriastradh $$ = $2; 5623464ebd5Sriastradh 5633464ebd5Sriastradh if ($1) { 5643464ebd5Sriastradh $$.Base.Negate = ~$$.Base.Negate; 5653464ebd5Sriastradh } 5663464ebd5Sriastradh } 5673464ebd5Sriastradh ; 5683464ebd5Sriastradh 5693464ebd5SriastradhscalarUse: srcReg scalarSuffix 5703464ebd5Sriastradh { 5713464ebd5Sriastradh $$ = $1; 5723464ebd5Sriastradh 5733464ebd5Sriastradh $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, 5743464ebd5Sriastradh $2.swizzle); 5753464ebd5Sriastradh } 5763464ebd5Sriastradh ; 5773464ebd5Sriastradh 5783464ebd5SriastradhswizzleSrcReg: optionalSign srcReg swizzleSuffix 5793464ebd5Sriastradh { 5803464ebd5Sriastradh $$ = $2; 5813464ebd5Sriastradh 5823464ebd5Sriastradh if ($1) { 5833464ebd5Sriastradh $$.Base.Negate = ~$$.Base.Negate; 5843464ebd5Sriastradh } 5853464ebd5Sriastradh 5863464ebd5Sriastradh $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, 5873464ebd5Sriastradh $3.swizzle); 5883464ebd5Sriastradh } 5893464ebd5Sriastradh ; 5903464ebd5Sriastradh 59101e04c3fSmrgmaskedDstReg: dstReg optionalMask 5923464ebd5Sriastradh { 5933464ebd5Sriastradh $$ = $1; 5943464ebd5Sriastradh $$.WriteMask = $2.mask; 5953464ebd5Sriastradh 5963464ebd5Sriastradh if ($$.File == PROGRAM_OUTPUT) { 5973464ebd5Sriastradh /* Technically speaking, this should check that it is in 5983464ebd5Sriastradh * vertex program mode. However, PositionInvariant can never be 5993464ebd5Sriastradh * set in fragment program mode, so it is somewhat irrelevant. 6003464ebd5Sriastradh */ 6013464ebd5Sriastradh if (state->option.PositionInvariant 602af69d88dSmrg && ($$.Index == VARYING_SLOT_POS)) { 6033464ebd5Sriastradh yyerror(& @1, state, "position-invariant programs cannot " 6043464ebd5Sriastradh "write position"); 6053464ebd5Sriastradh YYERROR; 6063464ebd5Sriastradh } 6073464ebd5Sriastradh 60801e04c3fSmrg state->prog->info.outputs_written |= BITFIELD64_BIT($$.Index); 6093464ebd5Sriastradh } 6103464ebd5Sriastradh } 6113464ebd5Sriastradh ; 6123464ebd5Sriastradh 6133464ebd5SriastradhmaskedAddrReg: addrReg addrWriteMask 6143464ebd5Sriastradh { 6153464ebd5Sriastradh set_dst_reg(& $$, PROGRAM_ADDRESS, 0); 6163464ebd5Sriastradh $$.WriteMask = $2.mask; 6173464ebd5Sriastradh } 6183464ebd5Sriastradh ; 6193464ebd5Sriastradh 6203464ebd5SriastradhextendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp 6213464ebd5Sriastradh { 6223464ebd5Sriastradh const unsigned xyzw_valid = 6233464ebd5Sriastradh ($1.xyzw_valid << 0) 6243464ebd5Sriastradh | ($3.xyzw_valid << 1) 6253464ebd5Sriastradh | ($5.xyzw_valid << 2) 6263464ebd5Sriastradh | ($7.xyzw_valid << 3); 6273464ebd5Sriastradh const unsigned rgba_valid = 6283464ebd5Sriastradh ($1.rgba_valid << 0) 6293464ebd5Sriastradh | ($3.rgba_valid << 1) 6303464ebd5Sriastradh | ($5.rgba_valid << 2) 6313464ebd5Sriastradh | ($7.rgba_valid << 3); 6323464ebd5Sriastradh 6333464ebd5Sriastradh /* All of the swizzle components have to be valid in either RGBA 6343464ebd5Sriastradh * or XYZW. Note that 0 and 1 are valid in both, so both masks 6353464ebd5Sriastradh * can have some bits set. 6363464ebd5Sriastradh * 6373464ebd5Sriastradh * We somewhat deviate from the spec here. It would be really hard 6383464ebd5Sriastradh * to figure out which component is the error, and there probably 6393464ebd5Sriastradh * isn't a lot of benefit. 6403464ebd5Sriastradh */ 6413464ebd5Sriastradh if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) { 6423464ebd5Sriastradh yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle " 6433464ebd5Sriastradh "components"); 6443464ebd5Sriastradh YYERROR; 6453464ebd5Sriastradh } 6463464ebd5Sriastradh 6473464ebd5Sriastradh $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz); 6483464ebd5Sriastradh $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2) 6493464ebd5Sriastradh | ($7.negate << 3); 6503464ebd5Sriastradh } 6513464ebd5Sriastradh ; 6523464ebd5Sriastradh 6533464ebd5SriastradhextSwizComp: optionalSign extSwizSel 6543464ebd5Sriastradh { 6553464ebd5Sriastradh $$ = $2; 6563464ebd5Sriastradh $$.negate = ($1) ? 1 : 0; 6573464ebd5Sriastradh } 6583464ebd5Sriastradh ; 6593464ebd5Sriastradh 6603464ebd5SriastradhextSwizSel: INTEGER 6613464ebd5Sriastradh { 6623464ebd5Sriastradh if (($1 != 0) && ($1 != 1)) { 6633464ebd5Sriastradh yyerror(& @1, state, "invalid extended swizzle selector"); 6643464ebd5Sriastradh YYERROR; 6653464ebd5Sriastradh } 6663464ebd5Sriastradh 6673464ebd5Sriastradh $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE; 668af69d88dSmrg $$.negate = 0; 6693464ebd5Sriastradh 6703464ebd5Sriastradh /* 0 and 1 are valid for both RGBA swizzle names and XYZW 6713464ebd5Sriastradh * swizzle names. 6723464ebd5Sriastradh */ 6733464ebd5Sriastradh $$.xyzw_valid = 1; 6743464ebd5Sriastradh $$.rgba_valid = 1; 6753464ebd5Sriastradh } 6763464ebd5Sriastradh | string 6773464ebd5Sriastradh { 6783464ebd5Sriastradh char s; 6793464ebd5Sriastradh 6803464ebd5Sriastradh if (strlen($1) > 1) { 6813464ebd5Sriastradh yyerror(& @1, state, "invalid extended swizzle selector"); 6823464ebd5Sriastradh YYERROR; 6833464ebd5Sriastradh } 6843464ebd5Sriastradh 6853464ebd5Sriastradh s = $1[0]; 6863464ebd5Sriastradh free($1); 6873464ebd5Sriastradh 688af69d88dSmrg $$.rgba_valid = 0; 689af69d88dSmrg $$.xyzw_valid = 0; 690af69d88dSmrg $$.negate = 0; 691af69d88dSmrg 6923464ebd5Sriastradh switch (s) { 6933464ebd5Sriastradh case 'x': 6943464ebd5Sriastradh $$.swz = SWIZZLE_X; 6953464ebd5Sriastradh $$.xyzw_valid = 1; 6963464ebd5Sriastradh break; 6973464ebd5Sriastradh case 'y': 6983464ebd5Sriastradh $$.swz = SWIZZLE_Y; 6993464ebd5Sriastradh $$.xyzw_valid = 1; 7003464ebd5Sriastradh break; 7013464ebd5Sriastradh case 'z': 7023464ebd5Sriastradh $$.swz = SWIZZLE_Z; 7033464ebd5Sriastradh $$.xyzw_valid = 1; 7043464ebd5Sriastradh break; 7053464ebd5Sriastradh case 'w': 7063464ebd5Sriastradh $$.swz = SWIZZLE_W; 7073464ebd5Sriastradh $$.xyzw_valid = 1; 7083464ebd5Sriastradh break; 7093464ebd5Sriastradh 7103464ebd5Sriastradh case 'r': 7113464ebd5Sriastradh $$.swz = SWIZZLE_X; 7123464ebd5Sriastradh $$.rgba_valid = 1; 7133464ebd5Sriastradh break; 7143464ebd5Sriastradh case 'g': 7153464ebd5Sriastradh $$.swz = SWIZZLE_Y; 7163464ebd5Sriastradh $$.rgba_valid = 1; 7173464ebd5Sriastradh break; 7183464ebd5Sriastradh case 'b': 7193464ebd5Sriastradh $$.swz = SWIZZLE_Z; 7203464ebd5Sriastradh $$.rgba_valid = 1; 7213464ebd5Sriastradh break; 7223464ebd5Sriastradh case 'a': 7233464ebd5Sriastradh $$.swz = SWIZZLE_W; 7243464ebd5Sriastradh $$.rgba_valid = 1; 7253464ebd5Sriastradh break; 7263464ebd5Sriastradh 7273464ebd5Sriastradh default: 7283464ebd5Sriastradh yyerror(& @1, state, "invalid extended swizzle selector"); 7293464ebd5Sriastradh YYERROR; 7303464ebd5Sriastradh break; 7313464ebd5Sriastradh } 7323464ebd5Sriastradh } 7333464ebd5Sriastradh ; 7343464ebd5Sriastradh 7353464ebd5SriastradhsrcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ 7363464ebd5Sriastradh { 7373464ebd5Sriastradh struct asm_symbol *const s = (struct asm_symbol *) 73801e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, $1); 7393464ebd5Sriastradh 7403464ebd5Sriastradh free($1); 7413464ebd5Sriastradh 7423464ebd5Sriastradh if (s == NULL) { 7433464ebd5Sriastradh yyerror(& @1, state, "invalid operand variable"); 7443464ebd5Sriastradh YYERROR; 7453464ebd5Sriastradh } else if ((s->type != at_param) && (s->type != at_temp) 7463464ebd5Sriastradh && (s->type != at_attrib)) { 7473464ebd5Sriastradh yyerror(& @1, state, "invalid operand variable"); 7483464ebd5Sriastradh YYERROR; 7493464ebd5Sriastradh } else if ((s->type == at_param) && s->param_is_array) { 7503464ebd5Sriastradh yyerror(& @1, state, "non-array access to array PARAM"); 7513464ebd5Sriastradh YYERROR; 7523464ebd5Sriastradh } 7533464ebd5Sriastradh 7543464ebd5Sriastradh init_src_reg(& $$); 7553464ebd5Sriastradh switch (s->type) { 7563464ebd5Sriastradh case at_temp: 7573464ebd5Sriastradh set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); 7583464ebd5Sriastradh break; 7593464ebd5Sriastradh case at_param: 7603464ebd5Sriastradh set_src_reg_swz(& $$, s->param_binding_type, 7613464ebd5Sriastradh s->param_binding_begin, 7623464ebd5Sriastradh s->param_binding_swizzle); 7633464ebd5Sriastradh break; 7643464ebd5Sriastradh case at_attrib: 7653464ebd5Sriastradh set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding); 76601e04c3fSmrg state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index); 7673464ebd5Sriastradh 7683464ebd5Sriastradh if (!validate_inputs(& @1, state)) { 7693464ebd5Sriastradh YYERROR; 7703464ebd5Sriastradh } 7713464ebd5Sriastradh break; 7723464ebd5Sriastradh 7733464ebd5Sriastradh default: 7743464ebd5Sriastradh YYERROR; 7753464ebd5Sriastradh break; 7763464ebd5Sriastradh } 7773464ebd5Sriastradh } 7783464ebd5Sriastradh | attribBinding 7793464ebd5Sriastradh { 7803464ebd5Sriastradh set_src_reg(& $$, PROGRAM_INPUT, $1); 78101e04c3fSmrg state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index); 7823464ebd5Sriastradh 7833464ebd5Sriastradh if (!validate_inputs(& @1, state)) { 7843464ebd5Sriastradh YYERROR; 7853464ebd5Sriastradh } 7863464ebd5Sriastradh } 7873464ebd5Sriastradh | progParamArray '[' progParamArrayMem ']' 7883464ebd5Sriastradh { 7893464ebd5Sriastradh if (! $3.Base.RelAddr 7903464ebd5Sriastradh && ((unsigned) $3.Base.Index >= $1->param_binding_length)) { 7913464ebd5Sriastradh yyerror(& @3, state, "out of bounds array access"); 7923464ebd5Sriastradh YYERROR; 7933464ebd5Sriastradh } 7943464ebd5Sriastradh 7953464ebd5Sriastradh init_src_reg(& $$); 7963464ebd5Sriastradh $$.Base.File = $1->param_binding_type; 7973464ebd5Sriastradh 7983464ebd5Sriastradh if ($3.Base.RelAddr) { 79901e04c3fSmrg state->prog->arb.IndirectRegisterFiles |= (1 << $$.Base.File); 8003464ebd5Sriastradh $1->param_accessed_indirectly = 1; 8013464ebd5Sriastradh 8023464ebd5Sriastradh $$.Base.RelAddr = 1; 8033464ebd5Sriastradh $$.Base.Index = $3.Base.Index; 8043464ebd5Sriastradh $$.Symbol = $1; 8053464ebd5Sriastradh } else { 8063464ebd5Sriastradh $$.Base.Index = $1->param_binding_begin + $3.Base.Index; 8073464ebd5Sriastradh } 8083464ebd5Sriastradh } 8093464ebd5Sriastradh | paramSingleItemUse 8103464ebd5Sriastradh { 8117ec681f3Smrg gl_register_file file = ($1.name != NULL) 8123464ebd5Sriastradh ? $1.param_binding_type 8133464ebd5Sriastradh : PROGRAM_CONSTANT; 8143464ebd5Sriastradh set_src_reg_swz(& $$, file, $1.param_binding_begin, 8153464ebd5Sriastradh $1.param_binding_swizzle); 8163464ebd5Sriastradh } 8173464ebd5Sriastradh ; 8183464ebd5Sriastradh 8193464ebd5SriastradhdstReg: resultBinding 8203464ebd5Sriastradh { 8213464ebd5Sriastradh set_dst_reg(& $$, PROGRAM_OUTPUT, $1); 8223464ebd5Sriastradh } 8233464ebd5Sriastradh | USED_IDENTIFIER /* temporaryReg | vertexResultReg */ 8243464ebd5Sriastradh { 8253464ebd5Sriastradh struct asm_symbol *const s = (struct asm_symbol *) 82601e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, $1); 8273464ebd5Sriastradh 8283464ebd5Sriastradh free($1); 8293464ebd5Sriastradh 8303464ebd5Sriastradh if (s == NULL) { 8313464ebd5Sriastradh yyerror(& @1, state, "invalid operand variable"); 8323464ebd5Sriastradh YYERROR; 8333464ebd5Sriastradh } else if ((s->type != at_output) && (s->type != at_temp)) { 8343464ebd5Sriastradh yyerror(& @1, state, "invalid operand variable"); 8353464ebd5Sriastradh YYERROR; 8363464ebd5Sriastradh } 8373464ebd5Sriastradh 8383464ebd5Sriastradh switch (s->type) { 8393464ebd5Sriastradh case at_temp: 8403464ebd5Sriastradh set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); 8413464ebd5Sriastradh break; 8423464ebd5Sriastradh case at_output: 8433464ebd5Sriastradh set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding); 8443464ebd5Sriastradh break; 8453464ebd5Sriastradh default: 8463464ebd5Sriastradh set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin); 8473464ebd5Sriastradh break; 8483464ebd5Sriastradh } 8493464ebd5Sriastradh } 8503464ebd5Sriastradh ; 8513464ebd5Sriastradh 8523464ebd5SriastradhprogParamArray: USED_IDENTIFIER 8533464ebd5Sriastradh { 8543464ebd5Sriastradh struct asm_symbol *const s = (struct asm_symbol *) 85501e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, $1); 8563464ebd5Sriastradh 8573464ebd5Sriastradh free($1); 8583464ebd5Sriastradh 8593464ebd5Sriastradh if (s == NULL) { 8603464ebd5Sriastradh yyerror(& @1, state, "invalid operand variable"); 8613464ebd5Sriastradh YYERROR; 8623464ebd5Sriastradh } else if ((s->type != at_param) || !s->param_is_array) { 8633464ebd5Sriastradh yyerror(& @1, state, "array access to non-PARAM variable"); 8643464ebd5Sriastradh YYERROR; 8653464ebd5Sriastradh } else { 8663464ebd5Sriastradh $$ = s; 8673464ebd5Sriastradh } 8683464ebd5Sriastradh } 8693464ebd5Sriastradh ; 8703464ebd5Sriastradh 8713464ebd5SriastradhprogParamArrayMem: progParamArrayAbs | progParamArrayRel; 8723464ebd5Sriastradh 8733464ebd5SriastradhprogParamArrayAbs: INTEGER 8743464ebd5Sriastradh { 8753464ebd5Sriastradh init_src_reg(& $$); 8763464ebd5Sriastradh $$.Base.Index = $1; 8773464ebd5Sriastradh } 8783464ebd5Sriastradh ; 8793464ebd5Sriastradh 8803464ebd5SriastradhprogParamArrayRel: addrReg addrComponent addrRegRelOffset 8813464ebd5Sriastradh { 8823464ebd5Sriastradh /* FINISHME: Add support for multiple address registers. 8833464ebd5Sriastradh */ 8843464ebd5Sriastradh /* FINISHME: Add support for 4-component address registers. 8853464ebd5Sriastradh */ 8863464ebd5Sriastradh init_src_reg(& $$); 8873464ebd5Sriastradh $$.Base.RelAddr = 1; 8883464ebd5Sriastradh $$.Base.Index = $3; 8893464ebd5Sriastradh } 8903464ebd5Sriastradh ; 8913464ebd5Sriastradh 8923464ebd5SriastradhaddrRegRelOffset: { $$ = 0; } 8933464ebd5Sriastradh | '+' addrRegPosOffset { $$ = $2; } 8943464ebd5Sriastradh | '-' addrRegNegOffset { $$ = -$2; } 8953464ebd5Sriastradh ; 8963464ebd5Sriastradh 8973464ebd5SriastradhaddrRegPosOffset: INTEGER 8983464ebd5Sriastradh { 8993464ebd5Sriastradh if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) { 9003464ebd5Sriastradh char s[100]; 9017ec681f3Smrg snprintf(s, sizeof(s), 9023464ebd5Sriastradh "relative address offset too large (%d)", $1); 9033464ebd5Sriastradh yyerror(& @1, state, s); 9043464ebd5Sriastradh YYERROR; 9053464ebd5Sriastradh } else { 9063464ebd5Sriastradh $$ = $1; 9073464ebd5Sriastradh } 9083464ebd5Sriastradh } 9093464ebd5Sriastradh ; 9103464ebd5Sriastradh 9113464ebd5SriastradhaddrRegNegOffset: INTEGER 9123464ebd5Sriastradh { 9133464ebd5Sriastradh if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) { 9143464ebd5Sriastradh char s[100]; 9157ec681f3Smrg snprintf(s, sizeof(s), 9163464ebd5Sriastradh "relative address offset too large (%d)", $1); 9173464ebd5Sriastradh yyerror(& @1, state, s); 9183464ebd5Sriastradh YYERROR; 9193464ebd5Sriastradh } else { 9203464ebd5Sriastradh $$ = $1; 9213464ebd5Sriastradh } 9223464ebd5Sriastradh } 9233464ebd5Sriastradh ; 9243464ebd5Sriastradh 9253464ebd5SriastradhaddrReg: USED_IDENTIFIER 9263464ebd5Sriastradh { 9273464ebd5Sriastradh struct asm_symbol *const s = (struct asm_symbol *) 92801e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, $1); 9293464ebd5Sriastradh 9303464ebd5Sriastradh free($1); 9313464ebd5Sriastradh 9323464ebd5Sriastradh if (s == NULL) { 9333464ebd5Sriastradh yyerror(& @1, state, "invalid array member"); 9343464ebd5Sriastradh YYERROR; 9353464ebd5Sriastradh } else if (s->type != at_address) { 9363464ebd5Sriastradh yyerror(& @1, state, 9373464ebd5Sriastradh "invalid variable for indexed array access"); 9383464ebd5Sriastradh YYERROR; 9393464ebd5Sriastradh } else { 9403464ebd5Sriastradh $$ = s; 9413464ebd5Sriastradh } 9423464ebd5Sriastradh } 9433464ebd5Sriastradh ; 9443464ebd5Sriastradh 9453464ebd5SriastradhaddrComponent: MASK1 9463464ebd5Sriastradh { 9473464ebd5Sriastradh if ($1.mask != WRITEMASK_X) { 9483464ebd5Sriastradh yyerror(& @1, state, "invalid address component selector"); 9493464ebd5Sriastradh YYERROR; 9503464ebd5Sriastradh } else { 9513464ebd5Sriastradh $$ = $1; 9523464ebd5Sriastradh } 9533464ebd5Sriastradh } 9543464ebd5Sriastradh ; 9553464ebd5Sriastradh 9563464ebd5SriastradhaddrWriteMask: MASK1 9573464ebd5Sriastradh { 9583464ebd5Sriastradh if ($1.mask != WRITEMASK_X) { 9593464ebd5Sriastradh yyerror(& @1, state, 9603464ebd5Sriastradh "address register write mask must be \".x\""); 9613464ebd5Sriastradh YYERROR; 9623464ebd5Sriastradh } else { 9633464ebd5Sriastradh $$ = $1; 9643464ebd5Sriastradh } 9653464ebd5Sriastradh } 9663464ebd5Sriastradh ; 9673464ebd5Sriastradh 9683464ebd5SriastradhscalarSuffix: MASK1; 9693464ebd5Sriastradh 9703464ebd5SriastradhswizzleSuffix: MASK1 9713464ebd5Sriastradh | MASK4 9723464ebd5Sriastradh | SWIZZLE 9733464ebd5Sriastradh | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } 9743464ebd5Sriastradh ; 9753464ebd5Sriastradh 9767ec681f3SmrgoptionalMask: MASK4 | MASK3 | MASK2 | MASK1 9773464ebd5Sriastradh | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } 9783464ebd5Sriastradh ; 9793464ebd5Sriastradh 9803464ebd5SriastradhnamingStatement: ATTRIB_statement 9813464ebd5Sriastradh | PARAM_statement 9823464ebd5Sriastradh | TEMP_statement 9833464ebd5Sriastradh | ADDRESS_statement 9843464ebd5Sriastradh | OUTPUT_statement 9853464ebd5Sriastradh | ALIAS_statement 9863464ebd5Sriastradh ; 9873464ebd5Sriastradh 9883464ebd5SriastradhATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding 9893464ebd5Sriastradh { 9903464ebd5Sriastradh struct asm_symbol *const s = 9913464ebd5Sriastradh declare_variable(state, $2, at_attrib, & @2); 9923464ebd5Sriastradh 9933464ebd5Sriastradh if (s == NULL) { 9943464ebd5Sriastradh free($2); 9953464ebd5Sriastradh YYERROR; 9963464ebd5Sriastradh } else { 9973464ebd5Sriastradh s->attrib_binding = $4; 998af69d88dSmrg state->InputsBound |= BITFIELD64_BIT(s->attrib_binding); 9993464ebd5Sriastradh 10003464ebd5Sriastradh if (!validate_inputs(& @4, state)) { 10013464ebd5Sriastradh YYERROR; 10023464ebd5Sriastradh } 10033464ebd5Sriastradh } 10043464ebd5Sriastradh } 10053464ebd5Sriastradh ; 10063464ebd5Sriastradh 10073464ebd5SriastradhattribBinding: VERTEX vtxAttribItem 10083464ebd5Sriastradh { 10093464ebd5Sriastradh $$ = $2; 10103464ebd5Sriastradh } 10113464ebd5Sriastradh | FRAGMENT fragAttribItem 10123464ebd5Sriastradh { 10133464ebd5Sriastradh $$ = $2; 10143464ebd5Sriastradh } 10153464ebd5Sriastradh ; 10163464ebd5Sriastradh 10173464ebd5SriastradhvtxAttribItem: POSITION 10183464ebd5Sriastradh { 10193464ebd5Sriastradh $$ = VERT_ATTRIB_POS; 10203464ebd5Sriastradh } 10213464ebd5Sriastradh | NORMAL 10223464ebd5Sriastradh { 10233464ebd5Sriastradh $$ = VERT_ATTRIB_NORMAL; 10243464ebd5Sriastradh } 10253464ebd5Sriastradh | COLOR optColorType 10263464ebd5Sriastradh { 10273464ebd5Sriastradh $$ = VERT_ATTRIB_COLOR0 + $2; 10283464ebd5Sriastradh } 10293464ebd5Sriastradh | FOGCOORD 10303464ebd5Sriastradh { 10313464ebd5Sriastradh $$ = VERT_ATTRIB_FOG; 10323464ebd5Sriastradh } 10333464ebd5Sriastradh | TEXCOORD optTexCoordUnitNum 10343464ebd5Sriastradh { 10353464ebd5Sriastradh $$ = VERT_ATTRIB_TEX0 + $2; 10363464ebd5Sriastradh } 10373464ebd5Sriastradh | MATRIXINDEX '[' vtxWeightNum ']' 10383464ebd5Sriastradh { 10393464ebd5Sriastradh yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); 10403464ebd5Sriastradh YYERROR; 10413464ebd5Sriastradh } 10423464ebd5Sriastradh | VTXATTRIB '[' vtxAttribNum ']' 10433464ebd5Sriastradh { 10443464ebd5Sriastradh $$ = VERT_ATTRIB_GENERIC0 + $3; 10453464ebd5Sriastradh } 10463464ebd5Sriastradh ; 10473464ebd5Sriastradh 10483464ebd5SriastradhvtxAttribNum: INTEGER 10493464ebd5Sriastradh { 10503464ebd5Sriastradh if ((unsigned) $1 >= state->limits->MaxAttribs) { 10513464ebd5Sriastradh yyerror(& @1, state, "invalid vertex attribute reference"); 10523464ebd5Sriastradh YYERROR; 10533464ebd5Sriastradh } 10543464ebd5Sriastradh 10553464ebd5Sriastradh $$ = $1; 10563464ebd5Sriastradh } 10573464ebd5Sriastradh ; 10583464ebd5Sriastradh 10593464ebd5SriastradhvtxWeightNum: INTEGER; 10603464ebd5Sriastradh 10613464ebd5SriastradhfragAttribItem: POSITION 10623464ebd5Sriastradh { 1063af69d88dSmrg $$ = VARYING_SLOT_POS; 10643464ebd5Sriastradh } 10653464ebd5Sriastradh | COLOR optColorType 10663464ebd5Sriastradh { 1067af69d88dSmrg $$ = VARYING_SLOT_COL0 + $2; 10683464ebd5Sriastradh } 10693464ebd5Sriastradh | FOGCOORD 10703464ebd5Sriastradh { 1071af69d88dSmrg $$ = VARYING_SLOT_FOGC; 10723464ebd5Sriastradh } 10733464ebd5Sriastradh | TEXCOORD optTexCoordUnitNum 10743464ebd5Sriastradh { 1075af69d88dSmrg $$ = VARYING_SLOT_TEX0 + $2; 10763464ebd5Sriastradh } 10773464ebd5Sriastradh ; 10783464ebd5Sriastradh 10793464ebd5SriastradhPARAM_statement: PARAM_singleStmt | PARAM_multipleStmt; 10803464ebd5Sriastradh 10813464ebd5SriastradhPARAM_singleStmt: PARAM IDENTIFIER paramSingleInit 10823464ebd5Sriastradh { 10833464ebd5Sriastradh struct asm_symbol *const s = 10843464ebd5Sriastradh declare_variable(state, $2, at_param, & @2); 10853464ebd5Sriastradh 10863464ebd5Sriastradh if (s == NULL) { 10873464ebd5Sriastradh free($2); 10883464ebd5Sriastradh YYERROR; 10893464ebd5Sriastradh } else { 10903464ebd5Sriastradh s->param_binding_type = $3.param_binding_type; 10913464ebd5Sriastradh s->param_binding_begin = $3.param_binding_begin; 10923464ebd5Sriastradh s->param_binding_length = $3.param_binding_length; 10933464ebd5Sriastradh s->param_binding_swizzle = $3.param_binding_swizzle; 10943464ebd5Sriastradh s->param_is_array = 0; 10953464ebd5Sriastradh } 10963464ebd5Sriastradh } 10973464ebd5Sriastradh ; 10983464ebd5Sriastradh 10993464ebd5SriastradhPARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit 11003464ebd5Sriastradh { 11013464ebd5Sriastradh if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) { 11023464ebd5Sriastradh free($2); 11037ec681f3Smrg yyerror(& @4, state, 11043464ebd5Sriastradh "parameter array size and number of bindings must match"); 11053464ebd5Sriastradh YYERROR; 11063464ebd5Sriastradh } else { 11073464ebd5Sriastradh struct asm_symbol *const s = 11083464ebd5Sriastradh declare_variable(state, $2, $6.type, & @2); 11093464ebd5Sriastradh 11103464ebd5Sriastradh if (s == NULL) { 11113464ebd5Sriastradh free($2); 11123464ebd5Sriastradh YYERROR; 11133464ebd5Sriastradh } else { 11143464ebd5Sriastradh s->param_binding_type = $6.param_binding_type; 11153464ebd5Sriastradh s->param_binding_begin = $6.param_binding_begin; 11163464ebd5Sriastradh s->param_binding_length = $6.param_binding_length; 11173464ebd5Sriastradh s->param_binding_swizzle = SWIZZLE_XYZW; 11183464ebd5Sriastradh s->param_is_array = 1; 11193464ebd5Sriastradh } 11203464ebd5Sriastradh } 11213464ebd5Sriastradh } 11223464ebd5Sriastradh ; 11233464ebd5Sriastradh 11243464ebd5SriastradhoptArraySize: 11253464ebd5Sriastradh { 11263464ebd5Sriastradh $$ = 0; 11273464ebd5Sriastradh } 11283464ebd5Sriastradh | INTEGER 11293464ebd5Sriastradh { 11303464ebd5Sriastradh if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) { 11313464ebd5Sriastradh char msg[100]; 11327ec681f3Smrg snprintf(msg, sizeof(msg), 11333464ebd5Sriastradh "invalid parameter array size (size=%d max=%u)", 11343464ebd5Sriastradh $1, state->limits->MaxParameters); 11353464ebd5Sriastradh yyerror(& @1, state, msg); 11363464ebd5Sriastradh YYERROR; 11373464ebd5Sriastradh } else { 11383464ebd5Sriastradh $$ = $1; 11393464ebd5Sriastradh } 11403464ebd5Sriastradh } 11413464ebd5Sriastradh ; 11423464ebd5Sriastradh 11433464ebd5SriastradhparamSingleInit: '=' paramSingleItemDecl 11443464ebd5Sriastradh { 11453464ebd5Sriastradh $$ = $2; 11463464ebd5Sriastradh } 11473464ebd5Sriastradh ; 11483464ebd5Sriastradh 11493464ebd5SriastradhparamMultipleInit: '=' '{' paramMultInitList '}' 11503464ebd5Sriastradh { 11513464ebd5Sriastradh $$ = $3; 11523464ebd5Sriastradh } 11533464ebd5Sriastradh ; 11543464ebd5Sriastradh 11553464ebd5SriastradhparamMultInitList: paramMultipleItem 11563464ebd5Sriastradh | paramMultInitList ',' paramMultipleItem 11573464ebd5Sriastradh { 11583464ebd5Sriastradh $1.param_binding_length += $3.param_binding_length; 11593464ebd5Sriastradh $$ = $1; 11603464ebd5Sriastradh } 11613464ebd5Sriastradh ; 11623464ebd5Sriastradh 11633464ebd5SriastradhparamSingleItemDecl: stateSingleItem 11643464ebd5Sriastradh { 11653464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 11663464ebd5Sriastradh $$.param_binding_begin = ~0; 11673464ebd5Sriastradh initialize_symbol_from_state(state->prog, & $$, $1); 11683464ebd5Sriastradh } 11693464ebd5Sriastradh | programSingleItem 11703464ebd5Sriastradh { 11713464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 11723464ebd5Sriastradh $$.param_binding_begin = ~0; 11733464ebd5Sriastradh initialize_symbol_from_param(state->prog, & $$, $1); 11743464ebd5Sriastradh } 11753464ebd5Sriastradh | paramConstDecl 11763464ebd5Sriastradh { 11773464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 11783464ebd5Sriastradh $$.param_binding_begin = ~0; 11793464ebd5Sriastradh initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); 11803464ebd5Sriastradh } 11813464ebd5Sriastradh ; 11823464ebd5Sriastradh 11833464ebd5SriastradhparamSingleItemUse: stateSingleItem 11843464ebd5Sriastradh { 11853464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 11863464ebd5Sriastradh $$.param_binding_begin = ~0; 11873464ebd5Sriastradh initialize_symbol_from_state(state->prog, & $$, $1); 11883464ebd5Sriastradh } 11893464ebd5Sriastradh | programSingleItem 11903464ebd5Sriastradh { 11913464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 11923464ebd5Sriastradh $$.param_binding_begin = ~0; 11933464ebd5Sriastradh initialize_symbol_from_param(state->prog, & $$, $1); 11943464ebd5Sriastradh } 11953464ebd5Sriastradh | paramConstUse 11963464ebd5Sriastradh { 11973464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 11983464ebd5Sriastradh $$.param_binding_begin = ~0; 11993464ebd5Sriastradh initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); 12003464ebd5Sriastradh } 12013464ebd5Sriastradh ; 12023464ebd5Sriastradh 12033464ebd5SriastradhparamMultipleItem: stateMultipleItem 12043464ebd5Sriastradh { 12053464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 12063464ebd5Sriastradh $$.param_binding_begin = ~0; 12073464ebd5Sriastradh initialize_symbol_from_state(state->prog, & $$, $1); 12083464ebd5Sriastradh } 12093464ebd5Sriastradh | programMultipleItem 12103464ebd5Sriastradh { 12113464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 12123464ebd5Sriastradh $$.param_binding_begin = ~0; 12133464ebd5Sriastradh initialize_symbol_from_param(state->prog, & $$, $1); 12143464ebd5Sriastradh } 12153464ebd5Sriastradh | paramConstDecl 12163464ebd5Sriastradh { 12173464ebd5Sriastradh memset(& $$, 0, sizeof($$)); 12183464ebd5Sriastradh $$.param_binding_begin = ~0; 12193464ebd5Sriastradh initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE); 12203464ebd5Sriastradh } 12213464ebd5Sriastradh ; 12223464ebd5Sriastradh 12233464ebd5SriastradhstateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); } 12243464ebd5Sriastradh | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); } 12253464ebd5Sriastradh ; 12263464ebd5Sriastradh 12273464ebd5SriastradhstateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); } 12283464ebd5Sriastradh | STATE stateLightItem { memcpy($$, $2, sizeof($$)); } 12293464ebd5Sriastradh | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); } 12303464ebd5Sriastradh | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); } 12313464ebd5Sriastradh | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); } 12323464ebd5Sriastradh | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); } 12333464ebd5Sriastradh | STATE stateFogItem { memcpy($$, $2, sizeof($$)); } 12343464ebd5Sriastradh | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); } 12353464ebd5Sriastradh | STATE statePointItem { memcpy($$, $2, sizeof($$)); } 12363464ebd5Sriastradh | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); } 12373464ebd5Sriastradh | STATE stateDepthItem { memcpy($$, $2, sizeof($$)); } 12383464ebd5Sriastradh ; 12393464ebd5Sriastradh 12403464ebd5SriastradhstateMaterialItem: MATERIAL optFaceType stateMatProperty 12413464ebd5Sriastradh { 12423464ebd5Sriastradh memset($$, 0, sizeof($$)); 12433464ebd5Sriastradh $$[0] = STATE_MATERIAL; 12447ec681f3Smrg $$[1] = $3 + $2; 12457ec681f3Smrg $$[2] = 0; 12463464ebd5Sriastradh } 12473464ebd5Sriastradh ; 12483464ebd5Sriastradh 12497ec681f3SmrgstateMatProperty: ambDiffSpecPropertyMaterial 12503464ebd5Sriastradh { 12513464ebd5Sriastradh $$ = $1; 12523464ebd5Sriastradh } 12533464ebd5Sriastradh | EMISSION 12543464ebd5Sriastradh { 12557ec681f3Smrg $$ = MAT_ATTRIB_FRONT_EMISSION; 12563464ebd5Sriastradh } 12573464ebd5Sriastradh | SHININESS 12583464ebd5Sriastradh { 12597ec681f3Smrg $$ = MAT_ATTRIB_FRONT_SHININESS; 12603464ebd5Sriastradh } 12613464ebd5Sriastradh ; 12623464ebd5Sriastradh 12633464ebd5SriastradhstateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty 12643464ebd5Sriastradh { 12653464ebd5Sriastradh memset($$, 0, sizeof($$)); 12663464ebd5Sriastradh $$[0] = STATE_LIGHT; 12673464ebd5Sriastradh $$[1] = $3; 12683464ebd5Sriastradh $$[2] = $5; 12693464ebd5Sriastradh } 12703464ebd5Sriastradh ; 12713464ebd5Sriastradh 12727ec681f3SmrgstateLightProperty: ambDiffSpecPropertyLight 12733464ebd5Sriastradh { 12743464ebd5Sriastradh $$ = $1; 12753464ebd5Sriastradh } 12763464ebd5Sriastradh | POSITION 12773464ebd5Sriastradh { 12783464ebd5Sriastradh $$ = STATE_POSITION; 12793464ebd5Sriastradh } 12803464ebd5Sriastradh | ATTENUATION 12813464ebd5Sriastradh { 12823464ebd5Sriastradh if (!state->ctx->Extensions.EXT_point_parameters) { 12833464ebd5Sriastradh yyerror(& @1, state, "GL_ARB_point_parameters not supported"); 12843464ebd5Sriastradh YYERROR; 12853464ebd5Sriastradh } 12863464ebd5Sriastradh 12873464ebd5Sriastradh $$ = STATE_ATTENUATION; 12883464ebd5Sriastradh } 12893464ebd5Sriastradh | SPOT stateSpotProperty 12903464ebd5Sriastradh { 12913464ebd5Sriastradh $$ = $2; 12923464ebd5Sriastradh } 12933464ebd5Sriastradh | HALF 12943464ebd5Sriastradh { 12953464ebd5Sriastradh $$ = STATE_HALF_VECTOR; 12963464ebd5Sriastradh } 12973464ebd5Sriastradh ; 12983464ebd5Sriastradh 12993464ebd5SriastradhstateSpotProperty: DIRECTION 13003464ebd5Sriastradh { 13013464ebd5Sriastradh $$ = STATE_SPOT_DIRECTION; 13023464ebd5Sriastradh } 13033464ebd5Sriastradh ; 13043464ebd5Sriastradh 13053464ebd5SriastradhstateLightModelItem: LIGHTMODEL stateLModProperty 13063464ebd5Sriastradh { 13073464ebd5Sriastradh $$[0] = $2[0]; 13083464ebd5Sriastradh $$[1] = $2[1]; 13093464ebd5Sriastradh } 13103464ebd5Sriastradh ; 13113464ebd5Sriastradh 13123464ebd5SriastradhstateLModProperty: AMBIENT 13133464ebd5Sriastradh { 13143464ebd5Sriastradh memset($$, 0, sizeof($$)); 13153464ebd5Sriastradh $$[0] = STATE_LIGHTMODEL_AMBIENT; 13163464ebd5Sriastradh } 13173464ebd5Sriastradh | optFaceType SCENECOLOR 13183464ebd5Sriastradh { 13193464ebd5Sriastradh memset($$, 0, sizeof($$)); 13203464ebd5Sriastradh $$[0] = STATE_LIGHTMODEL_SCENECOLOR; 13213464ebd5Sriastradh $$[1] = $1; 13223464ebd5Sriastradh } 13233464ebd5Sriastradh ; 13243464ebd5Sriastradh 13253464ebd5SriastradhstateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty 13263464ebd5Sriastradh { 13273464ebd5Sriastradh memset($$, 0, sizeof($$)); 13283464ebd5Sriastradh $$[0] = STATE_LIGHTPROD; 13293464ebd5Sriastradh $$[1] = $3; 13307ec681f3Smrg $$[2] = $6 + $5; 13317ec681f3Smrg $$[3] = 0; 13323464ebd5Sriastradh } 13333464ebd5Sriastradh ; 13343464ebd5Sriastradh 13357ec681f3SmrgstateLProdProperty: ambDiffSpecPropertyMaterial; 13363464ebd5Sriastradh 13373464ebd5SriastradhstateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty 13383464ebd5Sriastradh { 13393464ebd5Sriastradh memset($$, 0, sizeof($$)); 13403464ebd5Sriastradh $$[0] = $3; 13413464ebd5Sriastradh $$[1] = $2; 13423464ebd5Sriastradh } 13433464ebd5Sriastradh ; 13443464ebd5Sriastradh 13453464ebd5SriastradhstateTexEnvProperty: COLOR 13463464ebd5Sriastradh { 13473464ebd5Sriastradh $$ = STATE_TEXENV_COLOR; 13483464ebd5Sriastradh } 13493464ebd5Sriastradh ; 13503464ebd5Sriastradh 13517ec681f3SmrgambDiffSpecPropertyMaterial: AMBIENT 13523464ebd5Sriastradh { 13537ec681f3Smrg $$ = MAT_ATTRIB_FRONT_AMBIENT; 13543464ebd5Sriastradh } 13553464ebd5Sriastradh | DIFFUSE 13563464ebd5Sriastradh { 13577ec681f3Smrg $$ = MAT_ATTRIB_FRONT_DIFFUSE; 13583464ebd5Sriastradh } 13593464ebd5Sriastradh | SPECULAR 13603464ebd5Sriastradh { 13617ec681f3Smrg $$ = MAT_ATTRIB_FRONT_SPECULAR; 13623464ebd5Sriastradh } 13633464ebd5Sriastradh ; 13643464ebd5Sriastradh 13657ec681f3SmrgambDiffSpecPropertyLight: AMBIENT 13667ec681f3Smrg { 13677ec681f3Smrg $$ = STATE_AMBIENT; 13687ec681f3Smrg } 13697ec681f3Smrg | DIFFUSE 13707ec681f3Smrg { 13717ec681f3Smrg $$ = STATE_DIFFUSE; 13727ec681f3Smrg } 13737ec681f3Smrg | SPECULAR 13747ec681f3Smrg { 13757ec681f3Smrg $$ = STATE_SPECULAR; 13767ec681f3Smrg } 13777ec681f3Smrg ; 13787ec681f3Smrg 13793464ebd5SriastradhstateLightNumber: INTEGER 13803464ebd5Sriastradh { 13813464ebd5Sriastradh if ((unsigned) $1 >= state->MaxLights) { 13823464ebd5Sriastradh yyerror(& @1, state, "invalid light selector"); 13833464ebd5Sriastradh YYERROR; 13843464ebd5Sriastradh } 13853464ebd5Sriastradh 13863464ebd5Sriastradh $$ = $1; 13873464ebd5Sriastradh } 13883464ebd5Sriastradh ; 13893464ebd5Sriastradh 13903464ebd5SriastradhstateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord 13913464ebd5Sriastradh { 13923464ebd5Sriastradh memset($$, 0, sizeof($$)); 13933464ebd5Sriastradh $$[0] = STATE_TEXGEN; 13943464ebd5Sriastradh $$[1] = $2; 13953464ebd5Sriastradh $$[2] = $3 + $4; 13963464ebd5Sriastradh } 13973464ebd5Sriastradh ; 13983464ebd5Sriastradh 13993464ebd5SriastradhstateTexGenType: EYE 14003464ebd5Sriastradh { 14013464ebd5Sriastradh $$ = STATE_TEXGEN_EYE_S; 14023464ebd5Sriastradh } 14033464ebd5Sriastradh | OBJECT 14043464ebd5Sriastradh { 14053464ebd5Sriastradh $$ = STATE_TEXGEN_OBJECT_S; 14063464ebd5Sriastradh } 14073464ebd5Sriastradh ; 14083464ebd5SriastradhstateTexGenCoord: TEXGEN_S 14093464ebd5Sriastradh { 14103464ebd5Sriastradh $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; 14113464ebd5Sriastradh } 14123464ebd5Sriastradh | TEXGEN_T 14133464ebd5Sriastradh { 14143464ebd5Sriastradh $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; 14153464ebd5Sriastradh } 14163464ebd5Sriastradh | TEXGEN_R 14173464ebd5Sriastradh { 14183464ebd5Sriastradh $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; 14193464ebd5Sriastradh } 14203464ebd5Sriastradh | TEXGEN_Q 14213464ebd5Sriastradh { 14223464ebd5Sriastradh $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; 14233464ebd5Sriastradh } 14243464ebd5Sriastradh ; 14253464ebd5Sriastradh 14263464ebd5SriastradhstateFogItem: FOG stateFogProperty 14273464ebd5Sriastradh { 14283464ebd5Sriastradh memset($$, 0, sizeof($$)); 14293464ebd5Sriastradh $$[0] = $2; 14303464ebd5Sriastradh } 14313464ebd5Sriastradh ; 14323464ebd5Sriastradh 14333464ebd5SriastradhstateFogProperty: COLOR 14343464ebd5Sriastradh { 14353464ebd5Sriastradh $$ = STATE_FOG_COLOR; 14363464ebd5Sriastradh } 14373464ebd5Sriastradh | PARAMS 14383464ebd5Sriastradh { 14393464ebd5Sriastradh $$ = STATE_FOG_PARAMS; 14403464ebd5Sriastradh } 14413464ebd5Sriastradh ; 14423464ebd5Sriastradh 14433464ebd5SriastradhstateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE 14443464ebd5Sriastradh { 14453464ebd5Sriastradh memset($$, 0, sizeof($$)); 14463464ebd5Sriastradh $$[0] = STATE_CLIPPLANE; 14473464ebd5Sriastradh $$[1] = $3; 14483464ebd5Sriastradh } 14493464ebd5Sriastradh ; 14503464ebd5Sriastradh 14513464ebd5SriastradhstateClipPlaneNum: INTEGER 14523464ebd5Sriastradh { 14533464ebd5Sriastradh if ((unsigned) $1 >= state->MaxClipPlanes) { 14543464ebd5Sriastradh yyerror(& @1, state, "invalid clip plane selector"); 14553464ebd5Sriastradh YYERROR; 14563464ebd5Sriastradh } 14573464ebd5Sriastradh 14583464ebd5Sriastradh $$ = $1; 14593464ebd5Sriastradh } 14603464ebd5Sriastradh ; 14613464ebd5Sriastradh 14623464ebd5SriastradhstatePointItem: POINT_TOK statePointProperty 14633464ebd5Sriastradh { 14643464ebd5Sriastradh memset($$, 0, sizeof($$)); 14653464ebd5Sriastradh $$[0] = $2; 14663464ebd5Sriastradh } 14673464ebd5Sriastradh ; 14683464ebd5Sriastradh 14693464ebd5SriastradhstatePointProperty: SIZE_TOK 14703464ebd5Sriastradh { 14713464ebd5Sriastradh $$ = STATE_POINT_SIZE; 14723464ebd5Sriastradh } 14733464ebd5Sriastradh | ATTENUATION 14743464ebd5Sriastradh { 14753464ebd5Sriastradh $$ = STATE_POINT_ATTENUATION; 14763464ebd5Sriastradh } 14773464ebd5Sriastradh ; 14783464ebd5Sriastradh 14793464ebd5SriastradhstateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']' 14803464ebd5Sriastradh { 14817ec681f3Smrg $$[0] = $1[0] + $1[2]; 14823464ebd5Sriastradh $$[1] = $1[1]; 14833464ebd5Sriastradh $$[2] = $4; 14843464ebd5Sriastradh $$[3] = $4; 14853464ebd5Sriastradh } 14863464ebd5Sriastradh ; 14873464ebd5Sriastradh 14883464ebd5SriastradhstateMatrixRows: stateMatrixItem optMatrixRows 14893464ebd5Sriastradh { 14907ec681f3Smrg $$[0] = $1[0] + $1[2]; 14913464ebd5Sriastradh $$[1] = $1[1]; 14923464ebd5Sriastradh $$[2] = $2[2]; 14933464ebd5Sriastradh $$[3] = $2[3]; 14943464ebd5Sriastradh } 14953464ebd5Sriastradh ; 14963464ebd5Sriastradh 14973464ebd5SriastradhoptMatrixRows: 14983464ebd5Sriastradh { 14993464ebd5Sriastradh $$[2] = 0; 15003464ebd5Sriastradh $$[3] = 3; 15013464ebd5Sriastradh } 15023464ebd5Sriastradh | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']' 15033464ebd5Sriastradh { 15043464ebd5Sriastradh /* It seems logical that the matrix row range specifier would have 15053464ebd5Sriastradh * to specify a range or more than one row (i.e., $5 > $3). 15063464ebd5Sriastradh * However, the ARB_vertex_program spec says "a program will fail 15073464ebd5Sriastradh * to load if <a> is greater than <b>." This means that $3 == $5 15083464ebd5Sriastradh * is valid. 15093464ebd5Sriastradh */ 15103464ebd5Sriastradh if ($3 > $5) { 15113464ebd5Sriastradh yyerror(& @3, state, "invalid matrix row range"); 15123464ebd5Sriastradh YYERROR; 15133464ebd5Sriastradh } 15143464ebd5Sriastradh 15153464ebd5Sriastradh $$[2] = $3; 15163464ebd5Sriastradh $$[3] = $5; 15173464ebd5Sriastradh } 15183464ebd5Sriastradh ; 15193464ebd5Sriastradh 15203464ebd5SriastradhstateMatrixItem: MATRIX stateMatrixName stateOptMatModifier 15213464ebd5Sriastradh { 15223464ebd5Sriastradh $$[0] = $2[0]; 15233464ebd5Sriastradh $$[1] = $2[1]; 15243464ebd5Sriastradh $$[2] = $3; 15253464ebd5Sriastradh } 15263464ebd5Sriastradh ; 15273464ebd5Sriastradh 15287ec681f3SmrgstateOptMatModifier: 15293464ebd5Sriastradh { 15307ec681f3Smrg $$ = STATE_MATRIX_NO_MODIFIER; 15313464ebd5Sriastradh } 15323464ebd5Sriastradh | stateMatModifier 15333464ebd5Sriastradh { 15343464ebd5Sriastradh $$ = $1; 15353464ebd5Sriastradh } 15363464ebd5Sriastradh ; 15373464ebd5Sriastradh 15387ec681f3SmrgstateMatModifier: INVERSE 15393464ebd5Sriastradh { 15403464ebd5Sriastradh $$ = STATE_MATRIX_INVERSE; 15413464ebd5Sriastradh } 15427ec681f3Smrg | TRANSPOSE 15433464ebd5Sriastradh { 15443464ebd5Sriastradh $$ = STATE_MATRIX_TRANSPOSE; 15453464ebd5Sriastradh } 15463464ebd5Sriastradh | INVTRANS 15473464ebd5Sriastradh { 15483464ebd5Sriastradh $$ = STATE_MATRIX_INVTRANS; 15493464ebd5Sriastradh } 15503464ebd5Sriastradh ; 15513464ebd5Sriastradh 15523464ebd5SriastradhstateMatrixRowNum: INTEGER 15533464ebd5Sriastradh { 15543464ebd5Sriastradh if ($1 > 3) { 15553464ebd5Sriastradh yyerror(& @1, state, "invalid matrix row reference"); 15563464ebd5Sriastradh YYERROR; 15573464ebd5Sriastradh } 15583464ebd5Sriastradh 15593464ebd5Sriastradh $$ = $1; 15603464ebd5Sriastradh } 15613464ebd5Sriastradh ; 15623464ebd5Sriastradh 15633464ebd5SriastradhstateMatrixName: MODELVIEW stateOptModMatNum 15643464ebd5Sriastradh { 15653464ebd5Sriastradh $$[0] = STATE_MODELVIEW_MATRIX; 15663464ebd5Sriastradh $$[1] = $2; 15673464ebd5Sriastradh } 15683464ebd5Sriastradh | PROJECTION 15693464ebd5Sriastradh { 15703464ebd5Sriastradh $$[0] = STATE_PROJECTION_MATRIX; 15713464ebd5Sriastradh $$[1] = 0; 15723464ebd5Sriastradh } 15733464ebd5Sriastradh | MVP 15743464ebd5Sriastradh { 15753464ebd5Sriastradh $$[0] = STATE_MVP_MATRIX; 15763464ebd5Sriastradh $$[1] = 0; 15773464ebd5Sriastradh } 15783464ebd5Sriastradh | TEXTURE optTexCoordUnitNum 15793464ebd5Sriastradh { 15803464ebd5Sriastradh $$[0] = STATE_TEXTURE_MATRIX; 15813464ebd5Sriastradh $$[1] = $2; 15823464ebd5Sriastradh } 15833464ebd5Sriastradh | PALETTE '[' statePaletteMatNum ']' 15843464ebd5Sriastradh { 15853464ebd5Sriastradh yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); 15863464ebd5Sriastradh YYERROR; 15873464ebd5Sriastradh } 15883464ebd5Sriastradh | MAT_PROGRAM '[' stateProgramMatNum ']' 15893464ebd5Sriastradh { 15903464ebd5Sriastradh $$[0] = STATE_PROGRAM_MATRIX; 15913464ebd5Sriastradh $$[1] = $3; 15923464ebd5Sriastradh } 15933464ebd5Sriastradh ; 15943464ebd5Sriastradh 15953464ebd5SriastradhstateOptModMatNum: 15963464ebd5Sriastradh { 15973464ebd5Sriastradh $$ = 0; 15983464ebd5Sriastradh } 15993464ebd5Sriastradh | '[' stateModMatNum ']' 16003464ebd5Sriastradh { 16013464ebd5Sriastradh $$ = $2; 16023464ebd5Sriastradh } 16033464ebd5Sriastradh ; 16043464ebd5SriastradhstateModMatNum: INTEGER 16053464ebd5Sriastradh { 16063464ebd5Sriastradh /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix 16073464ebd5Sriastradh * zero is valid. 16083464ebd5Sriastradh */ 16093464ebd5Sriastradh if ($1 != 0) { 16103464ebd5Sriastradh yyerror(& @1, state, "invalid modelview matrix index"); 16113464ebd5Sriastradh YYERROR; 16123464ebd5Sriastradh } 16133464ebd5Sriastradh 16143464ebd5Sriastradh $$ = $1; 16153464ebd5Sriastradh } 16163464ebd5Sriastradh ; 16173464ebd5SriastradhstatePaletteMatNum: INTEGER 16183464ebd5Sriastradh { 16193464ebd5Sriastradh /* Since GL_ARB_matrix_palette isn't supported, just let any value 16203464ebd5Sriastradh * through here. The error will be generated later. 16213464ebd5Sriastradh */ 16223464ebd5Sriastradh $$ = $1; 16233464ebd5Sriastradh } 16243464ebd5Sriastradh ; 16253464ebd5SriastradhstateProgramMatNum: INTEGER 16263464ebd5Sriastradh { 16273464ebd5Sriastradh if ((unsigned) $1 >= state->MaxProgramMatrices) { 16283464ebd5Sriastradh yyerror(& @1, state, "invalid program matrix selector"); 16293464ebd5Sriastradh YYERROR; 16303464ebd5Sriastradh } 16313464ebd5Sriastradh 16323464ebd5Sriastradh $$ = $1; 16333464ebd5Sriastradh } 16343464ebd5Sriastradh ; 16353464ebd5Sriastradh 16363464ebd5SriastradhstateDepthItem: DEPTH RANGE 16373464ebd5Sriastradh { 16383464ebd5Sriastradh memset($$, 0, sizeof($$)); 16393464ebd5Sriastradh $$[0] = STATE_DEPTH_RANGE; 16403464ebd5Sriastradh } 16413464ebd5Sriastradh ; 16423464ebd5Sriastradh 16433464ebd5Sriastradh 16443464ebd5SriastradhprogramSingleItem: progEnvParam | progLocalParam; 16453464ebd5Sriastradh 16463464ebd5SriastradhprogramMultipleItem: progEnvParams | progLocalParams; 16473464ebd5Sriastradh 16483464ebd5SriastradhprogEnvParams: PROGRAM ENV '[' progEnvParamNums ']' 16493464ebd5Sriastradh { 16503464ebd5Sriastradh memset($$, 0, sizeof($$)); 16517ec681f3Smrg $$[0] = state->state_param_enum_env; 16527ec681f3Smrg $$[1] = $4[0]; 16537ec681f3Smrg $$[2] = $4[1]; 16547ec681f3Smrg $$[3] = 0; 16553464ebd5Sriastradh } 16563464ebd5Sriastradh ; 16573464ebd5Sriastradh 16583464ebd5SriastradhprogEnvParamNums: progEnvParamNum 16593464ebd5Sriastradh { 16603464ebd5Sriastradh $$[0] = $1; 16613464ebd5Sriastradh $$[1] = $1; 16623464ebd5Sriastradh } 16633464ebd5Sriastradh | progEnvParamNum DOT_DOT progEnvParamNum 16643464ebd5Sriastradh { 16653464ebd5Sriastradh $$[0] = $1; 16663464ebd5Sriastradh $$[1] = $3; 16673464ebd5Sriastradh } 16683464ebd5Sriastradh ; 16693464ebd5Sriastradh 16703464ebd5SriastradhprogEnvParam: PROGRAM ENV '[' progEnvParamNum ']' 16713464ebd5Sriastradh { 16723464ebd5Sriastradh memset($$, 0, sizeof($$)); 16737ec681f3Smrg $$[0] = state->state_param_enum_env; 16747ec681f3Smrg $$[1] = $4; 16753464ebd5Sriastradh $$[2] = $4; 16767ec681f3Smrg $$[3] = 0; 16773464ebd5Sriastradh } 16783464ebd5Sriastradh ; 16793464ebd5Sriastradh 16803464ebd5SriastradhprogLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']' 16813464ebd5Sriastradh { 16823464ebd5Sriastradh memset($$, 0, sizeof($$)); 16837ec681f3Smrg $$[0] = state->state_param_enum_local; 16847ec681f3Smrg $$[1] = $4[0]; 16857ec681f3Smrg $$[2] = $4[1]; 16867ec681f3Smrg $$[3] = 0; 16873464ebd5Sriastradh } 16883464ebd5Sriastradh 16893464ebd5SriastradhprogLocalParamNums: progLocalParamNum 16903464ebd5Sriastradh { 16913464ebd5Sriastradh $$[0] = $1; 16923464ebd5Sriastradh $$[1] = $1; 16933464ebd5Sriastradh } 16943464ebd5Sriastradh | progLocalParamNum DOT_DOT progLocalParamNum 16953464ebd5Sriastradh { 16963464ebd5Sriastradh $$[0] = $1; 16973464ebd5Sriastradh $$[1] = $3; 16983464ebd5Sriastradh } 16993464ebd5Sriastradh ; 17003464ebd5Sriastradh 17013464ebd5SriastradhprogLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']' 17023464ebd5Sriastradh { 17033464ebd5Sriastradh memset($$, 0, sizeof($$)); 17047ec681f3Smrg $$[0] = state->state_param_enum_local; 17057ec681f3Smrg $$[1] = $4; 17063464ebd5Sriastradh $$[2] = $4; 17077ec681f3Smrg $$[3] = 0; 17083464ebd5Sriastradh } 17093464ebd5Sriastradh ; 17103464ebd5Sriastradh 17113464ebd5SriastradhprogEnvParamNum: INTEGER 17123464ebd5Sriastradh { 17133464ebd5Sriastradh if ((unsigned) $1 >= state->limits->MaxEnvParams) { 17143464ebd5Sriastradh yyerror(& @1, state, "invalid environment parameter reference"); 17153464ebd5Sriastradh YYERROR; 17163464ebd5Sriastradh } 17173464ebd5Sriastradh $$ = $1; 17183464ebd5Sriastradh } 17193464ebd5Sriastradh ; 17203464ebd5Sriastradh 17213464ebd5SriastradhprogLocalParamNum: INTEGER 17223464ebd5Sriastradh { 17233464ebd5Sriastradh if ((unsigned) $1 >= state->limits->MaxLocalParams) { 17243464ebd5Sriastradh yyerror(& @1, state, "invalid local parameter reference"); 17253464ebd5Sriastradh YYERROR; 17263464ebd5Sriastradh } 17273464ebd5Sriastradh $$ = $1; 17283464ebd5Sriastradh } 17293464ebd5Sriastradh ; 17303464ebd5Sriastradh 17313464ebd5Sriastradh 17323464ebd5Sriastradh 17333464ebd5SriastradhparamConstDecl: paramConstScalarDecl | paramConstVector; 17343464ebd5SriastradhparamConstUse: paramConstScalarUse | paramConstVector; 17353464ebd5Sriastradh 17363464ebd5SriastradhparamConstScalarDecl: signedFloatConstant 17373464ebd5Sriastradh { 17383464ebd5Sriastradh $$.count = 4; 1739af69d88dSmrg $$.data[0].f = $1; 1740af69d88dSmrg $$.data[1].f = $1; 1741af69d88dSmrg $$.data[2].f = $1; 1742af69d88dSmrg $$.data[3].f = $1; 17433464ebd5Sriastradh } 17443464ebd5Sriastradh ; 17453464ebd5Sriastradh 17463464ebd5SriastradhparamConstScalarUse: REAL 17473464ebd5Sriastradh { 17483464ebd5Sriastradh $$.count = 1; 1749af69d88dSmrg $$.data[0].f = $1; 1750af69d88dSmrg $$.data[1].f = $1; 1751af69d88dSmrg $$.data[2].f = $1; 1752af69d88dSmrg $$.data[3].f = $1; 17533464ebd5Sriastradh } 17543464ebd5Sriastradh | INTEGER 17553464ebd5Sriastradh { 17563464ebd5Sriastradh $$.count = 1; 1757af69d88dSmrg $$.data[0].f = (float) $1; 1758af69d88dSmrg $$.data[1].f = (float) $1; 1759af69d88dSmrg $$.data[2].f = (float) $1; 1760af69d88dSmrg $$.data[3].f = (float) $1; 17613464ebd5Sriastradh } 17623464ebd5Sriastradh ; 17633464ebd5Sriastradh 17643464ebd5SriastradhparamConstVector: '{' signedFloatConstant '}' 17653464ebd5Sriastradh { 17663464ebd5Sriastradh $$.count = 4; 1767af69d88dSmrg $$.data[0].f = $2; 1768af69d88dSmrg $$.data[1].f = 0.0f; 1769af69d88dSmrg $$.data[2].f = 0.0f; 1770af69d88dSmrg $$.data[3].f = 1.0f; 17713464ebd5Sriastradh } 17723464ebd5Sriastradh | '{' signedFloatConstant ',' signedFloatConstant '}' 17733464ebd5Sriastradh { 17743464ebd5Sriastradh $$.count = 4; 1775af69d88dSmrg $$.data[0].f = $2; 1776af69d88dSmrg $$.data[1].f = $4; 1777af69d88dSmrg $$.data[2].f = 0.0f; 1778af69d88dSmrg $$.data[3].f = 1.0f; 17793464ebd5Sriastradh } 17803464ebd5Sriastradh | '{' signedFloatConstant ',' signedFloatConstant ',' 17813464ebd5Sriastradh signedFloatConstant '}' 17823464ebd5Sriastradh { 17833464ebd5Sriastradh $$.count = 4; 1784af69d88dSmrg $$.data[0].f = $2; 1785af69d88dSmrg $$.data[1].f = $4; 1786af69d88dSmrg $$.data[2].f = $6; 1787af69d88dSmrg $$.data[3].f = 1.0f; 17883464ebd5Sriastradh } 17893464ebd5Sriastradh | '{' signedFloatConstant ',' signedFloatConstant ',' 17903464ebd5Sriastradh signedFloatConstant ',' signedFloatConstant '}' 17913464ebd5Sriastradh { 17923464ebd5Sriastradh $$.count = 4; 1793af69d88dSmrg $$.data[0].f = $2; 1794af69d88dSmrg $$.data[1].f = $4; 1795af69d88dSmrg $$.data[2].f = $6; 1796af69d88dSmrg $$.data[3].f = $8; 17973464ebd5Sriastradh } 17983464ebd5Sriastradh ; 17993464ebd5Sriastradh 18003464ebd5SriastradhsignedFloatConstant: optionalSign REAL 18013464ebd5Sriastradh { 18023464ebd5Sriastradh $$ = ($1) ? -$2 : $2; 18033464ebd5Sriastradh } 18043464ebd5Sriastradh | optionalSign INTEGER 18053464ebd5Sriastradh { 18063464ebd5Sriastradh $$ = (float)(($1) ? -$2 : $2); 18073464ebd5Sriastradh } 18083464ebd5Sriastradh ; 18093464ebd5Sriastradh 18103464ebd5SriastradhoptionalSign: '+' { $$ = FALSE; } 18113464ebd5Sriastradh | '-' { $$ = TRUE; } 18123464ebd5Sriastradh | { $$ = FALSE; } 18133464ebd5Sriastradh ; 18143464ebd5Sriastradh 181501e04c3fSmrgTEMP_statement: TEMP { $<integer>$ = $1; } varNameList 18163464ebd5Sriastradh ; 18173464ebd5Sriastradh 18183464ebd5SriastradhADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList 18193464ebd5Sriastradh ; 18203464ebd5Sriastradh 18213464ebd5SriastradhvarNameList: varNameList ',' IDENTIFIER 18223464ebd5Sriastradh { 18233464ebd5Sriastradh if (!declare_variable(state, $3, $<integer>0, & @3)) { 18243464ebd5Sriastradh free($3); 18253464ebd5Sriastradh YYERROR; 18263464ebd5Sriastradh } 18273464ebd5Sriastradh } 18283464ebd5Sriastradh | IDENTIFIER 18293464ebd5Sriastradh { 18303464ebd5Sriastradh if (!declare_variable(state, $1, $<integer>0, & @1)) { 18313464ebd5Sriastradh free($1); 18323464ebd5Sriastradh YYERROR; 18333464ebd5Sriastradh } 18343464ebd5Sriastradh } 18353464ebd5Sriastradh ; 18363464ebd5Sriastradh 183701e04c3fSmrgOUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding 18383464ebd5Sriastradh { 18393464ebd5Sriastradh struct asm_symbol *const s = 184001e04c3fSmrg declare_variable(state, $2, at_output, & @2); 18413464ebd5Sriastradh 18423464ebd5Sriastradh if (s == NULL) { 184301e04c3fSmrg free($2); 18443464ebd5Sriastradh YYERROR; 18453464ebd5Sriastradh } else { 184601e04c3fSmrg s->output_binding = $4; 18473464ebd5Sriastradh } 18483464ebd5Sriastradh } 18493464ebd5Sriastradh ; 18503464ebd5Sriastradh 18513464ebd5SriastradhresultBinding: RESULT POSITION 18523464ebd5Sriastradh { 18533464ebd5Sriastradh if (state->mode == ARB_vertex) { 1854af69d88dSmrg $$ = VARYING_SLOT_POS; 18553464ebd5Sriastradh } else { 18563464ebd5Sriastradh yyerror(& @2, state, "invalid program result name"); 18573464ebd5Sriastradh YYERROR; 18583464ebd5Sriastradh } 18593464ebd5Sriastradh } 18603464ebd5Sriastradh | RESULT FOGCOORD 18613464ebd5Sriastradh { 18623464ebd5Sriastradh if (state->mode == ARB_vertex) { 1863af69d88dSmrg $$ = VARYING_SLOT_FOGC; 18643464ebd5Sriastradh } else { 18653464ebd5Sriastradh yyerror(& @2, state, "invalid program result name"); 18663464ebd5Sriastradh YYERROR; 18673464ebd5Sriastradh } 18683464ebd5Sriastradh } 18693464ebd5Sriastradh | RESULT resultColBinding 18703464ebd5Sriastradh { 18713464ebd5Sriastradh $$ = $2; 18723464ebd5Sriastradh } 18733464ebd5Sriastradh | RESULT POINTSIZE 18743464ebd5Sriastradh { 18753464ebd5Sriastradh if (state->mode == ARB_vertex) { 1876af69d88dSmrg $$ = VARYING_SLOT_PSIZ; 18773464ebd5Sriastradh } else { 18783464ebd5Sriastradh yyerror(& @2, state, "invalid program result name"); 18793464ebd5Sriastradh YYERROR; 18803464ebd5Sriastradh } 18813464ebd5Sriastradh } 18823464ebd5Sriastradh | RESULT TEXCOORD optTexCoordUnitNum 18833464ebd5Sriastradh { 18843464ebd5Sriastradh if (state->mode == ARB_vertex) { 1885af69d88dSmrg $$ = VARYING_SLOT_TEX0 + $3; 18863464ebd5Sriastradh } else { 18873464ebd5Sriastradh yyerror(& @2, state, "invalid program result name"); 18883464ebd5Sriastradh YYERROR; 18893464ebd5Sriastradh } 18903464ebd5Sriastradh } 18913464ebd5Sriastradh | RESULT DEPTH 18923464ebd5Sriastradh { 18933464ebd5Sriastradh if (state->mode == ARB_fragment) { 18943464ebd5Sriastradh $$ = FRAG_RESULT_DEPTH; 18953464ebd5Sriastradh } else { 18963464ebd5Sriastradh yyerror(& @2, state, "invalid program result name"); 18973464ebd5Sriastradh YYERROR; 18983464ebd5Sriastradh } 18993464ebd5Sriastradh } 19003464ebd5Sriastradh ; 19013464ebd5Sriastradh 19023464ebd5SriastradhresultColBinding: COLOR optResultFaceType optResultColorType 19033464ebd5Sriastradh { 19043464ebd5Sriastradh $$ = $2 + $3; 19053464ebd5Sriastradh } 19063464ebd5Sriastradh ; 19073464ebd5Sriastradh 19083464ebd5SriastradhoptResultFaceType: 19093464ebd5Sriastradh { 19103464ebd5Sriastradh if (state->mode == ARB_vertex) { 1911af69d88dSmrg $$ = VARYING_SLOT_COL0; 19123464ebd5Sriastradh } else { 19133464ebd5Sriastradh if (state->option.DrawBuffers) 19143464ebd5Sriastradh $$ = FRAG_RESULT_DATA0; 19153464ebd5Sriastradh else 19163464ebd5Sriastradh $$ = FRAG_RESULT_COLOR; 19173464ebd5Sriastradh } 19183464ebd5Sriastradh } 19193464ebd5Sriastradh | '[' INTEGER ']' 19203464ebd5Sriastradh { 19213464ebd5Sriastradh if (state->mode == ARB_vertex) { 19223464ebd5Sriastradh yyerror(& @1, state, "invalid program result name"); 19233464ebd5Sriastradh YYERROR; 19243464ebd5Sriastradh } else { 19253464ebd5Sriastradh if (!state->option.DrawBuffers) { 19263464ebd5Sriastradh /* From the ARB_draw_buffers spec (same text exists 19273464ebd5Sriastradh * for ATI_draw_buffers): 19283464ebd5Sriastradh * 19293464ebd5Sriastradh * If this option is not specified, a fragment 19303464ebd5Sriastradh * program that attempts to bind 19313464ebd5Sriastradh * "result.color[n]" will fail to load, and only 19323464ebd5Sriastradh * "result.color" will be allowed. 19333464ebd5Sriastradh */ 19343464ebd5Sriastradh yyerror(& @1, state, 19353464ebd5Sriastradh "result.color[] used without " 19363464ebd5Sriastradh "`OPTION ARB_draw_buffers' or " 19373464ebd5Sriastradh "`OPTION ATI_draw_buffers'"); 19383464ebd5Sriastradh YYERROR; 19393464ebd5Sriastradh } else if ($2 >= state->MaxDrawBuffers) { 19403464ebd5Sriastradh yyerror(& @1, state, 19413464ebd5Sriastradh "result.color[] exceeds MAX_DRAW_BUFFERS_ARB"); 19423464ebd5Sriastradh YYERROR; 19433464ebd5Sriastradh } 19443464ebd5Sriastradh $$ = FRAG_RESULT_DATA0 + $2; 19453464ebd5Sriastradh } 19463464ebd5Sriastradh } 19473464ebd5Sriastradh | FRONT 19483464ebd5Sriastradh { 19493464ebd5Sriastradh if (state->mode == ARB_vertex) { 1950af69d88dSmrg $$ = VARYING_SLOT_COL0; 19513464ebd5Sriastradh } else { 19523464ebd5Sriastradh yyerror(& @1, state, "invalid program result name"); 19533464ebd5Sriastradh YYERROR; 19543464ebd5Sriastradh } 19553464ebd5Sriastradh } 19563464ebd5Sriastradh | BACK 19573464ebd5Sriastradh { 19583464ebd5Sriastradh if (state->mode == ARB_vertex) { 1959af69d88dSmrg $$ = VARYING_SLOT_BFC0; 19603464ebd5Sriastradh } else { 19613464ebd5Sriastradh yyerror(& @1, state, "invalid program result name"); 19623464ebd5Sriastradh YYERROR; 19633464ebd5Sriastradh } 19643464ebd5Sriastradh } 19653464ebd5Sriastradh ; 19663464ebd5Sriastradh 19673464ebd5SriastradhoptResultColorType: 19683464ebd5Sriastradh { 19697ec681f3Smrg $$ = 0; 19703464ebd5Sriastradh } 19713464ebd5Sriastradh | PRIMARY 19723464ebd5Sriastradh { 19733464ebd5Sriastradh if (state->mode == ARB_vertex) { 19743464ebd5Sriastradh $$ = 0; 19753464ebd5Sriastradh } else { 19763464ebd5Sriastradh yyerror(& @1, state, "invalid program result name"); 19773464ebd5Sriastradh YYERROR; 19783464ebd5Sriastradh } 19793464ebd5Sriastradh } 19803464ebd5Sriastradh | SECONDARY 19813464ebd5Sriastradh { 19823464ebd5Sriastradh if (state->mode == ARB_vertex) { 19833464ebd5Sriastradh $$ = 1; 19843464ebd5Sriastradh } else { 19853464ebd5Sriastradh yyerror(& @1, state, "invalid program result name"); 19863464ebd5Sriastradh YYERROR; 19873464ebd5Sriastradh } 19883464ebd5Sriastradh } 19893464ebd5Sriastradh ; 19903464ebd5Sriastradh 19913464ebd5SriastradhoptFaceType: { $$ = 0; } 19923464ebd5Sriastradh | FRONT { $$ = 0; } 19933464ebd5Sriastradh | BACK { $$ = 1; } 19943464ebd5Sriastradh ; 19953464ebd5Sriastradh 19963464ebd5SriastradhoptColorType: { $$ = 0; } 19973464ebd5Sriastradh | PRIMARY { $$ = 0; } 19983464ebd5Sriastradh | SECONDARY { $$ = 1; } 19993464ebd5Sriastradh ; 20003464ebd5Sriastradh 20013464ebd5SriastradhoptTexCoordUnitNum: { $$ = 0; } 20023464ebd5Sriastradh | '[' texCoordUnitNum ']' { $$ = $2; } 20033464ebd5Sriastradh ; 20043464ebd5Sriastradh 20053464ebd5SriastradhoptTexImageUnitNum: { $$ = 0; } 20063464ebd5Sriastradh | '[' texImageUnitNum ']' { $$ = $2; } 20073464ebd5Sriastradh ; 20083464ebd5Sriastradh 20093464ebd5SriastradhoptLegacyTexUnitNum: { $$ = 0; } 20103464ebd5Sriastradh | '[' legacyTexUnitNum ']' { $$ = $2; } 20113464ebd5Sriastradh ; 20123464ebd5Sriastradh 20133464ebd5SriastradhtexCoordUnitNum: INTEGER 20143464ebd5Sriastradh { 20153464ebd5Sriastradh if ((unsigned) $1 >= state->MaxTextureCoordUnits) { 20163464ebd5Sriastradh yyerror(& @1, state, "invalid texture coordinate unit selector"); 20173464ebd5Sriastradh YYERROR; 20183464ebd5Sriastradh } 20193464ebd5Sriastradh 20203464ebd5Sriastradh $$ = $1; 20213464ebd5Sriastradh } 20223464ebd5Sriastradh ; 20233464ebd5Sriastradh 20243464ebd5SriastradhtexImageUnitNum: INTEGER 20253464ebd5Sriastradh { 20263464ebd5Sriastradh if ((unsigned) $1 >= state->MaxTextureImageUnits) { 20273464ebd5Sriastradh yyerror(& @1, state, "invalid texture image unit selector"); 20283464ebd5Sriastradh YYERROR; 20293464ebd5Sriastradh } 20303464ebd5Sriastradh 20313464ebd5Sriastradh $$ = $1; 20323464ebd5Sriastradh } 20333464ebd5Sriastradh ; 20343464ebd5Sriastradh 20353464ebd5SriastradhlegacyTexUnitNum: INTEGER 20363464ebd5Sriastradh { 20373464ebd5Sriastradh if ((unsigned) $1 >= state->MaxTextureUnits) { 20383464ebd5Sriastradh yyerror(& @1, state, "invalid texture unit selector"); 20393464ebd5Sriastradh YYERROR; 20403464ebd5Sriastradh } 20413464ebd5Sriastradh 20423464ebd5Sriastradh $$ = $1; 20433464ebd5Sriastradh } 20443464ebd5Sriastradh ; 20453464ebd5Sriastradh 20463464ebd5SriastradhALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER 20473464ebd5Sriastradh { 20483464ebd5Sriastradh struct asm_symbol *exist = (struct asm_symbol *) 204901e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, $2); 20503464ebd5Sriastradh struct asm_symbol *target = (struct asm_symbol *) 205101e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, $4); 20523464ebd5Sriastradh 20533464ebd5Sriastradh free($4); 20543464ebd5Sriastradh 20553464ebd5Sriastradh if (exist != NULL) { 20563464ebd5Sriastradh char m[1000]; 20577ec681f3Smrg snprintf(m, sizeof(m), "redeclared identifier: %s", $2); 20583464ebd5Sriastradh free($2); 20593464ebd5Sriastradh yyerror(& @2, state, m); 20603464ebd5Sriastradh YYERROR; 20613464ebd5Sriastradh } else if (target == NULL) { 20623464ebd5Sriastradh free($2); 20633464ebd5Sriastradh yyerror(& @4, state, 20643464ebd5Sriastradh "undefined variable binding in ALIAS statement"); 20653464ebd5Sriastradh YYERROR; 20663464ebd5Sriastradh } else { 206701e04c3fSmrg _mesa_symbol_table_add_symbol(state->st, $2, target); 20683464ebd5Sriastradh } 20693464ebd5Sriastradh } 20703464ebd5Sriastradh ; 20713464ebd5Sriastradh 20723464ebd5Sriastradhstring: IDENTIFIER 20733464ebd5Sriastradh | USED_IDENTIFIER 20743464ebd5Sriastradh ; 20753464ebd5Sriastradh 20763464ebd5Sriastradh%% 20773464ebd5Sriastradh 20783464ebd5Sriastradhvoid 20793464ebd5Sriastradhasm_instruction_set_operands(struct asm_instruction *inst, 20803464ebd5Sriastradh const struct prog_dst_register *dst, 20813464ebd5Sriastradh const struct asm_src_register *src0, 20823464ebd5Sriastradh const struct asm_src_register *src1, 20833464ebd5Sriastradh const struct asm_src_register *src2) 20843464ebd5Sriastradh{ 20853464ebd5Sriastradh /* In the core ARB extensions only the KIL instruction doesn't have a 20863464ebd5Sriastradh * destination register. 20873464ebd5Sriastradh */ 20883464ebd5Sriastradh if (dst == NULL) { 20893464ebd5Sriastradh init_dst_reg(& inst->Base.DstReg); 20903464ebd5Sriastradh } else { 20913464ebd5Sriastradh inst->Base.DstReg = *dst; 20923464ebd5Sriastradh } 20933464ebd5Sriastradh 20943464ebd5Sriastradh if (src0 != NULL) { 20953464ebd5Sriastradh inst->Base.SrcReg[0] = src0->Base; 20963464ebd5Sriastradh inst->SrcReg[0] = *src0; 20973464ebd5Sriastradh } else { 20983464ebd5Sriastradh init_src_reg(& inst->SrcReg[0]); 20993464ebd5Sriastradh } 21003464ebd5Sriastradh 21013464ebd5Sriastradh if (src1 != NULL) { 21023464ebd5Sriastradh inst->Base.SrcReg[1] = src1->Base; 21033464ebd5Sriastradh inst->SrcReg[1] = *src1; 21043464ebd5Sriastradh } else { 21053464ebd5Sriastradh init_src_reg(& inst->SrcReg[1]); 21063464ebd5Sriastradh } 21073464ebd5Sriastradh 21083464ebd5Sriastradh if (src2 != NULL) { 21093464ebd5Sriastradh inst->Base.SrcReg[2] = src2->Base; 21103464ebd5Sriastradh inst->SrcReg[2] = *src2; 21113464ebd5Sriastradh } else { 21123464ebd5Sriastradh init_src_reg(& inst->SrcReg[2]); 21133464ebd5Sriastradh } 21143464ebd5Sriastradh} 21153464ebd5Sriastradh 21163464ebd5Sriastradh 21173464ebd5Sriastradhstruct asm_instruction * 211801e04c3fSmrgasm_instruction_ctor(enum prog_opcode op, 21193464ebd5Sriastradh const struct prog_dst_register *dst, 21203464ebd5Sriastradh const struct asm_src_register *src0, 21213464ebd5Sriastradh const struct asm_src_register *src1, 21223464ebd5Sriastradh const struct asm_src_register *src2) 21233464ebd5Sriastradh{ 21243464ebd5Sriastradh struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); 21253464ebd5Sriastradh 21263464ebd5Sriastradh if (inst) { 21273464ebd5Sriastradh _mesa_init_instructions(& inst->Base, 1); 21283464ebd5Sriastradh inst->Base.Opcode = op; 21293464ebd5Sriastradh 21303464ebd5Sriastradh asm_instruction_set_operands(inst, dst, src0, src1, src2); 21313464ebd5Sriastradh } 21323464ebd5Sriastradh 21333464ebd5Sriastradh return inst; 21343464ebd5Sriastradh} 21353464ebd5Sriastradh 21363464ebd5Sriastradh 21373464ebd5Sriastradhstruct asm_instruction * 21383464ebd5Sriastradhasm_instruction_copy_ctor(const struct prog_instruction *base, 21393464ebd5Sriastradh const struct prog_dst_register *dst, 21403464ebd5Sriastradh const struct asm_src_register *src0, 21413464ebd5Sriastradh const struct asm_src_register *src1, 21423464ebd5Sriastradh const struct asm_src_register *src2) 21433464ebd5Sriastradh{ 21443464ebd5Sriastradh struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); 21453464ebd5Sriastradh 21463464ebd5Sriastradh if (inst) { 21473464ebd5Sriastradh _mesa_init_instructions(& inst->Base, 1); 21483464ebd5Sriastradh inst->Base.Opcode = base->Opcode; 214901e04c3fSmrg inst->Base.Saturate = base->Saturate; 21503464ebd5Sriastradh 21513464ebd5Sriastradh asm_instruction_set_operands(inst, dst, src0, src1, src2); 21523464ebd5Sriastradh } 21533464ebd5Sriastradh 21543464ebd5Sriastradh return inst; 21553464ebd5Sriastradh} 21563464ebd5Sriastradh 21573464ebd5Sriastradh 21583464ebd5Sriastradhvoid 21593464ebd5Sriastradhinit_dst_reg(struct prog_dst_register *r) 21603464ebd5Sriastradh{ 21613464ebd5Sriastradh memset(r, 0, sizeof(*r)); 21623464ebd5Sriastradh r->File = PROGRAM_UNDEFINED; 21633464ebd5Sriastradh r->WriteMask = WRITEMASK_XYZW; 21643464ebd5Sriastradh} 21653464ebd5Sriastradh 21663464ebd5Sriastradh 21673464ebd5Sriastradh/** Like init_dst_reg() but set the File and Index fields. */ 21683464ebd5Sriastradhvoid 21693464ebd5Sriastradhset_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index) 21703464ebd5Sriastradh{ 21713464ebd5Sriastradh const GLint maxIndex = 1 << INST_INDEX_BITS; 21723464ebd5Sriastradh const GLint minIndex = 0; 217301e04c3fSmrg assert(index >= minIndex); 21743464ebd5Sriastradh (void) minIndex; 217501e04c3fSmrg assert(index <= maxIndex); 21763464ebd5Sriastradh (void) maxIndex; 217701e04c3fSmrg assert(file == PROGRAM_TEMPORARY || 21783464ebd5Sriastradh file == PROGRAM_ADDRESS || 21793464ebd5Sriastradh file == PROGRAM_OUTPUT); 21803464ebd5Sriastradh memset(r, 0, sizeof(*r)); 21813464ebd5Sriastradh r->File = file; 21823464ebd5Sriastradh r->Index = index; 21833464ebd5Sriastradh r->WriteMask = WRITEMASK_XYZW; 21843464ebd5Sriastradh} 21853464ebd5Sriastradh 21863464ebd5Sriastradh 21873464ebd5Sriastradhvoid 21883464ebd5Sriastradhinit_src_reg(struct asm_src_register *r) 21893464ebd5Sriastradh{ 21903464ebd5Sriastradh memset(r, 0, sizeof(*r)); 21913464ebd5Sriastradh r->Base.File = PROGRAM_UNDEFINED; 21923464ebd5Sriastradh r->Base.Swizzle = SWIZZLE_NOOP; 21933464ebd5Sriastradh r->Symbol = NULL; 21943464ebd5Sriastradh} 21953464ebd5Sriastradh 21963464ebd5Sriastradh 21973464ebd5Sriastradh/** Like init_src_reg() but set the File and Index fields. 21983464ebd5Sriastradh * \return GL_TRUE if a valid src register, GL_FALSE otherwise 21993464ebd5Sriastradh */ 22003464ebd5Sriastradhvoid 22013464ebd5Sriastradhset_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) 22023464ebd5Sriastradh{ 22033464ebd5Sriastradh set_src_reg_swz(r, file, index, SWIZZLE_XYZW); 22043464ebd5Sriastradh} 22053464ebd5Sriastradh 22063464ebd5Sriastradh 22073464ebd5Sriastradhvoid 22083464ebd5Sriastradhset_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index, 22093464ebd5Sriastradh GLuint swizzle) 22103464ebd5Sriastradh{ 22113464ebd5Sriastradh const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; 22123464ebd5Sriastradh const GLint minIndex = -(1 << INST_INDEX_BITS); 221301e04c3fSmrg assert(file < PROGRAM_FILE_MAX); 221401e04c3fSmrg assert(index >= minIndex); 22153464ebd5Sriastradh (void) minIndex; 221601e04c3fSmrg assert(index <= maxIndex); 22173464ebd5Sriastradh (void) maxIndex; 22183464ebd5Sriastradh memset(r, 0, sizeof(*r)); 22193464ebd5Sriastradh r->Base.File = file; 22203464ebd5Sriastradh r->Base.Index = index; 22213464ebd5Sriastradh r->Base.Swizzle = swizzle; 22223464ebd5Sriastradh r->Symbol = NULL; 22233464ebd5Sriastradh} 22243464ebd5Sriastradh 22253464ebd5Sriastradh 22263464ebd5Sriastradh/** 22273464ebd5Sriastradh * Validate the set of inputs used by a program 22283464ebd5Sriastradh * 22293464ebd5Sriastradh * Validates that legal sets of inputs are used by the program. In this case 22303464ebd5Sriastradh * "used" included both reading the input or binding the input to a name using 22313464ebd5Sriastradh * the \c ATTRIB command. 22323464ebd5Sriastradh * 22333464ebd5Sriastradh * \return 22343464ebd5Sriastradh * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. 22353464ebd5Sriastradh */ 22363464ebd5Sriastradhint 22373464ebd5Sriastradhvalidate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) 22383464ebd5Sriastradh{ 223901e04c3fSmrg const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound; 224001e04c3fSmrg GLbitfield ff_inputs = 0; 22413464ebd5Sriastradh 224201e04c3fSmrg /* Since Mesa internal attribute indices are different from 224301e04c3fSmrg * how NV_vertex_program defines attribute aliasing, we have to construct 224401e04c3fSmrg * a separate usage mask based on how the aliasing is defined. 224501e04c3fSmrg * 224601e04c3fSmrg * Note that attribute aliasing is optional if NV_vertex_program is 224701e04c3fSmrg * unsupported. 224801e04c3fSmrg */ 224901e04c3fSmrg if (inputs & VERT_BIT_POS) 225001e04c3fSmrg ff_inputs |= 1 << 0; 225101e04c3fSmrg if (inputs & VERT_BIT_NORMAL) 225201e04c3fSmrg ff_inputs |= 1 << 2; 225301e04c3fSmrg if (inputs & VERT_BIT_COLOR0) 225401e04c3fSmrg ff_inputs |= 1 << 3; 225501e04c3fSmrg if (inputs & VERT_BIT_COLOR1) 225601e04c3fSmrg ff_inputs |= 1 << 4; 225701e04c3fSmrg if (inputs & VERT_BIT_FOG) 225801e04c3fSmrg ff_inputs |= 1 << 5; 225901e04c3fSmrg 226001e04c3fSmrg ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8; 226101e04c3fSmrg 226201e04c3fSmrg if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) { 22633464ebd5Sriastradh yyerror(locp, state, "illegal use of generic attribute and name attribute"); 22643464ebd5Sriastradh return 0; 22653464ebd5Sriastradh } 22663464ebd5Sriastradh 22673464ebd5Sriastradh return 1; 22683464ebd5Sriastradh} 22693464ebd5Sriastradh 22703464ebd5Sriastradh 22713464ebd5Sriastradhstruct asm_symbol * 22723464ebd5Sriastradhdeclare_variable(struct asm_parser_state *state, char *name, enum asm_type t, 22733464ebd5Sriastradh struct YYLTYPE *locp) 22743464ebd5Sriastradh{ 22753464ebd5Sriastradh struct asm_symbol *s = NULL; 22763464ebd5Sriastradh struct asm_symbol *exist = (struct asm_symbol *) 227701e04c3fSmrg _mesa_symbol_table_find_symbol(state->st, name); 22783464ebd5Sriastradh 22793464ebd5Sriastradh 22803464ebd5Sriastradh if (exist != NULL) { 22813464ebd5Sriastradh yyerror(locp, state, "redeclared identifier"); 22823464ebd5Sriastradh } else { 22833464ebd5Sriastradh s = calloc(1, sizeof(struct asm_symbol)); 22843464ebd5Sriastradh s->name = name; 22853464ebd5Sriastradh s->type = t; 22863464ebd5Sriastradh 22873464ebd5Sriastradh switch (t) { 22883464ebd5Sriastradh case at_temp: 228901e04c3fSmrg if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) { 22903464ebd5Sriastradh yyerror(locp, state, "too many temporaries declared"); 22913464ebd5Sriastradh free(s); 22923464ebd5Sriastradh return NULL; 22933464ebd5Sriastradh } 22943464ebd5Sriastradh 229501e04c3fSmrg s->temp_binding = state->prog->arb.NumTemporaries; 229601e04c3fSmrg state->prog->arb.NumTemporaries++; 22973464ebd5Sriastradh break; 22983464ebd5Sriastradh 22993464ebd5Sriastradh case at_address: 230001e04c3fSmrg if (state->prog->arb.NumAddressRegs >= 230101e04c3fSmrg state->limits->MaxAddressRegs) { 23023464ebd5Sriastradh yyerror(locp, state, "too many address registers declared"); 23033464ebd5Sriastradh free(s); 23043464ebd5Sriastradh return NULL; 23053464ebd5Sriastradh } 23063464ebd5Sriastradh 23073464ebd5Sriastradh /* FINISHME: Add support for multiple address registers. 23083464ebd5Sriastradh */ 230901e04c3fSmrg state->prog->arb.NumAddressRegs++; 23103464ebd5Sriastradh break; 23113464ebd5Sriastradh 23123464ebd5Sriastradh default: 23133464ebd5Sriastradh break; 23143464ebd5Sriastradh } 23153464ebd5Sriastradh 231601e04c3fSmrg _mesa_symbol_table_add_symbol(state->st, s->name, s); 23173464ebd5Sriastradh s->next = state->sym; 23183464ebd5Sriastradh state->sym = s; 23193464ebd5Sriastradh } 23203464ebd5Sriastradh 23213464ebd5Sriastradh return s; 23223464ebd5Sriastradh} 23233464ebd5Sriastradh 23243464ebd5Sriastradh 23253464ebd5Sriastradhint add_state_reference(struct gl_program_parameter_list *param_list, 232601e04c3fSmrg const gl_state_index16 tokens[STATE_LENGTH]) 23273464ebd5Sriastradh{ 23283464ebd5Sriastradh const GLuint size = 4; /* XXX fix */ 23293464ebd5Sriastradh char *name; 23303464ebd5Sriastradh GLint index; 23313464ebd5Sriastradh 23323464ebd5Sriastradh name = _mesa_program_state_string(tokens); 23333464ebd5Sriastradh index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, 233401e04c3fSmrg size, GL_NONE, NULL, tokens, true); 23353464ebd5Sriastradh param_list->StateFlags |= _mesa_program_state_flags(tokens); 23363464ebd5Sriastradh 23373464ebd5Sriastradh /* free name string here since we duplicated it in add_parameter() */ 23383464ebd5Sriastradh free(name); 23393464ebd5Sriastradh 23403464ebd5Sriastradh return index; 23413464ebd5Sriastradh} 23423464ebd5Sriastradh 23433464ebd5Sriastradh 23443464ebd5Sriastradhint 23453464ebd5Sriastradhinitialize_symbol_from_state(struct gl_program *prog, 23467ec681f3Smrg struct asm_symbol *param_var, 234701e04c3fSmrg const gl_state_index16 tokens[STATE_LENGTH]) 23483464ebd5Sriastradh{ 23493464ebd5Sriastradh int idx = -1; 235001e04c3fSmrg gl_state_index16 state_tokens[STATE_LENGTH]; 23513464ebd5Sriastradh 23523464ebd5Sriastradh 23533464ebd5Sriastradh memcpy(state_tokens, tokens, sizeof(state_tokens)); 23543464ebd5Sriastradh 23553464ebd5Sriastradh param_var->type = at_param; 23563464ebd5Sriastradh param_var->param_binding_type = PROGRAM_STATE_VAR; 23573464ebd5Sriastradh 23583464ebd5Sriastradh /* If we are adding a STATE_MATRIX that has multiple rows, we need to 23593464ebd5Sriastradh * unroll it and call add_state_reference() for each row 23603464ebd5Sriastradh */ 23617ec681f3Smrg if (state_tokens[0] >= STATE_MODELVIEW_MATRIX && 23627ec681f3Smrg state_tokens[0] <= STATE_PROGRAM_MATRIX_INVTRANS 23633464ebd5Sriastradh && (state_tokens[2] != state_tokens[3])) { 23643464ebd5Sriastradh int row; 23653464ebd5Sriastradh const int first_row = state_tokens[2]; 23663464ebd5Sriastradh const int last_row = state_tokens[3]; 23673464ebd5Sriastradh 23683464ebd5Sriastradh for (row = first_row; row <= last_row; row++) { 23693464ebd5Sriastradh state_tokens[2] = state_tokens[3] = row; 23703464ebd5Sriastradh 23713464ebd5Sriastradh idx = add_state_reference(prog->Parameters, state_tokens); 23723464ebd5Sriastradh if (param_var->param_binding_begin == ~0U) { 23733464ebd5Sriastradh param_var->param_binding_begin = idx; 23743464ebd5Sriastradh param_var->param_binding_swizzle = SWIZZLE_XYZW; 23753464ebd5Sriastradh } 23763464ebd5Sriastradh 23773464ebd5Sriastradh param_var->param_binding_length++; 23783464ebd5Sriastradh } 23793464ebd5Sriastradh } 23803464ebd5Sriastradh else { 23813464ebd5Sriastradh idx = add_state_reference(prog->Parameters, state_tokens); 23823464ebd5Sriastradh if (param_var->param_binding_begin == ~0U) { 23833464ebd5Sriastradh param_var->param_binding_begin = idx; 23843464ebd5Sriastradh param_var->param_binding_swizzle = SWIZZLE_XYZW; 23853464ebd5Sriastradh } 23863464ebd5Sriastradh param_var->param_binding_length++; 23873464ebd5Sriastradh } 23883464ebd5Sriastradh 23893464ebd5Sriastradh return idx; 23903464ebd5Sriastradh} 23913464ebd5Sriastradh 23923464ebd5Sriastradh 23933464ebd5Sriastradhint 23943464ebd5Sriastradhinitialize_symbol_from_param(struct gl_program *prog, 23957ec681f3Smrg struct asm_symbol *param_var, 239601e04c3fSmrg const gl_state_index16 tokens[STATE_LENGTH]) 23973464ebd5Sriastradh{ 23983464ebd5Sriastradh int idx = -1; 239901e04c3fSmrg gl_state_index16 state_tokens[STATE_LENGTH]; 24003464ebd5Sriastradh 24013464ebd5Sriastradh 24023464ebd5Sriastradh memcpy(state_tokens, tokens, sizeof(state_tokens)); 24033464ebd5Sriastradh 24047ec681f3Smrg assert(state_tokens[0] == STATE_VERTEX_PROGRAM_ENV || 24057ec681f3Smrg state_tokens[0] == STATE_VERTEX_PROGRAM_LOCAL || 24067ec681f3Smrg state_tokens[0] == STATE_FRAGMENT_PROGRAM_ENV || 24077ec681f3Smrg state_tokens[0] == STATE_FRAGMENT_PROGRAM_LOCAL); 24083464ebd5Sriastradh 24093464ebd5Sriastradh /* 24103464ebd5Sriastradh * The param type is STATE_VAR. The program parameter entry will 24113464ebd5Sriastradh * effectively be a pointer into the LOCAL or ENV parameter array. 24123464ebd5Sriastradh */ 24133464ebd5Sriastradh param_var->type = at_param; 24143464ebd5Sriastradh param_var->param_binding_type = PROGRAM_STATE_VAR; 24153464ebd5Sriastradh 24163464ebd5Sriastradh /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, 24173464ebd5Sriastradh * we need to unroll it and call add_state_reference() for each row 24183464ebd5Sriastradh */ 24197ec681f3Smrg if (state_tokens[1] != state_tokens[2]) { 24203464ebd5Sriastradh int row; 24217ec681f3Smrg const int first_row = state_tokens[1]; 24227ec681f3Smrg const int last_row = state_tokens[2]; 24233464ebd5Sriastradh 24243464ebd5Sriastradh for (row = first_row; row <= last_row; row++) { 24257ec681f3Smrg state_tokens[1] = state_tokens[2] = row; 24263464ebd5Sriastradh 24273464ebd5Sriastradh idx = add_state_reference(prog->Parameters, state_tokens); 24283464ebd5Sriastradh if (param_var->param_binding_begin == ~0U) { 24293464ebd5Sriastradh param_var->param_binding_begin = idx; 24303464ebd5Sriastradh param_var->param_binding_swizzle = SWIZZLE_XYZW; 24313464ebd5Sriastradh } 24323464ebd5Sriastradh param_var->param_binding_length++; 24333464ebd5Sriastradh } 24343464ebd5Sriastradh } 24353464ebd5Sriastradh else { 24363464ebd5Sriastradh idx = add_state_reference(prog->Parameters, state_tokens); 24373464ebd5Sriastradh if (param_var->param_binding_begin == ~0U) { 24383464ebd5Sriastradh param_var->param_binding_begin = idx; 24393464ebd5Sriastradh param_var->param_binding_swizzle = SWIZZLE_XYZW; 24403464ebd5Sriastradh } 24413464ebd5Sriastradh param_var->param_binding_length++; 24423464ebd5Sriastradh } 24433464ebd5Sriastradh 24443464ebd5Sriastradh return idx; 24453464ebd5Sriastradh} 24463464ebd5Sriastradh 24473464ebd5Sriastradh 24483464ebd5Sriastradh/** 24493464ebd5Sriastradh * Put a float/vector constant/literal into the parameter list. 24503464ebd5Sriastradh * \param param_var returns info about the parameter/constant's location, 24513464ebd5Sriastradh * binding, type, etc. 24523464ebd5Sriastradh * \param vec the vector/constant to add 24533464ebd5Sriastradh * \param allowSwizzle if true, try to consolidate constants which only differ 24543464ebd5Sriastradh * by a swizzle. We don't want to do this when building 24553464ebd5Sriastradh * arrays of constants that may be indexed indirectly. 24563464ebd5Sriastradh * \return index of the constant in the parameter list. 24573464ebd5Sriastradh */ 24583464ebd5Sriastradhint 24593464ebd5Sriastradhinitialize_symbol_from_const(struct gl_program *prog, 24607ec681f3Smrg struct asm_symbol *param_var, 24613464ebd5Sriastradh const struct asm_vector *vec, 24623464ebd5Sriastradh GLboolean allowSwizzle) 24633464ebd5Sriastradh{ 24643464ebd5Sriastradh unsigned swizzle; 24653464ebd5Sriastradh const int idx = _mesa_add_unnamed_constant(prog->Parameters, 24663464ebd5Sriastradh vec->data, vec->count, 24673464ebd5Sriastradh allowSwizzle ? &swizzle : NULL); 24683464ebd5Sriastradh 24693464ebd5Sriastradh param_var->type = at_param; 24703464ebd5Sriastradh param_var->param_binding_type = PROGRAM_CONSTANT; 24713464ebd5Sriastradh 24723464ebd5Sriastradh if (param_var->param_binding_begin == ~0U) { 24733464ebd5Sriastradh param_var->param_binding_begin = idx; 24743464ebd5Sriastradh param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW; 24753464ebd5Sriastradh } 24763464ebd5Sriastradh param_var->param_binding_length++; 24773464ebd5Sriastradh 24783464ebd5Sriastradh return idx; 24793464ebd5Sriastradh} 24803464ebd5Sriastradh 24813464ebd5Sriastradh 24823464ebd5Sriastradhchar * 24833464ebd5Sriastradhmake_error_string(const char *fmt, ...) 24843464ebd5Sriastradh{ 24853464ebd5Sriastradh int length; 24863464ebd5Sriastradh char *str; 24873464ebd5Sriastradh va_list args; 24883464ebd5Sriastradh 24893464ebd5Sriastradh 24903464ebd5Sriastradh /* Call vsnprintf once to determine how large the final string is. Call it 24913464ebd5Sriastradh * again to do the actual formatting. from the vsnprintf manual page: 24923464ebd5Sriastradh * 24933464ebd5Sriastradh * Upon successful return, these functions return the number of 24943464ebd5Sriastradh * characters printed (not including the trailing '\0' used to end 24953464ebd5Sriastradh * output to strings). 24963464ebd5Sriastradh */ 24973464ebd5Sriastradh va_start(args, fmt); 24983464ebd5Sriastradh length = 1 + vsnprintf(NULL, 0, fmt, args); 24993464ebd5Sriastradh va_end(args); 25003464ebd5Sriastradh 25013464ebd5Sriastradh str = malloc(length); 25023464ebd5Sriastradh if (str) { 25033464ebd5Sriastradh va_start(args, fmt); 25043464ebd5Sriastradh vsnprintf(str, length, fmt, args); 25053464ebd5Sriastradh va_end(args); 25063464ebd5Sriastradh } 25073464ebd5Sriastradh 25083464ebd5Sriastradh return str; 25093464ebd5Sriastradh} 25103464ebd5Sriastradh 25113464ebd5Sriastradh 25123464ebd5Sriastradhvoid 25133464ebd5Sriastradhyyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) 25143464ebd5Sriastradh{ 25153464ebd5Sriastradh char *err_str; 25163464ebd5Sriastradh 25173464ebd5Sriastradh 25183464ebd5Sriastradh err_str = make_error_string("glProgramStringARB(%s)\n", s); 25193464ebd5Sriastradh if (err_str) { 25203464ebd5Sriastradh _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str); 25213464ebd5Sriastradh free(err_str); 25223464ebd5Sriastradh } 25233464ebd5Sriastradh 25243464ebd5Sriastradh err_str = make_error_string("line %u, char %u: error: %s\n", 25253464ebd5Sriastradh locp->first_line, locp->first_column, s); 25263464ebd5Sriastradh _mesa_set_program_error(state->ctx, locp->position, err_str); 25273464ebd5Sriastradh 25283464ebd5Sriastradh if (err_str) { 25293464ebd5Sriastradh free(err_str); 25303464ebd5Sriastradh } 25313464ebd5Sriastradh} 25323464ebd5Sriastradh 25333464ebd5Sriastradh 25343464ebd5SriastradhGLboolean 25353464ebd5Sriastradh_mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str, 25363464ebd5Sriastradh GLsizei len, struct asm_parser_state *state) 25373464ebd5Sriastradh{ 25383464ebd5Sriastradh struct asm_instruction *inst; 25393464ebd5Sriastradh unsigned i; 25403464ebd5Sriastradh GLubyte *strz; 25413464ebd5Sriastradh GLboolean result = GL_FALSE; 25423464ebd5Sriastradh void *temp; 25433464ebd5Sriastradh struct asm_symbol *sym; 25443464ebd5Sriastradh 25453464ebd5Sriastradh state->ctx = ctx; 25463464ebd5Sriastradh state->prog->Target = target; 25473464ebd5Sriastradh state->prog->Parameters = _mesa_new_parameter_list(); 25483464ebd5Sriastradh 25493464ebd5Sriastradh /* Make a copy of the program string and force it to be NUL-terminated. 25503464ebd5Sriastradh */ 255101e04c3fSmrg strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 1); 25523464ebd5Sriastradh if (strz == NULL) { 25537ec681f3Smrg if (state->prog->Parameters) { 25547ec681f3Smrg _mesa_free_parameter_list(state->prog->Parameters); 25557ec681f3Smrg state->prog->Parameters = NULL; 25567ec681f3Smrg } 25573464ebd5Sriastradh _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); 25583464ebd5Sriastradh return GL_FALSE; 25593464ebd5Sriastradh } 25603464ebd5Sriastradh memcpy (strz, str, len); 25613464ebd5Sriastradh strz[len] = '\0'; 25623464ebd5Sriastradh 25633464ebd5Sriastradh state->prog->String = strz; 25643464ebd5Sriastradh 25653464ebd5Sriastradh state->st = _mesa_symbol_table_ctor(); 25663464ebd5Sriastradh 25673464ebd5Sriastradh state->limits = (target == GL_VERTEX_PROGRAM_ARB) 2568af69d88dSmrg ? & ctx->Const.Program[MESA_SHADER_VERTEX] 2569af69d88dSmrg : & ctx->Const.Program[MESA_SHADER_FRAGMENT]; 25703464ebd5Sriastradh 2571af69d88dSmrg state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; 25723464ebd5Sriastradh state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; 25733464ebd5Sriastradh state->MaxTextureUnits = ctx->Const.MaxTextureUnits; 25743464ebd5Sriastradh state->MaxClipPlanes = ctx->Const.MaxClipPlanes; 25753464ebd5Sriastradh state->MaxLights = ctx->Const.MaxLights; 25763464ebd5Sriastradh state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; 25773464ebd5Sriastradh state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers; 25783464ebd5Sriastradh 25797ec681f3Smrg state->state_param_enum_env = (target == GL_VERTEX_PROGRAM_ARB) 25807ec681f3Smrg ? STATE_VERTEX_PROGRAM_ENV : STATE_FRAGMENT_PROGRAM_ENV; 25817ec681f3Smrg state->state_param_enum_local = (target == GL_VERTEX_PROGRAM_ARB) 25827ec681f3Smrg ? STATE_VERTEX_PROGRAM_LOCAL : STATE_FRAGMENT_PROGRAM_LOCAL; 25833464ebd5Sriastradh 25843464ebd5Sriastradh _mesa_set_program_error(ctx, -1, NULL); 25853464ebd5Sriastradh 25863464ebd5Sriastradh _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len); 25873464ebd5Sriastradh yyparse(state); 25883464ebd5Sriastradh _mesa_program_lexer_dtor(state->scanner); 25893464ebd5Sriastradh 25903464ebd5Sriastradh 25913464ebd5Sriastradh if (ctx->Program.ErrorPos != -1) { 25923464ebd5Sriastradh goto error; 25933464ebd5Sriastradh } 25943464ebd5Sriastradh 25953464ebd5Sriastradh if (! _mesa_layout_parameters(state)) { 25963464ebd5Sriastradh struct YYLTYPE loc; 25973464ebd5Sriastradh 25983464ebd5Sriastradh loc.first_line = 0; 25993464ebd5Sriastradh loc.first_column = 0; 26003464ebd5Sriastradh loc.position = len; 26013464ebd5Sriastradh 26023464ebd5Sriastradh yyerror(& loc, state, "invalid PARAM usage"); 26033464ebd5Sriastradh goto error; 26043464ebd5Sriastradh } 26053464ebd5Sriastradh 26063464ebd5Sriastradh 26077ec681f3Smrg 26083464ebd5Sriastradh /* Add one instruction to store the "END" instruction. 26093464ebd5Sriastradh */ 261001e04c3fSmrg state->prog->arb.Instructions = 261101e04c3fSmrg rzalloc_array(state->mem_ctx, struct prog_instruction, 261201e04c3fSmrg state->prog->arb.NumInstructions + 1); 2613af69d88dSmrg 261401e04c3fSmrg if (state->prog->arb.Instructions == NULL) { 2615af69d88dSmrg goto error; 2616af69d88dSmrg } 2617af69d88dSmrg 26183464ebd5Sriastradh inst = state->inst_head; 261901e04c3fSmrg for (i = 0; i < state->prog->arb.NumInstructions; i++) { 26203464ebd5Sriastradh struct asm_instruction *const temp = inst->next; 26213464ebd5Sriastradh 262201e04c3fSmrg state->prog->arb.Instructions[i] = inst->Base; 26233464ebd5Sriastradh inst = temp; 26243464ebd5Sriastradh } 26253464ebd5Sriastradh 26263464ebd5Sriastradh /* Finally, tag on an OPCODE_END instruction */ 26273464ebd5Sriastradh { 262801e04c3fSmrg const GLuint numInst = state->prog->arb.NumInstructions; 262901e04c3fSmrg _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1); 263001e04c3fSmrg state->prog->arb.Instructions[numInst].Opcode = OPCODE_END; 26313464ebd5Sriastradh } 263201e04c3fSmrg state->prog->arb.NumInstructions++; 26333464ebd5Sriastradh 263401e04c3fSmrg state->prog->arb.NumParameters = state->prog->Parameters->NumParameters; 263501e04c3fSmrg state->prog->arb.NumAttributes = 263601e04c3fSmrg util_bitcount64(state->prog->info.inputs_read); 26373464ebd5Sriastradh 26383464ebd5Sriastradh /* 26393464ebd5Sriastradh * Initialize native counts to logical counts. The device driver may 26403464ebd5Sriastradh * change them if program is translated into a hardware program. 26413464ebd5Sriastradh */ 264201e04c3fSmrg state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions; 264301e04c3fSmrg state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries; 264401e04c3fSmrg state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters; 264501e04c3fSmrg state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes; 264601e04c3fSmrg state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs; 26473464ebd5Sriastradh 26483464ebd5Sriastradh result = GL_TRUE; 26493464ebd5Sriastradh 26503464ebd5Sriastradherror: 26513464ebd5Sriastradh for (inst = state->inst_head; inst != NULL; inst = temp) { 26523464ebd5Sriastradh temp = inst->next; 26533464ebd5Sriastradh free(inst); 26543464ebd5Sriastradh } 26553464ebd5Sriastradh 26563464ebd5Sriastradh state->inst_head = NULL; 26573464ebd5Sriastradh state->inst_tail = NULL; 26583464ebd5Sriastradh 26593464ebd5Sriastradh for (sym = state->sym; sym != NULL; sym = temp) { 26603464ebd5Sriastradh temp = sym->next; 26613464ebd5Sriastradh 26623464ebd5Sriastradh free((void *) sym->name); 26633464ebd5Sriastradh free(sym); 26643464ebd5Sriastradh } 26653464ebd5Sriastradh state->sym = NULL; 26663464ebd5Sriastradh 26673464ebd5Sriastradh _mesa_symbol_table_dtor(state->st); 26683464ebd5Sriastradh state->st = NULL; 26693464ebd5Sriastradh 26707ec681f3Smrg if (result != GL_TRUE) { 26717ec681f3Smrg if (state->prog->Parameters) { 26727ec681f3Smrg _mesa_free_parameter_list(state->prog->Parameters); 26737ec681f3Smrg state->prog->Parameters = NULL; 26747ec681f3Smrg } 26757ec681f3Smrg ralloc_free(state->prog->String); 26767ec681f3Smrg state->prog->String = NULL; 26777ec681f3Smrg } 26787ec681f3Smrg 26793464ebd5Sriastradh return result; 26803464ebd5Sriastradh} 2681