wineps: Handle EMR_INVERTRGN record in spool files.
[wine.git] / dlls / d3dcompiler_43 / asmparser.c
blob3e400827d92c73049d6ab9eac4bd3451e5153047
1 /*
2 * Direct3D asm shader parser
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 "wine/debug.h"
25 #include "d3dcompiler_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
28 WINE_DECLARE_DEBUG_CHANNEL(parsed_shader);
31 /* How to map vs 1.0 and 2.0 varyings to 3.0 ones
32 * oTx is mapped to ox, which happens to be an
33 * identical mapping since BWRITERSPR_TEXCRDOUT == BWRITERSPR_OUTPUT
34 * oPos, oFog and point size are mapped to general output regs as well.
35 * the vs 1.x and 2.x parser functions add varying declarations
36 * to the shader, and the 1.x and 2.x output functions check those varyings
38 #define OT0_REG 0
39 #define OT1_REG 1
40 #define OT2_REG 2
41 #define OT3_REG 3
42 #define OT4_REG 4
43 #define OT5_REG 5
44 #define OT6_REG 6
45 #define OT7_REG 7
46 #define OPOS_REG 8
47 #define OFOG_REG 9
48 #define OFOG_WRITEMASK BWRITERSP_WRITEMASK_0
49 #define OPTS_REG 9
50 #define OPTS_WRITEMASK BWRITERSP_WRITEMASK_1
51 #define OD0_REG 10
52 #define OD1_REG 11
54 /* Input color registers 0-1 are identically mapped */
55 #define C0_VARYING 0
56 #define C1_VARYING 1
57 #define T0_VARYING 2
58 #define T1_VARYING 3
59 #define T2_VARYING 4
60 #define T3_VARYING 5
61 #define T4_VARYING 6
62 #define T5_VARYING 7
63 #define T6_VARYING 8
64 #define T7_VARYING 9
66 /****************************************************************
67 * Common(non-version specific) shader parser control code *
68 ****************************************************************/
70 static void asmparser_end(struct asm_parser *This) {
71 TRACE("Finalizing shader\n");
74 static void asmparser_constF(struct asm_parser *parser, uint32_t reg, float x, float y, float z, float w)
76 if (!parser->shader)
77 return;
78 TRACE("Adding float constant %u at pos %u.\n", reg, parser->shader->num_cf);
79 TRACE_(parsed_shader)("def c%u, %f, %f, %f, %f\n", reg, x, y, z, w);
80 if (!add_constF(parser->shader, reg, x, y, z, w))
82 ERR("Out of memory.\n");
83 set_parse_status(&parser->status, PARSE_ERR);
87 static void asmparser_constB(struct asm_parser *parser, uint32_t reg, BOOL x)
89 if (!parser->shader)
90 return;
91 TRACE("Adding boolean constant %u at pos %u.\n", reg, parser->shader->num_cb);
92 TRACE_(parsed_shader)("def b%u, %s\n", reg, x ? "true" : "false");
93 if (!add_constB(parser->shader, reg, x))
95 ERR("Out of memory.\n");
96 set_parse_status(&parser->status, PARSE_ERR);
100 static void asmparser_constI(struct asm_parser *parser, uint32_t reg, int x, int y, int z, int w)
102 if (!parser->shader)
103 return;
104 TRACE("Adding integer constant %u at pos %u.\n", reg, parser->shader->num_ci);
105 TRACE_(parsed_shader)("def i%u, %d, %d, %d, %d\n", reg, x, y, z, w);
106 if (!add_constI(parser->shader, reg, x, y, z, w))
108 ERR("Out of memory.\n");
109 set_parse_status(&parser->status, PARSE_ERR);
113 static void asmparser_dcl_output(struct asm_parser *parser, uint32_t usage, uint32_t num,
114 const struct shader_reg *reg)
116 if (!parser->shader)
117 return;
118 if (parser->shader->type == ST_PIXEL)
120 asmparser_message(parser, "Line %u: Output register declared in a pixel shader\n", parser->line_no);
121 set_parse_status(&parser->status, PARSE_ERR);
123 if (!record_declaration(parser->shader, usage, num, 0, TRUE, reg->regnum, reg->writemask, FALSE))
125 ERR("Out of memory\n");
126 set_parse_status(&parser->status, PARSE_ERR);
130 static void asmparser_dcl_output_unsupported(struct asm_parser *parser, uint32_t usage, uint32_t num,
131 const struct shader_reg *reg)
133 asmparser_message(parser, "Line %u: Output declaration unsupported in this shader version\n", parser->line_no);
134 set_parse_status(&parser->status, PARSE_ERR);
137 static void asmparser_dcl_input(struct asm_parser *parser, uint32_t usage, uint32_t num, uint32_t mod,
138 const struct shader_reg *reg)
140 struct instruction instr;
142 if (!parser->shader)
143 return;
144 if (mod && (parser->shader->type != ST_PIXEL || parser->shader->major_version != 3
145 || (mod != BWRITERSPDM_MSAMPCENTROID && mod != BWRITERSPDM_PARTIALPRECISION)))
147 asmparser_message(parser, "Line %u: Unsupported modifier in dcl instruction\n", parser->line_no);
148 set_parse_status(&parser->status, PARSE_ERR);
149 return;
152 /* Check register type and modifiers */
153 instr.dstmod = mod;
154 instr.shift = 0;
155 parser->funcs->dstreg(parser, &instr, reg);
157 if (!record_declaration(parser->shader, usage, num, mod, FALSE, reg->regnum, reg->writemask, FALSE))
159 ERR("Out of memory\n");
160 set_parse_status(&parser->status, PARSE_ERR);
164 static void asmparser_dcl_input_ps_2(struct asm_parser *parser, uint32_t usage, uint32_t num, uint32_t mod,
165 const struct shader_reg *reg)
167 struct instruction instr;
169 if (!parser->shader)
170 return;
171 instr.dstmod = mod;
172 instr.shift = 0;
173 parser->funcs->dstreg(parser, &instr, reg);
174 if (!record_declaration(parser->shader, usage, num, mod, FALSE, instr.dst.regnum, instr.dst.writemask, FALSE))
176 ERR("Out of memory\n");
177 set_parse_status(&parser->status, PARSE_ERR);
181 static void asmparser_dcl_input_unsupported(struct asm_parser *parser, uint32_t usage, uint32_t num, uint32_t mod,
182 const struct shader_reg *reg)
184 asmparser_message(parser, "Line %u: Input declaration unsupported in this shader version\n", parser->line_no);
185 set_parse_status(&parser->status, PARSE_ERR);
188 static void asmparser_dcl_sampler(struct asm_parser *parser, uint32_t samptype, uint32_t mod, uint32_t regnum,
189 unsigned int line_no)
191 if (!parser->shader)
192 return;
193 if (mod && (parser->shader->type != ST_PIXEL || parser->shader->major_version != 3
194 || (mod != BWRITERSPDM_MSAMPCENTROID && mod != BWRITERSPDM_PARTIALPRECISION)))
196 asmparser_message(parser, "Line %u: Unsupported modifier in dcl instruction\n", parser->line_no);
197 set_parse_status(&parser->status, PARSE_ERR);
198 return;
200 if (!record_sampler(parser->shader, samptype, mod, regnum))
202 ERR("Out of memory\n");
203 set_parse_status(&parser->status, PARSE_ERR);
207 static void asmparser_dcl_sampler_unsupported(struct asm_parser *parser, uint32_t samptype, uint32_t mod,
208 uint32_t regnum, unsigned int line_no)
210 asmparser_message(parser, "Line %u: Sampler declaration unsupported in this shader version\n", parser->line_no);
211 set_parse_status(&parser->status, PARSE_ERR);
214 static void asmparser_sincos(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
215 const struct src_regs *srcs)
217 struct instruction *instr;
219 if (!srcs || srcs->count != 3)
221 asmparser_message(parser, "Line %u: sincos (vs 2) has an incorrect number of source registers\n", parser->line_no);
222 set_parse_status(&parser->status, PARSE_ERR);
223 return;
226 instr = alloc_instr(3);
227 if (!instr)
229 ERR("Error allocating memory for the instruction\n");
230 set_parse_status(&parser->status, PARSE_ERR);
231 return;
234 instr->opcode = BWRITERSIO_SINCOS;
235 instr->dstmod = mod;
236 instr->shift = shift;
237 instr->comptype = 0;
239 parser->funcs->dstreg(parser, instr, dst);
240 parser->funcs->srcreg(parser, instr, 0, &srcs->reg[0]);
241 parser->funcs->srcreg(parser, instr, 1, &srcs->reg[1]);
242 parser->funcs->srcreg(parser, instr, 2, &srcs->reg[2]);
244 if (!add_instruction(parser->shader, instr))
246 ERR("Out of memory\n");
247 set_parse_status(&parser->status, PARSE_ERR);
251 static struct shader_reg map_oldps_register(const struct shader_reg *reg, BOOL tex_varying)
253 struct shader_reg ret;
255 switch (reg->type)
257 case BWRITERSPR_TEXTURE:
258 if (tex_varying)
260 ret = *reg;
261 ret.type = BWRITERSPR_INPUT;
262 switch (reg->regnum)
264 case 0: ret.regnum = T0_VARYING; break;
265 case 1: ret.regnum = T1_VARYING; break;
266 case 2: ret.regnum = T2_VARYING; break;
267 case 3: ret.regnum = T3_VARYING; break;
268 case 4: ret.regnum = T4_VARYING; break;
269 case 5: ret.regnum = T5_VARYING; break;
270 case 6: ret.regnum = T6_VARYING; break;
271 case 7: ret.regnum = T7_VARYING; break;
272 default:
273 FIXME("Unexpected TEXTURE register t%u.\n", reg->regnum);
274 return *reg;
276 return ret;
278 else
280 ret = *reg;
281 ret.type = BWRITERSPR_TEMP;
282 switch(reg->regnum)
284 case 0: ret.regnum = T0_REG; break;
285 case 1: ret.regnum = T1_REG; break;
286 case 2: ret.regnum = T2_REG; break;
287 case 3: ret.regnum = T3_REG; break;
288 default:
289 FIXME("Unexpected TEXTURE register t%u.\n", reg->regnum);
290 return *reg;
292 return ret;
295 /* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
296 to 3.0 ones */
298 default: return *reg;
302 static void asmparser_texcoord(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
303 const struct src_regs *srcs)
305 struct instruction *instr;
307 if (srcs)
309 asmparser_message(parser, "Line %u: Source registers in texcoord instruction\n", parser->line_no);
310 set_parse_status(&parser->status, PARSE_ERR);
311 return;
314 instr = alloc_instr(1);
315 if (!instr)
317 ERR("Error allocating memory for the instruction\n");
318 set_parse_status(&parser->status, PARSE_ERR);
319 return;
322 /* texcoord copies the texture coord data into a temporary register-like
323 * readable form. In newer shader models this equals a MOV from v0 to r0,
324 * record it as this.
326 instr->opcode = BWRITERSIO_MOV;
327 instr->dstmod = mod | BWRITERSPDM_SATURATE; /* texcoord clamps to [0;1] */
328 instr->shift = shift;
329 instr->comptype = 0;
331 parser->funcs->dstreg(parser, instr, dst);
332 /* The src reg needs special care */
333 instr->src[0] = map_oldps_register(dst, TRUE);
335 if (!add_instruction(parser->shader, instr))
337 ERR("Out of memory\n");
338 set_parse_status(&parser->status, PARSE_ERR);
342 static void asmparser_texcrd(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
343 const struct src_regs *srcs)
345 struct instruction *instr;
347 if (!srcs || srcs->count != 1)
349 asmparser_message(parser, "Line %u: Wrong number of source registers in texcrd instruction\n", parser->line_no);
350 set_parse_status(&parser->status, PARSE_ERR);
351 return;
354 instr = alloc_instr(1);
355 if (!instr)
357 ERR("Error allocating memory for the instruction\n");
358 set_parse_status(&parser->status, PARSE_ERR);
359 return;
362 /* The job of texcrd is done by mov in later shader versions */
363 instr->opcode = BWRITERSIO_MOV;
364 instr->dstmod = mod;
365 instr->shift = shift;
366 instr->comptype = 0;
368 parser->funcs->dstreg(parser, instr, dst);
369 parser->funcs->srcreg(parser, instr, 0, &srcs->reg[0]);
371 if (!add_instruction(parser->shader, instr))
373 ERR("Out of memory\n");
374 set_parse_status(&parser->status, PARSE_ERR);
378 static void asmparser_texkill(struct asm_parser *parser, const struct shader_reg *dst)
380 struct instruction *instr = alloc_instr(0);
382 if (!instr)
384 ERR("Error allocating memory for the instruction\n");
385 set_parse_status(&parser->status, PARSE_ERR);
386 return;
389 instr->opcode = BWRITERSIO_TEXKILL;
390 instr->dstmod = 0;
391 instr->shift = 0;
392 instr->comptype = 0;
394 /* Do not run the dst register through the normal
395 * register conversion. If used with ps_1_0 to ps_1_3
396 * the texture coordinate from that register is used,
397 * not the temporary register value. In ps_1_4 and
398 * ps_2_0 t0 is always a varying and temporaries can
399 * be used with texkill.
401 instr->dst = map_oldps_register(dst, TRUE);
402 instr->has_dst = TRUE;
404 if (!add_instruction(parser->shader, instr))
406 ERR("Out of memory\n");
407 set_parse_status(&parser->status, PARSE_ERR);
411 static void asmparser_texhelper(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
412 const struct shader_reg *src0)
414 struct instruction *instr = alloc_instr(2);
416 if (!instr)
418 ERR("Error allocating memory for the instruction\n");
419 set_parse_status(&parser->status, PARSE_ERR);
420 return;
423 instr->opcode = BWRITERSIO_TEX;
424 instr->dstmod = mod;
425 instr->shift = shift;
426 instr->comptype = 0;
427 /* The dest register can be mapped normally to a temporary register */
428 parser->funcs->dstreg(parser, instr, dst);
429 /* Use the src passed as parameter by the specific instruction handler */
430 instr->src[0] = *src0;
432 /* The 2nd source register is the sampler register with the
433 * destination's regnum
435 ZeroMemory(&instr->src[1], sizeof(instr->src[1]));
436 instr->src[1].type = BWRITERSPR_SAMPLER;
437 instr->src[1].regnum = dst->regnum;
438 instr->src[1].swizzle = BWRITERVS_NOSWIZZLE;
439 instr->src[1].srcmod = BWRITERSPSM_NONE;
440 instr->src[1].rel_reg = NULL;
442 if (!add_instruction(parser->shader, instr))
444 ERR("Out of memory\n");
445 set_parse_status(&parser->status, PARSE_ERR);
449 static void asmparser_tex(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst)
451 struct shader_reg src;
453 /* The first source register is the varying containing the coordinate */
454 src = map_oldps_register(dst, TRUE);
455 asmparser_texhelper(parser, mod, shift, dst, &src);
458 static void asmparser_texld14(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
459 const struct src_regs *srcs)
461 struct instruction *instr;
463 if (!srcs || srcs->count != 1)
465 asmparser_message(parser, "Line %u: texld (PS 1.4) has a wrong number of source registers\n", parser->line_no);
466 set_parse_status(&parser->status, PARSE_ERR);
467 return;
470 instr = alloc_instr(2);
471 if (!instr)
473 ERR("Error allocating memory for the instruction\n");
474 set_parse_status(&parser->status, PARSE_ERR);
475 return;
478 /* This code is recording a texld instruction, not tex. However,
479 * texld borrows the opcode of tex
481 instr->opcode = BWRITERSIO_TEX;
482 instr->dstmod = mod;
483 instr->shift = shift;
484 instr->comptype = 0;
486 parser->funcs->dstreg(parser, instr, dst);
487 parser->funcs->srcreg(parser, instr, 0, &srcs->reg[0]);
489 /* The 2nd source register is the sampler register with the
490 * destination's regnum
492 ZeroMemory(&instr->src[1], sizeof(instr->src[1]));
493 instr->src[1].type = BWRITERSPR_SAMPLER;
494 instr->src[1].regnum = dst->regnum;
495 instr->src[1].swizzle = BWRITERVS_NOSWIZZLE;
496 instr->src[1].srcmod = BWRITERSPSM_NONE;
497 instr->src[1].rel_reg = NULL;
499 if (!add_instruction(parser->shader, instr))
501 ERR("Out of memory\n");
502 set_parse_status(&parser->status, PARSE_ERR);
506 static void asmparser_texreg2ar(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
507 const struct shader_reg *src0)
509 struct shader_reg src;
511 src = map_oldps_register(src0, FALSE);
512 /* Supply the correct swizzle */
513 src.swizzle = BWRITERVS_X_W | BWRITERVS_Y_X | BWRITERVS_Z_X | BWRITERVS_W_X;
514 asmparser_texhelper(parser, mod, shift, dst, &src);
517 static void asmparser_texreg2gb(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
518 const struct shader_reg *src0)
520 struct shader_reg src;
522 src = map_oldps_register(src0, FALSE);
523 /* Supply the correct swizzle */
524 src.swizzle = BWRITERVS_X_Y | BWRITERVS_Y_Z | BWRITERVS_Z_Z | BWRITERVS_W_Z;
525 asmparser_texhelper(parser, mod, shift, dst, &src);
528 static void asmparser_texreg2rgb(struct asm_parser *parser, uint32_t mod, uint32_t shift, const struct shader_reg *dst,
529 const struct shader_reg *src0)
531 struct shader_reg src;
533 src = map_oldps_register(src0, FALSE);
534 /* Supply the correct swizzle */
535 src.swizzle = BWRITERVS_X_X | BWRITERVS_Y_Y | BWRITERVS_Z_Z | BWRITERVS_W_Z;
536 asmparser_texhelper(parser, mod, shift, dst, &src);
539 /* Complex pixel shader 1.3 instructions like texm3x3tex are tricky - the
540 * bytecode writer works instruction by instruction, so we can't properly
541 * convert these from/to equivalent ps_3_0 instructions. Then simply keep using
542 * the ps_1_3 opcodes and just adapt the registers in the common fashion (i.e.
543 * go through asmparser_instr).
546 static void asmparser_instr(struct asm_parser *parser, uint32_t opcode, uint32_t mod, uint32_t shift,
547 enum bwriter_comparison_type comp, const struct shader_reg *dst,
548 const struct src_regs *srcs, int expectednsrcs)
550 unsigned int src_count = srcs ? srcs->count : 0;
551 struct bwriter_shader *shader = parser->shader;
552 struct instruction *instr;
553 BOOL firstreg = TRUE;
554 unsigned int i;
556 if (!parser->shader)
557 return;
559 TRACE_(parsed_shader)("%s%s%s%s ", debug_print_opcode(opcode),
560 debug_print_dstmod(mod),
561 debug_print_shift(shift),
562 debug_print_comp(comp));
563 if (dst)
565 TRACE_(parsed_shader)("%s", debug_print_dstreg(dst));
566 firstreg = FALSE;
568 for (i = 0; i < src_count; i++)
570 if (!firstreg)
571 TRACE_(parsed_shader)(", ");
572 else firstreg = FALSE;
573 TRACE_(parsed_shader)("%s", debug_print_srcreg(&srcs->reg[i]));
575 TRACE_(parsed_shader)("\n");
577 /* Check for instructions with different syntaxes in different shader versions */
578 switch(opcode)
580 case BWRITERSIO_SINCOS:
581 /* The syntax changes between vs 2 and the other shader versions */
582 if (parser->shader->type == ST_VERTEX && parser->shader->major_version == 2)
584 asmparser_sincos(parser, mod, shift, dst, srcs);
585 return;
587 /* Use the default handling */
588 break;
589 case BWRITERSIO_TEXCOORD:
590 /* texcoord/texcrd are two instructions present only in PS <= 1.3 and PS 1.4 respectively */
591 if (shader->type == ST_PIXEL && shader->major_version == 1 && shader->minor_version == 4)
592 asmparser_texcrd(parser, mod, shift, dst, srcs);
593 else
594 asmparser_texcoord(parser, mod, shift, dst, srcs);
595 return;
596 case BWRITERSIO_TEX:
597 /* this encodes both the tex PS 1.x instruction and the
598 texld 1.4/2.0+ instruction */
599 if (shader->type == ST_PIXEL && shader->major_version == 1)
601 if (shader->minor_version < 4)
602 asmparser_tex(parser, mod, shift, dst);
603 else
604 asmparser_texld14(parser, mod, shift, dst, srcs);
605 return;
607 /* else fallback to the standard behavior */
608 break;
611 if (src_count != expectednsrcs)
613 asmparser_message(parser, "Line %u: Wrong number of source registers\n", parser->line_no);
614 set_parse_status(&parser->status, PARSE_ERR);
615 return;
618 /* Handle PS 1.x instructions, "regularizing" them */
619 switch(opcode)
621 case BWRITERSIO_TEXKILL:
622 asmparser_texkill(parser, dst);
623 return;
624 case BWRITERSIO_TEXREG2AR:
625 asmparser_texreg2ar(parser, mod, shift, dst, &srcs->reg[0]);
626 return;
627 case BWRITERSIO_TEXREG2GB:
628 asmparser_texreg2gb(parser, mod, shift, dst, &srcs->reg[0]);
629 return;
630 case BWRITERSIO_TEXREG2RGB:
631 asmparser_texreg2rgb(parser, mod, shift, dst, &srcs->reg[0]);
632 return;
635 instr = alloc_instr(src_count);
636 if (!instr)
638 ERR("Error allocating memory for the instruction\n");
639 set_parse_status(&parser->status, PARSE_ERR);
640 return;
643 instr->opcode = opcode;
644 instr->dstmod = mod;
645 instr->shift = shift;
646 instr->comptype = comp;
647 if (dst)
648 parser->funcs->dstreg(parser, instr, dst);
649 for (i = 0; i < src_count; i++)
651 parser->funcs->srcreg(parser, instr, i, &srcs->reg[i]);
654 if (!add_instruction(parser->shader, instr))
656 ERR("Out of memory\n");
657 set_parse_status(&parser->status, PARSE_ERR);
661 static struct shader_reg map_oldvs_register(const struct shader_reg *reg)
663 struct shader_reg ret;
665 switch(reg->type)
667 case BWRITERSPR_RASTOUT:
668 ret = *reg;
669 ret.type = BWRITERSPR_OUTPUT;
670 switch(reg->regnum)
672 case BWRITERSRO_POSITION:
673 ret.regnum = OPOS_REG;
674 break;
675 case BWRITERSRO_FOG:
676 ret.regnum = OFOG_REG;
677 ret.writemask = OFOG_WRITEMASK;
678 break;
679 case BWRITERSRO_POINT_SIZE:
680 ret.regnum = OPTS_REG;
681 ret.writemask = OPTS_WRITEMASK;
682 break;
683 default:
684 FIXME("Unhandled RASTOUT register %u.\n", reg->regnum);
685 return *reg;
687 return ret;
689 case BWRITERSPR_TEXCRDOUT:
690 ret = *reg;
691 ret.type = BWRITERSPR_OUTPUT;
692 switch(reg->regnum)
694 case 0: ret.regnum = OT0_REG; break;
695 case 1: ret.regnum = OT1_REG; break;
696 case 2: ret.regnum = OT2_REG; break;
697 case 3: ret.regnum = OT3_REG; break;
698 case 4: ret.regnum = OT4_REG; break;
699 case 5: ret.regnum = OT5_REG; break;
700 case 6: ret.regnum = OT6_REG; break;
701 case 7: ret.regnum = OT7_REG; break;
702 default:
703 FIXME("Unhandled TEXCRDOUT regnum %u.\n", reg->regnum);
704 return *reg;
706 return ret;
708 case BWRITERSPR_ATTROUT:
709 ret = *reg;
710 ret.type = BWRITERSPR_OUTPUT;
711 switch(reg->regnum)
713 case 0: ret.regnum = OD0_REG; break;
714 case 1: ret.regnum = OD1_REG; break;
715 default:
716 FIXME("Unhandled ATTROUT regnum %u.\n", reg->regnum);
717 return *reg;
719 return ret;
721 default: return *reg;
725 /* Checks for unsupported source modifiers in VS (all versions) or
726 PS 2.0 and newer */
727 static void check_legacy_srcmod(struct asm_parser *parser, uint32_t srcmod)
729 if (srcmod == BWRITERSPSM_BIAS || srcmod == BWRITERSPSM_BIASNEG ||
730 srcmod == BWRITERSPSM_SIGN || srcmod == BWRITERSPSM_SIGNNEG ||
731 srcmod == BWRITERSPSM_COMP || srcmod == BWRITERSPSM_X2 ||
732 srcmod == BWRITERSPSM_X2NEG || srcmod == BWRITERSPSM_DZ ||
733 srcmod == BWRITERSPSM_DW)
735 asmparser_message(parser, "Line %u: Source modifier %s not supported in this shader version\n",
736 parser->line_no, debug_print_srcmod(srcmod));
737 set_parse_status(&parser->status, PARSE_ERR);
741 static void check_abs_srcmod(struct asm_parser *parser, uint32_t srcmod)
743 if (srcmod == BWRITERSPSM_ABS || srcmod == BWRITERSPSM_ABSNEG)
745 asmparser_message(parser, "Line %u: Source modifier %s not supported in this shader version\n",
746 parser->line_no, debug_print_srcmod(srcmod));
747 set_parse_status(&parser->status, PARSE_ERR);
751 static void check_loop_swizzle(struct asm_parser *parser, const struct shader_reg *src)
753 if ((src->type == BWRITERSPR_LOOP && src->swizzle != BWRITERVS_NOSWIZZLE)
754 || (src->rel_reg && src->rel_reg->type == BWRITERSPR_LOOP &&
755 src->rel_reg->swizzle != BWRITERVS_NOSWIZZLE))
757 asmparser_message(parser, "Line %u: Swizzle not allowed on aL register\n", parser->line_no);
758 set_parse_status(&parser->status, PARSE_ERR);
762 static void check_shift_dstmod(struct asm_parser *parser, uint32_t shift)
764 if (shift != 0)
766 asmparser_message(parser, "Line %u: Shift modifiers not supported in this shader version\n", parser->line_no);
767 set_parse_status(&parser->status, PARSE_ERR);
771 static void check_ps_dstmod(struct asm_parser *parser, uint32_t dstmod)
773 if(dstmod == BWRITERSPDM_PARTIALPRECISION || dstmod == BWRITERSPDM_MSAMPCENTROID)
775 asmparser_message(parser, "Line %u: Instruction modifier %s not supported in this shader version\n",
776 parser->line_no, debug_print_dstmod(dstmod));
777 set_parse_status(&parser->status, PARSE_ERR);
781 struct allowed_reg_type
783 uint32_t type;
784 unsigned int count;
785 BOOL reladdr;
788 static BOOL check_reg_type(const struct shader_reg *reg, const struct allowed_reg_type *allowed)
790 unsigned int i = 0;
792 while (allowed[i].type != ~0u)
794 if (reg->type == allowed[i].type)
796 if (reg->rel_reg)
798 /* The relative addressing register can have a negative value,
799 * we can't check the register index. */
800 if (allowed[i].reladdr)
801 return TRUE;
802 return FALSE;
804 if (reg->regnum < allowed[i].count)
805 return TRUE;
806 return FALSE;
808 i++;
810 return FALSE;
813 /* Native assembler doesn't do separate checks for src and dst registers */
814 static const struct allowed_reg_type vs_1_reg_allowed[] =
816 { BWRITERSPR_TEMP, 12, FALSE },
817 { BWRITERSPR_INPUT, 16, FALSE },
818 { BWRITERSPR_CONST, ~0u, TRUE },
819 { BWRITERSPR_ADDR, 1, FALSE },
820 { BWRITERSPR_RASTOUT, 3, FALSE }, /* oPos, oFog and oPts */
821 { BWRITERSPR_ATTROUT, 2, FALSE },
822 { BWRITERSPR_TEXCRDOUT, 8, FALSE },
823 { ~0u, 0 } /* End tag */
826 /* struct instruction *asmparser_srcreg
828 * Records a source register in the instruction and does shader version
829 * specific checks and modifications on it
831 * Parameters:
832 * This: Shader parser instance
833 * instr: instruction to store the register in
834 * num: Number of source register
835 * src: Pointer to source the register structure. The caller can free
836 * it afterwards
838 static void asmparser_srcreg_vs_1(struct asm_parser *parser, struct instruction *instr, int num,
839 const struct shader_reg *src)
841 struct shader_reg reg;
843 if (!check_reg_type(src, vs_1_reg_allowed))
845 asmparser_message(parser, "Line %u: Source register %s not supported in VS 1\n",
846 parser->line_no, debug_print_srcreg(src));
847 set_parse_status(&parser->status, PARSE_ERR);
849 check_legacy_srcmod(parser, src->srcmod);
850 check_abs_srcmod(parser, src->srcmod);
851 reg = map_oldvs_register(src);
852 instr->src[num] = reg;
855 static const struct allowed_reg_type vs_2_reg_allowed[] =
857 { BWRITERSPR_TEMP, 12, FALSE },
858 { BWRITERSPR_INPUT, 16, FALSE },
859 { BWRITERSPR_CONST, ~0u, TRUE },
860 { BWRITERSPR_ADDR, 1, FALSE },
861 { BWRITERSPR_CONSTBOOL, 16, FALSE },
862 { BWRITERSPR_CONSTINT, 16, FALSE },
863 { BWRITERSPR_LOOP, 1, FALSE },
864 { BWRITERSPR_LABEL, 2048, FALSE },
865 { BWRITERSPR_PREDICATE, 1, FALSE },
866 { BWRITERSPR_RASTOUT, 3, FALSE }, /* oPos, oFog and oPts */
867 { BWRITERSPR_ATTROUT, 2, FALSE },
868 { BWRITERSPR_TEXCRDOUT, 8, FALSE },
869 { ~0u, 0 } /* End tag */
872 static void asmparser_srcreg_vs_2(struct asm_parser *parser, struct instruction *instr, int num,
873 const struct shader_reg *src)
875 struct shader_reg reg;
877 if (!check_reg_type(src, vs_2_reg_allowed))
879 asmparser_message(parser, "Line %u: Source register %s not supported in VS 2\n",
880 parser->line_no, debug_print_srcreg(src));
881 set_parse_status(&parser->status, PARSE_ERR);
883 check_loop_swizzle(parser, src);
884 check_legacy_srcmod(parser, src->srcmod);
885 check_abs_srcmod(parser, src->srcmod);
886 reg = map_oldvs_register(src);
887 instr->src[num] = reg;
890 static const struct allowed_reg_type vs_3_reg_allowed[] =
892 { BWRITERSPR_TEMP, 32, FALSE },
893 { BWRITERSPR_INPUT, 16, TRUE },
894 { BWRITERSPR_CONST, ~0u, TRUE },
895 { BWRITERSPR_ADDR, 1, FALSE },
896 { BWRITERSPR_CONSTBOOL, 16, FALSE },
897 { BWRITERSPR_CONSTINT, 16, FALSE },
898 { BWRITERSPR_LOOP, 1, FALSE },
899 { BWRITERSPR_LABEL, 2048, FALSE },
900 { BWRITERSPR_PREDICATE, 1, FALSE },
901 { BWRITERSPR_SAMPLER, 4, FALSE },
902 { BWRITERSPR_OUTPUT, 12, TRUE },
903 { ~0u, 0 } /* End tag */
906 static void asmparser_srcreg_vs_3(struct asm_parser *parser, struct instruction *instr, int num,
907 const struct shader_reg *src)
909 if (!check_reg_type(src, vs_3_reg_allowed))
911 asmparser_message(parser, "Line %u: Source register %s not supported in VS 3.0\n",
912 parser->line_no, debug_print_srcreg(src));
913 set_parse_status(&parser->status, PARSE_ERR);
915 check_loop_swizzle(parser, src);
916 check_legacy_srcmod(parser, src->srcmod);
917 instr->src[num] = *src;
920 static const struct allowed_reg_type ps_1_0123_reg_allowed[] =
922 { BWRITERSPR_CONST, 8, FALSE },
923 { BWRITERSPR_TEMP, 2, FALSE },
924 { BWRITERSPR_TEXTURE, 4, FALSE },
925 { BWRITERSPR_INPUT, 2, FALSE },
926 { ~0u, 0 } /* End tag */
929 static void asmparser_srcreg_ps_1_0123(struct asm_parser *parser, struct instruction *instr, int num,
930 const struct shader_reg *src)
932 struct shader_reg reg;
934 if (!check_reg_type(src, ps_1_0123_reg_allowed))
936 asmparser_message(parser, "Line %u: Source register %s not supported in <== PS 1.3\n",
937 parser->line_no, debug_print_srcreg(src));
938 set_parse_status(&parser->status, PARSE_ERR);
940 check_abs_srcmod(parser, src->srcmod);
941 reg = map_oldps_register(src, FALSE);
942 instr->src[num] = reg;
945 static const struct allowed_reg_type ps_1_4_reg_allowed[] =
947 { BWRITERSPR_CONST, 8, FALSE },
948 { BWRITERSPR_TEMP, 6, FALSE },
949 { BWRITERSPR_TEXTURE, 6, FALSE },
950 { BWRITERSPR_INPUT, 2, FALSE },
951 { ~0u, 0 } /* End tag */
954 static void asmparser_srcreg_ps_1_4(struct asm_parser *parser, struct instruction *instr, int num,
955 const struct shader_reg *src)
957 struct shader_reg reg;
959 if (!check_reg_type(src, ps_1_4_reg_allowed))
961 asmparser_message(parser, "Line %u: Source register %s not supported in PS 1.4\n",
962 parser->line_no, debug_print_srcreg(src));
963 set_parse_status(&parser->status, PARSE_ERR);
965 check_abs_srcmod(parser, src->srcmod);
966 reg = map_oldps_register(src, TRUE);
967 instr->src[num] = reg;
970 static const struct allowed_reg_type ps_2_0_reg_allowed[] =
972 { BWRITERSPR_INPUT, 2, FALSE },
973 { BWRITERSPR_TEMP, 32, FALSE },
974 { BWRITERSPR_CONST, 32, FALSE },
975 { BWRITERSPR_CONSTINT, 16, FALSE },
976 { BWRITERSPR_CONSTBOOL, 16, FALSE },
977 { BWRITERSPR_SAMPLER, 16, FALSE },
978 { BWRITERSPR_TEXTURE, 8, FALSE },
979 { BWRITERSPR_COLOROUT, 4, FALSE },
980 { BWRITERSPR_DEPTHOUT, 1, FALSE },
981 { ~0u, 0 } /* End tag */
984 static void asmparser_srcreg_ps_2(struct asm_parser *parser, struct instruction *instr, int num,
985 const struct shader_reg *src)
987 struct shader_reg reg;
989 if (!check_reg_type(src, ps_2_0_reg_allowed))
991 asmparser_message(parser, "Line %u: Source register %s not supported in PS 2.0\n",
992 parser->line_no, debug_print_srcreg(src));
993 set_parse_status(&parser->status, PARSE_ERR);
995 check_legacy_srcmod(parser, src->srcmod);
996 check_abs_srcmod(parser, src->srcmod);
997 reg = map_oldps_register(src, TRUE);
998 instr->src[num] = reg;
1001 static const struct allowed_reg_type ps_2_x_reg_allowed[] =
1003 { BWRITERSPR_INPUT, 2, FALSE },
1004 { BWRITERSPR_TEMP, 32, FALSE },
1005 { BWRITERSPR_CONST, 32, FALSE },
1006 { BWRITERSPR_CONSTINT, 16, FALSE },
1007 { BWRITERSPR_CONSTBOOL, 16, FALSE },
1008 { BWRITERSPR_PREDICATE, 1, FALSE },
1009 { BWRITERSPR_SAMPLER, 16, FALSE },
1010 { BWRITERSPR_TEXTURE, 8, FALSE },
1011 { BWRITERSPR_LABEL, 2048, FALSE },
1012 { BWRITERSPR_COLOROUT, 4, FALSE },
1013 { BWRITERSPR_DEPTHOUT, 1, FALSE },
1014 { ~0u, 0 } /* End tag */
1017 static void asmparser_srcreg_ps_2_x(struct asm_parser *parser, struct instruction *instr, int num,
1018 const struct shader_reg *src)
1020 struct shader_reg reg;
1022 if (!check_reg_type(src, ps_2_x_reg_allowed))
1024 asmparser_message(parser, "Line %u: Source register %s not supported in PS 2.x\n",
1025 parser->line_no, debug_print_srcreg(src));
1026 set_parse_status(&parser->status, PARSE_ERR);
1028 check_legacy_srcmod(parser, src->srcmod);
1029 check_abs_srcmod(parser, src->srcmod);
1030 reg = map_oldps_register(src, TRUE);
1031 instr->src[num] = reg;
1034 static const struct allowed_reg_type ps_3_reg_allowed[] =
1036 { BWRITERSPR_INPUT, 10, TRUE },
1037 { BWRITERSPR_TEMP, 32, FALSE },
1038 { BWRITERSPR_CONST, 224, FALSE },
1039 { BWRITERSPR_CONSTINT, 16, FALSE },
1040 { BWRITERSPR_CONSTBOOL, 16, FALSE },
1041 { BWRITERSPR_PREDICATE, 1, FALSE },
1042 { BWRITERSPR_SAMPLER, 16, FALSE },
1043 { BWRITERSPR_MISCTYPE, 2, FALSE }, /* vPos and vFace */
1044 { BWRITERSPR_LOOP, 1, FALSE },
1045 { BWRITERSPR_LABEL, 2048, FALSE },
1046 { BWRITERSPR_COLOROUT, 4, FALSE },
1047 { BWRITERSPR_DEPTHOUT, 1, FALSE },
1048 { ~0u, 0 } /* End tag */
1051 static void asmparser_srcreg_ps_3(struct asm_parser *parser,struct instruction *instr, int num,
1052 const struct shader_reg *src)
1054 if (!check_reg_type(src, ps_3_reg_allowed))
1056 asmparser_message(parser, "Line %u: Source register %s not supported in PS 3.0\n",
1057 parser->line_no, debug_print_srcreg(src));
1058 set_parse_status(&parser->status, PARSE_ERR);
1060 check_loop_swizzle(parser, src);
1061 check_legacy_srcmod(parser, src->srcmod);
1062 instr->src[num] = *src;
1065 static void asmparser_dstreg_vs_1(struct asm_parser *parser, struct instruction *instr,
1066 const struct shader_reg *dst)
1068 struct shader_reg reg;
1070 if (!check_reg_type(dst, vs_1_reg_allowed))
1072 asmparser_message(parser, "Line %u: Destination register %s not supported in VS 1\n",
1073 parser->line_no, debug_print_dstreg(dst));
1074 set_parse_status(&parser->status, PARSE_ERR);
1076 check_ps_dstmod(parser, instr->dstmod);
1077 check_shift_dstmod(parser, instr->shift);
1078 reg = map_oldvs_register(dst);
1079 instr->dst = reg;
1080 instr->has_dst = TRUE;
1083 static void asmparser_dstreg_vs_2(struct asm_parser *parser, struct instruction *instr,
1084 const struct shader_reg *dst)
1086 struct shader_reg reg;
1088 if (!check_reg_type(dst, vs_2_reg_allowed))
1090 asmparser_message(parser, "Line %u: Destination register %s not supported in VS 2.0\n",
1091 parser->line_no, debug_print_dstreg(dst));
1092 set_parse_status(&parser->status, PARSE_ERR);
1094 check_ps_dstmod(parser, instr->dstmod);
1095 check_shift_dstmod(parser, instr->shift);
1096 reg = map_oldvs_register(dst);
1097 instr->dst = reg;
1098 instr->has_dst = TRUE;
1101 static void asmparser_dstreg_vs_3(struct asm_parser *parser,struct instruction *instr,
1102 const struct shader_reg *dst)
1104 if (!check_reg_type(dst, vs_3_reg_allowed))
1106 asmparser_message(parser, "Line %u: Destination register %s not supported in VS 3.0\n",
1107 parser->line_no, debug_print_dstreg(dst));
1108 set_parse_status(&parser->status, PARSE_ERR);
1110 check_ps_dstmod(parser, instr->dstmod);
1111 check_shift_dstmod(parser, instr->shift);
1112 instr->dst = *dst;
1113 instr->has_dst = TRUE;
1116 static void asmparser_dstreg_ps_1_0123(struct asm_parser *parser, struct instruction *instr,
1117 const struct shader_reg *dst)
1119 struct shader_reg reg;
1121 if (!check_reg_type(dst, ps_1_0123_reg_allowed))
1123 asmparser_message(parser, "Line %u: Destination register %s not supported in PS 1\n",
1124 parser->line_no, debug_print_dstreg(dst));
1125 set_parse_status(&parser->status, PARSE_ERR);
1127 reg = map_oldps_register(dst, FALSE);
1128 instr->dst = reg;
1129 instr->has_dst = TRUE;
1132 static void asmparser_dstreg_ps_1_4(struct asm_parser *parser, struct instruction *instr,
1133 const struct shader_reg *dst)
1135 struct shader_reg reg;
1137 if (!check_reg_type(dst, ps_1_4_reg_allowed))
1139 asmparser_message(parser, "Line %u: Destination register %s not supported in PS 1\n",
1140 parser->line_no, debug_print_dstreg(dst));
1141 set_parse_status(&parser->status, PARSE_ERR);
1143 reg = map_oldps_register(dst, TRUE);
1144 instr->dst = reg;
1145 instr->has_dst = TRUE;
1148 static void asmparser_dstreg_ps_2(struct asm_parser *parser, struct instruction *instr,
1149 const struct shader_reg *dst)
1151 struct shader_reg reg;
1153 if (!check_reg_type(dst, ps_2_0_reg_allowed))
1155 asmparser_message(parser, "Line %u: Destination register %s not supported in PS 2.0\n",
1156 parser->line_no, debug_print_dstreg(dst));
1157 set_parse_status(&parser->status, PARSE_ERR);
1159 check_shift_dstmod(parser, instr->shift);
1160 reg = map_oldps_register(dst, TRUE);
1161 instr->dst = reg;
1162 instr->has_dst = TRUE;
1165 static void asmparser_dstreg_ps_2_x(struct asm_parser *parser, struct instruction *instr,
1166 const struct shader_reg *dst)
1168 struct shader_reg reg;
1170 if (!check_reg_type(dst, ps_2_x_reg_allowed))
1172 asmparser_message(parser, "Line %u: Destination register %s not supported in PS 2.x\n",
1173 parser->line_no, debug_print_dstreg(dst));
1174 set_parse_status(&parser->status, PARSE_ERR);
1176 check_shift_dstmod(parser, instr->shift);
1177 reg = map_oldps_register(dst, TRUE);
1178 instr->dst = reg;
1179 instr->has_dst = TRUE;
1182 static void asmparser_dstreg_ps_3(struct asm_parser *parser, struct instruction *instr,
1183 const struct shader_reg *dst)
1185 if (!check_reg_type(dst, ps_3_reg_allowed))
1187 asmparser_message(parser, "Line %u: Destination register %s not supported in PS 3.0\n",
1188 parser->line_no, debug_print_dstreg(dst));
1189 set_parse_status(&parser->status, PARSE_ERR);
1191 check_shift_dstmod(parser, instr->shift);
1192 instr->dst = *dst;
1193 instr->has_dst = TRUE;
1196 static void asmparser_predicate_supported(struct asm_parser *parser, const struct shader_reg *predicate)
1198 if (!parser->shader)
1199 return;
1200 if (parser->shader->num_instrs == 0)
1201 ERR("Predicate without an instruction.\n");
1202 /* Set the predicate of the last instruction added to the shader. */
1203 parser->shader->instr[parser->shader->num_instrs - 1]->has_predicate = TRUE;
1204 parser->shader->instr[parser->shader->num_instrs - 1]->predicate = *predicate;
1207 static void asmparser_predicate_unsupported(struct asm_parser *parser, const struct shader_reg *predicate)
1209 asmparser_message(parser, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", parser->line_no);
1210 set_parse_status(&parser->status, PARSE_ERR);
1213 static void asmparser_coissue_supported(struct asm_parser *parser)
1215 if (!parser->shader)
1216 return;
1217 if (parser->shader->num_instrs == 0)
1219 asmparser_message(parser, "Line %u: Coissue flag on the first shader instruction\n", parser->line_no);
1220 set_parse_status(&parser->status, PARSE_ERR);
1222 /* Set the coissue flag of the last instruction added to the shader. */
1223 parser->shader->instr[parser->shader->num_instrs - 1]->coissue = TRUE;
1226 static void asmparser_coissue_unsupported(struct asm_parser *parser)
1228 asmparser_message(parser, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", parser->line_no);
1229 set_parse_status(&parser->status, PARSE_ERR);
1232 static const struct asmparser_backend parser_vs_1 = {
1233 asmparser_constF,
1234 asmparser_constI,
1235 asmparser_constB,
1237 asmparser_dstreg_vs_1,
1238 asmparser_srcreg_vs_1,
1240 asmparser_predicate_unsupported,
1241 asmparser_coissue_unsupported,
1243 asmparser_dcl_output_unsupported,
1244 asmparser_dcl_input,
1245 asmparser_dcl_sampler_unsupported,
1247 asmparser_end,
1249 asmparser_instr,
1252 static const struct asmparser_backend parser_vs_2 = {
1253 asmparser_constF,
1254 asmparser_constI,
1255 asmparser_constB,
1257 asmparser_dstreg_vs_2,
1258 asmparser_srcreg_vs_2,
1260 asmparser_predicate_supported,
1261 asmparser_coissue_unsupported,
1263 asmparser_dcl_output_unsupported,
1264 asmparser_dcl_input,
1265 asmparser_dcl_sampler_unsupported,
1267 asmparser_end,
1269 asmparser_instr,
1272 static const struct asmparser_backend parser_vs_3 = {
1273 asmparser_constF,
1274 asmparser_constI,
1275 asmparser_constB,
1277 asmparser_dstreg_vs_3,
1278 asmparser_srcreg_vs_3,
1280 asmparser_predicate_supported,
1281 asmparser_coissue_unsupported,
1283 asmparser_dcl_output,
1284 asmparser_dcl_input,
1285 asmparser_dcl_sampler,
1287 asmparser_end,
1289 asmparser_instr,
1292 static const struct asmparser_backend parser_ps_1_0123 = {
1293 asmparser_constF,
1294 asmparser_constI,
1295 asmparser_constB,
1297 asmparser_dstreg_ps_1_0123,
1298 asmparser_srcreg_ps_1_0123,
1300 asmparser_predicate_unsupported,
1301 asmparser_coissue_supported,
1303 asmparser_dcl_output_unsupported,
1304 asmparser_dcl_input_unsupported,
1305 asmparser_dcl_sampler_unsupported,
1307 asmparser_end,
1309 asmparser_instr,
1312 static const struct asmparser_backend parser_ps_1_4 = {
1313 asmparser_constF,
1314 asmparser_constI,
1315 asmparser_constB,
1317 asmparser_dstreg_ps_1_4,
1318 asmparser_srcreg_ps_1_4,
1320 asmparser_predicate_unsupported,
1321 asmparser_coissue_supported,
1323 asmparser_dcl_output_unsupported,
1324 asmparser_dcl_input_unsupported,
1325 asmparser_dcl_sampler_unsupported,
1327 asmparser_end,
1329 asmparser_instr,
1332 static const struct asmparser_backend parser_ps_2 = {
1333 asmparser_constF,
1334 asmparser_constI,
1335 asmparser_constB,
1337 asmparser_dstreg_ps_2,
1338 asmparser_srcreg_ps_2,
1340 asmparser_predicate_unsupported,
1341 asmparser_coissue_unsupported,
1343 asmparser_dcl_output_unsupported,
1344 asmparser_dcl_input_ps_2,
1345 asmparser_dcl_sampler,
1347 asmparser_end,
1349 asmparser_instr,
1352 static const struct asmparser_backend parser_ps_2_x = {
1353 asmparser_constF,
1354 asmparser_constI,
1355 asmparser_constB,
1357 asmparser_dstreg_ps_2_x,
1358 asmparser_srcreg_ps_2_x,
1360 asmparser_predicate_supported,
1361 asmparser_coissue_unsupported,
1363 asmparser_dcl_output_unsupported,
1364 asmparser_dcl_input_ps_2,
1365 asmparser_dcl_sampler,
1367 asmparser_end,
1369 asmparser_instr,
1372 static const struct asmparser_backend parser_ps_3 = {
1373 asmparser_constF,
1374 asmparser_constI,
1375 asmparser_constB,
1377 asmparser_dstreg_ps_3,
1378 asmparser_srcreg_ps_3,
1380 asmparser_predicate_supported,
1381 asmparser_coissue_unsupported,
1383 asmparser_dcl_output_unsupported,
1384 asmparser_dcl_input,
1385 asmparser_dcl_sampler,
1387 asmparser_end,
1389 asmparser_instr,
1392 static void gen_oldvs_output(struct bwriter_shader *shader) {
1393 record_declaration(shader, BWRITERDECLUSAGE_POSITION, 0, 0, TRUE, OPOS_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1394 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, 0, TRUE, OT0_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1395 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, 0, TRUE, OT1_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1396 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, 0, TRUE, OT2_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1397 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, 0, TRUE, OT3_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1398 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, 0, TRUE, OT4_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1399 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, 0, TRUE, OT5_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1400 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, 0, TRUE, OT6_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1401 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, 0, TRUE, OT7_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1402 record_declaration(shader, BWRITERDECLUSAGE_FOG, 0, 0, TRUE, OFOG_REG, OFOG_WRITEMASK, TRUE);
1403 record_declaration(shader, BWRITERDECLUSAGE_PSIZE, 0, 0, TRUE, OPTS_REG, OPTS_WRITEMASK, TRUE);
1404 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, 0, TRUE, OD0_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1405 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, 0, TRUE, OD1_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1408 static void gen_oldps_input(struct bwriter_shader *shader, uint32_t texcoords)
1410 switch(texcoords)
1412 case 8: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, 0, FALSE, T7_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1413 /* fall through */
1414 case 7: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, 0, FALSE, T6_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1415 /* fall through */
1416 case 6: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, 0, FALSE, T5_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1417 /* fall through */
1418 case 5: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, 0, FALSE, T4_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1419 /* fall through */
1420 case 4: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, 0, FALSE, T3_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1421 /* fall through */
1422 case 3: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, 0, FALSE, T2_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1423 /* fall through */
1424 case 2: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, 0, FALSE, T1_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1425 /* fall through */
1426 case 1: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, 0, FALSE, T0_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1428 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, 0, FALSE, C0_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1429 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, 0, FALSE, C1_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1432 void create_vs10_parser(struct asm_parser *ret) {
1433 TRACE_(parsed_shader)("vs_1_0\n");
1435 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1436 if(!ret->shader) {
1437 ERR("Failed to allocate memory for the shader\n");
1438 set_parse_status(&ret->status, PARSE_ERR);
1439 return;
1442 ret->shader->type = ST_VERTEX;
1443 ret->shader->major_version = 1;
1444 ret->shader->minor_version = 0;
1445 ret->funcs = &parser_vs_1;
1446 gen_oldvs_output(ret->shader);
1449 void create_vs11_parser(struct asm_parser *ret) {
1450 TRACE_(parsed_shader)("vs_1_1\n");
1452 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1453 if(!ret->shader) {
1454 ERR("Failed to allocate memory for the shader\n");
1455 set_parse_status(&ret->status, PARSE_ERR);
1456 return;
1459 ret->shader->type = ST_VERTEX;
1460 ret->shader->major_version = 1;
1461 ret->shader->minor_version = 1;
1462 ret->funcs = &parser_vs_1;
1463 gen_oldvs_output(ret->shader);
1466 void create_vs20_parser(struct asm_parser *ret) {
1467 TRACE_(parsed_shader)("vs_2_0\n");
1469 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1470 if(!ret->shader) {
1471 ERR("Failed to allocate memory for the shader\n");
1472 set_parse_status(&ret->status, PARSE_ERR);
1473 return;
1476 ret->shader->type = ST_VERTEX;
1477 ret->shader->major_version = 2;
1478 ret->shader->minor_version = 0;
1479 ret->funcs = &parser_vs_2;
1480 gen_oldvs_output(ret->shader);
1483 void create_vs2x_parser(struct asm_parser *ret) {
1484 TRACE_(parsed_shader)("vs_2_x\n");
1486 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1487 if(!ret->shader) {
1488 ERR("Failed to allocate memory for the shader\n");
1489 set_parse_status(&ret->status, PARSE_ERR);
1490 return;
1493 ret->shader->type = ST_VERTEX;
1494 ret->shader->major_version = 2;
1495 ret->shader->minor_version = 1;
1496 ret->funcs = &parser_vs_2;
1497 gen_oldvs_output(ret->shader);
1500 void create_vs30_parser(struct asm_parser *ret) {
1501 TRACE_(parsed_shader)("vs_3_0\n");
1503 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1504 if(!ret->shader) {
1505 ERR("Failed to allocate memory for the shader\n");
1506 set_parse_status(&ret->status, PARSE_ERR);
1507 return;
1510 ret->shader->type = ST_VERTEX;
1511 ret->shader->major_version = 3;
1512 ret->shader->minor_version = 0;
1513 ret->funcs = &parser_vs_3;
1516 void create_ps10_parser(struct asm_parser *ret) {
1517 TRACE_(parsed_shader)("ps_1_0\n");
1519 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1520 if(!ret->shader) {
1521 ERR("Failed to allocate memory for the shader\n");
1522 set_parse_status(&ret->status, PARSE_ERR);
1523 return;
1526 ret->shader->type = ST_PIXEL;
1527 ret->shader->major_version = 1;
1528 ret->shader->minor_version = 0;
1529 ret->funcs = &parser_ps_1_0123;
1530 gen_oldps_input(ret->shader, 4);
1533 void create_ps11_parser(struct asm_parser *ret) {
1534 TRACE_(parsed_shader)("ps_1_1\n");
1536 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1537 if(!ret->shader) {
1538 ERR("Failed to allocate memory for the shader\n");
1539 set_parse_status(&ret->status, PARSE_ERR);
1540 return;
1543 ret->shader->type = ST_PIXEL;
1544 ret->shader->major_version = 1;
1545 ret->shader->minor_version = 1;
1546 ret->funcs = &parser_ps_1_0123;
1547 gen_oldps_input(ret->shader, 4);
1550 void create_ps12_parser(struct asm_parser *ret) {
1551 TRACE_(parsed_shader)("ps_1_2\n");
1553 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1554 if(!ret->shader) {
1555 ERR("Failed to allocate memory for the shader\n");
1556 set_parse_status(&ret->status, PARSE_ERR);
1557 return;
1560 ret->shader->type = ST_PIXEL;
1561 ret->shader->major_version = 1;
1562 ret->shader->minor_version = 2;
1563 ret->funcs = &parser_ps_1_0123;
1564 gen_oldps_input(ret->shader, 4);
1567 void create_ps13_parser(struct asm_parser *ret) {
1568 TRACE_(parsed_shader)("ps_1_3\n");
1570 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1571 if(!ret->shader) {
1572 ERR("Failed to allocate memory for the shader\n");
1573 set_parse_status(&ret->status, PARSE_ERR);
1574 return;
1577 ret->shader->type = ST_PIXEL;
1578 ret->shader->major_version = 1;
1579 ret->shader->minor_version = 3;
1580 ret->funcs = &parser_ps_1_0123;
1581 gen_oldps_input(ret->shader, 4);
1584 void create_ps14_parser(struct asm_parser *ret) {
1585 TRACE_(parsed_shader)("ps_1_4\n");
1587 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1588 if(!ret->shader) {
1589 ERR("Failed to allocate memory for the shader\n");
1590 set_parse_status(&ret->status, PARSE_ERR);
1591 return;
1594 ret->shader->type = ST_PIXEL;
1595 ret->shader->major_version = 1;
1596 ret->shader->minor_version = 4;
1597 ret->funcs = &parser_ps_1_4;
1598 gen_oldps_input(ret->shader, 6);
1601 void create_ps20_parser(struct asm_parser *ret) {
1602 TRACE_(parsed_shader)("ps_2_0\n");
1604 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1605 if(!ret->shader) {
1606 ERR("Failed to allocate memory for the shader\n");
1607 set_parse_status(&ret->status, PARSE_ERR);
1608 return;
1611 ret->shader->type = ST_PIXEL;
1612 ret->shader->major_version = 2;
1613 ret->shader->minor_version = 0;
1614 ret->funcs = &parser_ps_2;
1615 gen_oldps_input(ret->shader, 8);
1618 void create_ps2x_parser(struct asm_parser *ret) {
1619 TRACE_(parsed_shader)("ps_2_x\n");
1621 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1622 if(!ret->shader) {
1623 ERR("Failed to allocate memory for the shader\n");
1624 set_parse_status(&ret->status, PARSE_ERR);
1625 return;
1628 ret->shader->type = ST_PIXEL;
1629 ret->shader->major_version = 2;
1630 ret->shader->minor_version = 1;
1631 ret->funcs = &parser_ps_2_x;
1632 gen_oldps_input(ret->shader, 8);
1635 void create_ps30_parser(struct asm_parser *ret) {
1636 TRACE_(parsed_shader)("ps_3_0\n");
1638 ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1639 if(!ret->shader) {
1640 ERR("Failed to allocate memory for the shader\n");
1641 set_parse_status(&ret->status, PARSE_ERR);
1642 return;
1645 ret->shader->type = ST_PIXEL;
1646 ret->shader->major_version = 3;
1647 ret->shader->minor_version = 0;
1648 ret->funcs = &parser_ps_3;