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_instr(struct asm_parser
*This
, DWORD opcode
,
42 DWORD mod
, DWORD shift
,
43 BWRITER_COMPARISON_TYPE comp
,
44 const struct shader_reg
*dst
,
45 const struct src_regs
*srcs
, int expectednsrcs
) {
46 struct instruction
*instr
;
49 unsigned int src_count
= srcs
? srcs
->count
: 0;
51 if(!This
->shader
) return;
53 TRACE_(parsed_shader
)("%s ", debug_print_opcode(opcode
));
55 TRACE_(parsed_shader
)("%s", debug_print_dstreg(dst
, This
->shader
->type
));
58 for(i
= 0; i
< src_count
; i
++) {
59 if(!firstreg
) TRACE_(parsed_shader
)(", ");
60 else firstreg
= FALSE
;
61 TRACE_(parsed_shader
)("%s", debug_print_srcreg(&srcs
->reg
[i
],
64 TRACE_(parsed_shader
)("\n");
66 if(src_count
!= expectednsrcs
) {
67 asmparser_message(This
, "Line %u: Wrong number of source registers\n", This
->line_no
);
68 set_parse_status(This
, PARSE_ERR
);
72 instr
= alloc_instr(src_count
);
74 ERR("Error allocating memory for the instruction\n");
75 set_parse_status(This
, PARSE_ERR
);
79 instr
->opcode
= opcode
;
82 instr
->comptype
= comp
;
83 if(dst
) This
->funcs
->dstreg(This
, instr
, dst
);
84 for(i
= 0; i
< src_count
; i
++) {
85 This
->funcs
->srcreg(This
, instr
, i
, &srcs
->reg
[i
]);
88 if(!add_instruction(This
->shader
, instr
)) {
89 ERR("Out of memory\n");
90 set_parse_status(This
, PARSE_ERR
);
94 static void asmparser_srcreg_vs_3(struct asm_parser
*This
,
95 struct instruction
*instr
, int num
,
96 const struct shader_reg
*src
) {
97 memcpy(&instr
->src
[num
], src
, sizeof(*src
));
100 static void asmparser_dstreg_vs_3(struct asm_parser
*This
,
101 struct instruction
*instr
,
102 const struct shader_reg
*dst
) {
103 memcpy(&instr
->dst
, dst
, sizeof(*dst
));
104 instr
->has_dst
= TRUE
;
107 static void asmparser_predicate_unsupported(struct asm_parser
*This
,
108 const struct shader_reg
*predicate
) {
109 asmparser_message(This
, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This
->line_no
);
110 set_parse_status(This
, PARSE_ERR
);
113 static void asmparser_coissue_unsupported(struct asm_parser
*This
) {
114 asmparser_message(This
, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This
->line_no
);
115 set_parse_status(This
, PARSE_ERR
);
118 static const struct asmparser_backend parser_vs_3
= {
119 asmparser_dstreg_vs_3
,
120 asmparser_srcreg_vs_3
,
122 asmparser_predicate_unsupported
,
123 asmparser_coissue_unsupported
,
130 void create_vs30_parser(struct asm_parser
*ret
) {
131 TRACE_(parsed_shader
)("vs_3_0\n");
133 ret
->shader
= asm_alloc(sizeof(*ret
->shader
));
135 ERR("Failed to allocate memory for the shader\n");
136 set_parse_status(ret
, PARSE_ERR
);
140 ret
->shader
->type
= ST_VERTEX
;
141 ret
->shader
->version
= BWRITERVS_VERSION(3, 0);
142 ret
->funcs
= &parser_vs_3
;