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
, 0, TRUE
, reg
->regnum
, reg
->writemask
, FALSE
)) {
114 ERR("Out of memory\n");
115 set_parse_status(This
, PARSE_ERR
);
119 static void asmparser_dcl_output_unsupported(struct asm_parser
*This
, DWORD usage
, DWORD num
,
120 const struct shader_reg
*reg
) {
121 asmparser_message(This
, "Line %u: Output declaration unsupported in this shader version\n", This
->line_no
);
122 set_parse_status(This
, PARSE_ERR
);
125 static void asmparser_dcl_input(struct asm_parser
*This
, DWORD usage
, DWORD num
,
126 DWORD mod
, const struct shader_reg
*reg
) {
127 struct instruction instr
;
129 if(!This
->shader
) return;
131 (This
->shader
->version
!= BWRITERPS_VERSION(3, 0) ||
132 (mod
!= BWRITERSPDM_MSAMPCENTROID
&&
133 mod
!= BWRITERSPDM_PARTIALPRECISION
))) {
134 asmparser_message(This
, "Line %u: Unsupported modifier in dcl instruction\n", This
->line_no
);
135 set_parse_status(This
, PARSE_ERR
);
139 /* Check register type and modifiers */
142 This
->funcs
->dstreg(This
, &instr
, reg
);
144 if(!record_declaration(This
->shader
, usage
, num
, mod
, FALSE
, reg
->regnum
, reg
->writemask
, FALSE
)) {
145 ERR("Out of memory\n");
146 set_parse_status(This
, PARSE_ERR
);
150 static void asmparser_dcl_input_ps_2(struct asm_parser
*This
, DWORD usage
, DWORD num
,
151 DWORD mod
, const struct shader_reg
*reg
) {
152 struct instruction instr
;
154 if(!This
->shader
) return;
157 This
->funcs
->dstreg(This
, &instr
, reg
);
158 if(!record_declaration(This
->shader
, usage
, num
, mod
, FALSE
, instr
.dst
.regnum
, instr
.dst
.writemask
, FALSE
)) {
159 ERR("Out of memory\n");
160 set_parse_status(This
, PARSE_ERR
);
164 static void asmparser_dcl_input_unsupported(struct asm_parser
*This
, DWORD usage
, DWORD num
,
165 DWORD mod
, const struct shader_reg
*reg
) {
166 asmparser_message(This
, "Line %u: Input declaration unsupported in this shader version\n", This
->line_no
);
167 set_parse_status(This
, PARSE_ERR
);
170 static void asmparser_dcl_sampler(struct asm_parser
*This
, DWORD samptype
,
171 DWORD mod
, DWORD regnum
,
172 unsigned int line_no
) {
173 if(!This
->shader
) return;
175 (This
->shader
->version
!= BWRITERPS_VERSION(3, 0) ||
176 (mod
!= BWRITERSPDM_MSAMPCENTROID
&&
177 mod
!= BWRITERSPDM_PARTIALPRECISION
))) {
178 asmparser_message(This
, "Line %u: Unsupported modifier in dcl instruction\n", This
->line_no
);
179 set_parse_status(This
, PARSE_ERR
);
182 if(!record_sampler(This
->shader
, samptype
, mod
, regnum
)) {
183 ERR("Out of memory\n");
184 set_parse_status(This
, PARSE_ERR
);
188 static void asmparser_dcl_sampler_unsupported(struct asm_parser
*This
, DWORD samptype
,
189 DWORD mod
, DWORD regnum
,
190 unsigned int line_no
) {
191 asmparser_message(This
, "Line %u: Sampler declaration unsupported in this shader version\n", This
->line_no
);
192 set_parse_status(This
, PARSE_ERR
);
195 static void asmparser_sincos(struct asm_parser
*This
, DWORD mod
, DWORD shift
,
196 const struct shader_reg
*dst
,
197 const struct src_regs
*srcs
) {
198 struct instruction
*instr
;
200 if(!srcs
|| srcs
->count
!= 3) {
201 asmparser_message(This
, "Line %u: sincos (vs 2) has an incorrect number of source registers\n", This
->line_no
);
202 set_parse_status(This
, PARSE_ERR
);
206 instr
= alloc_instr(3);
208 ERR("Error allocating memory for the instruction\n");
209 set_parse_status(This
, PARSE_ERR
);
213 instr
->opcode
= BWRITERSIO_SINCOS
;
215 instr
->shift
= shift
;
218 This
->funcs
->dstreg(This
, instr
, dst
);
219 This
->funcs
->srcreg(This
, instr
, 0, &srcs
->reg
[0]);
220 This
->funcs
->srcreg(This
, instr
, 1, &srcs
->reg
[1]);
221 This
->funcs
->srcreg(This
, instr
, 2, &srcs
->reg
[2]);
223 if(!add_instruction(This
->shader
, instr
)) {
224 ERR("Out of memory\n");
225 set_parse_status(This
, PARSE_ERR
);
229 static void asmparser_texcrd(struct asm_parser
*This
, DWORD mod
, DWORD shift
,
230 const struct shader_reg
*dst
,
231 const struct src_regs
*srcs
) {
232 struct instruction
*instr
;
234 if(!srcs
|| srcs
->count
!= 1) {
235 asmparser_message(This
, "Line %u: Wrong number of source registers in texcrd instruction\n", This
->line_no
);
236 set_parse_status(This
, PARSE_ERR
);
240 instr
= alloc_instr(1);
242 ERR("Error allocating memory for the instruction\n");
243 set_parse_status(This
, PARSE_ERR
);
247 /* The job of texcrd is done by mov in later shader versions */
248 instr
->opcode
= BWRITERSIO_MOV
;
250 instr
->shift
= shift
;
253 This
->funcs
->dstreg(This
, instr
, dst
);
254 This
->funcs
->srcreg(This
, instr
, 0, &srcs
->reg
[0]);
256 if(!add_instruction(This
->shader
, instr
)) {
257 ERR("Out of memory\n");
258 set_parse_status(This
, PARSE_ERR
);
262 static void asmparser_texld14(struct asm_parser
*This
, DWORD mod
, DWORD shift
,
263 const struct shader_reg
*dst
,
264 const struct src_regs
*srcs
) {
265 struct instruction
*instr
;
267 if(!srcs
|| srcs
->count
!= 1) {
268 asmparser_message(This
, "Line %u: texld (PS 1.4) has a wrong number of source registers\n", This
->line_no
);
269 set_parse_status(This
, PARSE_ERR
);
273 instr
= alloc_instr(2);
275 ERR("Error allocating memory for the instruction\n");
276 set_parse_status(This
, PARSE_ERR
);
280 /* This code is recording a texld instruction, not tex. However,
281 * texld borrows the opcode of tex
283 instr
->opcode
= BWRITERSIO_TEX
;
285 instr
->shift
= shift
;
288 This
->funcs
->dstreg(This
, instr
, dst
);
289 This
->funcs
->srcreg(This
, instr
, 0, &srcs
->reg
[0]);
291 /* The 2nd source register is the sampler register with the
292 * destination's regnum
294 ZeroMemory(&instr
->src
[1], sizeof(instr
->src
[1]));
295 instr
->src
[1].type
= BWRITERSPR_SAMPLER
;
296 instr
->src
[1].regnum
= dst
->regnum
;
297 instr
->src
[1].swizzle
= BWRITERVS_NOSWIZZLE
;
298 instr
->src
[1].srcmod
= BWRITERSPSM_NONE
;
299 instr
->src
[1].rel_reg
= NULL
;
301 if(!add_instruction(This
->shader
, instr
)) {
302 ERR("Out of memory\n");
303 set_parse_status(This
, PARSE_ERR
);
307 static void asmparser_instr(struct asm_parser
*This
, DWORD opcode
,
308 DWORD mod
, DWORD shift
,
309 BWRITER_COMPARISON_TYPE comp
,
310 const struct shader_reg
*dst
,
311 const struct src_regs
*srcs
, int expectednsrcs
) {
312 struct instruction
*instr
;
314 BOOL firstreg
= TRUE
;
315 unsigned int src_count
= srcs
? srcs
->count
: 0;
317 if(!This
->shader
) return;
319 TRACE_(parsed_shader
)("%s%s%s%s ", debug_print_opcode(opcode
),
320 debug_print_dstmod(mod
),
321 debug_print_shift(shift
),
322 debug_print_comp(comp
));
324 TRACE_(parsed_shader
)("%s", debug_print_dstreg(dst
));
327 for(i
= 0; i
< src_count
; i
++) {
328 if(!firstreg
) TRACE_(parsed_shader
)(", ");
329 else firstreg
= FALSE
;
330 TRACE_(parsed_shader
)("%s", debug_print_srcreg(&srcs
->reg
[i
]));
332 TRACE_(parsed_shader
)("\n");
334 /* Check for instructions with different syntaxes in different shader versio
337 case BWRITERSIO_SINCOS
:
338 /* The syntax changes between vs 2 and the other shader versions */
339 if(This
->shader
->version
== BWRITERVS_VERSION(2, 0) ||
340 This
->shader
->version
== BWRITERVS_VERSION(2, 1)) {
341 asmparser_sincos(This
, mod
, shift
, dst
, srcs
);
344 /* Use the default handling */
346 case BWRITERSIO_TEXCOORD
:
347 /* texcoord/texcrd are two instructions present only in PS <= 1.3 and PS 1.4 respectively */
348 asmparser_texcrd(This
, mod
, shift
, dst
, srcs
);
351 /* this encodes both the tex PS 1.x instruction and the
352 texld 1.4/2.0+ instruction */
353 if(This
->shader
->version
== BWRITERPS_VERSION(1, 4)) {
354 asmparser_texld14(This
, mod
, shift
, dst
, srcs
);
357 /* else fallback to the standard behavior */
361 if(src_count
!= expectednsrcs
) {
362 asmparser_message(This
, "Line %u: Wrong number of source registers\n", This
->line_no
);
363 set_parse_status(This
, PARSE_ERR
);
367 instr
= alloc_instr(src_count
);
369 ERR("Error allocating memory for the instruction\n");
370 set_parse_status(This
, PARSE_ERR
);
374 instr
->opcode
= opcode
;
376 instr
->shift
= shift
;
377 instr
->comptype
= comp
;
378 if(dst
) This
->funcs
->dstreg(This
, instr
, dst
);
379 for(i
= 0; i
< src_count
; i
++) {
380 This
->funcs
->srcreg(This
, instr
, i
, &srcs
->reg
[i
]);
383 if(!add_instruction(This
->shader
, instr
)) {
384 ERR("Out of memory\n");
385 set_parse_status(This
, PARSE_ERR
);
389 static struct shader_reg
map_oldvs_register(const struct shader_reg
*reg
) {
390 struct shader_reg ret
;
392 case BWRITERSPR_RASTOUT
:
394 ret
.type
= BWRITERSPR_OUTPUT
;
395 switch(reg
->regnum
) {
396 case BWRITERSRO_POSITION
:
397 ret
.regnum
= OPOS_REG
;
400 ret
.regnum
= OFOG_REG
;
401 ret
.writemask
= OFOG_WRITEMASK
;
403 case BWRITERSRO_POINT_SIZE
:
404 ret
.regnum
= OPTS_REG
;
405 ret
.writemask
= OPTS_WRITEMASK
;
408 FIXME("Unhandled RASTOUT register %u\n", reg
->regnum
);
413 case BWRITERSPR_TEXCRDOUT
:
415 ret
.type
= BWRITERSPR_OUTPUT
;
416 switch(reg
->regnum
) {
417 case 0: ret
.regnum
= OT0_REG
; break;
418 case 1: ret
.regnum
= OT1_REG
; break;
419 case 2: ret
.regnum
= OT2_REG
; break;
420 case 3: ret
.regnum
= OT3_REG
; break;
421 case 4: ret
.regnum
= OT4_REG
; break;
422 case 5: ret
.regnum
= OT5_REG
; break;
423 case 6: ret
.regnum
= OT6_REG
; break;
424 case 7: ret
.regnum
= OT7_REG
; break;
426 FIXME("Unhandled TEXCRDOUT regnum %u\n", reg
->regnum
);
431 case BWRITERSPR_ATTROUT
:
433 ret
.type
= BWRITERSPR_OUTPUT
;
434 switch(reg
->regnum
) {
435 case 0: ret
.regnum
= OD0_REG
; break;
436 case 1: ret
.regnum
= OD1_REG
; break;
438 FIXME("Unhandled ATTROUT regnum %u\n", reg
->regnum
);
443 default: return *reg
;
447 static struct shader_reg
map_oldps_register(const struct shader_reg
*reg
, BOOL tex_varying
) {
448 struct shader_reg ret
;
450 case BWRITERSPR_TEXTURE
:
453 ret
.type
= BWRITERSPR_INPUT
;
454 switch(reg
->regnum
) {
455 case 0: ret
.regnum
= T0_VARYING
; break;
456 case 1: ret
.regnum
= T1_VARYING
; break;
457 case 2: ret
.regnum
= T2_VARYING
; break;
458 case 3: ret
.regnum
= T3_VARYING
; break;
459 case 4: ret
.regnum
= T4_VARYING
; break;
460 case 5: ret
.regnum
= T5_VARYING
; break;
461 case 6: ret
.regnum
= T6_VARYING
; break;
462 case 7: ret
.regnum
= T7_VARYING
; break;
464 FIXME("Unexpected TEXTURE register t%u\n", reg
->regnum
);
469 FIXME("TODO: ps_1_x texture register mapping\n");
473 /* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
476 default: return *reg
;
480 /* Checks for unsupported source modifiers in VS (all versions) or
482 static void check_legacy_srcmod(struct asm_parser
*This
, DWORD srcmod
) {
483 if(srcmod
== BWRITERSPSM_BIAS
|| srcmod
== BWRITERSPSM_BIASNEG
||
484 srcmod
== BWRITERSPSM_SIGN
|| srcmod
== BWRITERSPSM_SIGNNEG
||
485 srcmod
== BWRITERSPSM_COMP
|| srcmod
== BWRITERSPSM_X2
||
486 srcmod
== BWRITERSPSM_X2NEG
|| srcmod
== BWRITERSPSM_DZ
||
487 srcmod
== BWRITERSPSM_DW
) {
488 asmparser_message(This
, "Line %u: Source modifier %s not supported in this shader version\n",
490 debug_print_srcmod(srcmod
));
491 set_parse_status(This
, PARSE_ERR
);
495 static void check_abs_srcmod(struct asm_parser
*This
, DWORD srcmod
) {
496 if(srcmod
== BWRITERSPSM_ABS
|| srcmod
== BWRITERSPSM_ABSNEG
) {
497 asmparser_message(This
, "Line %u: Source modifier %s not supported in this shader version\n",
499 debug_print_srcmod(srcmod
));
500 set_parse_status(This
, PARSE_ERR
);
504 static void check_loop_swizzle(struct asm_parser
*This
,
505 const struct shader_reg
*src
) {
506 if((src
->type
== BWRITERSPR_LOOP
&& src
->swizzle
!= BWRITERVS_NOSWIZZLE
) ||
507 (src
->rel_reg
&& src
->rel_reg
->type
== BWRITERSPR_LOOP
&&
508 src
->rel_reg
->swizzle
!= BWRITERVS_NOSWIZZLE
)) {
509 asmparser_message(This
, "Line %u: Swizzle not allowed on aL register\n", This
->line_no
);
510 set_parse_status(This
, PARSE_ERR
);
514 static void check_shift_dstmod(struct asm_parser
*This
, DWORD shift
) {
516 asmparser_message(This
, "Line %u: Shift modifiers not supported in this shader version\n",
518 set_parse_status(This
, PARSE_ERR
);
522 static void check_ps_dstmod(struct asm_parser
*This
, DWORD dstmod
) {
523 if(dstmod
== BWRITERSPDM_PARTIALPRECISION
||
524 dstmod
== BWRITERSPDM_MSAMPCENTROID
) {
525 asmparser_message(This
, "Line %u: Instruction modifier %s not supported in this shader version\n",
527 debug_print_dstmod(dstmod
));
528 set_parse_status(This
, PARSE_ERR
);
532 struct allowed_reg_type
{
538 static BOOL
check_reg_type(const struct shader_reg
*reg
,
539 const struct allowed_reg_type
*allowed
) {
542 while(allowed
[i
].type
!= ~0U) {
543 if(reg
->type
== allowed
[i
].type
) {
545 if(allowed
[i
].reladdr
)
546 return TRUE
; /* The relative addressing register
547 can have a negative value, we
548 can't check the register index */
551 if(reg
->regnum
< allowed
[i
].count
) return TRUE
;
559 /* Native assembler doesn't do separate checks for src and dst registers */
560 static const struct allowed_reg_type vs_1_reg_allowed
[] = {
561 { BWRITERSPR_TEMP
, 12, FALSE
},
562 { BWRITERSPR_INPUT
, 16, FALSE
},
563 { BWRITERSPR_CONST
, ~0U, TRUE
},
564 { BWRITERSPR_ADDR
, 1, FALSE
},
565 { BWRITERSPR_RASTOUT
, 3, FALSE
}, /* oPos, oFog and oPts */
566 { BWRITERSPR_ATTROUT
, 2, FALSE
},
567 { BWRITERSPR_TEXCRDOUT
, 8, FALSE
},
568 { ~0U, 0 } /* End tag */
571 /* struct instruction *asmparser_srcreg
573 * Records a source register in the instruction and does shader version
574 * specific checks and modifications on it
577 * This: Shader parser instance
578 * instr: instruction to store the register in
579 * num: Number of source register
580 * src: Pointer to source the register structure. The caller can free
583 static void asmparser_srcreg_vs_1(struct asm_parser
*This
,
584 struct instruction
*instr
, int num
,
585 const struct shader_reg
*src
) {
586 struct shader_reg reg
;
588 if(!check_reg_type(src
, vs_1_reg_allowed
)) {
589 asmparser_message(This
, "Line %u: Source register %s not supported in VS 1\n",
591 debug_print_srcreg(src
));
592 set_parse_status(This
, PARSE_ERR
);
594 check_legacy_srcmod(This
, src
->srcmod
);
595 check_abs_srcmod(This
, src
->srcmod
);
596 reg
= map_oldvs_register(src
);
597 memcpy(&instr
->src
[num
], ®
, sizeof(reg
));
600 static const struct allowed_reg_type vs_2_reg_allowed
[] = {
601 { BWRITERSPR_TEMP
, 12, FALSE
},
602 { BWRITERSPR_INPUT
, 16, FALSE
},
603 { BWRITERSPR_CONST
, ~0U, TRUE
},
604 { BWRITERSPR_ADDR
, 1, FALSE
},
605 { BWRITERSPR_CONSTBOOL
, 16, FALSE
},
606 { BWRITERSPR_CONSTINT
, 16, FALSE
},
607 { BWRITERSPR_LOOP
, 1, FALSE
},
608 { BWRITERSPR_LABEL
, 2048, FALSE
},
609 { BWRITERSPR_PREDICATE
, 1, FALSE
},
610 { BWRITERSPR_RASTOUT
, 3, FALSE
}, /* oPos, oFog and oPts */
611 { BWRITERSPR_ATTROUT
, 2, FALSE
},
612 { BWRITERSPR_TEXCRDOUT
, 8, FALSE
},
613 { ~0U, 0 } /* End tag */
616 static void asmparser_srcreg_vs_2(struct asm_parser
*This
,
617 struct instruction
*instr
, int num
,
618 const struct shader_reg
*src
) {
619 struct shader_reg reg
;
621 if(!check_reg_type(src
, vs_2_reg_allowed
)) {
622 asmparser_message(This
, "Line %u: Source register %s not supported in VS 2\n",
624 debug_print_srcreg(src
));
625 set_parse_status(This
, PARSE_ERR
);
627 check_loop_swizzle(This
, src
);
628 check_legacy_srcmod(This
, src
->srcmod
);
629 check_abs_srcmod(This
, src
->srcmod
);
630 reg
= map_oldvs_register(src
);
631 memcpy(&instr
->src
[num
], ®
, sizeof(reg
));
634 static const struct allowed_reg_type vs_3_reg_allowed
[] = {
635 { BWRITERSPR_TEMP
, 32, FALSE
},
636 { BWRITERSPR_INPUT
, 16, TRUE
},
637 { BWRITERSPR_CONST
, ~0U, TRUE
},
638 { BWRITERSPR_ADDR
, 1, FALSE
},
639 { BWRITERSPR_CONSTBOOL
, 16, FALSE
},
640 { BWRITERSPR_CONSTINT
, 16, FALSE
},
641 { BWRITERSPR_LOOP
, 1, FALSE
},
642 { BWRITERSPR_LABEL
, 2048, FALSE
},
643 { BWRITERSPR_PREDICATE
, 1, FALSE
},
644 { BWRITERSPR_SAMPLER
, 4, FALSE
},
645 { BWRITERSPR_OUTPUT
, 12, TRUE
},
646 { ~0U, 0 } /* End tag */
649 static void asmparser_srcreg_vs_3(struct asm_parser
*This
,
650 struct instruction
*instr
, int num
,
651 const struct shader_reg
*src
) {
652 if(!check_reg_type(src
, vs_3_reg_allowed
)) {
653 asmparser_message(This
, "Line %u: Source register %s not supported in VS 3.0\n",
655 debug_print_srcreg(src
));
656 set_parse_status(This
, PARSE_ERR
);
658 check_loop_swizzle(This
, src
);
659 check_legacy_srcmod(This
, src
->srcmod
);
660 memcpy(&instr
->src
[num
], src
, sizeof(*src
));
663 static const struct allowed_reg_type ps_1_4_reg_allowed
[] = {
664 { BWRITERSPR_CONST
, 8, FALSE
},
665 { BWRITERSPR_TEMP
, 6, FALSE
},
666 { BWRITERSPR_TEXTURE
, 6, FALSE
},
667 { BWRITERSPR_INPUT
, 2, FALSE
},
668 { ~0U, 0 } /* End tag */
671 static void asmparser_srcreg_ps_1_4(struct asm_parser
*This
,
672 struct instruction
*instr
, int num
,
673 const struct shader_reg
*src
) {
674 struct shader_reg reg
;
676 if(!check_reg_type(src
, ps_1_4_reg_allowed
)) {
677 asmparser_message(This
, "Line %u: Source register %s not supported in PS 1.4\n",
679 debug_print_srcreg(src
));
680 set_parse_status(This
, PARSE_ERR
);
682 check_abs_srcmod(This
, src
->srcmod
);
683 reg
= map_oldps_register(src
, TRUE
);
684 memcpy(&instr
->src
[num
], ®
, sizeof(reg
));
687 static const struct allowed_reg_type ps_2_0_reg_allowed
[] = {
688 { BWRITERSPR_INPUT
, 2, FALSE
},
689 { BWRITERSPR_TEMP
, 32, FALSE
},
690 { BWRITERSPR_CONST
, 32, FALSE
},
691 { BWRITERSPR_CONSTINT
, 16, FALSE
},
692 { BWRITERSPR_CONSTBOOL
, 16, FALSE
},
693 { BWRITERSPR_SAMPLER
, 16, FALSE
},
694 { BWRITERSPR_TEXTURE
, 8, FALSE
},
695 { BWRITERSPR_COLOROUT
, 4, FALSE
},
696 { BWRITERSPR_DEPTHOUT
, 1, FALSE
},
697 { ~0U, 0 } /* End tag */
700 static void asmparser_srcreg_ps_2(struct asm_parser
*This
,
701 struct instruction
*instr
, int num
,
702 const struct shader_reg
*src
) {
703 struct shader_reg reg
;
705 if(!check_reg_type(src
, ps_2_0_reg_allowed
)) {
706 asmparser_message(This
, "Line %u: Source register %s not supported in PS 2.0\n",
708 debug_print_srcreg(src
));
709 set_parse_status(This
, PARSE_ERR
);
711 check_legacy_srcmod(This
, src
->srcmod
);
712 check_abs_srcmod(This
, src
->srcmod
);
713 reg
= map_oldps_register(src
, TRUE
);
714 memcpy(&instr
->src
[num
], ®
, sizeof(reg
));
717 static const struct allowed_reg_type ps_2_x_reg_allowed
[] = {
718 { BWRITERSPR_INPUT
, 2, FALSE
},
719 { BWRITERSPR_TEMP
, 32, FALSE
},
720 { BWRITERSPR_CONST
, 32, FALSE
},
721 { BWRITERSPR_CONSTINT
, 16, FALSE
},
722 { BWRITERSPR_CONSTBOOL
, 16, FALSE
},
723 { BWRITERSPR_PREDICATE
, 1, FALSE
},
724 { BWRITERSPR_SAMPLER
, 16, FALSE
},
725 { BWRITERSPR_TEXTURE
, 8, FALSE
},
726 { BWRITERSPR_LABEL
, 2048, FALSE
},
727 { BWRITERSPR_COLOROUT
, 4, FALSE
},
728 { BWRITERSPR_DEPTHOUT
, 1, FALSE
},
729 { ~0U, 0 } /* End tag */
732 static void asmparser_srcreg_ps_2_x(struct asm_parser
*This
,
733 struct instruction
*instr
, int num
,
734 const struct shader_reg
*src
) {
735 struct shader_reg reg
;
737 if(!check_reg_type(src
, ps_2_x_reg_allowed
)) {
738 asmparser_message(This
, "Line %u: Source register %s not supported in PS 2.x\n",
740 debug_print_srcreg(src
));
741 set_parse_status(This
, PARSE_ERR
);
743 check_legacy_srcmod(This
, src
->srcmod
);
744 check_abs_srcmod(This
, src
->srcmod
);
745 reg
= map_oldps_register(src
, TRUE
);
746 memcpy(&instr
->src
[num
], ®
, sizeof(reg
));
749 static const struct allowed_reg_type ps_3_reg_allowed
[] = {
750 { BWRITERSPR_INPUT
, 10, TRUE
},
751 { BWRITERSPR_TEMP
, 32, FALSE
},
752 { BWRITERSPR_CONST
, 224, FALSE
},
753 { BWRITERSPR_CONSTINT
, 16, FALSE
},
754 { BWRITERSPR_CONSTBOOL
, 16, FALSE
},
755 { BWRITERSPR_PREDICATE
, 1, FALSE
},
756 { BWRITERSPR_SAMPLER
, 16, FALSE
},
757 { BWRITERSPR_MISCTYPE
, 2, FALSE
}, /* vPos and vFace */
758 { BWRITERSPR_LOOP
, 1, FALSE
},
759 { BWRITERSPR_LABEL
, 2048, FALSE
},
760 { BWRITERSPR_COLOROUT
, 4, FALSE
},
761 { BWRITERSPR_DEPTHOUT
, 1, FALSE
},
762 { ~0U, 0 } /* End tag */
765 static void asmparser_srcreg_ps_3(struct asm_parser
*This
,
766 struct instruction
*instr
, int num
,
767 const struct shader_reg
*src
) {
768 if(!check_reg_type(src
, ps_3_reg_allowed
)) {
769 asmparser_message(This
, "Line %u: Source register %s not supported in PS 3.0\n",
771 debug_print_srcreg(src
));
772 set_parse_status(This
, PARSE_ERR
);
774 check_loop_swizzle(This
, src
);
775 check_legacy_srcmod(This
, src
->srcmod
);
776 memcpy(&instr
->src
[num
], src
, sizeof(*src
));
779 static void asmparser_dstreg_vs_1(struct asm_parser
*This
,
780 struct instruction
*instr
,
781 const struct shader_reg
*dst
) {
782 struct shader_reg reg
;
784 if(!check_reg_type(dst
, vs_1_reg_allowed
)) {
785 asmparser_message(This
, "Line %u: Destination register %s not supported in VS 1\n",
787 debug_print_dstreg(dst
));
788 set_parse_status(This
, PARSE_ERR
);
790 check_ps_dstmod(This
, instr
->dstmod
);
791 check_shift_dstmod(This
, instr
->shift
);
792 reg
= map_oldvs_register(dst
);
793 memcpy(&instr
->dst
, ®
, sizeof(reg
));
794 instr
->has_dst
= TRUE
;
797 static void asmparser_dstreg_vs_2(struct asm_parser
*This
,
798 struct instruction
*instr
,
799 const struct shader_reg
*dst
) {
800 struct shader_reg reg
;
802 if(!check_reg_type(dst
, vs_2_reg_allowed
)) {
803 asmparser_message(This
, "Line %u: Destination register %s not supported in VS 2.0\n",
805 debug_print_dstreg(dst
));
806 set_parse_status(This
, PARSE_ERR
);
808 check_ps_dstmod(This
, instr
->dstmod
);
809 check_shift_dstmod(This
, instr
->shift
);
810 reg
= map_oldvs_register(dst
);
811 memcpy(&instr
->dst
, ®
, sizeof(reg
));
812 instr
->has_dst
= TRUE
;
815 static void asmparser_dstreg_vs_3(struct asm_parser
*This
,
816 struct instruction
*instr
,
817 const struct shader_reg
*dst
) {
818 if(!check_reg_type(dst
, vs_3_reg_allowed
)) {
819 asmparser_message(This
, "Line %u: Destination register %s not supported in VS 3.0\n",
821 debug_print_dstreg(dst
));
822 set_parse_status(This
, PARSE_ERR
);
824 check_ps_dstmod(This
, instr
->dstmod
);
825 check_shift_dstmod(This
, instr
->shift
);
826 memcpy(&instr
->dst
, dst
, sizeof(*dst
));
827 instr
->has_dst
= TRUE
;
830 static void asmparser_dstreg_ps_1_4(struct asm_parser
*This
,
831 struct instruction
*instr
,
832 const struct shader_reg
*dst
) {
833 struct shader_reg reg
;
835 if(!check_reg_type(dst
, ps_1_4_reg_allowed
)) {
836 asmparser_message(This
, "Line %u: Destination register %s not supported in PS 1\n",
838 debug_print_dstreg(dst
));
839 set_parse_status(This
, PARSE_ERR
);
841 reg
= map_oldps_register(dst
, FALSE
);
842 memcpy(&instr
->dst
, ®
, sizeof(reg
));
843 instr
->has_dst
= TRUE
;
846 static void asmparser_dstreg_ps_2(struct asm_parser
*This
,
847 struct instruction
*instr
,
848 const struct shader_reg
*dst
) {
849 struct shader_reg reg
;
851 if(!check_reg_type(dst
, ps_2_0_reg_allowed
)) {
852 asmparser_message(This
, "Line %u: Destination register %s not supported in PS 2.0\n",
854 debug_print_dstreg(dst
));
855 set_parse_status(This
, PARSE_ERR
);
857 check_shift_dstmod(This
, instr
->shift
);
858 reg
= map_oldps_register(dst
, TRUE
);
859 memcpy(&instr
->dst
, ®
, sizeof(reg
));
860 instr
->has_dst
= TRUE
;
863 static void asmparser_dstreg_ps_2_x(struct asm_parser
*This
,
864 struct instruction
*instr
,
865 const struct shader_reg
*dst
) {
866 struct shader_reg reg
;
868 if(!check_reg_type(dst
, ps_2_x_reg_allowed
)) {
869 asmparser_message(This
, "Line %u: Destination register %s not supported in PS 2.x\n",
871 debug_print_dstreg(dst
));
872 set_parse_status(This
, PARSE_ERR
);
874 check_shift_dstmod(This
, instr
->shift
);
875 reg
= map_oldps_register(dst
, TRUE
);
876 memcpy(&instr
->dst
, ®
, sizeof(reg
));
877 instr
->has_dst
= TRUE
;
880 static void asmparser_dstreg_ps_3(struct asm_parser
*This
,
881 struct instruction
*instr
,
882 const struct shader_reg
*dst
) {
883 if(!check_reg_type(dst
, ps_3_reg_allowed
)) {
884 asmparser_message(This
, "Line %u: Destination register %s not supported in PS 3.0\n",
886 debug_print_dstreg(dst
));
887 set_parse_status(This
, PARSE_ERR
);
889 check_shift_dstmod(This
, instr
->shift
);
890 memcpy(&instr
->dst
, dst
, sizeof(*dst
));
891 instr
->has_dst
= TRUE
;
894 static void asmparser_predicate_supported(struct asm_parser
*This
,
895 const struct shader_reg
*predicate
) {
896 /* this sets the predicate of the last instruction added to the shader */
897 if(!This
->shader
) return;
898 if(This
->shader
->num_instrs
== 0) ERR("Predicate without an instruction\n");
899 This
->shader
->instr
[This
->shader
->num_instrs
- 1]->has_predicate
= TRUE
;
900 memcpy(&This
->shader
->instr
[This
->shader
->num_instrs
- 1]->predicate
, predicate
, sizeof(*predicate
));
903 static void asmparser_predicate_unsupported(struct asm_parser
*This
,
904 const struct shader_reg
*predicate
) {
905 asmparser_message(This
, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This
->line_no
);
906 set_parse_status(This
, PARSE_ERR
);
909 static void asmparser_coissue_supported(struct asm_parser
*This
) {
910 /* this sets the coissue flag of the last instruction added to the shader */
911 if(!This
->shader
) return;
912 if(This
->shader
->num_instrs
== 0){
913 asmparser_message(This
, "Line %u: Coissue flag on the first shader instruction\n", This
->line_no
);
914 set_parse_status(This
, PARSE_ERR
);
916 This
->shader
->instr
[This
->shader
->num_instrs
-1]->coissue
= TRUE
;
919 static void asmparser_coissue_unsupported(struct asm_parser
*This
) {
920 asmparser_message(This
, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This
->line_no
);
921 set_parse_status(This
, PARSE_ERR
);
924 static const struct asmparser_backend parser_vs_1
= {
929 asmparser_dstreg_vs_1
,
930 asmparser_srcreg_vs_1
,
932 asmparser_predicate_unsupported
,
933 asmparser_coissue_unsupported
,
935 asmparser_dcl_output_unsupported
,
937 asmparser_dcl_sampler_unsupported
,
944 static const struct asmparser_backend parser_vs_2
= {
949 asmparser_dstreg_vs_2
,
950 asmparser_srcreg_vs_2
,
952 asmparser_predicate_supported
,
953 asmparser_coissue_unsupported
,
955 asmparser_dcl_output_unsupported
,
957 asmparser_dcl_sampler_unsupported
,
964 static const struct asmparser_backend parser_vs_3
= {
969 asmparser_dstreg_vs_3
,
970 asmparser_srcreg_vs_3
,
972 asmparser_predicate_supported
,
973 asmparser_coissue_unsupported
,
975 asmparser_dcl_output
,
977 asmparser_dcl_sampler
,
984 static const struct asmparser_backend parser_ps_1_4
= {
989 asmparser_dstreg_ps_1_4
,
990 asmparser_srcreg_ps_1_4
,
992 asmparser_predicate_unsupported
,
993 asmparser_coissue_supported
,
995 asmparser_dcl_output_unsupported
,
996 asmparser_dcl_input_unsupported
,
997 asmparser_dcl_sampler_unsupported
,
1004 static const struct asmparser_backend parser_ps_2
= {
1009 asmparser_dstreg_ps_2
,
1010 asmparser_srcreg_ps_2
,
1012 asmparser_predicate_unsupported
,
1013 asmparser_coissue_unsupported
,
1015 asmparser_dcl_output_unsupported
,
1016 asmparser_dcl_input_ps_2
,
1017 asmparser_dcl_sampler
,
1024 static const struct asmparser_backend parser_ps_2_x
= {
1029 asmparser_dstreg_ps_2_x
,
1030 asmparser_srcreg_ps_2_x
,
1032 asmparser_predicate_supported
,
1033 asmparser_coissue_unsupported
,
1035 asmparser_dcl_output_unsupported
,
1036 asmparser_dcl_input_ps_2
,
1037 asmparser_dcl_sampler
,
1044 static const struct asmparser_backend parser_ps_3
= {
1049 asmparser_dstreg_ps_3
,
1050 asmparser_srcreg_ps_3
,
1052 asmparser_predicate_supported
,
1053 asmparser_coissue_unsupported
,
1055 asmparser_dcl_output_unsupported
,
1056 asmparser_dcl_input
,
1057 asmparser_dcl_sampler
,
1064 static void gen_oldvs_output(struct bwriter_shader
*shader
) {
1065 record_declaration(shader
, BWRITERDECLUSAGE_POSITION
, 0, 0, TRUE
, OPOS_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1066 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 0, 0, TRUE
, OT0_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1067 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 1, 0, TRUE
, OT1_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1068 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 2, 0, TRUE
, OT2_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1069 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 3, 0, TRUE
, OT3_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1070 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 4, 0, TRUE
, OT4_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1071 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 5, 0, TRUE
, OT5_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1072 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 6, 0, TRUE
, OT6_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1073 record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 7, 0, TRUE
, OT7_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1074 record_declaration(shader
, BWRITERDECLUSAGE_FOG
, 0, 0, TRUE
, OFOG_REG
, OFOG_WRITEMASK
, TRUE
);
1075 record_declaration(shader
, BWRITERDECLUSAGE_PSIZE
, 0, 0, TRUE
, OPTS_REG
, OPTS_WRITEMASK
, TRUE
);
1076 record_declaration(shader
, BWRITERDECLUSAGE_COLOR
, 0, 0, TRUE
, OD0_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1077 record_declaration(shader
, BWRITERDECLUSAGE_COLOR
, 1, 0, TRUE
, OD1_REG
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1080 static void gen_oldps_input(struct bwriter_shader
*shader
, DWORD texcoords
) {
1082 case 8: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 7, 0, FALSE
, T7_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1083 case 7: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 6, 0, FALSE
, T6_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1084 case 6: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 5, 0, FALSE
, T5_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1085 case 5: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 4, 0, FALSE
, T4_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1086 case 4: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 3, 0, FALSE
, T3_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1087 case 3: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 2, 0, FALSE
, T2_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1088 case 2: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 1, 0, FALSE
, T1_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1089 case 1: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 0, 0, FALSE
, T0_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1091 record_declaration(shader
, BWRITERDECLUSAGE_COLOR
, 0, 0, FALSE
, C0_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1092 record_declaration(shader
, BWRITERDECLUSAGE_COLOR
, 1, 0, FALSE
, C1_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1095 void create_vs10_parser(struct asm_parser
*ret
) {
1096 TRACE_(parsed_shader
)("vs_1_0\n");
1098 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1100 ERR("Failed to allocate memory for the shader\n");
1101 set_parse_status(ret
, PARSE_ERR
);
1105 ret
->shader
->type
= ST_VERTEX
;
1106 ret
->shader
->version
= BWRITERVS_VERSION(1, 0);
1107 ret
->funcs
= &parser_vs_1
;
1108 gen_oldvs_output(ret
->shader
);
1111 void create_vs11_parser(struct asm_parser
*ret
) {
1112 TRACE_(parsed_shader
)("vs_1_1\n");
1114 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1116 ERR("Failed to allocate memory for the shader\n");
1117 set_parse_status(ret
, PARSE_ERR
);
1121 ret
->shader
->type
= ST_VERTEX
;
1122 ret
->shader
->version
= BWRITERVS_VERSION(1, 1);
1123 ret
->funcs
= &parser_vs_1
;
1124 gen_oldvs_output(ret
->shader
);
1127 void create_vs20_parser(struct asm_parser
*ret
) {
1128 TRACE_(parsed_shader
)("vs_2_0\n");
1130 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1132 ERR("Failed to allocate memory for the shader\n");
1133 set_parse_status(ret
, PARSE_ERR
);
1137 ret
->shader
->type
= ST_VERTEX
;
1138 ret
->shader
->version
= BWRITERVS_VERSION(2, 0);
1139 ret
->funcs
= &parser_vs_2
;
1140 gen_oldvs_output(ret
->shader
);
1143 void create_vs2x_parser(struct asm_parser
*ret
) {
1144 TRACE_(parsed_shader
)("vs_2_x\n");
1146 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1148 ERR("Failed to allocate memory for the shader\n");
1149 set_parse_status(ret
, PARSE_ERR
);
1153 ret
->shader
->type
= ST_VERTEX
;
1154 ret
->shader
->version
= BWRITERVS_VERSION(2, 1);
1155 ret
->funcs
= &parser_vs_2
;
1156 gen_oldvs_output(ret
->shader
);
1159 void create_vs30_parser(struct asm_parser
*ret
) {
1160 TRACE_(parsed_shader
)("vs_3_0\n");
1162 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1164 ERR("Failed to allocate memory for the shader\n");
1165 set_parse_status(ret
, PARSE_ERR
);
1169 ret
->shader
->type
= ST_VERTEX
;
1170 ret
->shader
->version
= BWRITERVS_VERSION(3, 0);
1171 ret
->funcs
= &parser_vs_3
;
1174 void create_ps14_parser(struct asm_parser
*ret
) {
1175 TRACE_(parsed_shader
)("ps_1_4\n");
1177 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1179 ERR("Failed to allocate memory for the shader\n");
1180 set_parse_status(ret
, PARSE_ERR
);
1184 ret
->shader
->type
= ST_PIXEL
;
1185 ret
->shader
->version
= BWRITERPS_VERSION(1, 4);
1186 ret
->funcs
= &parser_ps_1_4
;
1187 gen_oldps_input(ret
->shader
, 6);
1190 void create_ps20_parser(struct asm_parser
*ret
) {
1191 TRACE_(parsed_shader
)("ps_2_0\n");
1193 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1195 ERR("Failed to allocate memory for the shader\n");
1196 set_parse_status(ret
, PARSE_ERR
);
1200 ret
->shader
->type
= ST_PIXEL
;
1201 ret
->shader
->version
= BWRITERPS_VERSION(2, 0);
1202 ret
->funcs
= &parser_ps_2
;
1203 gen_oldps_input(ret
->shader
, 8);
1206 void create_ps2x_parser(struct asm_parser
*ret
) {
1207 TRACE_(parsed_shader
)("ps_2_x\n");
1209 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1211 ERR("Failed to allocate memory for the shader\n");
1212 set_parse_status(ret
, PARSE_ERR
);
1216 ret
->shader
->type
= ST_PIXEL
;
1217 ret
->shader
->version
= BWRITERPS_VERSION(2, 1);
1218 ret
->funcs
= &parser_ps_2_x
;
1219 gen_oldps_input(ret
->shader
, 8);
1222 void create_ps30_parser(struct asm_parser
*ret
) {
1223 TRACE_(parsed_shader
)("ps_3_0\n");
1225 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
1227 ERR("Failed to allocate memory for the shader\n");
1228 set_parse_status(ret
, PARSE_ERR
);
1232 ret
->shader
->type
= ST_PIXEL
;
1233 ret
->shader
->version
= BWRITERPS_VERSION(3, 0);
1234 ret
->funcs
= &parser_ps_3
;