diff options
author | Ian Romanick <[email protected]> | 2009-07-20 17:44:36 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2009-07-20 17:44:36 -0700 |
commit | 770cebbc29863ae944a31463ee4bdeb789105aba (patch) | |
tree | 9792859ab2c18f730cb0646812d75063f2c02076 /src/mesa/shader/program_lexer.l | |
parent | 480567d5c451511a72744b0c849960c2b712e093 (diff) |
ARB_fp/vp: Initial import of new ARB vp/fp assembler
This still needs quite a bit of work, but a bunch of the programs in progs/vp
produce correct results.
Diffstat (limited to 'src/mesa/shader/program_lexer.l')
-rw-r--r-- | src/mesa/shader/program_lexer.l | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/src/mesa/shader/program_lexer.l b/src/mesa/shader/program_lexer.l new file mode 100644 index 00000000000..2d207726315 --- /dev/null +++ b/src/mesa/shader/program_lexer.l @@ -0,0 +1,482 @@ +%{ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "main/glheader.h" +#include "prog_instruction.h" + +#include "program_parser.h" +#include "program_parse.tab.h" + +#define require_ARB_vp (yyextra->mode == ARB_vertex) +#define require_ARB_fp (yyextra->mode == ARB_fragment) + +#define return_token_or_IDENTIFIER(condition, token) \ + do { \ + if (condition) { \ + return token; \ + } else { \ + yylval->string = strdup(yytext); \ + return IDENTIFIER; \ + } \ + } while (0) + +#define return_token_or_DOT(condition, token) \ + do { \ + if (condition) { \ + return token; \ + } else { \ + yyless(1); \ + return DOT; \ + } \ + } while (0) + + +#define return_opcode(condition, token, opcode, sat) \ + do { \ + if (condition) { \ + yylval->temp_inst.Opcode = OPCODE_ ## opcode; \ + yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \ + return token; \ + } else { \ + yylval->string = strdup(yytext); \ + return IDENTIFIER; \ + } \ + } while (0) + +#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ + SWIZZLE_NIL, SWIZZLE_NIL) + +static unsigned +mask_from_char(char c) +{ + switch (c) { + case 'x': + case 'r': + return WRITEMASK_X; + case 'y': + case 'g': + return WRITEMASK_Y; + case 'z': + case 'b': + return WRITEMASK_Z; + case 'w': + case 'a': + return WRITEMASK_W; + } + + return 0; +} + +static unsigned +swiz_from_char(char c) +{ + switch (c) { + case 'x': + case 'r': + return SWIZZLE_X; + case 'y': + case 'g': + return SWIZZLE_Y; + case 'z': + case 'b': + return SWIZZLE_Z; + case 'w': + case 'a': + return SWIZZLE_W; + } + + return 0; +} + +#define YY_USER_ACTION \ + do { \ + yylloc->first_column = yylloc->last_column; \ + yylloc->last_column += yyleng; \ + if ((yylloc->first_line == 1) \ + && (yylloc->first_column == 1)) { \ + yylloc->position = 1; \ + } else { \ + yylloc->position += yylloc->last_column - yylloc->first_column; \ + } \ + } while(0); + +#define YY_EXTRA_TYPE struct asm_parser_state * +%} + +num [0-9]+ +exp [Ee][-+]?[0-9]+ +frac "."[0-9]+ +dot "."[ \t]* + +%option bison-bridge bison-locations reentrant noyywrap +%% + +"!!ARBvp1.0" { return ARBvp_10; } +"!!ARBfp1.0" { return ARBfp_10; } +ADDRESS { + yylval->integer = at_address; + return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS); +} +ALIAS { return ALIAS; } +ATTRIB { return ATTRIB; } +END { return END; } +OPTION { return OPTION; } +OUTPUT { return OUTPUT; } +PARAM { return PARAM; } +TEMP { yylval->integer = at_temp; return TEMP; } + +ABS { return_opcode( 1, VECTOR_OP, ABS, OFF); } +ABS_SAT { return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); } +ADD { return_opcode( 1, BIN_OP, ADD, OFF); } +ADD_SAT { return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); } +ARL { return_opcode(require_ARB_vp, ARL, ARL, OFF); } + +CMP { return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); } +CMP_SAT { return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); } +COS { return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); } +COS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); } + +DP3 { return_opcode( 1, BIN_OP, DP3, OFF); } +DP3_SAT { return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); } +DP4 { return_opcode( 1, BIN_OP, DP4, OFF); } +DP4_SAT { return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); } +DPH { return_opcode( 1, BIN_OP, DPH, OFF); } +DPH_SAT { return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); } +DST { return_opcode( 1, BIN_OP, DST, OFF); } +DST_SAT { return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); } + +EX2 { return_opcode( 1, SCALAR_OP, EX2, OFF); } +EX2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); } +EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); } + +FLR { return_opcode( 1, VECTOR_OP, FLR, OFF); } +FLR_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); } +FRC { return_opcode( 1, VECTOR_OP, FRC, OFF); } +FRC_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); } + +KIL { return_opcode(require_ARB_fp, KIL, KIL, OFF); } + +LIT { return_opcode( 1, VECTOR_OP, LIT, OFF); } +LIT_SAT { return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); } +LG2 { return_opcode( 1, SCALAR_OP, LG2, OFF); } +LG2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); } +LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); } +LRP { return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); } +LRP_SAT { return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); } + +MAD { return_opcode( 1, TRI_OP, MAD, OFF); } +MAD_SAT { return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); } +MAX { return_opcode( 1, BIN_OP, MAX, OFF); } +MAX_SAT { return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); } +MIN { return_opcode( 1, BIN_OP, MIN, OFF); } +MIN_SAT { return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); } +MOV { return_opcode( 1, VECTOR_OP, MOV, OFF); } +MOV_SAT { return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); } +MUL { return_opcode( 1, BIN_OP, MUL, OFF); } +MUL_SAT { return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); } + +POW { return_opcode( 1, BINSC_OP, POW, OFF); } +POW_SAT { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); } + +RCP { return_opcode( 1, SCALAR_OP, RCP, OFF); } +RCP_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); } +RSQ { return_opcode( 1, SCALAR_OP, RSQ, OFF); } +RSQ_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); } + +SCS { return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); } +SCS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); } +SGE { return_opcode( 1, BIN_OP, SGE, OFF); } +SGE_SAT { return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); } +SIN { return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); } +SIN_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); } +SLT { return_opcode( 1, BIN_OP, SLT, OFF); } +SLT_SAT { return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); } +SUB { return_opcode( 1, BIN_OP, SUB, OFF); } +SUB_SAT { return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); } +SWZ { return_opcode( 1, SWZ, SWZ, OFF); } +SWZ_SAT { return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); } + +TEX { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); } +TEX_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); } +TXB { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); } +TXB_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); } +TXP { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); } +TXP_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); } + +XPD { return_opcode( 1, BIN_OP, XPD, OFF); } +XPD_SAT { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); } + +vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); } +fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); } +program { return PROGRAM; } +state { return STATE; } +result { return RESULT; } + +{dot}ambient { return AMBIENT; } +{dot}attenuation { return_token_or_DOT(require_ARB_vp, ATTENUATION); } +{dot}back { return BACK; } +{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); } +{dot}color { return COLOR; } +{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); } +{dot}diffuse { return DIFFUSE; } +{dot}direction { return DIRECTION; } +{dot}emission { return EMISSION; } +{dot}env { return ENV; } +{dot}eye { return EYE; } +{dot}fogcoord { return FOGCOORD; } +{dot}fog { return FOG; } +{dot}front { return FRONT; } +{dot}half { return HALF; } +{dot}inverse { return INVERSE; } +{dot}invtrans { return INVTRANS; } +{dot}light { return LIGHT; } +{dot}lightmodel { return LIGHTMODEL; } +{dot}lightprod { return LIGHTPROD; } +{dot}local { return LOCAL; } +{dot}material { return MATERIAL; } +{dot}program { return MAT_PROGRAM; } +{dot}matrix { return MATRIX; } +{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); } +{dot}modelview { return MODELVIEW; } +{dot}mvp { return MVP; } +{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); } +{dot}object { return OBJECT; } +{dot}palette { return PALETTE; } +{dot}params { return PARAMS; } +{dot}plane { return PLANE; } +{dot}point { return_token_or_DOT(require_ARB_vp, POINT); } +{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); } +{dot}position { return POSITION; } +{dot}primary { return PRIMARY; } +{dot}projection { return PROJECTION; } +{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); } +{dot}row { return ROW; } +{dot}scenecolor { return SCENECOLOR; } +{dot}secondary { return SECONDARY; } +{dot}shininess { return SHININESS; } +{dot}size { return_token_or_DOT(require_ARB_vp, SIZE); } +{dot}specular { return SPECULAR; } +{dot}spot { return SPOT; } +{dot}texcoord { return TEXCOORD; } +{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); } +{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); } +{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); } +{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); } +{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); } +{dot}texture { return TEXTURE; } +{dot}transpose { return TRANSPOSE; } +{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); } +{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); } + +texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); } +1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); } +2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); } +3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); } +CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); } +RECT { return_token_or_IDENTIFIER(require_ARB_fp, TEX_RECT); } + +[_a-zA-Z$][_a-zA-Z0-9$]* { + yylval->string = strdup(yytext); + return IDENTIFIER; +} + +".." { return DOT_DOT; } + +{num} { + yylval->integer = strtol(yytext, NULL, 10); + return INTEGER; +} +{num}?{frac}{exp}? { + yylval->real = strtod(yytext, NULL); + return REAL; +} +{num}"."/[^.] { + yylval->real = strtod(yytext, NULL); + return REAL; +} +{num}{exp} { + yylval->real = strtod(yytext, NULL); + return REAL; +} +{num}"."{exp} { + yylval->real = strtod(yytext, NULL); + return REAL; +} + +".xyzw" { + yylval->swiz_mask.swizzle = SWIZZLE_NOOP; + yylval->swiz_mask.mask = WRITEMASK_XYZW; + return MASK4; +} + +".xy"[zw] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XY + | mask_from_char(yytext[3]); + return MASK3; +} +".xzw" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XZW; + return MASK3; +} +".yzw" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_YZW; + return MASK3; +} + +".x"[yzw] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_X + | mask_from_char(yytext[2]); + return MASK2; +} +".y"[zw] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_Y + | mask_from_char(yytext[2]); + return MASK2; +} +".zw" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_ZW; + return MASK2; +} + +"."[xyzw] { + const unsigned s = swiz_from_char(yytext[1]); + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); + yylval->swiz_mask.mask = mask_from_char(yytext[1]); + return MASK1; +} + +"."[xyzw]{4} { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), + swiz_from_char(yytext[2]), + swiz_from_char(yytext[3]), + swiz_from_char(yytext[4])); + yylval->swiz_mask.mask = 0; + return SWIZZLE; +} + +".rgba" { + yylval->swiz_mask.swizzle = SWIZZLE_NOOP; + yylval->swiz_mask.mask = WRITEMASK_XYZW; + return_token_or_DOT(require_ARB_fp, MASK4); +} + +".rg"[ba] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XY + | mask_from_char(yytext[3]); + return_token_or_DOT(require_ARB_fp, MASK3); +} +".rba" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XZW; + return_token_or_DOT(require_ARB_fp, MASK3); +} +".gba" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_YZW; + return_token_or_DOT(require_ARB_fp, MASK3); +} + +".r"[gba] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_X + | mask_from_char(yytext[2]); + return_token_or_DOT(require_ARB_fp, MASK2); +} +".g"[ba] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_Y + | mask_from_char(yytext[2]); + return_token_or_DOT(require_ARB_fp, MASK2); +} +".ba" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_ZW; + return_token_or_DOT(require_ARB_fp, MASK2); +} + +"."[gba] { + const unsigned s = swiz_from_char(yytext[1]); + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); + yylval->swiz_mask.mask = mask_from_char(yytext[1]); + return_token_or_DOT(require_ARB_fp, MASK1); +} + + +".r" { + if (require_ARB_vp) { + return TEXGEN_R; + } else { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, + SWIZZLE_X, SWIZZLE_X); + yylval->swiz_mask.mask = WRITEMASK_X; + return MASK1; + } +} + +"."[rgba]{4} { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), + swiz_from_char(yytext[2]), + swiz_from_char(yytext[3]), + swiz_from_char(yytext[4])); + yylval->swiz_mask.mask = 0; + return_token_or_DOT(require_ARB_fp, SWIZZLE); +} + +"." { return DOT; } + +\n { + yylloc->first_line++; + yylloc->first_column = 1; + yylloc->last_line++; + yylloc->last_column = 1; + yylloc->position++; +} +[ \t]+ /* eat whitespace */ ; +#.*$ /* eat comments */ ; +. { return yytext[0]; } +%% + +void +_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state, + const char *string, size_t len) +{ + yylex_init_extra(state, scanner); + yy_scan_bytes(string, len, *scanner); +} + +void +_mesa_program_lexer_dtor(void *scanner) +{ + /* FINISHME: It's not clear to me whether or not the buffer state returned + * FINISHME: by yy_scan_bytes in _mesa_program_lexer_ctor needs to be + * FINISHME: explicitly destroyed here or not. + */ + yylex_destroy(scanner); +} |