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 /****************************************************************
34 * Common(non-version specific) shader parser control code *
35 ****************************************************************/
37 static void asmparser_end(struct asm_parser
*This
) {
38 TRACE("Finalizing shader\n");
41 static void asmparser_dcl_output(struct asm_parser
*This
, DWORD usage
, DWORD num
,
42 const struct shader_reg
*reg
) {
43 if(!This
->shader
) return;
44 if(This
->shader
->type
== ST_PIXEL
) {
45 asmparser_message(This
, "Line %u: Output register declared in a pixel shader\n", This
->line_no
);
46 set_parse_status(This
, PARSE_ERR
);
48 if(!record_declaration(This
->shader
, usage
, num
, TRUE
, reg
->regnum
, reg
->writemask
)) {
49 ERR("Out of memory\n");
50 set_parse_status(This
, PARSE_ERR
);
54 static void asmparser_dcl_input(struct asm_parser
*This
, DWORD usage
, DWORD num
,
55 const struct shader_reg
*reg
) {
56 if(!This
->shader
) return;
57 if(!record_declaration(This
->shader
, usage
, num
, FALSE
, reg
->regnum
, reg
->writemask
)) {
58 ERR("Out of memory\n");
59 set_parse_status(This
, PARSE_ERR
);
63 static void asmparser_dcl_sampler(struct asm_parser
*This
, DWORD samptype
, DWORD regnum
, unsigned int line_no
) {
64 if(!This
->shader
) return;
65 if(!record_sampler(This
->shader
, samptype
, regnum
)) {
66 ERR("Out of memory\n");
67 set_parse_status(This
, PARSE_ERR
);
71 static void asmparser_instr(struct asm_parser
*This
, DWORD opcode
,
72 DWORD mod
, DWORD shift
,
73 BWRITER_COMPARISON_TYPE comp
,
74 const struct shader_reg
*dst
,
75 const struct src_regs
*srcs
, int expectednsrcs
) {
76 struct instruction
*instr
;
79 unsigned int src_count
= srcs
? srcs
->count
: 0;
81 if(!This
->shader
) return;
83 TRACE_(parsed_shader
)("%s%s%s ", debug_print_opcode(opcode
),
84 debug_print_dstmod(mod
),
85 debug_print_comp(comp
));
87 TRACE_(parsed_shader
)("%s", debug_print_dstreg(dst
, This
->shader
->type
));
90 for(i
= 0; i
< src_count
; i
++) {
91 if(!firstreg
) TRACE_(parsed_shader
)(", ");
92 else firstreg
= FALSE
;
93 TRACE_(parsed_shader
)("%s", debug_print_srcreg(&srcs
->reg
[i
],
96 TRACE_(parsed_shader
)("\n");
98 if(src_count
!= expectednsrcs
) {
99 asmparser_message(This
, "Line %u: Wrong number of source registers\n", This
->line_no
);
100 set_parse_status(This
, PARSE_ERR
);
104 instr
= alloc_instr(src_count
);
106 ERR("Error allocating memory for the instruction\n");
107 set_parse_status(This
, PARSE_ERR
);
111 instr
->opcode
= opcode
;
113 instr
->shift
= shift
;
114 instr
->comptype
= comp
;
115 if(dst
) This
->funcs
->dstreg(This
, instr
, dst
);
116 for(i
= 0; i
< src_count
; i
++) {
117 This
->funcs
->srcreg(This
, instr
, i
, &srcs
->reg
[i
]);
120 if(!add_instruction(This
->shader
, instr
)) {
121 ERR("Out of memory\n");
122 set_parse_status(This
, PARSE_ERR
);
126 static void asmparser_srcreg_vs_3(struct asm_parser
*This
,
127 struct instruction
*instr
, int num
,
128 const struct shader_reg
*src
) {
129 memcpy(&instr
->src
[num
], src
, sizeof(*src
));
132 static void asmparser_dstreg_vs_3(struct asm_parser
*This
,
133 struct instruction
*instr
,
134 const struct shader_reg
*dst
) {
135 memcpy(&instr
->dst
, dst
, sizeof(*dst
));
136 instr
->has_dst
= TRUE
;
139 static void asmparser_predicate_supported(struct asm_parser
*This
,
140 const struct shader_reg
*predicate
) {
141 /* this sets the predicate of the last instruction added to the shader */
142 if(!This
->shader
) return;
143 if(This
->shader
->num_instrs
== 0) ERR("Predicate without an instruction\n");
144 This
->shader
->instr
[This
->shader
->num_instrs
- 1]->has_predicate
= TRUE
;
145 memcpy(&This
->shader
->instr
[This
->shader
->num_instrs
- 1]->predicate
, predicate
, sizeof(*predicate
));
149 static void asmparser_predicate_unsupported(struct asm_parser
*This
,
150 const struct shader_reg
*predicate
) {
151 asmparser_message(This
, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This
->line_no
);
152 set_parse_status(This
, PARSE_ERR
);
156 static void asmparser_coissue_unsupported(struct asm_parser
*This
) {
157 asmparser_message(This
, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This
->line_no
);
158 set_parse_status(This
, PARSE_ERR
);
161 static const struct asmparser_backend parser_vs_3
= {
162 asmparser_dstreg_vs_3
,
163 asmparser_srcreg_vs_3
,
165 asmparser_predicate_supported
,
166 asmparser_coissue_unsupported
,
168 asmparser_dcl_output
,
170 asmparser_dcl_sampler
,
177 void create_vs30_parser(struct asm_parser
*ret
) {
178 TRACE_(parsed_shader
)("vs_3_0\n");
180 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
182 ERR("Failed to allocate memory for the shader\n");
183 set_parse_status(ret
, PARSE_ERR
);
187 ret
->shader
->type
= ST_VERTEX
;
188 ret
->shader
->version
= BWRITERVS_VERSION(3, 0);
189 ret
->funcs
= &parser_vs_3
;