shell32: Add printers CLSID to test, clean up a bit.
[wine/testsucceed.git] / dlls / d3dx9_36 / asmshader.y
blob93741b6a6406bac65966f9df2713c54ae84ca2c3
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"
29 #include <stdio.h>
31 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
33 struct asm_parser asm_ctx;
35 /* Needed lexer functions declarations */
36 void asmshader_error(const char *s);
37 int asmshader_lex(void);
39 void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
40 reg->rel_reg = NULL;
45 %union {
46 unsigned int regnum;
47 struct shader_reg reg;
48 struct {
49 DWORD swizzle;
50 DWORD writemask;
51 } swizzle_wmask;
52 DWORD writemask;
53 DWORD swizzle;
54 struct {
55 DWORD mod;
56 DWORD shift;
57 } modshift;
58 struct rel_reg rel_reg;
59 struct src_regs sregs;
62 /* Common instructions between vertex and pixel shaders */
63 %token INSTR_MOV
65 /* Registers */
66 %token <regnum> REG_TEMP
67 %token <regnum> REG_CONSTFLOAT
69 /* Version tokens */
70 %token VER_VS10
71 %token VER_VS11
72 %token VER_VS20
73 %token VER_VS2X
74 %token VER_VS30
76 %token VER_PS10
77 %token VER_PS11
78 %token VER_PS12
79 %token VER_PS13
80 %token VER_PS14
81 %token VER_PS20
82 %token VER_PS2X
83 %token VER_PS30
86 %type <reg> dreg_name
87 %type <reg> dreg
88 %type <reg> sreg_name
89 %type <reg> sreg
90 %type <swizzle> swizzle
91 %type <modshift> omods
92 %type <rel_reg> rel_reg
93 %type <sregs> sregs
97 shader: version_marker instructions
99 asm_ctx.funcs->end(&asm_ctx);
102 version_marker: VER_VS10
104 TRACE("Vertex shader 1.0\n");
105 set_parse_status(&asm_ctx, PARSE_ERR);
106 YYABORT;
108 | VER_VS11
110 TRACE("Vertex shader 1.1\n");
111 set_parse_status(&asm_ctx, PARSE_ERR);
112 YYABORT;
114 | VER_VS20
116 TRACE("Vertex shader 2.0\n");
117 set_parse_status(&asm_ctx, PARSE_ERR);
118 YYABORT;
120 | VER_VS2X
122 TRACE("Vertex shader 2.x\n");
123 set_parse_status(&asm_ctx, PARSE_ERR);
124 YYABORT;
126 | VER_VS30
128 TRACE("Vertex shader 3.0\n");
129 create_vs30_parser(&asm_ctx);
131 | VER_PS10
133 TRACE("Pixel shader 1.0\n");
134 set_parse_status(&asm_ctx, PARSE_ERR);
135 YYABORT;
137 | VER_PS11
139 TRACE("Pixel shader 1.1\n");
140 set_parse_status(&asm_ctx, PARSE_ERR);
141 YYABORT;
143 | VER_PS12
145 TRACE("Pixel shader 1.2\n");
146 set_parse_status(&asm_ctx, PARSE_ERR);
147 YYABORT;
149 | VER_PS13
151 TRACE("Pixel shader 1.3\n");
152 set_parse_status(&asm_ctx, PARSE_ERR);
153 YYABORT;
155 | VER_PS14
157 TRACE("Pixel shader 1.4\n");
158 set_parse_status(&asm_ctx, PARSE_ERR);
159 YYABORT;
161 | VER_PS20
163 TRACE("Pixel shader 2.0\n");
164 set_parse_status(&asm_ctx, PARSE_ERR);
165 YYABORT;
167 | VER_PS2X
169 TRACE("Pixel shader 2.x\n");
170 set_parse_status(&asm_ctx, PARSE_ERR);
171 YYABORT;
173 | VER_PS30
175 TRACE("Pixel shader 3.0\n");
176 set_parse_status(&asm_ctx, PARSE_ERR);
177 YYABORT;
180 instructions: /* empty */
181 | instructions complexinstr
183 /* Nothing to do */
186 complexinstr: instruction
191 instruction: INSTR_MOV omods dreg ',' sregs
193 TRACE("MOV\n");
194 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOV, $2.mod, $2.shift, 0, &$3, &$5, 1);
197 dreg: dreg_name rel_reg
199 $$.regnum = $1.regnum;
200 $$.type = $1.type;
201 $$.writemask = BWRITERSP_WRITEMASK_ALL;
202 $$.srcmod = BWRITERSPSM_NONE;
203 set_rel_reg(&$$, &$2);
206 dreg_name: REG_TEMP
208 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
211 swizzle: /* empty */
213 $$ = BWRITERVS_NOSWIZZLE;
214 TRACE("Default swizzle: %08x\n", $$);
217 omods: /* Empty */
219 $$.mod = 0;
220 $$.shift = 0;
223 sregs: sreg
225 $$.reg[0] = $1;
226 $$.count = 1;
228 | sregs ',' sreg
230 if($$.count == MAX_SRC_REGS){
231 asmparser_message(&asm_ctx, "Line %u: Too many source registers in this instruction\n",
232 asm_ctx.line_no);
233 set_parse_status(&asm_ctx, PARSE_ERR);
235 else
236 $$.reg[$$.count++] = $3;
239 sreg: sreg_name rel_reg swizzle
241 $$.type = $1.type;
242 $$.regnum = $1.regnum;
243 $$.swizzle = $3;
244 $$.srcmod = BWRITERSPSM_NONE;
245 set_rel_reg(&$$, &$2);
248 rel_reg: /* empty */
250 $$.has_rel_reg = FALSE;
251 $$.additional_offset = 0;
254 sreg_name: REG_TEMP
256 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
258 | REG_CONSTFLOAT
260 $$.regnum = $1; $$.type = BWRITERSPR_CONST;
265 void asmshader_error (char const *s) {
266 asmparser_message(&asm_ctx, "Line %u: Error \"%s\" from bison\n", asm_ctx.line_no, s);
267 set_parse_status(&asm_ctx, PARSE_ERR);
270 /* Error reporting function */
271 void asmparser_message(struct asm_parser *ctx, const char *fmt, ...) {
272 va_list args;
273 char* newbuffer;
274 int rc, newsize;
276 if(ctx->messagecapacity == 0) {
277 ctx->messages = asm_alloc(MESSAGEBUFFER_INITIAL_SIZE);
278 if(ctx->messages == NULL) {
279 ERR("Error allocating memory for parser messages\n");
280 return;
282 ctx->messagecapacity = MESSAGEBUFFER_INITIAL_SIZE;
285 while(1) {
286 va_start(args, fmt);
287 rc = vsnprintf(ctx->messages + ctx->messagesize,
288 ctx->messagecapacity - ctx->messagesize, fmt, args);
289 va_end(args);
291 if (rc < 0 || /* C89 */
292 rc >= ctx->messagecapacity - ctx->messagesize) { /* C99 */
293 /* Resize the buffer */
294 newsize = ctx->messagecapacity * 2;
295 newbuffer = asm_realloc(ctx->messages, newsize);
296 if(newbuffer == NULL){
297 ERR("Error reallocating memory for parser messages\n");
298 return;
300 ctx->messages = newbuffer;
301 ctx->messagecapacity = newsize;
302 } else {
303 ctx->messagesize += rc;
304 return;
309 /* New status is the worst between current status and parameter value */
310 void set_parse_status(struct asm_parser *ctx, enum parse_status status) {
311 if(status == PARSE_ERR) ctx->status = PARSE_ERR;
312 else if(status == PARSE_WARN && ctx->status == PARSE_SUCCESS) ctx->status = PARSE_WARN;
315 struct bwriter_shader *parse_asm_shader(char **messages) {
316 struct bwriter_shader *ret = NULL;
318 asm_ctx.shader = NULL;
319 asm_ctx.status = PARSE_SUCCESS;
320 asm_ctx.messagesize = asm_ctx.messagecapacity = 0;
321 asm_ctx.line_no = 1;
323 asmshader_parse();
325 if(asm_ctx.status != PARSE_ERR) ret = asm_ctx.shader;
326 else if(asm_ctx.shader) SlDeleteShader(asm_ctx.shader);
328 if(messages) {
329 if(asm_ctx.messagesize) {
330 /* Shrink the buffer to the used size */
331 *messages = asm_realloc(asm_ctx.messages, asm_ctx.messagesize + 1);
332 if(!*messages) {
333 ERR("Out of memory, no messages reported\n");
334 asm_free(asm_ctx.messages);
336 } else {
337 *messages = NULL;
339 } else {
340 if(asm_ctx.messagecapacity) asm_free(asm_ctx.messages);
343 return ret;