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
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dx9_36_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
30 WINE_DECLARE_DEBUG_CHANNEL(parsed_shader);
33 /* How to map vs 1.0 and 2.0 varyings to 3.0 ones
34 * oTx is mapped to ox, which happens to be an
35 * identical mapping since BWRITERSPR_TEXCRDOUT == BWRITERSPR_OUTPUT
36 * oPos, oFog and point size are mapped to general output regs as well.
37 * the vs 1.x and 2.x parser functions add varying declarations
38 * to the shader, and the 1.x and 2.x output functions check those varyings
50 #define OFOG_WRITEMASK BWRITERSP_WRITEMASK_0
52 #define OPTS_WRITEMASK BWRITERSP_WRITEMASK_1
56 /* Input color registers 0-1 are identically mapped */
68 /****************************************************************
69 * Common(non-version specific) shader parser control code *
70 ****************************************************************/
72 static void asmparser_end(struct asm_parser *This) {
73 TRACE("Finalizing shader\n");
76 static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float y, float z, float w) {
77 if(!This->shader) return;
78 TRACE("Adding float constant %u at pos %u\n", reg, This->shader->num_cf);
79 TRACE_(parsed_shader)("def c%u, %f, %f, %f, %f\n", reg, x, y, z, w);
80 if(!add_constF(This->shader, reg, x, y, z, w)) {
81 ERR("Out of memory\n");
82 set_parse_status(This, PARSE_ERR);
86 static void asmparser_constB(struct asm_parser *This, DWORD reg, BOOL x) {
87 if(!This->shader) return;
88 TRACE("Adding boolean constant %u at pos %u\n", reg, This->shader->num_cb);
89 TRACE_(parsed_shader)("def b%u, %s\n", reg, x ? "true" : "false");
90 if(!add_constB(This->shader, reg, x)) {
91 ERR("Out of memory\n");
92 set_parse_status(This, PARSE_ERR);
96 static void asmparser_constI(struct asm_parser *This, DWORD reg, INT x, INT y, INT z, INT w) {
97 if(!This->shader) return;
98 TRACE("Adding integer constant %u at pos %u\n", reg, This->shader->num_ci);
99 TRACE_(parsed_shader)("def i%u, %d, %d, %d, %d\n", reg, x, y, z, w);
100 if(!add_constI(This->shader, reg, x, y, z, w)) {
101 ERR("Out of memory\n");
102 set_parse_status(This, PARSE_ERR);
106 static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num,
107 const struct shader_reg *reg) {
108 if(!This->shader) return;
109 if(This->shader->type == ST_PIXEL) {
110 asmparser_message(This, "Line %u: Output register declared in a pixel shader\n", This->line_no);
111 set_parse_status(This, PARSE_ERR);
113 if(!record_declaration(This->shader, usage, num, TRUE, reg->regnum, reg->writemask)) {
114 ERR("Out of memory\n");
115 set_parse_status(This, PARSE_ERR);
119 static void asmparser_dcl_input(struct asm_parser *This, DWORD usage, DWORD num,
120 const struct shader_reg *reg) {
121 if(!This->shader) return;
122 if(!record_declaration(This->shader, usage, num, FALSE, reg->regnum, reg->writemask)) {
123 ERR("Out of memory\n");
124 set_parse_status(This, PARSE_ERR);
128 static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype, DWORD regnum, unsigned int line_no) {
129 if(!This->shader) return;
130 if(!record_sampler(This->shader, samptype, regnum)) {
131 ERR("Out of memory\n");
132 set_parse_status(This, PARSE_ERR);
136 static void asmparser_sincos(struct asm_parser *This, DWORD mod, DWORD shift,
137 const struct shader_reg *dst,
138 const struct src_regs *srcs) {
139 struct instruction *instr;
141 if(!srcs || srcs->count != 3) {
142 asmparser_message(This, "Line %u: sincos (vs 2) has an incorrect number of source registers\n", This->line_no);
143 set_parse_status(This, PARSE_ERR);
147 instr = alloc_instr(3);
149 ERR("Error allocating memory for the instruction\n");
150 set_parse_status(This, PARSE_ERR);
154 instr->opcode = BWRITERSIO_SINCOS;
156 instr->shift = shift;
159 This->funcs->dstreg(This, instr, dst);
160 This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
161 This->funcs->srcreg(This, instr, 1, &srcs->reg[1]);
162 This->funcs->srcreg(This, instr, 2, &srcs->reg[2]);
164 if(!add_instruction(This->shader, instr)) {
165 ERR("Out of memory\n");
166 set_parse_status(This, PARSE_ERR);
170 static void asmparser_instr(struct asm_parser *This, DWORD opcode,
171 DWORD mod, DWORD shift,
172 BWRITER_COMPARISON_TYPE comp,
173 const struct shader_reg *dst,
174 const struct src_regs *srcs, int expectednsrcs) {
175 struct instruction *instr;
177 BOOL firstreg = TRUE;
178 unsigned int src_count = srcs ? srcs->count : 0;
180 if(!This->shader) return;
182 TRACE_(parsed_shader)("%s%s%s ", debug_print_opcode(opcode),
183 debug_print_dstmod(mod),
184 debug_print_comp(comp));
186 TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type));
189 for(i = 0; i < src_count; i++) {
190 if(!firstreg) TRACE_(parsed_shader)(", ");
191 else firstreg = FALSE;
192 TRACE_(parsed_shader)("%s", debug_print_srcreg(&srcs->reg[i],
193 This->shader->type));
195 TRACE_(parsed_shader)("\n");
197 /* Check for instructions with different syntaxes in different shader versio
200 case BWRITERSIO_SINCOS:
201 /* The syntax changes between vs 2 and the other shader versions */
202 if(This->shader->version == BWRITERVS_VERSION(2, 0) ||
203 This->shader->version == BWRITERVS_VERSION(2, 1)) {
204 asmparser_sincos(This, mod, shift, dst, srcs);
207 /* Use the default handling */
211 if(src_count != expectednsrcs) {
212 asmparser_message(This, "Line %u: Wrong number of source registers\n", This->line_no);
213 set_parse_status(This, PARSE_ERR);
217 instr = alloc_instr(src_count);
219 ERR("Error allocating memory for the instruction\n");
220 set_parse_status(This, PARSE_ERR);
224 instr->opcode = opcode;
226 instr->shift = shift;
227 instr->comptype = comp;
228 if(dst) This->funcs->dstreg(This, instr, dst);
229 for(i = 0; i < src_count; i++) {
230 This->funcs->srcreg(This, instr, i, &srcs->reg[i]);
233 if(!add_instruction(This->shader, instr)) {
234 ERR("Out of memory\n");
235 set_parse_status(This, PARSE_ERR);
239 static struct shader_reg map_oldvs_register(const struct shader_reg *reg) {
240 struct shader_reg ret;
242 case BWRITERSPR_RASTOUT:
244 ret.type = BWRITERSPR_OUTPUT;
245 switch(reg->regnum) {
246 case BWRITERSRO_POSITION:
247 ret.regnum = OPOS_REG;
250 ret.regnum = OFOG_REG;
251 ret.writemask = OFOG_WRITEMASK;
253 case BWRITERSRO_POINT_SIZE:
254 ret.regnum = OPTS_REG;
255 ret.writemask = OPTS_WRITEMASK;
258 FIXME("Unhandled RASTOUT register %u\n", reg->regnum);
263 case BWRITERSPR_TEXCRDOUT:
265 ret.type = BWRITERSPR_OUTPUT;
266 switch(reg->regnum) {
267 case 0: ret.regnum = OT0_REG; break;
268 case 1: ret.regnum = OT1_REG; break;
269 case 2: ret.regnum = OT2_REG; break;
270 case 3: ret.regnum = OT3_REG; break;
271 case 4: ret.regnum = OT4_REG; break;
272 case 5: ret.regnum = OT5_REG; break;
273 case 6: ret.regnum = OT6_REG; break;
274 case 7: ret.regnum = OT7_REG; break;
276 FIXME("Unhandled TEXCRDOUT regnum %u\n", reg->regnum);
281 case BWRITERSPR_ATTROUT:
283 ret.type = BWRITERSPR_OUTPUT;
284 switch(reg->regnum) {
285 case 0: ret.regnum = OD0_REG; break;
286 case 1: ret.regnum = OD1_REG; break;
288 FIXME("Unhandled ATTROUT regnum %u\n", reg->regnum);
293 default: return *reg;
297 static struct shader_reg map_oldps_register(const struct shader_reg *reg, BOOL tex_varying) {
298 struct shader_reg ret;
300 case BWRITERSPR_TEXTURE:
303 ret.type = BWRITERSPR_INPUT;
304 switch(reg->regnum) {
305 case 0: ret.regnum = T0_VARYING; break;
306 case 1: ret.regnum = T1_VARYING; break;
307 case 2: ret.regnum = T2_VARYING; break;
308 case 3: ret.regnum = T3_VARYING; break;
309 case 4: ret.regnum = T4_VARYING; break;
310 case 5: ret.regnum = T5_VARYING; break;
311 case 6: ret.regnum = T6_VARYING; break;
312 case 7: ret.regnum = T7_VARYING; break;
314 FIXME("Unexpected TEXTURE register t%u\n", reg->regnum);
319 FIXME("TODO: ps_1_x texture register mapping\n");
323 /* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
326 default: return *reg;
330 /* Checks for unsupported source modifiers in VS (all versions) or
332 static void check_legacy_srcmod(struct asm_parser *This, DWORD srcmod) {
333 if(srcmod == BWRITERSPSM_BIAS || srcmod == BWRITERSPSM_BIASNEG ||
334 srcmod == BWRITERSPSM_SIGN || srcmod == BWRITERSPSM_SIGNNEG ||
335 srcmod == BWRITERSPSM_COMP || srcmod == BWRITERSPSM_X2 ||
336 srcmod == BWRITERSPSM_X2NEG || srcmod == BWRITERSPSM_DZ ||
337 srcmod == BWRITERSPSM_DW) {
338 asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
340 debug_print_srcmod(srcmod));
341 set_parse_status(This, PARSE_ERR);
345 static void check_abs_srcmod(struct asm_parser *This, DWORD srcmod) {
346 if(srcmod == BWRITERSPSM_ABS || srcmod == BWRITERSPSM_ABSNEG) {
347 asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
349 debug_print_srcmod(srcmod));
350 set_parse_status(This, PARSE_ERR);
354 static void check_loop_swizzle(struct asm_parser *This,
355 const struct shader_reg *src) {
356 if((src->type == BWRITERSPR_LOOP && src->swizzle != BWRITERVS_NOSWIZZLE) ||
357 (src->rel_reg && src->rel_reg->type == BWRITERSPR_LOOP &&
358 src->rel_reg->swizzle != BWRITERVS_NOSWIZZLE)) {
359 asmparser_message(This, "Line %u: Swizzle not allowed on aL register\n", This->line_no);
360 set_parse_status(This, PARSE_ERR);
364 static void check_shift_dstmod(struct asm_parser *This, DWORD shift) {
366 asmparser_message(This, "Line %u: Shift modifiers not supported in this shader version\n",
368 set_parse_status(This, PARSE_ERR);
372 static void check_ps_dstmod(struct asm_parser *This, DWORD dstmod) {
373 if(dstmod == BWRITERSPDM_PARTIALPRECISION ||
374 dstmod == BWRITERSPDM_MSAMPCENTROID) {
375 asmparser_message(This, "Line %u: Instruction modifier %s not supported in this shader version\n",
377 debug_print_dstmod(dstmod));
378 set_parse_status(This, PARSE_ERR);
382 struct allowed_reg_type {
387 static BOOL check_reg_type(const struct shader_reg *reg,
388 const struct allowed_reg_type *allowed) {
391 while(allowed[i].type != ~0U) {
392 if(reg->type == allowed[i].type) {
393 if(reg->rel_reg) return TRUE; /* The relative addressing register
394 can have a negative value, we
395 can't check the register index */
396 if(reg->regnum < allowed[i].count) return TRUE;
404 /* Native assembler doesn't do separate checks for src and dst registers */
405 static const struct allowed_reg_type vs_2_reg_allowed[] = {
406 { BWRITERSPR_TEMP, 12 },
407 { BWRITERSPR_INPUT, 16 },
408 { BWRITERSPR_CONST, ~0U },
409 { BWRITERSPR_ADDR, 1 },
410 { BWRITERSPR_CONSTBOOL, 16 },
411 { BWRITERSPR_CONSTINT, 16 },
412 { BWRITERSPR_LOOP, 1 },
413 { BWRITERSPR_LABEL, 2048 },
414 { BWRITERSPR_PREDICATE, 1 },
415 { BWRITERSPR_RASTOUT, 3 }, /* oPos, oFog and oPts */
416 { BWRITERSPR_ATTROUT, 2 },
417 { BWRITERSPR_TEXCRDOUT, 8 },
418 { ~0U, 0 } /* End tag */
421 static void asmparser_srcreg_vs_2(struct asm_parser *This,
422 struct instruction *instr, int num,
423 const struct shader_reg *src) {
424 struct shader_reg reg;
426 if(!check_reg_type(src, vs_2_reg_allowed)) {
427 asmparser_message(This, "Line %u: Source register %s not supported in VS 2\n",
429 debug_print_srcreg(src, ST_VERTEX));
430 set_parse_status(This, PARSE_ERR);
432 check_loop_swizzle(This, src);
433 check_legacy_srcmod(This, src->srcmod);
434 check_abs_srcmod(This, src->srcmod);
435 reg = map_oldvs_register(src);
436 memcpy(&instr->src[num], ®, sizeof(reg));
439 static const struct allowed_reg_type vs_3_reg_allowed[] = {
440 { BWRITERSPR_TEMP, 32 },
441 { BWRITERSPR_INPUT, 16 },
442 { BWRITERSPR_CONST, ~0U },
443 { BWRITERSPR_ADDR, 1 },
444 { BWRITERSPR_CONSTBOOL, 16 },
445 { BWRITERSPR_CONSTINT, 16 },
446 { BWRITERSPR_LOOP, 1 },
447 { BWRITERSPR_LABEL, 2048 },
448 { BWRITERSPR_PREDICATE, 1 },
449 { BWRITERSPR_SAMPLER, 4 },
450 { BWRITERSPR_OUTPUT, 12 },
451 { ~0U, 0 } /* End tag */
454 static void asmparser_srcreg_vs_3(struct asm_parser *This,
455 struct instruction *instr, int num,
456 const struct shader_reg *src) {
457 if(!check_reg_type(src, vs_3_reg_allowed)) {
458 asmparser_message(This, "Line %u: Source register %s not supported in VS 3.0\n",
460 debug_print_srcreg(src, ST_VERTEX));
461 set_parse_status(This, PARSE_ERR);
463 check_loop_swizzle(This, src);
464 check_legacy_srcmod(This, src->srcmod);
465 memcpy(&instr->src[num], src, sizeof(*src));
468 static const struct allowed_reg_type ps_2_0_reg_allowed[] = {
469 { BWRITERSPR_INPUT, 2 },
470 { BWRITERSPR_TEMP, 32 },
471 { BWRITERSPR_CONST, 32 },
472 { BWRITERSPR_CONSTINT, 16 },
473 { BWRITERSPR_CONSTBOOL, 16 },
474 { BWRITERSPR_SAMPLER, 16 },
475 { BWRITERSPR_TEXTURE, 8 },
476 { BWRITERSPR_COLOROUT, 4 },
477 { BWRITERSPR_DEPTHOUT, 1 },
478 { ~0U, 0 } /* End tag */
481 static void asmparser_srcreg_ps_2(struct asm_parser *This,
482 struct instruction *instr, int num,
483 const struct shader_reg *src) {
484 struct shader_reg reg;
486 if(!check_reg_type(src, ps_2_0_reg_allowed)) {
487 asmparser_message(This, "Line %u: Source register %s not supported in PS 2.0\n",
489 debug_print_srcreg(src, ST_PIXEL));
490 set_parse_status(This, PARSE_ERR);
492 check_legacy_srcmod(This, src->srcmod);
493 check_abs_srcmod(This, src->srcmod);
494 reg = map_oldps_register(src, TRUE);
495 memcpy(&instr->src[num], ®, sizeof(reg));
498 static const struct allowed_reg_type ps_2_x_reg_allowed[] = {
499 { BWRITERSPR_INPUT, 2 },
500 { BWRITERSPR_TEMP, 32 },
501 { BWRITERSPR_CONST, 32 },
502 { BWRITERSPR_CONSTINT, 16 },
503 { BWRITERSPR_CONSTBOOL, 16 },
504 { BWRITERSPR_PREDICATE, 1 },
505 { BWRITERSPR_SAMPLER, 16 },
506 { BWRITERSPR_TEXTURE, 8 },
507 { BWRITERSPR_LABEL, 2048 },
508 { BWRITERSPR_COLOROUT, 4 },
509 { BWRITERSPR_DEPTHOUT, 1 },
510 { ~0U, 0 } /* End tag */
513 static void asmparser_srcreg_ps_2_x(struct asm_parser *This,
514 struct instruction *instr, int num,
515 const struct shader_reg *src) {
516 struct shader_reg reg;
518 if(!check_reg_type(src, ps_2_x_reg_allowed)) {
519 asmparser_message(This, "Line %u: Source register %s not supported in PS 2.x\n",
521 debug_print_srcreg(src, ST_PIXEL));
522 set_parse_status(This, PARSE_ERR);
524 check_legacy_srcmod(This, src->srcmod);
525 check_abs_srcmod(This, src->srcmod);
526 reg = map_oldps_register(src, TRUE);
527 memcpy(&instr->src[num], ®, sizeof(reg));
530 static const struct allowed_reg_type ps_3_reg_allowed[] = {
531 { BWRITERSPR_INPUT, 10 },
532 { BWRITERSPR_TEMP, 32 },
533 { BWRITERSPR_CONST, 224 },
534 { BWRITERSPR_CONSTINT, 16 },
535 { BWRITERSPR_CONSTBOOL, 16 },
536 { BWRITERSPR_PREDICATE, 1 },
537 { BWRITERSPR_SAMPLER, 16 },
538 { BWRITERSPR_MISCTYPE, 2 }, /* vPos and vFace */
539 { BWRITERSPR_LOOP, 1 },
540 { BWRITERSPR_LABEL, 2048 },
541 { BWRITERSPR_COLOROUT, 4 },
542 { BWRITERSPR_DEPTHOUT, 1 },
543 { ~0U, 0 } /* End tag */
546 static void asmparser_srcreg_ps_3(struct asm_parser *This,
547 struct instruction *instr, int num,
548 const struct shader_reg *src) {
549 if(!check_reg_type(src, ps_3_reg_allowed)) {
550 asmparser_message(This, "Line %u: Source register %s not supported in PS 3.0\n",
552 debug_print_srcreg(src, ST_PIXEL));
553 set_parse_status(This, PARSE_ERR);
555 check_loop_swizzle(This, src);
556 check_legacy_srcmod(This, src->srcmod);
557 memcpy(&instr->src[num], src, sizeof(*src));
560 static void asmparser_dstreg_vs_2(struct asm_parser *This,
561 struct instruction *instr,
562 const struct shader_reg *dst) {
563 struct shader_reg reg;
565 if(!check_reg_type(dst, vs_2_reg_allowed)) {
566 asmparser_message(This, "Line %u: Destination register %s not supported in VS 2.0\n",
568 debug_print_dstreg(dst, ST_VERTEX));
569 set_parse_status(This, PARSE_ERR);
571 check_ps_dstmod(This, instr->dstmod);
572 check_shift_dstmod(This, instr->shift);
573 reg = map_oldvs_register(dst);
574 memcpy(&instr->dst, ®, sizeof(reg));
575 instr->has_dst = TRUE;
578 static void asmparser_dstreg_vs_3(struct asm_parser *This,
579 struct instruction *instr,
580 const struct shader_reg *dst) {
581 if(!check_reg_type(dst, vs_3_reg_allowed)) {
582 asmparser_message(This, "Line %u: Destination register %s not supported in VS 3.0\n",
584 debug_print_dstreg(dst, ST_VERTEX));
585 set_parse_status(This, PARSE_ERR);
587 check_ps_dstmod(This, instr->dstmod);
588 check_shift_dstmod(This, instr->shift);
589 memcpy(&instr->dst, dst, sizeof(*dst));
590 instr->has_dst = TRUE;
593 static void asmparser_dstreg_ps_2(struct asm_parser *This,
594 struct instruction *instr,
595 const struct shader_reg *dst) {
596 struct shader_reg reg;
598 if(!check_reg_type(dst, ps_2_0_reg_allowed)) {
599 asmparser_message(This, "Line %u: Destination register %s not supported in PS 2.0\n",
601 debug_print_dstreg(dst, ST_PIXEL));
602 set_parse_status(This, PARSE_ERR);
604 check_shift_dstmod(This, instr->shift);
605 reg = map_oldps_register(dst, TRUE);
606 memcpy(&instr->dst, ®, sizeof(reg));
607 instr->has_dst = TRUE;
610 static void asmparser_dstreg_ps_2_x(struct asm_parser *This,
611 struct instruction *instr,
612 const struct shader_reg *dst) {
613 struct shader_reg reg;
615 if(!check_reg_type(dst, ps_2_x_reg_allowed)) {
616 asmparser_message(This, "Line %u: Destination register %s not supported in PS 2.x\n",
618 debug_print_dstreg(dst, ST_PIXEL));
619 set_parse_status(This, PARSE_ERR);
621 check_shift_dstmod(This, instr->shift);
622 reg = map_oldps_register(dst, TRUE);
623 memcpy(&instr->dst, ®, sizeof(reg));
624 instr->has_dst = TRUE;
627 static void asmparser_dstreg_ps_3(struct asm_parser *This,
628 struct instruction *instr,
629 const struct shader_reg *dst) {
630 if(!check_reg_type(dst, ps_3_reg_allowed)) {
631 asmparser_message(This, "Line %u: Destination register %s not supported in PS 3.0\n",
633 debug_print_dstreg(dst, ST_PIXEL));
634 set_parse_status(This, PARSE_ERR);
636 check_shift_dstmod(This, instr->shift);
637 memcpy(&instr->dst, dst, sizeof(*dst));
638 instr->has_dst = TRUE;
641 static void asmparser_predicate_supported(struct asm_parser *This,
642 const struct shader_reg *predicate) {
643 /* this sets the predicate of the last instruction added to the shader */
644 if(!This->shader) return;
645 if(This->shader->num_instrs == 0) ERR("Predicate without an instruction\n");
646 This->shader->instr[This->shader->num_instrs - 1]->has_predicate = TRUE;
647 memcpy(&This->shader->instr[This->shader->num_instrs - 1]->predicate, predicate, sizeof(*predicate));
650 static void asmparser_predicate_unsupported(struct asm_parser *This,
651 const struct shader_reg *predicate) {
652 asmparser_message(This, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This->line_no);
653 set_parse_status(This, PARSE_ERR);
656 static void asmparser_coissue_unsupported(struct asm_parser *This) {
657 asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
658 set_parse_status(This, PARSE_ERR);
661 static const struct asmparser_backend parser_vs_2 = {
666 asmparser_dstreg_vs_2,
667 asmparser_srcreg_vs_2,
669 asmparser_predicate_supported,
670 asmparser_coissue_unsupported,
672 asmparser_dcl_output,
674 asmparser_dcl_sampler,
681 static const struct asmparser_backend parser_vs_3 = {
686 asmparser_dstreg_vs_3,
687 asmparser_srcreg_vs_3,
689 asmparser_predicate_supported,
690 asmparser_coissue_unsupported,
692 asmparser_dcl_output,
694 asmparser_dcl_sampler,
701 static const struct asmparser_backend parser_ps_2 = {
706 asmparser_dstreg_ps_2,
707 asmparser_srcreg_ps_2,
709 asmparser_predicate_unsupported,
710 asmparser_coissue_unsupported,
712 asmparser_dcl_output,
714 asmparser_dcl_sampler,
721 static const struct asmparser_backend parser_ps_2_x = {
726 asmparser_dstreg_ps_2_x,
727 asmparser_srcreg_ps_2_x,
729 asmparser_predicate_supported,
730 asmparser_coissue_unsupported,
732 asmparser_dcl_output,
734 asmparser_dcl_sampler,
741 static const struct asmparser_backend parser_ps_3 = {
746 asmparser_dstreg_ps_3,
747 asmparser_srcreg_ps_3,
749 asmparser_predicate_supported,
750 asmparser_coissue_unsupported,
752 asmparser_dcl_output,
754 asmparser_dcl_sampler,
761 static void gen_oldvs_output(struct bwriter_shader *shader) {
762 record_declaration(shader, BWRITERDECLUSAGE_POSITION, 0, TRUE, OPOS_REG, BWRITERSP_WRITEMASK_ALL);
763 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, TRUE, OT0_REG, BWRITERSP_WRITEMASK_ALL);
764 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, TRUE, OT1_REG, BWRITERSP_WRITEMASK_ALL);
765 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, TRUE, OT2_REG, BWRITERSP_WRITEMASK_ALL);
766 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, TRUE, OT3_REG, BWRITERSP_WRITEMASK_ALL);
767 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, TRUE, OT4_REG, BWRITERSP_WRITEMASK_ALL);
768 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, TRUE, OT5_REG, BWRITERSP_WRITEMASK_ALL);
769 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, TRUE, OT6_REG, BWRITERSP_WRITEMASK_ALL);
770 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, TRUE, OT7_REG, BWRITERSP_WRITEMASK_ALL);
771 record_declaration(shader, BWRITERDECLUSAGE_FOG, 0, TRUE, OFOG_REG, OFOG_WRITEMASK);
772 record_declaration(shader, BWRITERDECLUSAGE_PSIZE, 0, TRUE, OPTS_REG, OPTS_WRITEMASK);
773 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, TRUE, OD0_REG, BWRITERSP_WRITEMASK_ALL);
774 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, TRUE, OD1_REG, BWRITERSP_WRITEMASK_ALL);
777 static void gen_oldps_input(struct bwriter_shader *shader, DWORD texcoords) {
779 case 8: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, FALSE, T7_VARYING, BWRITERSP_WRITEMASK_ALL);
780 case 7: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, FALSE, T6_VARYING, BWRITERSP_WRITEMASK_ALL);
781 case 6: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, FALSE, T5_VARYING, BWRITERSP_WRITEMASK_ALL);
782 case 5: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, FALSE, T4_VARYING, BWRITERSP_WRITEMASK_ALL);
783 case 4: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, FALSE, T3_VARYING, BWRITERSP_WRITEMASK_ALL);
784 case 3: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, FALSE, T2_VARYING, BWRITERSP_WRITEMASK_ALL);
785 case 2: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, FALSE, T1_VARYING, BWRITERSP_WRITEMASK_ALL);
786 case 1: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, FALSE, T0_VARYING, BWRITERSP_WRITEMASK_ALL);
788 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, FALSE, C0_VARYING, BWRITERSP_WRITEMASK_ALL);
789 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, FALSE, C1_VARYING, BWRITERSP_WRITEMASK_ALL);
792 void create_vs20_parser(struct asm_parser *ret) {
793 TRACE_(parsed_shader)("vs_2_0\n");
795 ret->shader = asm_alloc(sizeof(*ret->shader));
797 ERR("Failed to allocate memory for the shader\n");
798 set_parse_status(ret, PARSE_ERR);
802 ret->shader->type = ST_VERTEX;
803 ret->shader->version = BWRITERVS_VERSION(2, 0);
804 ret->funcs = &parser_vs_2;
805 gen_oldvs_output(ret->shader);
808 void create_vs2x_parser(struct asm_parser *ret) {
809 TRACE_(parsed_shader)("vs_2_x\n");
811 ret->shader = asm_alloc(sizeof(*ret->shader));
813 ERR("Failed to allocate memory for the shader\n");
814 set_parse_status(ret, PARSE_ERR);
818 ret->shader->type = ST_VERTEX;
819 ret->shader->version = BWRITERVS_VERSION(2, 1);
820 ret->funcs = &parser_vs_2;
821 gen_oldvs_output(ret->shader);
824 void create_vs30_parser(struct asm_parser *ret) {
825 TRACE_(parsed_shader)("vs_3_0\n");
827 ret->shader = asm_alloc(sizeof(*ret->shader));
829 ERR("Failed to allocate memory for the shader\n");
830 set_parse_status(ret, PARSE_ERR);
834 ret->shader->type = ST_VERTEX;
835 ret->shader->version = BWRITERVS_VERSION(3, 0);
836 ret->funcs = &parser_vs_3;
839 void create_ps20_parser(struct asm_parser *ret) {
840 TRACE_(parsed_shader)("ps_2_0\n");
842 ret->shader = asm_alloc(sizeof(*ret->shader));
844 ERR("Failed to allocate memory for the shader\n");
845 set_parse_status(ret, PARSE_ERR);
849 ret->shader->type = ST_PIXEL;
850 ret->shader->version = BWRITERPS_VERSION(2, 0);
851 ret->funcs = &parser_ps_2;
852 gen_oldps_input(ret->shader, 8);
855 void create_ps2x_parser(struct asm_parser *ret) {
856 TRACE_(parsed_shader)("ps_2_x\n");
858 ret->shader = asm_alloc(sizeof(*ret->shader));
860 ERR("Failed to allocate memory for the shader\n");
861 set_parse_status(ret, PARSE_ERR);
865 ret->shader->type = ST_PIXEL;
866 ret->shader->version = BWRITERPS_VERSION(2, 1);
867 ret->funcs = &parser_ps_2_x;
868 gen_oldps_input(ret->shader, 8);
871 void create_ps30_parser(struct asm_parser *ret) {
872 TRACE_(parsed_shader)("ps_3_0\n");
874 ret->shader = asm_alloc(sizeof(*ret->shader));
876 ERR("Failed to allocate memory for the shader\n");
877 set_parse_status(ret, PARSE_ERR);
881 ret->shader->type = ST_PIXEL;
882 ret->shader->version = BWRITERPS_VERSION(3, 0);
883 ret->funcs = &parser_ps_3;