wined3d: Get rid of some mostly useless local variables in IWineD3DDeviceImpl_UpdateS...
[wine.git] / dlls / d3dx9_36 / asmshader.y
blob8bc93c1753908382d04ffc00c560a03956f73b8b
1 /*
2 * Direct3D shader assembler
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2009 Matteo Bruni
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.
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.
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
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 #include <stdio.h>
32 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
34 struct asm_parser asm_ctx;
36 /* Needed lexer functions declarations */
37 void asmshader_error(const char *s);
38 int asmshader_lex(void);
40 void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
41 reg->rel_reg = NULL;
46 %union {
47 unsigned int regnum;
48 struct shader_reg reg;
49 struct {
50 DWORD swizzle;
51 DWORD writemask;
52 } swizzle_wmask;
53 DWORD writemask;
54 DWORD swizzle;
55 struct {
56 DWORD mod;
57 DWORD shift;
58 } modshift;
59 struct rel_reg rel_reg;
60 struct src_regs sregs;
63 /* Common instructions between vertex and pixel shaders */
64 %token INSTR_MOV
66 /* Registers */
67 %token <regnum> REG_TEMP
68 %token <regnum> REG_CONSTFLOAT
70 /* Version tokens */
71 %token VER_VS10
72 %token VER_VS11
73 %token VER_VS20
74 %token VER_VS2X
75 %token VER_VS30
77 %token VER_PS10
78 %token VER_PS11
79 %token VER_PS12
80 %token VER_PS13
81 %token VER_PS14
82 %token VER_PS20
83 %token VER_PS2X
84 %token VER_PS30
87 %type <reg> dreg_name
88 %type <reg> dreg
89 %type <reg> sreg_name
90 %type <reg> sreg
91 %type <swizzle> swizzle
92 %type <modshift> omods
93 %type <rel_reg> rel_reg
94 %type <sregs> sregs
98 shader: version_marker instructions
100 asm_ctx.funcs->end(&asm_ctx);
103 version_marker: VER_VS10
105 TRACE("Vertex shader 1.0\n");
106 set_parse_status(&asm_ctx, PARSE_ERR);
107 YYABORT;
109 | VER_VS11
111 TRACE("Vertex shader 1.1\n");
112 set_parse_status(&asm_ctx, PARSE_ERR);
113 YYABORT;
115 | VER_VS20
117 TRACE("Vertex shader 2.0\n");
118 set_parse_status(&asm_ctx, PARSE_ERR);
119 YYABORT;
121 | VER_VS2X
123 TRACE("Vertex shader 2.x\n");
124 set_parse_status(&asm_ctx, PARSE_ERR);
125 YYABORT;
127 | VER_VS30
129 TRACE("Vertex shader 3.0\n");
130 create_vs30_parser(&asm_ctx);
132 | VER_PS10
134 TRACE("Pixel shader 1.0\n");
135 set_parse_status(&asm_ctx, PARSE_ERR);
136 YYABORT;
138 | VER_PS11
140 TRACE("Pixel shader 1.1\n");
141 set_parse_status(&asm_ctx, PARSE_ERR);
142 YYABORT;
144 | VER_PS12
146 TRACE("Pixel shader 1.2\n");
147 set_parse_status(&asm_ctx, PARSE_ERR);
148 YYABORT;
150 | VER_PS13
152 TRACE("Pixel shader 1.3\n");
153 set_parse_status(&asm_ctx, PARSE_ERR);
154 YYABORT;
156 | VER_PS14
158 TRACE("Pixel shader 1.4\n");
159 set_parse_status(&asm_ctx, PARSE_ERR);
160 YYABORT;
162 | VER_PS20
164 TRACE("Pixel shader 2.0\n");
165 set_parse_status(&asm_ctx, PARSE_ERR);
166 YYABORT;
168 | VER_PS2X
170 TRACE("Pixel shader 2.x\n");
171 set_parse_status(&asm_ctx, PARSE_ERR);
172 YYABORT;
174 | VER_PS30
176 TRACE("Pixel shader 3.0\n");
177 set_parse_status(&asm_ctx, PARSE_ERR);
178 YYABORT;
181 instructions: /* empty */
182 | instructions complexinstr
184 /* Nothing to do */
187 complexinstr: instruction
192 instruction: INSTR_MOV omods dreg ',' sregs
194 TRACE("MOV\n");
195 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOV, $2.mod, $2.shift, 0, &$3, &$5, 1);
198 dreg: dreg_name rel_reg
200 $$.regnum = $1.regnum;
201 $$.type = $1.type;
202 $$.writemask = BWRITERSP_WRITEMASK_ALL;
203 $$.srcmod = BWRITERSPSM_NONE;
204 set_rel_reg(&$$, &$2);
207 dreg_name: REG_TEMP
209 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
212 swizzle: /* empty */
214 $$ = BWRITERVS_NOSWIZZLE;
215 TRACE("Default swizzle: %08x\n", $$);
218 omods: /* Empty */
220 $$.mod = 0;
221 $$.shift = 0;
224 sregs: sreg
226 $$.reg[0] = $1;
227 $$.count = 1;
229 | sregs ',' sreg
231 if($$.count == MAX_SRC_REGS){
232 asmparser_message(&asm_ctx, "Line %u: Too many source registers in this instruction\n",
233 asm_ctx.line_no);
234 set_parse_status(&asm_ctx, PARSE_ERR);
236 else
237 $$.reg[$$.count++] = $3;
240 sreg: sreg_name rel_reg swizzle
242 $$.type = $1.type;
243 $$.regnum = $1.regnum;
244 $$.swizzle = $3;
245 $$.srcmod = BWRITERSPSM_NONE;
246 set_rel_reg(&$$, &$2);
249 rel_reg: /* empty */
251 $$.has_rel_reg = FALSE;
252 $$.additional_offset = 0;
255 sreg_name: REG_TEMP
257 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
259 | REG_CONSTFLOAT
261 $$.regnum = $1; $$.type = BWRITERSPR_CONST;
266 void asmshader_error (char const *s) {
267 asmparser_message(&asm_ctx, "Line %u: Error \"%s\" from bison\n", asm_ctx.line_no, s);
268 set_parse_status(&asm_ctx, PARSE_ERR);
271 /* Error reporting function */
272 void asmparser_message(struct asm_parser *ctx, const char *fmt, ...) {
273 va_list args;
274 char* newbuffer;
275 int rc, newsize;
277 if(ctx->messagecapacity == 0) {
278 ctx->messages = asm_alloc(MESSAGEBUFFER_INITIAL_SIZE);
279 if(ctx->messages == NULL) {
280 ERR("Error allocating memory for parser messages\n");
281 return;
283 ctx->messagecapacity = MESSAGEBUFFER_INITIAL_SIZE;
286 while(1) {
287 va_start(args, fmt);
288 rc = vsnprintf(ctx->messages + ctx->messagesize,
289 ctx->messagecapacity - ctx->messagesize, fmt, args);
290 va_end(args);
292 if (rc < 0 || /* C89 */
293 rc >= ctx->messagecapacity - ctx->messagesize) { /* C99 */
294 /* Resize the buffer */
295 newsize = ctx->messagecapacity * 2;
296 newbuffer = asm_realloc(ctx->messages, newsize);
297 if(newbuffer == NULL){
298 ERR("Error reallocating memory for parser messages\n");
299 return;
301 ctx->messages = newbuffer;
302 ctx->messagecapacity = newsize;
303 } else {
304 ctx->messagesize += rc;
305 return;
310 /* New status is the worst between current status and parameter value */
311 void set_parse_status(struct asm_parser *ctx, enum parse_status status) {
312 if(status == PARSE_ERR) ctx->status = PARSE_ERR;
313 else if(status == PARSE_WARN && ctx->status == PARSE_SUCCESS) ctx->status = PARSE_WARN;
316 struct bwriter_shader *parse_asm_shader(char **messages) {
317 struct bwriter_shader *ret = NULL;
319 asm_ctx.shader = NULL;
320 asm_ctx.status = PARSE_SUCCESS;
321 asm_ctx.messagesize = asm_ctx.messagecapacity = 0;
322 asm_ctx.line_no = 1;
324 asmshader_parse();
326 if(asm_ctx.status != PARSE_ERR) ret = asm_ctx.shader;
327 else if(asm_ctx.shader) SlDeleteShader(asm_ctx.shader);
329 if(messages) {
330 if(asm_ctx.messagesize) {
331 /* Shrink the buffer to the used size */
332 *messages = asm_realloc(asm_ctx.messages, asm_ctx.messagesize + 1);
333 if(!*messages) {
334 ERR("Out of memory, no messages reported\n");
335 asm_free(asm_ctx.messages);
337 } else {
338 *messages = NULL;
340 } else {
341 if(asm_ctx.messagecapacity) asm_free(asm_ctx.messages);
344 return ret;