d3dx9: Add relative addressing support to the shader assembler.
[wine.git] / dlls / d3dx9_36 / asmshader.l
blob1d0e4b6efdaf0d4b5bc53799f6b5c024ce816f03
1 /*
2  * Direct3D shader assembler
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2009 Matteo Bruni
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
23 #include "config.h"
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dx9_36_private.h"
28 #include "asmshader.tab.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
33 %option noyywrap
34 %option prefix="asmshader_"
35 %option noinput nounput
37 /* Swizzles and writemasks consist of a dot and up to 4 x, y, z or w characters,
38  * or up to 4 a, r, g, b characters. There are different rules for swizzles and
39  * writemasks wrt repetition, those are handled in the grammar.
40  */
41 DOT                     \.
42 COMPONENT               [xyzw]|[rgba]
44 /* Registers */
45 REG_TEMP                r[0-9]+
46 /* for relative addressing in the form o[x], v[x] and c[x] */
47 REG_OUTPUT              o[0-9]*
48 REG_INPUT               v[0-9]*
49 REG_CONSTFLOAT          c[0-9]*
50 REG_CONSTINT            i[0-9]+
51 REG_CONSTBOOL           b[0-9]+
52 REG_TEXTURE             t[0-9]+
53 REG_TEXCRDOUT           oT[0-9]+
54 REG_SAMPLER             s[0-9]+
55 REG_OPOS                oPos
56 REG_OFOG                oFog
57 REG_OPTS                oPts
58 REG_VERTEXCOLOR         oD[01]
59 REG_FRAGCOLOR           oC[0-9]+
60 REG_FRAGDEPTH           oDepth
61 REG_VPOS                vPos
62 REG_VFACE               vFace
63 REG_ADDRESS             a0
64 REG_LOOP                aL
65 REG_PREDICATE           p0
66 /* Not really a register, but it is considered as such */
67 REG_LABEL               l[0-9]+
69 PREPROCESSORDIRECTIVE   #[^\n]*\n
71 /* Comments */
72 DOUBLESLASHCOMMENT      "//"[^\n]*
73 SEMICOLONCOMMENT        ";"[^\n]*
75 /* Whitespaces are spaces, tabs and newlines */
76 WHITESPACE              [ \t]+
77 NEWLINE                 (\n)|(\r\n)
79 COMMA                   ","
81 IMMVAL                  \-?(([0-9]+)|([0-9]*\.[0-9]+))(f)?
83 ANY                     (.)
87     /* Common instructions(vertex and pixel shaders) */
88 mov                     {return INSTR_MOV;          }
90 {REG_TEMP}              {
91                             asmshader_lval.regnum = atoi(yytext + 1);
92                             return REG_TEMP;
93                         }
94 {REG_OUTPUT}            {
95                             asmshader_lval.regnum = atoi(yytext + 1);
96                             return REG_OUTPUT;
97                         }
98 {REG_INPUT}             {
99                             asmshader_lval.regnum = atoi(yytext + 1);
100                             return REG_INPUT;
101                         }
102 {REG_CONSTFLOAT}        {
103                             asmshader_lval.regnum = atoi(yytext + 1);
104                             return REG_CONSTFLOAT;
105                         }
106 {REG_CONSTINT}          {
107                             asmshader_lval.regnum = atoi(yytext + 1);
108                             return REG_CONSTINT;
109                         }
110 {REG_CONSTBOOL}         {
111                             asmshader_lval.regnum = atoi(yytext + 1);
112                             return REG_CONSTBOOL;
113                         }
114 {REG_TEXTURE}           {
115                             asmshader_lval.regnum = atoi(yytext + 1);
116                             return REG_TEXTURE;
117                         }
118 {REG_TEXCRDOUT}         {
119                             asmshader_lval.regnum = atoi(yytext + 2);
120                             return REG_TEXCRDOUT;
121                         }
122 {REG_SAMPLER}           {
123                             asmshader_lval.regnum = atoi(yytext + 1);
124                             return REG_SAMPLER;
125                         }
126 {REG_OPOS}              {return REG_OPOS;           }
127 {REG_OFOG}              {return REG_OFOG;           }
128 {REG_OPTS}              {return REG_OPTS;           }
129 {REG_VERTEXCOLOR}       {
130                             asmshader_lval.regnum = atoi(yytext + 2);
131                             return REG_VERTEXCOLOR;
132                         }
133 {REG_FRAGCOLOR}         {
134                             asmshader_lval.regnum = atoi(yytext + 2);
135                             return REG_FRAGCOLOR;
136                         }
137 {REG_FRAGDEPTH}         {return REG_FRAGDEPTH;      }
138 {REG_VPOS}              {return REG_VPOS;           }
139 {REG_VFACE}             {return REG_VFACE;          }
140 {REG_ADDRESS}           {return REG_ADDRESS;        }
141 {REG_LOOP}              {return REG_LOOP;           }
142 {REG_PREDICATE}         {return REG_PREDICATE;      }
144 {REG_LABEL}             {
145                             asmshader_lval.regnum = atoi(yytext + 1);
146                             return REG_LABEL;
147                         }
149     /* Shader versions. These are important to select the correct
150      * parser profile.
151      */
152 vs\.1\.0|vs_1_0         {return VER_VS10;       }
153 vs\.1\.1|vs_1_1         {return VER_VS11;       }
155 vs_2_0                  {return VER_VS20;       }
156 vs_2_x                  {return VER_VS2X;       }
157 vs_3_0                  {return VER_VS30;       }
159 ps\.1\.0|ps_1_0         {return VER_PS10;       }
160 ps\.1\.1|ps_1_1         {return VER_PS11;       }
161 ps\.1\.2|ps_1_2         {return VER_PS12;       }
162 ps\.1\.3|ps_1_3         {return VER_PS13;       }
163 ps\.1\.4|ps_1_4         {return VER_PS14;       }
165 ps_2_0                  {return VER_PS20;       }
166 ps_2_x                  {return VER_PS2X;       }
167 ps_3_0                  {return VER_PS30;       }
169 {DOT}                   {return yytext[0];      }
170 {COMPONENT}             {
171                             switch(yytext[0]) {
172                                 case 'x':
173                                 case 'r':
174                                     asmshader_lval.component = 0;
175                                     break;
176                                 case 'y':
177                                 case 'g':
178                                     asmshader_lval.component = 1;
179                                     break;
180                                 case 'z':
181                                 case 'b':
182                                     asmshader_lval.component = 2;
183                                     break;
184                                 case 'w':
185                                 case 'a':
186                                     asmshader_lval.component = 3;
187                                     break;
188                             }
189                             return COMPONENT;
190                         }
192     /* Output modifiers */
193 \_sat                   {return MOD_SAT;            }
194 \_pp                    {return MOD_PP;             }
195 \_centroid              {return MOD_CENTROID;       }
197 {IMMVAL}                {
198                             asmshader_lval.immval.val = atof(yytext);
199                             asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL));
200                             return IMMVAL;
201                         }
203 {COMMA}                 {return yytext[0];          }
204 -                       {return yytext[0];          }
205 \(                      {return yytext[0];          }
206 \)                      {return yytext[0];          }
208     /* for relative addressing */
209 \[|\]|\+                {return yytext[0];          }
211 \_abs                   {return SMOD_ABS;           }
213 {PREPROCESSORDIRECTIVE} {
214                             /* TODO: update current line information */
215                             TRACE("line info update: %s", yytext);
216                         }
218     /* Skip comments */
219 {DOUBLESLASHCOMMENT}    {                           }
220 {SEMICOLONCOMMENT}      {                           }
222 {WHITESPACE}            { /* Do nothing */          }
223 {NEWLINE}               {
224                             asm_ctx.line_no++;
225                         }
227 {ANY}                   {
228                             asmparser_message(&asm_ctx, "Line %u: Unexpected input %s\n", asm_ctx.line_no, yytext);
229                             set_parse_status(&asm_ctx, PARSE_ERR);
230                         }
234 struct bwriter_shader *SlAssembleShader(const char *text, char **messages) {
235     struct bwriter_shader *ret = NULL;
236     YY_BUFFER_STATE buffer;
237     TRACE("%p, %p\n", text, messages);
239     buffer = asmshader__scan_string(text);
240     asmshader__switch_to_buffer(buffer);
242     ret = parse_asm_shader(messages);
244     asmshader__delete_buffer(buffer);
246     return ret;