comctl32: Also generate an alpha channel when replacing an image or icon in an imagelist.
[wine/multimedia.git] / dlls / d3dx9_36 / asmparser.c
blob6d0d31f065a74c2bd86d63f6a2700a51561828cb
1 /*
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 "config.h"
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;
77 unsigned int i;
78 BOOL firstreg = TRUE;
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));
86 if(dst) {
87 TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type));
88 firstreg = FALSE;
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],
94 This->shader->type));
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);
101 return;
104 instr = alloc_instr(src_count);
105 if(!instr) {
106 ERR("Error allocating memory for the instruction\n");
107 set_parse_status(This, PARSE_ERR);
108 return;
111 instr->opcode = opcode;
112 instr->dstmod = mod;
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));
148 #if 0
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);
154 #endif
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,
169 asmparser_dcl_input,
170 asmparser_dcl_sampler,
172 asmparser_end,
174 asmparser_instr,
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));
181 if(!ret->shader) {
182 ERR("Failed to allocate memory for the shader\n");
183 set_parse_status(ret, PARSE_ERR);
184 return;
187 ret->shader->type = ST_VERTEX;
188 ret->shader->version = BWRITERVS_VERSION(3, 0);
189 ret->funcs = &parser_vs_3;