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
48 #define OFOG_WRITEMASK BWRITERSP_WRITEMASK_0
50 #define OPTS_WRITEMASK BWRITERSP_WRITEMASK_1
54 /* Input color registers 0-1 are identically mapped */
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
)
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
)
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
)
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
)
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
;
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
);
152 /* Check register type and modifiers */
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
;
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
)
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
);
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
);
226 instr
= alloc_instr(3);
229 ERR("Error allocating memory for the instruction\n");
230 set_parse_status(&parser
->status
, PARSE_ERR
);
234 instr
->opcode
= BWRITERSIO_SINCOS
;
236 instr
->shift
= shift
;
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
;
257 case BWRITERSPR_TEXTURE
:
261 ret
.type
= BWRITERSPR_INPUT
;
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;
273 FIXME("Unexpected TEXTURE register t%u.\n", reg
->regnum
);
281 ret
.type
= BWRITERSPR_TEMP
;
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;
289 FIXME("Unexpected TEXTURE register t%u.\n", reg
->regnum
);
295 /* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
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
;
309 asmparser_message(parser
, "Line %u: Source registers in texcoord instruction\n", parser
->line_no
);
310 set_parse_status(&parser
->status
, PARSE_ERR
);
314 instr
= alloc_instr(1);
317 ERR("Error allocating memory for the instruction\n");
318 set_parse_status(&parser
->status
, PARSE_ERR
);
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,
326 instr
->opcode
= BWRITERSIO_MOV
;
327 instr
->dstmod
= mod
| BWRITERSPDM_SATURATE
; /* texcoord clamps to [0;1] */
328 instr
->shift
= shift
;
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
);
354 instr
= alloc_instr(1);
357 ERR("Error allocating memory for the instruction\n");
358 set_parse_status(&parser
->status
, PARSE_ERR
);
362 /* The job of texcrd is done by mov in later shader versions */
363 instr
->opcode
= BWRITERSIO_MOV
;
365 instr
->shift
= shift
;
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);
384 ERR("Error allocating memory for the instruction\n");
385 set_parse_status(&parser
->status
, PARSE_ERR
);
389 instr
->opcode
= BWRITERSIO_TEXKILL
;
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);
418 ERR("Error allocating memory for the instruction\n");
419 set_parse_status(&parser
->status
, PARSE_ERR
);
423 instr
->opcode
= BWRITERSIO_TEX
;
425 instr
->shift
= shift
;
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
);
470 instr
= alloc_instr(2);
473 ERR("Error allocating memory for the instruction\n");
474 set_parse_status(&parser
->status
, PARSE_ERR
);
478 /* This code is recording a texld instruction, not tex. However,
479 * texld borrows the opcode of tex
481 instr
->opcode
= BWRITERSIO_TEX
;
483 instr
->shift
= shift
;
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
;
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
));
565 TRACE_(parsed_shader
)("%s", debug_print_dstreg(dst
));
568 for (i
= 0; i
< src_count
; i
++)
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 */
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
);
587 /* Use the default handling */
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
);
594 asmparser_texcoord(parser
, mod
, shift
, dst
, srcs
);
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
);
604 asmparser_texld14(parser
, mod
, shift
, dst
, srcs
);
607 /* else fallback to the standard behavior */
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
);
618 /* Handle PS 1.x instructions, "regularizing" them */
621 case BWRITERSIO_TEXKILL
:
622 asmparser_texkill(parser
, dst
);
624 case BWRITERSIO_TEXREG2AR
:
625 asmparser_texreg2ar(parser
, mod
, shift
, dst
, &srcs
->reg
[0]);
627 case BWRITERSIO_TEXREG2GB
:
628 asmparser_texreg2gb(parser
, mod
, shift
, dst
, &srcs
->reg
[0]);
630 case BWRITERSIO_TEXREG2RGB
:
631 asmparser_texreg2rgb(parser
, mod
, shift
, dst
, &srcs
->reg
[0]);
635 instr
= alloc_instr(src_count
);
638 ERR("Error allocating memory for the instruction\n");
639 set_parse_status(&parser
->status
, PARSE_ERR
);
643 instr
->opcode
= opcode
;
645 instr
->shift
= shift
;
646 instr
->comptype
= comp
;
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
;
667 case BWRITERSPR_RASTOUT
:
669 ret
.type
= BWRITERSPR_OUTPUT
;
672 case BWRITERSRO_POSITION
:
673 ret
.regnum
= OPOS_REG
;
676 ret
.regnum
= OFOG_REG
;
677 ret
.writemask
= OFOG_WRITEMASK
;
679 case BWRITERSRO_POINT_SIZE
:
680 ret
.regnum
= OPTS_REG
;
681 ret
.writemask
= OPTS_WRITEMASK
;
684 FIXME("Unhandled RASTOUT register %u.\n", reg
->regnum
);
689 case BWRITERSPR_TEXCRDOUT
:
691 ret
.type
= BWRITERSPR_OUTPUT
;
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;
703 FIXME("Unhandled TEXCRDOUT regnum %u.\n", reg
->regnum
);
708 case BWRITERSPR_ATTROUT
:
710 ret
.type
= BWRITERSPR_OUTPUT
;
713 case 0: ret
.regnum
= OD0_REG
; break;
714 case 1: ret
.regnum
= OD1_REG
; break;
716 FIXME("Unhandled ATTROUT regnum %u.\n", reg
->regnum
);
721 default: return *reg
;
725 /* Checks for unsupported source modifiers in VS (all versions) or
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
)
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
788 static BOOL
check_reg_type(const struct shader_reg
*reg
, const struct allowed_reg_type
*allowed
)
792 while (allowed
[i
].type
!= ~0u)
794 if (reg
->type
== allowed
[i
].type
)
798 /* The relative addressing register can have a negative value,
799 * we can't check the register index. */
800 if (allowed
[i
].reladdr
)
804 if (reg
->regnum
< allowed
[i
].count
)
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
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
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1193 instr
->has_dst
= TRUE
;
1196 static void asmparser_predicate_supported(struct asm_parser
*parser
, const struct shader_reg
*predicate
)
1198 if (!parser
->shader
)
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
)
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
= {
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
,
1252 static const struct asmparser_backend parser_vs_2
= {
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
,
1272 static const struct asmparser_backend parser_vs_3
= {
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
,
1292 static const struct asmparser_backend parser_ps_1_0123
= {
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
,
1312 static const struct asmparser_backend parser_ps_1_4
= {
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
,
1332 static const struct asmparser_backend parser_ps_2
= {
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
,
1352 static const struct asmparser_backend parser_ps_2_x
= {
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
,
1372 static const struct asmparser_backend parser_ps_3
= {
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
,
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
)
1412 case 8: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 7, 0, FALSE
, T7_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1414 case 7: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 6, 0, FALSE
, T6_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1416 case 6: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 5, 0, FALSE
, T5_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1418 case 5: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 4, 0, FALSE
, T4_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1420 case 4: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 3, 0, FALSE
, T3_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1422 case 3: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 2, 0, FALSE
, T2_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
1424 case 2: record_declaration(shader
, BWRITERDECLUSAGE_TEXCOORD
, 1, 0, FALSE
, T1_VARYING
, BWRITERSP_WRITEMASK_ALL
, TRUE
);
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
));
1437 ERR("Failed to allocate memory for the shader\n");
1438 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1454 ERR("Failed to allocate memory for the shader\n");
1455 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1471 ERR("Failed to allocate memory for the shader\n");
1472 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1488 ERR("Failed to allocate memory for the shader\n");
1489 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1505 ERR("Failed to allocate memory for the shader\n");
1506 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1521 ERR("Failed to allocate memory for the shader\n");
1522 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1538 ERR("Failed to allocate memory for the shader\n");
1539 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1555 ERR("Failed to allocate memory for the shader\n");
1556 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1572 ERR("Failed to allocate memory for the shader\n");
1573 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1589 ERR("Failed to allocate memory for the shader\n");
1590 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1606 ERR("Failed to allocate memory for the shader\n");
1607 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1623 ERR("Failed to allocate memory for the shader\n");
1624 set_parse_status(&ret
->status
, PARSE_ERR
);
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
));
1640 ERR("Failed to allocate memory for the shader\n");
1641 set_parse_status(&ret
->status
, PARSE_ERR
);
1645 ret
->shader
->type
= ST_PIXEL
;
1646 ret
->shader
->major_version
= 3;
1647 ret
->shader
->minor_version
= 0;
1648 ret
->funcs
= &parser_ps_3
;