d3dx9: Fix ID3DXBaseEffect::GetFloat().
[wine] / dlls / d3dx9_36 / effect.c
1 /*
2  * Copyright 2010 Christian Costa
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wine/debug.h"
22 #include "wine/unicode.h"
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "d3dx9_36_private.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
28
29 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl;
30 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl;
31 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl;
32
33 enum STATE_CLASS
34 {
35     SC_LIGHTENABLE,
36     SC_FVF,
37     SC_LIGHT,
38     SC_MATERIAL,
39     SC_NPATCHMODE,
40     SC_PIXELSHADER,
41     SC_RENDERSTATE,
42     SC_SETSAMPLER,
43     SC_SAMPLERSTATE,
44     SC_TEXTURE,
45     SC_TEXTURESTAGE,
46     SC_TRANSFORM,
47     SC_VERTEXSHADER,
48     SC_SHADERCONST,
49     SC_UNKNOWN,
50 };
51
52 enum MATERIAL_TYPE
53 {
54     MT_DIFFUSE,
55     MT_AMBIENT,
56     MT_SPECULAR,
57     MT_EMISSIVE,
58     MT_POWER,
59 };
60
61 enum LIGHT_TYPE
62 {
63     LT_TYPE,
64     LT_DIFFUSE,
65     LT_SPECULAR,
66     LT_AMBIENT,
67     LT_POSITION,
68     LT_DIRECTION,
69     LT_RANGE,
70     LT_FALLOFF,
71     LT_ATTENUATION0,
72     LT_ATTENUATION1,
73     LT_ATTENUATION2,
74     LT_THETA,
75     LT_PHI,
76 };
77
78 enum SHADER_CONSTANT_TYPE
79 {
80     SCT_VSFLOAT,
81     SCT_VSBOOL,
82     SCT_VSINT,
83     SCT_PSFLOAT,
84     SCT_PSBOOL,
85     SCT_PSINT,
86 };
87
88 enum STATE_TYPE
89 {
90     ST_CONSTANT,
91     ST_PARAMETER,
92     ST_FXLC,
93 };
94
95 struct d3dx_parameter
96 {
97     char *name;
98     char *semantic;
99     void *data;
100     D3DXPARAMETER_CLASS class;
101     D3DXPARAMETER_TYPE  type;
102     UINT rows;
103     UINT columns;
104     UINT element_count;
105     UINT annotation_count;
106     UINT member_count;
107     DWORD flags;
108     UINT bytes;
109
110     D3DXHANDLE *annotation_handles;
111     D3DXHANDLE *member_handles;
112 };
113
114 struct d3dx_state
115 {
116     UINT operation;
117     UINT index;
118     enum STATE_TYPE type;
119     D3DXHANDLE parameter;
120 };
121
122 struct d3dx_sampler
123 {
124     UINT state_count;
125     struct d3dx_state *states;
126 };
127
128 struct d3dx_pass
129 {
130     char *name;
131     UINT state_count;
132     UINT annotation_count;
133
134     struct d3dx_state *states;
135     D3DXHANDLE *annotation_handles;
136 };
137
138 struct d3dx_technique
139 {
140     char *name;
141     UINT pass_count;
142     UINT annotation_count;
143
144     D3DXHANDLE *annotation_handles;
145     D3DXHANDLE *pass_handles;
146 };
147
148 struct ID3DXBaseEffectImpl
149 {
150     ID3DXBaseEffect ID3DXBaseEffect_iface;
151     LONG ref;
152
153     struct ID3DXEffectImpl *effect;
154
155     UINT parameter_count;
156     UINT technique_count;
157
158     D3DXHANDLE *parameter_handles;
159     D3DXHANDLE *technique_handles;
160 };
161
162 struct ID3DXEffectImpl
163 {
164     ID3DXEffect ID3DXEffect_iface;
165     LONG ref;
166
167     LPD3DXEFFECTSTATEMANAGER manager;
168     LPDIRECT3DDEVICE9 device;
169     LPD3DXEFFECTPOOL pool;
170     D3DXHANDLE active_technique;
171     D3DXHANDLE active_pass;
172
173     ID3DXBaseEffect *base_effect;
174 };
175
176 struct ID3DXEffectCompilerImpl
177 {
178     ID3DXEffectCompiler ID3DXEffectCompiler_iface;
179     LONG ref;
180
181     ID3DXBaseEffect *base_effect;
182 };
183
184 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
185         struct d3dx_parameter *parameter, LPCSTR name);
186 static struct d3dx_parameter *get_parameter_annotation_by_name(struct d3dx_parameter *parameter, LPCSTR name);
187 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects);
188 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st);
189
190 static const struct
191 {
192     enum STATE_CLASS class;
193     UINT op;
194     LPCSTR name;
195 }
196 state_table[] =
197 {
198     /* Render sates */
199     {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
200     {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
201     {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
202     {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
203     {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
204     {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
205     {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
206     {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
207     {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
208     {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
209     {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
210     {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
211     {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
212     {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
213     {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
214     {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
215     {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
216     {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
217     {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
218     {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
219     {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
220     {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
221     {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
222     {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
223     {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
224     {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
225     {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
226     {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
227     {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
228     {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
229     {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
230     {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
231     {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
232     {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
233     {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
234     {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
235     {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
236     {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
237     {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
238     {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
239     {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
240     {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
241     {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
242     {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
243     {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
244     {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
245     {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
246     {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
247     {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
248     {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
249     {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
250     {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
251     {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
252     {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
253     {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
254     {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
255     {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
256     {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
257     {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
258     {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
259     {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
260     {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
261     {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
262     {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
263     {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
264     {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
265     {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
266     {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
267     {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
268     {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
269     {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
270     {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
271     {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
272     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
273     {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
274     {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
275     {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
276     {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
277     {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
278     {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
279     {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
280     {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
281     {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
282     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
283     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
284     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
285     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
286     {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
287     {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
288     {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
289     {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
290     {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
291     {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
292     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
293     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
294     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
295     {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
296     {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
297     {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
298     {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
299     {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
300     {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
301     {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
302     /* Texture stages */
303     {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
304     {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
305     {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
306     {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
307     {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
308     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
309     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
310     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
311     {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
312     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
313     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
314     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
315     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
316     {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
317     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
318     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
319     {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
320     /* */
321     {SC_UNKNOWN, 0, "UNKNOWN"},
322     /* NPatchMode */
323     {SC_NPATCHMODE, 0, "NPatchMode"},
324     /* */
325     {SC_UNKNOWN, 0, "UNKNOWN"},
326     /* Transform */
327     {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
328     {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
329     {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
330     {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
331     /* Material */
332     {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
333     {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
334     {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
335     {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
336     {SC_MATERIAL, MT_POWER, "MaterialPower"},
337     /* Light */
338     {SC_LIGHT, LT_TYPE, "LightType"},
339     {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
340     {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
341     {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
342     {SC_LIGHT, LT_POSITION, "LightPosition"},
343     {SC_LIGHT, LT_DIRECTION, "LightDirection"},
344     {SC_LIGHT, LT_RANGE, "LightRange"},
345     {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
346     {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
347     {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
348     {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
349     {SC_LIGHT, LT_THETA, "LightTheta"},
350     {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
351     /* Ligthenable */
352     {SC_LIGHTENABLE, 0, "LightEnable"},
353     /* Vertexshader */
354     {SC_VERTEXSHADER, 0, "Vertexshader"},
355     /* Pixelshader */
356     {SC_PIXELSHADER, 0, "Pixelshader"},
357     /* Shader constants */
358     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
359     {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
360     {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
361     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
362     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
363     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
364     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
365     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
366     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
367     {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
368     {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
369     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
370     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
371     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
372     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
373     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
374     /* Texture */
375     {SC_TEXTURE, 0, "Texture"},
376     /* Sampler states */
377     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
378     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
379     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
380     {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
381     {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
382     {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
383     {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
384     {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
385     {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
386     {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
387     {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
388     {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
389     {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
390     /* Set sampler */
391     {SC_SETSAMPLER, 0, "Sampler"},
392 };
393
394 static inline void read_dword(const char **ptr, DWORD *d)
395 {
396     memcpy(d, *ptr, sizeof(*d));
397     *ptr += sizeof(*d);
398 }
399
400 static void skip_dword_unknown(const char **ptr, unsigned int count)
401 {
402     unsigned int i;
403     DWORD d;
404
405     FIXME("Skipping %u unknown DWORDs:\n", count);
406     for (i = 0; i < count; ++i)
407     {
408         read_dword(ptr, &d);
409         FIXME("\t0x%08x\n", d);
410     }
411 }
412
413 static inline struct d3dx_parameter *get_parameter_struct(D3DXHANDLE handle)
414 {
415     return (struct d3dx_parameter *) handle;
416 }
417
418 static inline struct d3dx_pass *get_pass_struct(D3DXHANDLE handle)
419 {
420     return (struct d3dx_pass *) handle;
421 }
422
423 static inline struct d3dx_technique *get_technique_struct(D3DXHANDLE handle)
424 {
425     return (struct d3dx_technique *) handle;
426 }
427
428 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
429 {
430     return (D3DXHANDLE) parameter;
431 }
432
433 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
434 {
435     return (D3DXHANDLE) technique;
436 }
437
438 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
439 {
440     return (D3DXHANDLE) pass;
441 }
442
443 static struct d3dx_technique *is_valid_technique(struct ID3DXBaseEffectImpl *base, D3DXHANDLE technique)
444 {
445     unsigned int i;
446
447     for (i = 0; i < base->technique_count; ++i)
448     {
449         if (base->technique_handles[i] == technique)
450         {
451             return get_technique_struct(technique);
452         }
453     }
454
455     return NULL;
456 }
457
458 static struct d3dx_pass *is_valid_pass(struct ID3DXBaseEffectImpl *base, D3DXHANDLE pass)
459 {
460     unsigned int i, k;
461
462     for (i = 0; i < base->technique_count; ++i)
463     {
464         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
465
466         for (k = 0; k < technique->pass_count; ++k)
467         {
468             if (technique->pass_handles[k] == pass)
469             {
470                 return get_pass_struct(pass);
471             }
472         }
473     }
474
475     return NULL;
476 }
477
478 static struct d3dx_parameter *is_valid_sub_parameter(struct d3dx_parameter *param, D3DXHANDLE parameter)
479 {
480     unsigned int i, count;
481     struct d3dx_parameter *p;
482
483     for (i = 0; i < param->annotation_count; ++i)
484     {
485         if (param->annotation_handles[i] == parameter)
486         {
487             return get_parameter_struct(parameter);
488         }
489
490         p = is_valid_sub_parameter(get_parameter_struct(param->annotation_handles[i]), parameter);
491         if (p) return p;
492     }
493
494     if (param->element_count) count = param->element_count;
495     else count = param->member_count;
496
497     for (i = 0; i < count; ++i)
498     {
499         if (param->member_handles[i] == parameter)
500         {
501             return get_parameter_struct(parameter);
502         }
503
504         p = is_valid_sub_parameter(get_parameter_struct(param->member_handles[i]), parameter);
505         if (p) return p;
506     }
507
508     return NULL;
509 }
510
511 static struct d3dx_parameter *is_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
512 {
513     unsigned int i, k, m;
514     struct d3dx_parameter *p;
515
516     for (i = 0; i < base->parameter_count; ++i)
517     {
518         if (base->parameter_handles[i] == parameter)
519         {
520             return get_parameter_struct(parameter);
521         }
522
523         p = is_valid_sub_parameter(get_parameter_struct(base->parameter_handles[i]), parameter);
524         if (p) return p;
525     }
526
527     for (i = 0; i < base->technique_count; ++i)
528     {
529         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
530
531         for (k = 0; k < technique->pass_count; ++k)
532         {
533             struct d3dx_pass *pass = get_pass_struct(technique->pass_handles[k]);
534
535             for (m = 0; m < pass->annotation_count; ++m)
536             {
537                 if (pass->annotation_handles[i] == parameter)
538                 {
539                     return get_parameter_struct(parameter);
540                 }
541
542                 p = is_valid_sub_parameter(get_parameter_struct(pass->annotation_handles[m]), parameter);
543                 if (p) return p;
544             }
545         }
546
547         for (k = 0; k < technique->annotation_count; ++k)
548         {
549             if (technique->annotation_handles[k] == parameter)
550             {
551                 return get_parameter_struct(parameter);
552             }
553
554             p = is_valid_sub_parameter(get_parameter_struct(technique->annotation_handles[k]), parameter);
555             if (p) return p;
556         }
557     }
558
559     return NULL;
560 }
561
562 static inline struct d3dx_parameter *get_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
563 {
564     struct d3dx_parameter *param = is_valid_parameter(base, parameter);
565
566     if (!param) param = get_parameter_by_name(base, NULL, parameter);
567
568     return param;
569 }
570
571 static void free_state(struct d3dx_state *state)
572 {
573     free_parameter_state(state->parameter, FALSE, FALSE, state->type);
574 }
575
576 static void free_sampler(struct d3dx_sampler *sampler)
577 {
578     UINT i;
579
580     for (i = 0; i < sampler->state_count; ++i)
581     {
582         free_state(&sampler->states[i]);
583     }
584     HeapFree(GetProcessHeap(), 0, sampler->states);
585 }
586
587 static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
588 {
589     free_parameter_state(handle, element, child, ST_CONSTANT);
590 }
591
592 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st)
593 {
594     unsigned int i;
595     struct d3dx_parameter *param = get_parameter_struct(handle);
596
597     TRACE("Free parameter %p, name %s, type %s, child %s, state_type %x\n", param, param->name,
598             debug_d3dxparameter_type(param->type), child ? "yes" : "no", st);
599
600     if (!param)
601     {
602         return;
603     }
604
605     if (param->annotation_handles)
606     {
607         for (i = 0; i < param->annotation_count; ++i)
608         {
609             free_parameter(param->annotation_handles[i], FALSE, FALSE);
610         }
611         HeapFree(GetProcessHeap(), 0, param->annotation_handles);
612     }
613
614     if (param->member_handles)
615     {
616         unsigned int count;
617
618         if (param->element_count) count = param->element_count;
619         else count = param->member_count;
620
621         for (i = 0; i < count; ++i)
622         {
623             free_parameter(param->member_handles[i], param->element_count != 0, TRUE);
624         }
625         HeapFree(GetProcessHeap(), 0, param->member_handles);
626     }
627
628     if (param->class == D3DXPC_OBJECT && !param->element_count)
629     {
630         switch (param->type)
631         {
632             case D3DXPT_STRING:
633                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
634                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
635                 break;
636
637             case D3DXPT_TEXTURE:
638             case D3DXPT_TEXTURE1D:
639             case D3DXPT_TEXTURE2D:
640             case D3DXPT_TEXTURE3D:
641             case D3DXPT_TEXTURECUBE:
642             case D3DXPT_PIXELSHADER:
643             case D3DXPT_VERTEXSHADER:
644                 if (st == ST_CONSTANT)
645                 {
646                     if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
647                 }
648                 else
649                 {
650                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
651                 }
652                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
653                 break;
654
655             case D3DXPT_SAMPLER:
656             case D3DXPT_SAMPLER1D:
657             case D3DXPT_SAMPLER2D:
658             case D3DXPT_SAMPLER3D:
659             case D3DXPT_SAMPLERCUBE:
660                 if (st == ST_CONSTANT)
661                 {
662                     free_sampler((struct d3dx_sampler *)param->data);
663                 }
664                 else
665                 {
666                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
667                 }
668                 /* samplers have always own data, so free that */
669                 HeapFree(GetProcessHeap(), 0, param->data);
670                 break;
671
672             default:
673                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
674                 break;
675         }
676     }
677     else
678     {
679         if (!child)
680         {
681             if (st != ST_CONSTANT)
682             {
683                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
684             }
685             HeapFree(GetProcessHeap(), 0, param->data);
686         }
687     }
688
689     /* only the parent has to release name and semantic */
690     if (!element)
691     {
692         HeapFree(GetProcessHeap(), 0, param->name);
693         HeapFree(GetProcessHeap(), 0, param->semantic);
694     }
695
696     HeapFree(GetProcessHeap(), 0, param);
697 }
698
699 static void free_pass(D3DXHANDLE handle)
700 {
701     unsigned int i;
702     struct d3dx_pass *pass = get_pass_struct(handle);
703
704     TRACE("Free pass %p\n", pass);
705
706     if (!pass)
707     {
708         return;
709     }
710
711     if (pass->annotation_handles)
712     {
713         for (i = 0; i < pass->annotation_count; ++i)
714         {
715             free_parameter(pass->annotation_handles[i], FALSE, FALSE);
716         }
717         HeapFree(GetProcessHeap(), 0, pass->annotation_handles);
718     }
719
720     if (pass->states)
721     {
722         for (i = 0; i < pass->state_count; ++i)
723         {
724             free_state(&pass->states[i]);
725         }
726         HeapFree(GetProcessHeap(), 0, pass->states);
727     }
728
729     HeapFree(GetProcessHeap(), 0, pass->name);
730     HeapFree(GetProcessHeap(), 0, pass);
731 }
732
733 static void free_technique(D3DXHANDLE handle)
734 {
735     unsigned int i;
736     struct d3dx_technique *technique = get_technique_struct(handle);
737
738     TRACE("Free technique %p\n", technique);
739
740     if (!technique)
741     {
742         return;
743     }
744
745     if (technique->annotation_handles)
746     {
747         for (i = 0; i < technique->annotation_count; ++i)
748         {
749             free_parameter(technique->annotation_handles[i], FALSE, FALSE);
750         }
751         HeapFree(GetProcessHeap(), 0, technique->annotation_handles);
752     }
753
754     if (technique->pass_handles)
755     {
756         for (i = 0; i < technique->pass_count; ++i)
757         {
758             free_pass(technique->pass_handles[i]);
759         }
760         HeapFree(GetProcessHeap(), 0, technique->pass_handles);
761     }
762
763     HeapFree(GetProcessHeap(), 0, technique->name);
764     HeapFree(GetProcessHeap(), 0, technique);
765 }
766
767 static void free_base_effect(struct ID3DXBaseEffectImpl *base)
768 {
769     unsigned int i;
770
771     TRACE("Free base effect %p\n", base);
772
773     if (base->parameter_handles)
774     {
775         for (i = 0; i < base->parameter_count; ++i)
776         {
777             free_parameter(base->parameter_handles[i], FALSE, FALSE);
778         }
779         HeapFree(GetProcessHeap(), 0, base->parameter_handles);
780     }
781
782     if (base->technique_handles)
783     {
784         for (i = 0; i < base->technique_count; ++i)
785         {
786             free_technique(base->technique_handles[i]);
787         }
788         HeapFree(GetProcessHeap(), 0, base->technique_handles);
789     }
790 }
791
792 static void free_effect(struct ID3DXEffectImpl *effect)
793 {
794     TRACE("Free effect %p\n", effect);
795
796     if (effect->base_effect)
797     {
798         effect->base_effect->lpVtbl->Release(effect->base_effect);
799     }
800
801     if (effect->pool)
802     {
803         effect->pool->lpVtbl->Release(effect->pool);
804     }
805
806     if (effect->manager)
807     {
808         IUnknown_Release(effect->manager);
809     }
810
811     IDirect3DDevice9_Release(effect->device);
812 }
813
814 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
815 {
816     TRACE("Free effect compiler %p\n", compiler);
817
818     if (compiler->base_effect)
819     {
820         compiler->base_effect->lpVtbl->Release(compiler->base_effect);
821     }
822 }
823
824 static INT get_int(D3DXPARAMETER_TYPE type, void *data)
825 {
826     INT i;
827
828     switch (type)
829     {
830         case D3DXPT_FLOAT:
831             i = *(FLOAT *)data;
832             break;
833
834         case D3DXPT_INT:
835             i = *(INT *)data;
836             break;
837
838         case D3DXPT_BOOL:
839             i = *(BOOL *)data;
840             break;
841
842         default:
843             i = 0;
844             FIXME("Unhandled type %s. This should not happen!\n", debug_d3dxparameter_type(type));
845             break;
846     }
847
848     return i;
849 }
850
851 inline static FLOAT get_float(D3DXPARAMETER_TYPE type, void *data)
852 {
853     FLOAT f;
854
855     switch (type)
856     {
857         case D3DXPT_FLOAT:
858             f = *(FLOAT *)data;
859             break;
860
861         case D3DXPT_INT:
862             f = *(INT *)data;
863             break;
864
865         case D3DXPT_BOOL:
866             f = *(BOOL *)data;
867             break;
868
869         default:
870             f = 0.0f;
871             FIXME("Unhandled type %s. This should not happen!\n", debug_d3dxparameter_type(type));
872             break;
873     }
874
875     return f;
876 }
877
878 static inline BOOL get_bool(void *data)
879 {
880     return (*(DWORD *)data) ? TRUE : FALSE;
881 }
882
883 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
884 {
885     vector->x = get_float(param->type, (float *)param->data);
886     vector->y = param->columns > 1 ? get_float(param->type, (float *)param->data + 1) : 0.0f;
887     vector->z = param->columns > 2 ? get_float(param->type, (float *)param->data + 2) : 0.0f;
888     vector->w = param->columns > 3 ? get_float(param->type, (float *)param->data + 3) : 0.0f;
889 }
890
891 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix)
892 {
893     unsigned int i, k;
894
895     for (i = 0; i < 4; ++i)
896     {
897         for (k = 0; k < 4; ++k)
898         {
899             if ((i < param->rows) && (k < param->columns))
900                 matrix->m[i][k] = get_float(param->type, (float *)param->data + i * param->columns + k);
901             else
902                 matrix->m[i][k] = 0.0f;
903         }
904     }
905 }
906
907 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_parameter *parameter, LPCSTR name)
908 {
909     UINT element;
910     struct d3dx_parameter *temp_parameter;
911     LPCSTR part;
912
913     TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
914
915     if (!name || !*name) return parameter;
916
917     element = atoi(name);
918     part = strchr(name, ']') + 1;
919
920     if (parameter->element_count > element)
921     {
922         temp_parameter = get_parameter_struct(parameter->member_handles[element]);
923
924         switch (*part++)
925         {
926             case '.':
927                 return get_parameter_by_name(NULL, temp_parameter, part);
928
929             case '@':
930                 return get_parameter_annotation_by_name(temp_parameter, part);
931
932             case '\0':
933                 TRACE("Returning parameter %p\n", temp_parameter);
934                 return temp_parameter;
935
936             default:
937                 FIXME("Unhandled case \"%c\"\n", *--part);
938                 break;
939         }
940     }
941
942     TRACE("Parameter not found\n");
943     return NULL;
944 }
945
946 static struct d3dx_parameter *get_parameter_annotation_by_name(struct d3dx_parameter *parameter, LPCSTR name)
947 {
948     UINT i, length;
949     struct d3dx_parameter *temp_parameter;
950     LPCSTR part;
951
952     TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
953
954     if (!name || !*name) return parameter;
955
956     length = strcspn( name, "[.@" );
957     part = name + length;
958
959     for (i = 0; i < parameter->annotation_count; ++i)
960     {
961         temp_parameter = get_parameter_struct(parameter->annotation_handles[i]);
962
963         if (!strcmp(temp_parameter->name, name))
964         {
965             TRACE("Returning parameter %p\n", temp_parameter);
966             return temp_parameter;
967         }
968         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
969         {
970             switch (*part++)
971             {
972                 case '.':
973                     return get_parameter_by_name(NULL, temp_parameter, part);
974
975                 case '[':
976                     return get_parameter_element_by_name(temp_parameter, part);
977
978                 default:
979                     FIXME("Unhandled case \"%c\"\n", *--part);
980                     break;
981             }
982         }
983     }
984
985     TRACE("Parameter not found\n");
986     return NULL;
987 }
988
989 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
990         struct d3dx_parameter *parameter, LPCSTR name)
991 {
992     UINT i, count, length;
993     struct d3dx_parameter *temp_parameter;
994     D3DXHANDLE *handles;
995     LPCSTR part;
996
997     TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
998
999     if (!name || !*name) return parameter;
1000
1001     if (!parameter)
1002     {
1003         count = base->parameter_count;
1004         handles = base->parameter_handles;
1005     }
1006     else
1007     {
1008         count = parameter->member_count;
1009         handles = parameter->member_handles;
1010     }
1011
1012     length = strcspn( name, "[.@" );
1013     part = name + length;
1014
1015     for (i = 0; i < count; i++)
1016     {
1017         temp_parameter = get_parameter_struct(handles[i]);
1018
1019         if (!strcmp(temp_parameter->name, name))
1020         {
1021             TRACE("Returning parameter %p\n", temp_parameter);
1022             return temp_parameter;
1023         }
1024         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1025         {
1026             switch (*part++)
1027             {
1028                 case '.':
1029                     return get_parameter_by_name(NULL, temp_parameter, part);
1030
1031                 case '@':
1032                     return get_parameter_annotation_by_name(temp_parameter, part);
1033
1034                 case '[':
1035                     return get_parameter_element_by_name(temp_parameter, part);
1036
1037                 default:
1038                     FIXME("Unhandled case \"%c\"\n", *--part);
1039                     break;
1040             }
1041         }
1042     }
1043
1044     TRACE("Parameter not found\n");
1045     return NULL;
1046 }
1047
1048 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
1049 {
1050     return (0xfeff0000 | ((major) << 8) | (minor));
1051 }
1052
1053 static inline struct ID3DXBaseEffectImpl *impl_from_ID3DXBaseEffect(ID3DXBaseEffect *iface)
1054 {
1055     return CONTAINING_RECORD(iface, struct ID3DXBaseEffectImpl, ID3DXBaseEffect_iface);
1056 }
1057
1058 /*** IUnknown methods ***/
1059 static HRESULT WINAPI ID3DXBaseEffectImpl_QueryInterface(ID3DXBaseEffect *iface, REFIID riid, void **object)
1060 {
1061     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1062
1063     TRACE("iface %p, riid %s, object %p\n", This, debugstr_guid(riid), object);
1064
1065     if (IsEqualGUID(riid, &IID_IUnknown) ||
1066         IsEqualGUID(riid, &IID_ID3DXBaseEffect))
1067     {
1068         This->ID3DXBaseEffect_iface.lpVtbl->AddRef(iface);
1069         *object = This;
1070         return S_OK;
1071     }
1072
1073     ERR("Interface %s not found\n", debugstr_guid(riid));
1074
1075     return E_NOINTERFACE;
1076 }
1077
1078 static ULONG WINAPI ID3DXBaseEffectImpl_AddRef(ID3DXBaseEffect *iface)
1079 {
1080     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1081
1082     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
1083
1084     return InterlockedIncrement(&This->ref);
1085 }
1086
1087 static ULONG WINAPI ID3DXBaseEffectImpl_Release(ID3DXBaseEffect *iface)
1088 {
1089     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1090     ULONG ref = InterlockedDecrement(&This->ref);
1091
1092     TRACE("iface %p: Release from %u\n", iface, ref + 1);
1093
1094     if (!ref)
1095     {
1096         free_base_effect(This);
1097         HeapFree(GetProcessHeap(), 0, This);
1098     }
1099
1100     return ref;
1101 }
1102
1103 /*** ID3DXBaseEffect methods ***/
1104 static HRESULT WINAPI ID3DXBaseEffectImpl_GetDesc(ID3DXBaseEffect *iface, D3DXEFFECT_DESC *desc)
1105 {
1106     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1107
1108     FIXME("iface %p, desc %p partial stub\n", This, desc);
1109
1110     if (!desc)
1111     {
1112         WARN("Invalid argument specified.\n");
1113         return D3DERR_INVALIDCALL;
1114     }
1115
1116     /* Todo: add creator and function count */
1117     desc->Creator = NULL;
1118     desc->Functions = 0;
1119     desc->Parameters = This->parameter_count;
1120     desc->Techniques = This->technique_count;
1121
1122     return D3D_OK;
1123 }
1124
1125 static HRESULT WINAPI ID3DXBaseEffectImpl_GetParameterDesc(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
1126 {
1127     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1128     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1129
1130     TRACE("iface %p, parameter %p, desc %p\n", This, parameter, desc);
1131
1132     if (!desc || !param)
1133     {
1134         WARN("Invalid argument specified.\n");
1135         return D3DERR_INVALIDCALL;
1136     }
1137
1138     desc->Name = param->name;
1139     desc->Semantic = param->semantic;
1140     desc->Class = param->class;
1141     desc->Type = param->type;
1142     desc->Rows = param->rows;
1143     desc->Columns = param->columns;
1144     desc->Elements = param->element_count;
1145     desc->Annotations = param->annotation_count;
1146     desc->StructMembers = param->member_count;
1147     desc->Flags = param->flags;
1148     desc->Bytes = param->bytes;
1149
1150     return D3D_OK;
1151 }
1152
1153 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTechniqueDesc(ID3DXBaseEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1154 {
1155     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1156     struct d3dx_technique *tech = technique ? is_valid_technique(This, technique) : get_technique_struct(This->technique_handles[0]);
1157
1158     TRACE("iface %p, technique %p, desc %p\n", This, technique, desc);
1159
1160     if (!desc || !tech)
1161     {
1162         WARN("Invalid argument specified.\n");
1163         return D3DERR_INVALIDCALL;
1164     }
1165
1166     desc->Name = tech->name;
1167     desc->Passes = tech->pass_count;
1168     desc->Annotations = tech->annotation_count;
1169
1170     return D3D_OK;
1171 }
1172
1173 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPassDesc(ID3DXBaseEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
1174 {
1175     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1176     struct d3dx_pass *p = is_valid_pass(This, pass);
1177
1178     TRACE("iface %p, pass %p, desc %p\n", This, pass, desc);
1179
1180     if (!desc || !p)
1181     {
1182         WARN("Invalid argument specified.\n");
1183         return D3DERR_INVALIDCALL;
1184     }
1185
1186     desc->Name = p->name;
1187     desc->Annotations = p->annotation_count;
1188
1189     FIXME("Pixel shader and vertex shader are not supported, yet.\n");
1190     desc->pVertexShaderFunction = NULL;
1191     desc->pPixelShaderFunction = NULL;
1192
1193     return D3D_OK;
1194 }
1195
1196 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFunctionDesc(ID3DXBaseEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
1197 {
1198     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1199
1200     FIXME("iface %p, shader %p, desc %p stub\n", This, shader, desc);
1201
1202     return E_NOTIMPL;
1203 }
1204
1205 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
1206 {
1207     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1208     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1209
1210     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
1211
1212     if (!parameter)
1213     {
1214         if (index < This->parameter_count)
1215         {
1216             TRACE("Returning parameter %p\n", This->parameter_handles[index]);
1217             return This->parameter_handles[index];
1218         }
1219     }
1220     else
1221     {
1222         if (param && !param->element_count && index < param->member_count)
1223         {
1224             TRACE("Returning parameter %p\n", param->member_handles[index]);
1225             return param->member_handles[index];
1226         }
1227     }
1228
1229     WARN("Invalid argument specified.\n");
1230
1231     return NULL;
1232 }
1233
1234 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR name)
1235 {
1236     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1237     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1238     D3DXHANDLE handle;
1239
1240     TRACE("iface %p, parameter %p, name %s\n", This, parameter, debugstr_a(name));
1241
1242     if (!name)
1243     {
1244         handle = get_parameter_handle(param);
1245         TRACE("Returning parameter %p\n", handle);
1246         return handle;
1247     }
1248
1249     handle = get_parameter_handle(get_parameter_by_name(This, param, name));
1250     TRACE("Returning parameter %p\n", handle);
1251
1252     return handle;
1253 }
1254
1255 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterBySemantic(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
1256 {
1257     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1258     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1259     struct d3dx_parameter *temp_param;
1260     UINT i;
1261
1262     TRACE("iface %p, parameter %p, semantic %s\n", This, parameter, debugstr_a(semantic));
1263
1264     if (!parameter)
1265     {
1266         for (i = 0; i < This->parameter_count; ++i)
1267         {
1268             temp_param = get_parameter_struct(This->parameter_handles[i]);
1269
1270             if (!temp_param->semantic)
1271             {
1272                 if (!semantic)
1273                 {
1274                     TRACE("Returning parameter %p\n", This->parameter_handles[i]);
1275                     return This->parameter_handles[i];
1276                 }
1277                 continue;
1278             }
1279
1280             if (!strcasecmp(temp_param->semantic, semantic))
1281             {
1282                 TRACE("Returning parameter %p\n", This->parameter_handles[i]);
1283                 return This->parameter_handles[i];
1284             }
1285         }
1286     }
1287     else if (param)
1288     {
1289         for (i = 0; i < param->member_count; ++i)
1290         {
1291             temp_param = get_parameter_struct(param->member_handles[i]);
1292
1293             if (!temp_param->semantic)
1294             {
1295                 if (!semantic)
1296                 {
1297                     TRACE("Returning parameter %p\n", param->member_handles[i]);
1298                     return param->member_handles[i];
1299                 }
1300                 continue;
1301             }
1302
1303             if (!strcasecmp(temp_param->semantic, semantic))
1304             {
1305                 TRACE("Returning parameter %p\n", param->member_handles[i]);
1306                 return param->member_handles[i];
1307             }
1308         }
1309     }
1310
1311     WARN("Invalid argument specified\n");
1312
1313     return NULL;
1314 }
1315
1316 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterElement(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
1317 {
1318     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1319     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1320
1321     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
1322
1323     if (!param)
1324     {
1325         if (index < This->parameter_count)
1326         {
1327             TRACE("Returning parameter %p\n", This->parameter_handles[index]);
1328             return This->parameter_handles[index];
1329         }
1330     }
1331     else
1332     {
1333         if (index < param->element_count)
1334         {
1335             TRACE("Returning parameter %p\n", param->member_handles[index]);
1336             return param->member_handles[index];
1337         }
1338     }
1339
1340     WARN("Invalid argument specified\n");
1341
1342     return NULL;
1343 }
1344
1345 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechnique(ID3DXBaseEffect *iface, UINT index)
1346 {
1347     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1348
1349     TRACE("iface %p, index %u\n", This, index);
1350
1351     if (index >= This->technique_count)
1352     {
1353         WARN("Invalid argument specified.\n");
1354         return NULL;
1355     }
1356
1357     TRACE("Returning technique %p\n", This->technique_handles[index]);
1358
1359     return This->technique_handles[index];
1360 }
1361
1362 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechniqueByName(ID3DXBaseEffect *iface, LPCSTR name)
1363 {
1364     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1365     unsigned int i;
1366
1367     TRACE("iface %p, name %s stub\n", This, debugstr_a(name));
1368
1369     if (!name)
1370     {
1371         WARN("Invalid argument specified.\n");
1372         return NULL;
1373     }
1374
1375     for (i = 0; i < This->technique_count; ++i)
1376     {
1377         struct d3dx_technique *tech = get_technique_struct(This->technique_handles[i]);
1378
1379         if (!strcmp(tech->name, name))
1380         {
1381             TRACE("Returning technique %p\n", This->technique_handles[i]);
1382             return This->technique_handles[i];
1383         }
1384     }
1385
1386     WARN("Invalid argument specified.\n");
1387
1388     return NULL;
1389 }
1390
1391 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPass(ID3DXBaseEffect *iface, D3DXHANDLE technique, UINT index)
1392 {
1393     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1394     struct d3dx_technique *tech = is_valid_technique(This, technique);
1395
1396     TRACE("iface %p, technique %p, index %u\n", This, technique, index);
1397
1398     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
1399
1400     if (tech && index < tech->pass_count)
1401     {
1402         TRACE("Returning pass %p\n", tech->pass_handles[index]);
1403         return tech->pass_handles[index];
1404     }
1405
1406     WARN("Invalid argument specified.\n");
1407
1408     return NULL;
1409 }
1410
1411 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPassByName(ID3DXBaseEffect *iface, D3DXHANDLE technique, LPCSTR name)
1412 {
1413     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1414     struct d3dx_technique *tech = is_valid_technique(This, technique);
1415
1416     TRACE("iface %p, technique %p, name %s\n", This, technique, debugstr_a(name));
1417
1418     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
1419
1420     if (tech && name)
1421     {
1422         unsigned int i;
1423
1424         for (i = 0; i < tech->pass_count; ++i)
1425         {
1426             struct d3dx_pass *pass = get_pass_struct(tech->pass_handles[i]);
1427
1428             if (!strcmp(pass->name, name))
1429             {
1430                 TRACE("Returning pass %p\n", tech->pass_handles[i]);
1431                 return tech->pass_handles[i];
1432             }
1433         }
1434     }
1435
1436     WARN("Invalid argument specified.\n");
1437
1438     return NULL;
1439 }
1440
1441 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunction(ID3DXBaseEffect *iface, UINT index)
1442 {
1443     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1444
1445     FIXME("iface %p, index %u stub\n", This, index);
1446
1447     return NULL;
1448 }
1449
1450 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunctionByName(ID3DXBaseEffect *iface, LPCSTR name)
1451 {
1452     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1453
1454     FIXME("iface %p, name %s stub\n", This, debugstr_a(name));
1455
1456     return NULL;
1457 }
1458
1459 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotation(ID3DXBaseEffect *iface, D3DXHANDLE object, UINT index)
1460 {
1461     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1462     struct d3dx_parameter *param = get_valid_parameter(This, object);
1463     struct d3dx_pass *pass = is_valid_pass(This, object);
1464     struct d3dx_technique *technique = is_valid_technique(This, object);
1465     UINT annotation_count = 0;
1466     D3DXHANDLE *annotation_handles = NULL;
1467
1468     FIXME("iface %p, object %p, index %u partial stub\n", This, object, index);
1469
1470     if (pass)
1471     {
1472         annotation_count = pass->annotation_count;
1473         annotation_handles = pass->annotation_handles;
1474     }
1475     else if (technique)
1476     {
1477         annotation_count = technique->annotation_count;
1478         annotation_handles = technique->annotation_handles;
1479     }
1480     else if (param)
1481     {
1482         annotation_count = param->annotation_count;
1483         annotation_handles = param->annotation_handles;
1484     }
1485     /* Todo: add funcs */
1486
1487     if (index < annotation_count)
1488     {
1489         TRACE("Returning parameter %p\n", annotation_handles[index]);
1490         return annotation_handles[index];
1491     }
1492
1493     WARN("Invalid argument specified\n");
1494
1495     return NULL;
1496 }
1497
1498 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotationByName(ID3DXBaseEffect *iface, D3DXHANDLE object, LPCSTR name)
1499 {
1500     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1501     struct d3dx_parameter *param = get_valid_parameter(This, object);
1502     struct d3dx_pass *pass = is_valid_pass(This, object);
1503     struct d3dx_technique *technique = is_valid_technique(This, object);
1504     UINT annotation_count = 0, i;
1505     D3DXHANDLE *annotation_handles = NULL;
1506
1507     FIXME("iface %p, object %p, name %s partial stub\n", This, object, debugstr_a(name));
1508
1509     if (!name)
1510     {
1511         WARN("Invalid argument specified\n");
1512         return NULL;
1513     }
1514
1515     if (pass)
1516     {
1517         annotation_count = pass->annotation_count;
1518         annotation_handles = pass->annotation_handles;
1519     }
1520     else if (technique)
1521     {
1522         annotation_count = technique->annotation_count;
1523         annotation_handles = technique->annotation_handles;
1524     }
1525     else if (param)
1526     {
1527         annotation_count = param->annotation_count;
1528         annotation_handles = param->annotation_handles;
1529     }
1530     /* Todo: add funcs */
1531
1532     for (i = 0; i < annotation_count; i++)
1533     {
1534         struct d3dx_parameter *anno = get_parameter_struct(annotation_handles[i]);
1535
1536         if (!strcmp(anno->name, name))
1537         {
1538             TRACE("Returning parameter %p\n", anno);
1539             return get_parameter_handle(anno);
1540         }
1541     }
1542
1543     WARN("Invalid argument specified\n");
1544
1545     return NULL;
1546 }
1547
1548 static HRESULT WINAPI ID3DXBaseEffectImpl_SetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
1549 {
1550     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1551
1552     FIXME("iface %p, parameter %p, data %p, bytes %u stub\n", This, parameter, data, bytes);
1553
1554     return E_NOTIMPL;
1555 }
1556
1557 static HRESULT WINAPI ID3DXBaseEffectImpl_GetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
1558 {
1559     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1560     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1561
1562     TRACE("iface %p, parameter %p, data %p, bytes %u\n", This, parameter, data, bytes);
1563
1564     if (!param)
1565     {
1566         WARN("Invalid parameter %p specified\n", parameter);
1567         return D3DERR_INVALIDCALL;
1568     }
1569
1570     /* samplers don't touch data */
1571     if (param->class == D3DXPC_OBJECT && (param->type == D3DXPT_SAMPLER
1572             || param->type == D3DXPT_SAMPLER1D || param->type == D3DXPT_SAMPLER2D
1573             || param->type == D3DXPT_SAMPLER3D || param->type == D3DXPT_SAMPLERCUBE))
1574     {
1575         TRACE("Sampler: returning E_FAIL\n");
1576         return E_FAIL;
1577     }
1578
1579     if (data && param->bytes <= bytes)
1580     {
1581         TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1582
1583         switch (param->type)
1584         {
1585             case D3DXPT_VOID:
1586             case D3DXPT_BOOL:
1587             case D3DXPT_INT:
1588             case D3DXPT_FLOAT:
1589             case D3DXPT_STRING:
1590                 break;
1591
1592             case D3DXPT_VERTEXSHADER:
1593             case D3DXPT_PIXELSHADER:
1594             case D3DXPT_TEXTURE:
1595             case D3DXPT_TEXTURE1D:
1596             case D3DXPT_TEXTURE2D:
1597             case D3DXPT_TEXTURE3D:
1598             case D3DXPT_TEXTURECUBE:
1599             {
1600                 UINT i;
1601
1602                 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1603                 {
1604                     IUnknown *unk = ((IUnknown **)param->data)[i];
1605                     if (unk) IUnknown_AddRef(unk);
1606                 }
1607                 break;
1608             }
1609
1610             default:
1611                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1612                 break;
1613         }
1614
1615         TRACE("Copy %u bytes\n", param->bytes);
1616         memcpy(data, param->data, param->bytes);
1617         return D3D_OK;
1618     }
1619
1620     WARN("Invalid argument specified\n");
1621
1622     return D3DERR_INVALIDCALL;
1623 }
1624
1625 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL b)
1626 {
1627     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1628
1629     FIXME("iface %p, parameter %p, b %u stub\n", This, parameter, b);
1630
1631     return E_NOTIMPL;
1632 }
1633
1634 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b)
1635 {
1636     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1637     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1638
1639     TRACE("iface %p, parameter %p, b %p\n", This, parameter, b);
1640
1641     if (b && param && !param->element_count && param->class == D3DXPC_SCALAR)
1642     {
1643         *b = get_bool(param->data);
1644         TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1645         return D3D_OK;
1646     }
1647
1648     WARN("Invalid argument specified\n");
1649
1650     return D3DERR_INVALIDCALL;
1651 }
1652
1653 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
1654 {
1655     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1656
1657     FIXME("iface %p, parameter %p, b %p, count %u stub\n", This, parameter, b, count);
1658
1659     return E_NOTIMPL;
1660 }
1661
1662 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
1663 {
1664     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1665     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1666
1667     TRACE("iface %p, parameter %p, b %p, count %u\n", This, parameter, b, count);
1668
1669     if (b && param && (param->class == D3DXPC_SCALAR
1670             || param->class == D3DXPC_VECTOR
1671             || param->class == D3DXPC_MATRIX_ROWS
1672             || param->class == D3DXPC_MATRIX_COLUMNS))
1673     {
1674         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1675
1676         for (i = 0; i < size; ++i)
1677         {
1678             b[i] = get_bool((DWORD *)param->data + i);
1679         }
1680         return D3D_OK;
1681     }
1682
1683     WARN("Invalid argument specified\n");
1684
1685     return D3DERR_INVALIDCALL;
1686 }
1687
1688 static HRESULT WINAPI ID3DXBaseEffectImpl_SetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT n)
1689 {
1690     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1691
1692     FIXME("iface %p, parameter %p, n %u stub\n", This, parameter, n);
1693
1694     return E_NOTIMPL;
1695 }
1696
1697 static HRESULT WINAPI ID3DXBaseEffectImpl_GetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n)
1698 {
1699     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1700     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1701
1702     TRACE("iface %p, parameter %p, n %p\n", This, parameter, n);
1703
1704     if (n && param && !param->element_count && param->class == D3DXPC_SCALAR)
1705     {
1706         *n = get_int(param->type, param->data);
1707         TRACE("Returning %i\n", *n);
1708         return D3D_OK;
1709     }
1710
1711     WARN("Invalid argument specified\n");
1712
1713     return D3DERR_INVALIDCALL;
1714 }
1715
1716 static HRESULT WINAPI ID3DXBaseEffectImpl_SetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
1717 {
1718     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1719
1720     FIXME("iface %p, parameter %p, n %p, count %u stub\n", This, parameter, n, count);
1721
1722     return E_NOTIMPL;
1723 }
1724
1725 static HRESULT WINAPI ID3DXBaseEffectImpl_GetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
1726 {
1727     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1728     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1729
1730     TRACE("iface %p, parameter %p, n %p, count %u\n", This, parameter, n, count);
1731
1732     if (n && param && (param->class == D3DXPC_SCALAR
1733             || param->class == D3DXPC_VECTOR
1734             || param->class == D3DXPC_MATRIX_ROWS
1735             || param->class == D3DXPC_MATRIX_COLUMNS))
1736     {
1737         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1738
1739         for (i = 0; i < size; ++i)
1740         {
1741             n[i] = get_int(param->type, (DWORD *)param->data + i);
1742         }
1743         return D3D_OK;
1744     }
1745
1746     WARN("Invalid argument specified\n");
1747
1748     return D3DERR_INVALIDCALL;
1749 }
1750
1751 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT f)
1752 {
1753     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1754
1755     FIXME("iface %p, parameter %p, f %f stub\n", This, parameter, f);
1756
1757     return E_NOTIMPL;
1758 }
1759
1760 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f)
1761 {
1762     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1763     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1764
1765     TRACE("iface %p, parameter %p, f %p\n", This, parameter, f);
1766
1767     if (f && param && !param->element_count && param->class == D3DXPC_SCALAR)
1768     {
1769         *f = get_float(param->type, (DWORD *)param->data);
1770         TRACE("Returning %f\n", *f);
1771         return D3D_OK;
1772     }
1773
1774     WARN("Invalid argument specified\n");
1775
1776     return D3DERR_INVALIDCALL;
1777 }
1778
1779 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
1780 {
1781     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1782
1783     FIXME("iface %p, parameter %p, f %p, count %u stub\n", This, parameter, f, count);
1784
1785     return E_NOTIMPL;
1786 }
1787
1788 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
1789 {
1790     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1791     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1792
1793     TRACE("iface %p, parameter %p, f %p, count %u\n", This, parameter, f, count);
1794
1795     if (f && param && (param->class == D3DXPC_SCALAR
1796             || param->class == D3DXPC_VECTOR
1797             || param->class == D3DXPC_MATRIX_ROWS
1798             || param->class == D3DXPC_MATRIX_COLUMNS))
1799     {
1800         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1801
1802         for (i = 0; i < size; ++i)
1803         {
1804             f[i] = get_float(param->type, (DWORD *)param->data + i);
1805         }
1806         return D3D_OK;
1807     }
1808
1809     WARN("Invalid argument specified\n");
1810
1811     return D3DERR_INVALIDCALL;
1812 }
1813
1814 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVector(ID3DXBaseEffect* iface, D3DXHANDLE parameter, CONST D3DXVECTOR4* vector)
1815 {
1816     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1817
1818     FIXME("iface %p, parameter %p, vector %p stub\n", This, parameter, vector);
1819
1820     return E_NOTIMPL;
1821 }
1822
1823 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVector(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
1824 {
1825     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1826
1827     FIXME("iface %p, parameter %p, vector %p stub\n", This, parameter, vector);
1828
1829     return E_NOTIMPL;
1830 }
1831
1832 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
1833 {
1834     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1835
1836     FIXME("iface %p, parameter %p, vector %p, count %u stub\n", This, parameter, vector, count);
1837
1838     return E_NOTIMPL;
1839 }
1840
1841 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
1842 {
1843     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1844     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1845
1846     TRACE("iface %p, parameter %p, vector %p, count %u\n", This, parameter, vector, count);
1847
1848     if (!count) return D3D_OK;
1849
1850     if (vector && param && count <= param->element_count)
1851     {
1852         UINT i;
1853
1854         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1855
1856         switch (param->class)
1857         {
1858             case D3DXPC_VECTOR:
1859                 for (i = 0; i < count; ++i)
1860                 {
1861                     get_vector(get_parameter_struct(param->member_handles[i]), &vector[i]);
1862                 }
1863                 return D3D_OK;
1864
1865             case D3DXPC_SCALAR:
1866             case D3DXPC_MATRIX_ROWS:
1867             case D3DXPC_OBJECT:
1868             case D3DXPC_STRUCT:
1869                 break;
1870
1871             default:
1872                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1873                 break;
1874         }
1875     }
1876
1877     WARN("Invalid argument specified\n");
1878
1879     return D3DERR_INVALIDCALL;
1880 }
1881
1882 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
1883 {
1884     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1885
1886     FIXME("iface %p, parameter %p, matrix %p stub\n", This, parameter, matrix);
1887
1888     return E_NOTIMPL;
1889 }
1890
1891 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
1892 {
1893     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1894     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1895
1896     TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
1897
1898     if (matrix && param && !param->element_count)
1899     {
1900         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1901
1902         switch (param->class)
1903         {
1904             case D3DXPC_MATRIX_ROWS:
1905                 get_matrix(param, matrix);
1906                 return D3D_OK;
1907
1908             case D3DXPC_SCALAR:
1909             case D3DXPC_VECTOR:
1910             case D3DXPC_OBJECT:
1911             case D3DXPC_STRUCT:
1912                 break;
1913
1914             default:
1915                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1916                 break;
1917         }
1918     }
1919
1920     WARN("Invalid argument specified\n");
1921
1922     return D3DERR_INVALIDCALL;
1923 }
1924
1925 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
1926 {
1927     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1928
1929     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1930
1931     return E_NOTIMPL;
1932 }
1933
1934 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
1935 {
1936     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1937
1938     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1939
1940     return E_NOTIMPL;
1941 }
1942
1943 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
1944 {
1945     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1946
1947     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1948
1949     return E_NOTIMPL;
1950 }
1951
1952 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
1953 {
1954     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1955
1956     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1957
1958     return E_NOTIMPL;
1959 }
1960
1961 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
1962 {
1963     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1964
1965     FIXME("iface %p, parameter %p, matrix %p stub\n", This, parameter, matrix);
1966
1967     return E_NOTIMPL;
1968 }
1969
1970 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
1971 {
1972     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1973     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1974     D3DXMATRIX m;
1975
1976     TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
1977
1978     if (matrix && param && !param->element_count)
1979     {
1980         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1981
1982         switch (param->class)
1983         {
1984             case D3DXPC_SCALAR:
1985             case D3DXPC_VECTOR:
1986                 get_matrix(param, matrix);
1987                 return D3D_OK;
1988
1989             case D3DXPC_MATRIX_ROWS:
1990                 get_matrix(param, &m);
1991                 D3DXMatrixTranspose(matrix, &m);
1992                 return D3D_OK;
1993
1994             case D3DXPC_OBJECT:
1995             case D3DXPC_STRUCT:
1996                 break;
1997
1998             default:
1999                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2000                 break;
2001         }
2002     }
2003
2004     WARN("Invalid argument specified\n");
2005
2006     return D3DERR_INVALIDCALL;
2007 }
2008
2009 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2010 {
2011     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2012
2013     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2014
2015     return E_NOTIMPL;
2016 }
2017
2018 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2019 {
2020     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2021
2022     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2023
2024     return E_NOTIMPL;
2025 }
2026
2027 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2028 {
2029     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2030
2031     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2032
2033     return E_NOTIMPL;
2034 }
2035
2036 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2037 {
2038     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2039
2040     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2041
2042     return E_NOTIMPL;
2043 }
2044
2045 static HRESULT WINAPI ID3DXBaseEffectImpl_SetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR string)
2046 {
2047     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2048
2049     FIXME("iface %p, parameter %p, string %p stub\n", This, parameter, string);
2050
2051     return E_NOTIMPL;
2052 }
2053
2054 static HRESULT WINAPI ID3DXBaseEffectImpl_GetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
2055 {
2056     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2057     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2058
2059     TRACE("iface %p, parameter %p, string %p\n", This, parameter, string);
2060
2061     if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2062     {
2063         *string = *(LPCSTR *)param->data;
2064         TRACE("Returning %s\n", debugstr_a(*string));
2065         return D3D_OK;
2066     }
2067
2068     WARN("Invalid argument specified\n");
2069
2070     return D3DERR_INVALIDCALL;
2071 }
2072
2073 static HRESULT WINAPI ID3DXBaseEffectImpl_SetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
2074 {
2075     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2076     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2077
2078     TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
2079
2080     if (texture && param && !param->element_count &&
2081             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2082             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
2083             || param->type == D3DXPT_TEXTURECUBE))
2084     {
2085         LPDIRECT3DBASETEXTURE9 oltexture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
2086
2087         if (texture) IDirect3DBaseTexture9_AddRef(texture);
2088         if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2089
2090         *(LPDIRECT3DBASETEXTURE9 *)param->data = texture;
2091
2092         return D3D_OK;
2093     }
2094
2095     WARN("Invalid argument specified\n");
2096
2097     return D3DERR_INVALIDCALL;
2098 }
2099
2100 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
2101 {
2102     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2103     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2104
2105     TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
2106
2107     if (texture && param && !param->element_count &&
2108             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2109             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
2110             || param->type == D3DXPT_TEXTURECUBE))
2111     {
2112         *texture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
2113         if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2114         TRACE("Returning %p\n", *texture);
2115         return D3D_OK;
2116     }
2117
2118     WARN("Invalid argument specified\n");
2119
2120     return D3DERR_INVALIDCALL;
2121 }
2122
2123 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPixelShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
2124 {
2125     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2126     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2127
2128     TRACE("iface %p, parameter %p, pshader %p\n", This, parameter, pshader);
2129
2130     if (pshader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2131     {
2132         *pshader = *(LPDIRECT3DPIXELSHADER9 *)param->data;
2133         if (*pshader) IDirect3DPixelShader9_AddRef(*pshader);
2134         TRACE("Returning %p\n", *pshader);
2135         return D3D_OK;
2136     }
2137
2138     WARN("Invalid argument specified\n");
2139
2140     return D3DERR_INVALIDCALL;
2141 }
2142
2143 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVertexShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
2144 {
2145     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2146     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2147
2148     TRACE("iface %p, parameter %p, vshader %p\n", This, parameter, vshader);
2149
2150     if (vshader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2151     {
2152         *vshader = *(LPDIRECT3DVERTEXSHADER9 *)param->data;
2153         if (*vshader) IDirect3DVertexShader9_AddRef(*vshader);
2154         TRACE("Returning %p\n", *vshader);
2155         return D3D_OK;
2156     }
2157
2158     WARN("Invalid argument specified\n");
2159
2160     return D3DERR_INVALIDCALL;
2161 }
2162
2163 static HRESULT WINAPI ID3DXBaseEffectImpl_SetArrayRange(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
2164 {
2165     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2166
2167     FIXME("iface %p, parameter %p, start %u, end %u stub\n", This, parameter, start, end);
2168
2169     return E_NOTIMPL;
2170 }
2171
2172 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl =
2173 {
2174     /*** IUnknown methods ***/
2175     ID3DXBaseEffectImpl_QueryInterface,
2176     ID3DXBaseEffectImpl_AddRef,
2177     ID3DXBaseEffectImpl_Release,
2178     /*** ID3DXBaseEffect methods ***/
2179     ID3DXBaseEffectImpl_GetDesc,
2180     ID3DXBaseEffectImpl_GetParameterDesc,
2181     ID3DXBaseEffectImpl_GetTechniqueDesc,
2182     ID3DXBaseEffectImpl_GetPassDesc,
2183     ID3DXBaseEffectImpl_GetFunctionDesc,
2184     ID3DXBaseEffectImpl_GetParameter,
2185     ID3DXBaseEffectImpl_GetParameterByName,
2186     ID3DXBaseEffectImpl_GetParameterBySemantic,
2187     ID3DXBaseEffectImpl_GetParameterElement,
2188     ID3DXBaseEffectImpl_GetTechnique,
2189     ID3DXBaseEffectImpl_GetTechniqueByName,
2190     ID3DXBaseEffectImpl_GetPass,
2191     ID3DXBaseEffectImpl_GetPassByName,
2192     ID3DXBaseEffectImpl_GetFunction,
2193     ID3DXBaseEffectImpl_GetFunctionByName,
2194     ID3DXBaseEffectImpl_GetAnnotation,
2195     ID3DXBaseEffectImpl_GetAnnotationByName,
2196     ID3DXBaseEffectImpl_SetValue,
2197     ID3DXBaseEffectImpl_GetValue,
2198     ID3DXBaseEffectImpl_SetBool,
2199     ID3DXBaseEffectImpl_GetBool,
2200     ID3DXBaseEffectImpl_SetBoolArray,
2201     ID3DXBaseEffectImpl_GetBoolArray,
2202     ID3DXBaseEffectImpl_SetInt,
2203     ID3DXBaseEffectImpl_GetInt,
2204     ID3DXBaseEffectImpl_SetIntArray,
2205     ID3DXBaseEffectImpl_GetIntArray,
2206     ID3DXBaseEffectImpl_SetFloat,
2207     ID3DXBaseEffectImpl_GetFloat,
2208     ID3DXBaseEffectImpl_SetFloatArray,
2209     ID3DXBaseEffectImpl_GetFloatArray,
2210     ID3DXBaseEffectImpl_SetVector,
2211     ID3DXBaseEffectImpl_GetVector,
2212     ID3DXBaseEffectImpl_SetVectorArray,
2213     ID3DXBaseEffectImpl_GetVectorArray,
2214     ID3DXBaseEffectImpl_SetMatrix,
2215     ID3DXBaseEffectImpl_GetMatrix,
2216     ID3DXBaseEffectImpl_SetMatrixArray,
2217     ID3DXBaseEffectImpl_GetMatrixArray,
2218     ID3DXBaseEffectImpl_SetMatrixPointerArray,
2219     ID3DXBaseEffectImpl_GetMatrixPointerArray,
2220     ID3DXBaseEffectImpl_SetMatrixTranspose,
2221     ID3DXBaseEffectImpl_GetMatrixTranspose,
2222     ID3DXBaseEffectImpl_SetMatrixTransposeArray,
2223     ID3DXBaseEffectImpl_GetMatrixTransposeArray,
2224     ID3DXBaseEffectImpl_SetMatrixTransposePointerArray,
2225     ID3DXBaseEffectImpl_GetMatrixTransposePointerArray,
2226     ID3DXBaseEffectImpl_SetString,
2227     ID3DXBaseEffectImpl_GetString,
2228     ID3DXBaseEffectImpl_SetTexture,
2229     ID3DXBaseEffectImpl_GetTexture,
2230     ID3DXBaseEffectImpl_GetPixelShader,
2231     ID3DXBaseEffectImpl_GetVertexShader,
2232     ID3DXBaseEffectImpl_SetArrayRange,
2233 };
2234
2235 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
2236 {
2237     return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
2238 }
2239
2240 /*** IUnknown methods ***/
2241 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
2242 {
2243     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2244
2245     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
2246
2247     if (IsEqualGUID(riid, &IID_IUnknown) ||
2248         IsEqualGUID(riid, &IID_ID3DXEffect))
2249     {
2250         This->ID3DXEffect_iface.lpVtbl->AddRef(iface);
2251         *object = This;
2252         return S_OK;
2253     }
2254
2255     ERR("Interface %s not found\n", debugstr_guid(riid));
2256
2257     return E_NOINTERFACE;
2258 }
2259
2260 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
2261 {
2262     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2263
2264     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
2265
2266     return InterlockedIncrement(&This->ref);
2267 }
2268
2269 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
2270 {
2271     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2272     ULONG ref = InterlockedDecrement(&This->ref);
2273
2274     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
2275
2276     if (!ref)
2277     {
2278         free_effect(This);
2279         HeapFree(GetProcessHeap(), 0, This);
2280     }
2281
2282     return ref;
2283 }
2284
2285 /*** ID3DXBaseEffect methods ***/
2286 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
2287 {
2288     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2289     ID3DXBaseEffect *base = This->base_effect;
2290
2291     TRACE("Forward iface %p, base %p\n", This, base);
2292
2293     return ID3DXBaseEffectImpl_GetDesc(base, desc);
2294 }
2295
2296 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
2297 {
2298     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2299     ID3DXBaseEffect *base = This->base_effect;
2300
2301     TRACE("Forward iface %p, base %p\n", This, base);
2302
2303     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
2304 }
2305
2306 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
2307 {
2308     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2309     ID3DXBaseEffect *base = This->base_effect;
2310
2311     TRACE("Forward iface %p, base %p\n", This, base);
2312
2313     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
2314 }
2315
2316 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
2317 {
2318     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2319     ID3DXBaseEffect *base = This->base_effect;
2320
2321     TRACE("Forward iface %p, base %p\n", This, base);
2322
2323     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
2324 }
2325
2326 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
2327 {
2328     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2329     ID3DXBaseEffect *base = This->base_effect;
2330
2331     TRACE("Forward iface %p, base %p\n", This, base);
2332
2333     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
2334 }
2335
2336 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2337 {
2338     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2339     ID3DXBaseEffect *base = This->base_effect;
2340
2341     TRACE("Forward iface %p, base %p\n", This, base);
2342
2343     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
2344 }
2345
2346 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR name)
2347 {
2348     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2349     ID3DXBaseEffect *base = This->base_effect;
2350
2351     TRACE("Forward iface %p, base %p\n", This, base);
2352
2353     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
2354 }
2355
2356 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
2357 {
2358     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2359     ID3DXBaseEffect *base = This->base_effect;
2360
2361     TRACE("Forward iface %p, base %p\n", This, base);
2362
2363     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
2364 }
2365
2366 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2367 {
2368     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2369     ID3DXBaseEffect *base = This->base_effect;
2370
2371     TRACE("Forward iface %p, base %p\n", This, base);
2372
2373     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
2374 }
2375
2376 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
2377 {
2378     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2379     ID3DXBaseEffect *base = This->base_effect;
2380
2381     TRACE("Forward iface %p, base %p\n", This, base);
2382
2383     return ID3DXBaseEffectImpl_GetTechnique(base, index);
2384 }
2385
2386 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, LPCSTR name)
2387 {
2388     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2389     ID3DXBaseEffect *base = This->base_effect;
2390
2391     TRACE("Forward iface %p, base %p\n", This, base);
2392
2393     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
2394 }
2395
2396 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
2397 {
2398     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2399     ID3DXBaseEffect *base = This->base_effect;
2400
2401     TRACE("Forward iface %p, base %p\n", This, base);
2402
2403     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
2404 }
2405
2406 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, LPCSTR name)
2407 {
2408     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2409     ID3DXBaseEffect *base = This->base_effect;
2410
2411     TRACE("Forward iface %p, base %p\n", This, base);
2412
2413     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
2414 }
2415
2416 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
2417 {
2418     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2419     ID3DXBaseEffect *base = This->base_effect;
2420
2421     TRACE("Forward iface %p, base %p\n", This, base);
2422
2423     return ID3DXBaseEffectImpl_GetFunction(base, index);
2424 }
2425
2426 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, LPCSTR name)
2427 {
2428     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2429     ID3DXBaseEffect *base = This->base_effect;
2430
2431     TRACE("Forward iface %p, base %p\n", This, base);
2432
2433     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
2434 }
2435
2436 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
2437 {
2438     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2439     ID3DXBaseEffect *base = This->base_effect;
2440
2441     TRACE("Forward iface %p, base %p\n", This, base);
2442
2443     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
2444 }
2445
2446 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object, LPCSTR name)
2447 {
2448     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2449     ID3DXBaseEffect *base = This->base_effect;
2450
2451     TRACE("Forward iface %p, base %p\n", This, base);
2452
2453     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
2454 }
2455
2456 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
2457 {
2458     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2459     ID3DXBaseEffect *base = This->base_effect;
2460
2461     TRACE("Forward iface %p, base %p\n", This, base);
2462
2463     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
2464 }
2465
2466 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
2467 {
2468     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2469     ID3DXBaseEffect *base = This->base_effect;
2470
2471     TRACE("Forward iface %p, base %p\n", This, base);
2472
2473     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
2474 }
2475
2476 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
2477 {
2478     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2479     ID3DXBaseEffect *base = This->base_effect;
2480
2481     TRACE("Forward iface %p, base %p\n", This, base);
2482
2483     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
2484 }
2485
2486 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
2487 {
2488     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2489     ID3DXBaseEffect *base = This->base_effect;
2490
2491     TRACE("Forward iface %p, base %p\n", This, base);
2492
2493     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
2494 }
2495
2496 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
2497 {
2498     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2499     ID3DXBaseEffect *base = This->base_effect;
2500
2501     TRACE("Forward iface %p, base %p\n", This, base);
2502
2503     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
2504 }
2505
2506 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
2507 {
2508     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2509     ID3DXBaseEffect *base = This->base_effect;
2510
2511     TRACE("Forward iface %p, base %p\n", This, base);
2512
2513     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
2514 }
2515
2516 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
2517 {
2518     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2519     ID3DXBaseEffect *base = This->base_effect;
2520
2521     TRACE("Forward iface %p, base %p\n", This, base);
2522
2523     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
2524 }
2525
2526 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
2527 {
2528     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2529     ID3DXBaseEffect *base = This->base_effect;
2530
2531     TRACE("Forward iface %p, base %p\n", This, base);
2532
2533     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
2534 }
2535
2536 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
2537 {
2538     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2539     ID3DXBaseEffect *base = This->base_effect;
2540
2541     TRACE("Forward iface %p, base %p\n", This, base);
2542
2543     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
2544 }
2545
2546 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
2547 {
2548     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2549     ID3DXBaseEffect *base = This->base_effect;
2550
2551     TRACE("Forward iface %p, base %p\n", This, base);
2552
2553     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
2554 }
2555
2556 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT f)
2557 {
2558     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2559     ID3DXBaseEffect *base = This->base_effect;
2560
2561     TRACE("Forward iface %p, base %p\n", This, base);
2562
2563     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
2564 }
2565
2566 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f)
2567 {
2568     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2569     ID3DXBaseEffect *base = This->base_effect;
2570
2571     TRACE("Forward iface %p, base %p\n", This, base);
2572
2573     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
2574 }
2575
2576 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
2577 {
2578     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2579     ID3DXBaseEffect *base = This->base_effect;
2580
2581     TRACE("Forward iface %p, base %p\n", This, base);
2582
2583     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
2584 }
2585
2586 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
2587 {
2588     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2589     ID3DXBaseEffect *base = This->base_effect;
2590
2591     TRACE("Forward iface %p, base %p\n", This, base);
2592
2593     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
2594 }
2595
2596 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
2597 {
2598     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2599     ID3DXBaseEffect *base = This->base_effect;
2600
2601     TRACE("Forward iface %p, base %p\n", This, base);
2602
2603     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
2604 }
2605
2606 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2607 {
2608     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2609     ID3DXBaseEffect *base = This->base_effect;
2610
2611     TRACE("Forward iface %p, base %p\n", This, base);
2612
2613     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
2614 }
2615
2616 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
2617 {
2618     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2619     ID3DXBaseEffect *base = This->base_effect;
2620
2621     TRACE("Forward iface %p, base %p\n", This, base);
2622
2623     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
2624 }
2625
2626 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2627 {
2628     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2629     ID3DXBaseEffect *base = This->base_effect;
2630
2631     TRACE("Forward iface %p, base %p\n", This, base);
2632
2633     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
2634 }
2635
2636 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2637 {
2638     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2639     ID3DXBaseEffect *base = This->base_effect;
2640
2641     TRACE("Forward iface %p, base %p\n", This, base);
2642
2643     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
2644 }
2645
2646 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2647 {
2648     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2649     ID3DXBaseEffect *base = This->base_effect;
2650
2651     TRACE("Forward iface %p, base %p\n", This, base);
2652
2653     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
2654 }
2655
2656 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2657 {
2658     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2659     ID3DXBaseEffect *base = This->base_effect;
2660
2661     TRACE("Forward iface %p, base %p\n", This, base);
2662
2663     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
2664 }
2665
2666 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2667 {
2668     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2669     ID3DXBaseEffect *base = This->base_effect;
2670
2671     TRACE("Forward iface %p, base %p\n", This, base);
2672
2673     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
2674 }
2675
2676 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2677 {
2678     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2679     ID3DXBaseEffect *base = This->base_effect;
2680
2681     TRACE("Forward iface %p, base %p\n", This, base);
2682
2683     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
2684 }
2685
2686 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2687 {
2688     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2689     ID3DXBaseEffect *base = This->base_effect;
2690
2691     TRACE("Forward iface %p, base %p\n", This, base);
2692
2693     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
2694 }
2695
2696 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2697 {
2698     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2699     ID3DXBaseEffect *base = This->base_effect;
2700
2701     TRACE("Forward iface %p, base %p\n", This, base);
2702
2703     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
2704 }
2705
2706 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2707 {
2708     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2709     ID3DXBaseEffect *base = This->base_effect;
2710
2711     TRACE("Forward iface %p, base %p\n", This, base);
2712
2713     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
2714 }
2715
2716 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2717 {
2718     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2719     ID3DXBaseEffect *base = This->base_effect;
2720
2721     TRACE("Forward iface %p, base %p\n", This, base);
2722
2723     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
2724 }
2725
2726 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2727 {
2728     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2729     ID3DXBaseEffect *base = This->base_effect;
2730
2731     TRACE("Forward iface %p, base %p\n", This, base);
2732
2733     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
2734 }
2735
2736 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2737 {
2738     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2739     ID3DXBaseEffect *base = This->base_effect;
2740
2741     TRACE("Forward iface %p, base %p\n", This, base);
2742
2743     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
2744 }
2745
2746 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2747 {
2748     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2749     ID3DXBaseEffect *base = This->base_effect;
2750
2751     TRACE("Forward iface %p, base %p\n", This, base);
2752
2753     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
2754 }
2755
2756 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR string)
2757 {
2758     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2759     ID3DXBaseEffect *base = This->base_effect;
2760
2761     TRACE("Forward iface %p, base %p\n", This, base);
2762
2763     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
2764 }
2765
2766 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
2767 {
2768     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2769     ID3DXBaseEffect *base = This->base_effect;
2770
2771     TRACE("Forward iface %p, base %p\n", This, base);
2772
2773     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
2774 }
2775
2776 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
2777 {
2778     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2779     ID3DXBaseEffect *base = This->base_effect;
2780
2781     TRACE("Forward iface %p, base %p\n", This, base);
2782
2783     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
2784 }
2785
2786 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
2787 {
2788     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2789     ID3DXBaseEffect *base = This->base_effect;
2790
2791     TRACE("Forward iface %p, base %p\n", This, base);
2792
2793     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
2794 }
2795
2796 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
2797 {
2798     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2799     ID3DXBaseEffect *base = This->base_effect;
2800
2801     TRACE("Forward iface %p, base %p\n", This, base);
2802
2803     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
2804 }
2805
2806 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
2807 {
2808     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2809     ID3DXBaseEffect *base = This->base_effect;
2810
2811     TRACE("Forward iface %p, base %p\n", This, base);
2812
2813     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
2814 }
2815
2816 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
2817 {
2818     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2819     ID3DXBaseEffect *base = This->base_effect;
2820
2821     TRACE("Forward iface %p, base %p\n", This, base);
2822
2823     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
2824 }
2825
2826 /*** ID3DXEffect methods ***/
2827 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, LPD3DXEFFECTPOOL *pool)
2828 {
2829     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2830
2831     TRACE("iface %p, pool %p\n", This, pool);
2832
2833     if (!pool)
2834     {
2835         WARN("Invalid argument supplied.\n");
2836         return D3DERR_INVALIDCALL;
2837     }
2838
2839     if (This->pool)
2840     {
2841         This->pool->lpVtbl->AddRef(This->pool);
2842     }
2843
2844     *pool = This->pool;
2845
2846     TRACE("Returning pool %p\n", *pool);
2847
2848     return S_OK;
2849 }
2850
2851 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
2852 {
2853     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2854     struct ID3DXBaseEffectImpl *base = impl_from_ID3DXBaseEffect(This->base_effect);
2855     struct d3dx_technique *tech = is_valid_technique(base, technique);
2856
2857     TRACE("iface %p, technique %p\n", This, technique);
2858
2859     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
2860
2861     if (tech)
2862     {
2863         UINT i;
2864
2865         for (i = 0; i < base->technique_count; ++i)
2866         {
2867             struct d3dx_technique *t = get_technique_struct(base->technique_handles[i]);
2868
2869             if (tech == t)
2870             {
2871                 This->active_technique = get_technique_handle(t);
2872                 TRACE("Technique %u (%p)\n", i, tech);
2873                 return D3D_OK;
2874             }
2875         }
2876     }
2877
2878     WARN("Invalid argument supplied.\n");
2879
2880     return D3DERR_INVALIDCALL;
2881 }
2882
2883 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
2884 {
2885     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2886
2887     TRACE("iface %p\n", This);
2888
2889     return This->active_technique;
2890 }
2891
2892 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
2893 {
2894     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2895
2896     FIXME("(%p)->(%p): stub\n", This, technique);
2897
2898     return D3D_OK;
2899 }
2900
2901 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
2902 {
2903     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2904
2905     FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
2906
2907     return E_NOTIMPL;
2908 }
2909
2910 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
2911 {
2912     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2913
2914     FIXME("(%p)->(%p, %p): stub\n", This, parameter, technique);
2915
2916     return FALSE;
2917 }
2918
2919 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
2920 {
2921     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2922     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
2923
2924     FIXME("iface %p, passes %p, flags %#x partial stub\n", This, passes, flags);
2925
2926     if (passes && technique)
2927     {
2928         if (This->manager || flags & D3DXFX_DONOTSAVESTATE)
2929         {
2930             TRACE("State capturing disabled.\n");
2931         }
2932         else
2933         {
2934             FIXME("State capturing not supported, yet!\n");
2935         }
2936
2937         *passes = technique->pass_count;
2938
2939         return D3D_OK;
2940     }
2941
2942     WARN("Invalid argument supplied.\n");
2943
2944     return D3DERR_INVALIDCALL;
2945 }
2946
2947 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
2948 {
2949     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2950     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
2951
2952     TRACE("iface %p, pass %u\n", This, pass);
2953
2954     if (technique && pass < technique->pass_count && !This->active_pass)
2955     {
2956         This->active_pass = technique->pass_handles[pass];
2957
2958         FIXME("No states applied, yet!\n");
2959
2960         return D3D_OK;
2961     }
2962
2963     WARN("Invalid argument supplied.\n");
2964
2965     return D3DERR_INVALIDCALL;
2966 }
2967
2968 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect* iface)
2969 {
2970     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2971
2972     FIXME("(%p)->(): stub\n", This);
2973
2974     return E_NOTIMPL;
2975 }
2976
2977 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
2978 {
2979     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2980
2981     TRACE("iface %p\n", This);
2982
2983     if (This->active_pass)
2984     {
2985          This->active_pass = NULL;
2986          return D3D_OK;
2987     }
2988
2989     WARN("Invalid call.\n");
2990
2991     return D3DERR_INVALIDCALL;
2992 }
2993
2994 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect* iface)
2995 {
2996     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2997
2998     FIXME("(%p)->(): stub\n", This);
2999
3000     return E_NOTIMPL;
3001 }
3002
3003 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, LPDIRECT3DDEVICE9 *device)
3004 {
3005     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3006
3007     TRACE("iface %p, device %p\n", This, device);
3008
3009     if (!device)
3010     {
3011         WARN("Invalid argument supplied.\n");
3012         return D3DERR_INVALIDCALL;
3013     }
3014
3015     IDirect3DDevice9_AddRef(This->device);
3016
3017     *device = This->device;
3018
3019     TRACE("Returning device %p\n", *device);
3020
3021     return S_OK;
3022 }
3023
3024 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
3025 {
3026     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3027
3028     FIXME("(%p)->(): stub\n", This);
3029
3030     return E_NOTIMPL;
3031 }
3032
3033 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
3034 {
3035     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3036
3037     FIXME("(%p)->(): stub\n", This);
3038
3039     return E_NOTIMPL;
3040 }
3041
3042 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER manager)
3043 {
3044     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3045
3046     TRACE("iface %p, manager %p\n", This, manager);
3047
3048     if (manager) IUnknown_AddRef(manager);
3049     if (This->manager) IUnknown_Release(This->manager);    
3050
3051     This->manager = manager;
3052
3053     return D3D_OK;
3054 }
3055
3056 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER *manager)
3057 {
3058     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3059
3060     TRACE("iface %p, manager %p\n", This, manager);
3061
3062     if (!manager)
3063     {
3064         WARN("Invalid argument supplied.\n");
3065         return D3DERR_INVALIDCALL;
3066     }
3067
3068     if (This->manager) IUnknown_AddRef(This->manager);
3069     *manager = This->manager;
3070
3071     return D3D_OK;
3072 }
3073
3074 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
3075 {
3076     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3077
3078     FIXME("(%p)->(): stub\n", This);
3079
3080     return E_NOTIMPL;
3081 }
3082
3083 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
3084 {
3085     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3086
3087     FIXME("(%p)->(): stub\n", This);
3088
3089     return NULL;
3090 }
3091
3092 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
3093 {
3094     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3095
3096     FIXME("(%p)->(%p): stub\n", This, parameter_block);
3097
3098     return E_NOTIMPL;
3099 }
3100
3101 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
3102 {
3103     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3104
3105     FIXME("(%p)->(%p): stub\n", This, parameter_block);
3106
3107     return E_NOTIMPL;
3108 }
3109
3110 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect* iface, LPDIRECT3DDEVICE9 device, LPD3DXEFFECT* effect)
3111 {
3112     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3113
3114     FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
3115
3116     return E_NOTIMPL;
3117 }
3118
3119 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect* iface, D3DXHANDLE parameter, LPCVOID data, UINT byte_offset, UINT bytes)
3120 {
3121     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3122
3123     FIXME("(%p)->(%p, %p, %u, %u): stub\n", This, parameter, data, byte_offset, bytes);
3124
3125     return E_NOTIMPL;
3126 }
3127
3128 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
3129 {
3130     /*** IUnknown methods ***/
3131     ID3DXEffectImpl_QueryInterface,
3132     ID3DXEffectImpl_AddRef,
3133     ID3DXEffectImpl_Release,
3134     /*** ID3DXBaseEffect methods ***/
3135     ID3DXEffectImpl_GetDesc,
3136     ID3DXEffectImpl_GetParameterDesc,
3137     ID3DXEffectImpl_GetTechniqueDesc,
3138     ID3DXEffectImpl_GetPassDesc,
3139     ID3DXEffectImpl_GetFunctionDesc,
3140     ID3DXEffectImpl_GetParameter,
3141     ID3DXEffectImpl_GetParameterByName,
3142     ID3DXEffectImpl_GetParameterBySemantic,
3143     ID3DXEffectImpl_GetParameterElement,
3144     ID3DXEffectImpl_GetTechnique,
3145     ID3DXEffectImpl_GetTechniqueByName,
3146     ID3DXEffectImpl_GetPass,
3147     ID3DXEffectImpl_GetPassByName,
3148     ID3DXEffectImpl_GetFunction,
3149     ID3DXEffectImpl_GetFunctionByName,
3150     ID3DXEffectImpl_GetAnnotation,
3151     ID3DXEffectImpl_GetAnnotationByName,
3152     ID3DXEffectImpl_SetValue,
3153     ID3DXEffectImpl_GetValue,
3154     ID3DXEffectImpl_SetBool,
3155     ID3DXEffectImpl_GetBool,
3156     ID3DXEffectImpl_SetBoolArray,
3157     ID3DXEffectImpl_GetBoolArray,
3158     ID3DXEffectImpl_SetInt,
3159     ID3DXEffectImpl_GetInt,
3160     ID3DXEffectImpl_SetIntArray,
3161     ID3DXEffectImpl_GetIntArray,
3162     ID3DXEffectImpl_SetFloat,
3163     ID3DXEffectImpl_GetFloat,
3164     ID3DXEffectImpl_SetFloatArray,
3165     ID3DXEffectImpl_GetFloatArray,
3166     ID3DXEffectImpl_SetVector,
3167     ID3DXEffectImpl_GetVector,
3168     ID3DXEffectImpl_SetVectorArray,
3169     ID3DXEffectImpl_GetVectorArray,
3170     ID3DXEffectImpl_SetMatrix,
3171     ID3DXEffectImpl_GetMatrix,
3172     ID3DXEffectImpl_SetMatrixArray,
3173     ID3DXEffectImpl_GetMatrixArray,
3174     ID3DXEffectImpl_SetMatrixPointerArray,
3175     ID3DXEffectImpl_GetMatrixPointerArray,
3176     ID3DXEffectImpl_SetMatrixTranspose,
3177     ID3DXEffectImpl_GetMatrixTranspose,
3178     ID3DXEffectImpl_SetMatrixTransposeArray,
3179     ID3DXEffectImpl_GetMatrixTransposeArray,
3180     ID3DXEffectImpl_SetMatrixTransposePointerArray,
3181     ID3DXEffectImpl_GetMatrixTransposePointerArray,
3182     ID3DXEffectImpl_SetString,
3183     ID3DXEffectImpl_GetString,
3184     ID3DXEffectImpl_SetTexture,
3185     ID3DXEffectImpl_GetTexture,
3186     ID3DXEffectImpl_GetPixelShader,
3187     ID3DXEffectImpl_GetVertexShader,
3188     ID3DXEffectImpl_SetArrayRange,
3189     /*** ID3DXEffect methods ***/
3190     ID3DXEffectImpl_GetPool,
3191     ID3DXEffectImpl_SetTechnique,
3192     ID3DXEffectImpl_GetCurrentTechnique,
3193     ID3DXEffectImpl_ValidateTechnique,
3194     ID3DXEffectImpl_FindNextValidTechnique,
3195     ID3DXEffectImpl_IsParameterUsed,
3196     ID3DXEffectImpl_Begin,
3197     ID3DXEffectImpl_BeginPass,
3198     ID3DXEffectImpl_CommitChanges,
3199     ID3DXEffectImpl_EndPass,
3200     ID3DXEffectImpl_End,
3201     ID3DXEffectImpl_GetDevice,
3202     ID3DXEffectImpl_OnLostDevice,
3203     ID3DXEffectImpl_OnResetDevice,
3204     ID3DXEffectImpl_SetStateManager,
3205     ID3DXEffectImpl_GetStateManager,
3206     ID3DXEffectImpl_BeginParameterBlock,
3207     ID3DXEffectImpl_EndParameterBlock,
3208     ID3DXEffectImpl_ApplyParameterBlock,
3209     ID3DXEffectImpl_DeleteParameterBlock,
3210     ID3DXEffectImpl_CloneEffect,
3211     ID3DXEffectImpl_SetRawValue
3212 };
3213
3214 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
3215 {
3216     return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
3217 }
3218
3219 /*** IUnknown methods ***/
3220 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
3221 {
3222     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3223
3224     TRACE("iface %p, riid %s, object %p\n", This, debugstr_guid(riid), object);
3225
3226     if (IsEqualGUID(riid, &IID_IUnknown) ||
3227         IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
3228     {
3229         This->ID3DXEffectCompiler_iface.lpVtbl->AddRef(iface);
3230         *object = This;
3231         return S_OK;
3232     }
3233
3234     ERR("Interface %s not found\n", debugstr_guid(riid));
3235
3236     return E_NOINTERFACE;
3237 }
3238
3239 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
3240 {
3241     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3242
3243     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
3244
3245     return InterlockedIncrement(&This->ref);
3246 }
3247
3248 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
3249 {
3250     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3251     ULONG ref = InterlockedDecrement(&This->ref);
3252
3253     TRACE("iface %p: Release from %u\n", iface, ref + 1);
3254
3255     if (!ref)
3256     {
3257         free_effect_compiler(This);
3258         HeapFree(GetProcessHeap(), 0, This);
3259     }
3260
3261     return ref;
3262 }
3263
3264 /*** ID3DXBaseEffect methods ***/
3265 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
3266 {
3267     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3268     ID3DXBaseEffect *base = This->base_effect;
3269
3270     TRACE("Forward iface %p, base %p\n", This, base);
3271
3272     return ID3DXBaseEffectImpl_GetDesc(base, desc);
3273 }
3274
3275 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3276 {
3277     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3278     ID3DXBaseEffect *base = This->base_effect;
3279
3280     TRACE("Forward iface %p, base %p\n", This, base);
3281
3282     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
3283 }
3284
3285 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3286 {
3287     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3288     ID3DXBaseEffect *base = This->base_effect;
3289
3290     TRACE("Forward iface %p, base %p\n", This, base);
3291
3292     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
3293 }
3294
3295 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3296 {
3297     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3298     ID3DXBaseEffect *base = This->base_effect;
3299
3300     TRACE("Forward iface %p, base %p\n", This, base);
3301
3302     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
3303 }
3304
3305 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3306 {
3307     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3308     ID3DXBaseEffect *base = This->base_effect;
3309
3310     TRACE("Forward iface %p, base %p\n", This, base);
3311
3312     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
3313 }
3314
3315 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
3316 {
3317     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3318     ID3DXBaseEffect *base = This->base_effect;
3319
3320     TRACE("Forward iface %p, base %p\n", This, base);
3321
3322     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
3323 }
3324
3325 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR name)
3326 {
3327     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3328     ID3DXBaseEffect *base = This->base_effect;
3329
3330     TRACE("Forward iface %p, base %p\n", This, base);
3331
3332     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
3333 }
3334
3335 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR semantic)
3336 {
3337     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3338     ID3DXBaseEffect *base = This->base_effect;
3339
3340     TRACE("Forward iface %p, base %p\n", This, base);
3341
3342     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
3343 }
3344
3345 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
3346 {
3347     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3348     ID3DXBaseEffect *base = This->base_effect;
3349
3350     TRACE("Forward iface %p, base %p\n", This, base);
3351
3352     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
3353 }
3354
3355 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
3356 {
3357     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3358     ID3DXBaseEffect *base = This->base_effect;
3359
3360     TRACE("Forward iface %p, base %p\n", This, base);
3361
3362     return ID3DXBaseEffectImpl_GetTechnique(base, index);
3363 }
3364
3365 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, LPCSTR name)
3366 {
3367     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3368     ID3DXBaseEffect *base = This->base_effect;
3369
3370     TRACE("Forward iface %p, base %p\n", This, base);
3371
3372     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
3373 }
3374
3375 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
3376 {
3377     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3378     ID3DXBaseEffect *base = This->base_effect;
3379
3380     TRACE("Forward iface %p, base %p\n", This, base);
3381
3382     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
3383 }
3384
3385 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, D3DXHANDLE technique, LPCSTR name)
3386 {
3387     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3388     ID3DXBaseEffect *base = This->base_effect;
3389
3390     TRACE("Forward iface %p, base %p\n", This, base);
3391
3392     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
3393 }
3394
3395 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
3396 {
3397     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3398     ID3DXBaseEffect *base = This->base_effect;
3399
3400     TRACE("Forward iface %p, base %p\n", This, base);
3401
3402     return ID3DXBaseEffectImpl_GetFunction(base, index);
3403 }
3404
3405 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, LPCSTR name)
3406 {
3407     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3408     ID3DXBaseEffect *base = This->base_effect;
3409
3410     TRACE("Forward iface %p, base %p\n", This, base);
3411
3412     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
3413 }
3414
3415 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, D3DXHANDLE object, UINT index)
3416 {
3417     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3418     ID3DXBaseEffect *base = This->base_effect;
3419
3420     TRACE("Forward iface %p, base %p\n", This, base);
3421
3422     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
3423 }
3424
3425 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, D3DXHANDLE object, LPCSTR name)
3426 {
3427     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3428     ID3DXBaseEffect *base = This->base_effect;
3429
3430     TRACE("Forward iface %p, base %p\n", This, base);
3431
3432     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
3433 }
3434
3435 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
3436 {
3437     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3438     ID3DXBaseEffect *base = This->base_effect;
3439
3440     TRACE("Forward iface %p, base %p\n", This, base);
3441
3442     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
3443 }
3444
3445 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
3446 {
3447     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3448     ID3DXBaseEffect *base = This->base_effect;
3449
3450     TRACE("Forward iface %p, base %p\n", This, base);
3451
3452     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
3453 }
3454
3455 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
3456 {
3457     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3458     ID3DXBaseEffect *base = This->base_effect;
3459
3460     TRACE("Forward iface %p, base %p\n", This, base);
3461
3462     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
3463 }
3464
3465 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
3466 {
3467     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3468     ID3DXBaseEffect *base = This->base_effect;
3469
3470     TRACE("Forward iface %p, base %p\n", This, base);
3471
3472     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
3473 }
3474
3475 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
3476 {
3477     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3478     ID3DXBaseEffect *base = This->base_effect;
3479
3480     TRACE("Forward iface %p, base %p\n", This, base);
3481
3482     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
3483 }
3484
3485 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
3486 {
3487     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3488     ID3DXBaseEffect *base = This->base_effect;
3489
3490     TRACE("Forward iface %p, base %p\n", This, base);
3491
3492     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
3493 }
3494
3495 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
3496 {
3497     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3498     ID3DXBaseEffect *base = This->base_effect;
3499
3500     TRACE("Forward iface %p, base %p\n", This, base);
3501
3502     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
3503 }
3504
3505 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
3506 {
3507     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3508     ID3DXBaseEffect *base = This->base_effect;
3509
3510     TRACE("Forward iface %p, base %p\n", This, base);
3511
3512     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
3513 }
3514
3515 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
3516 {
3517     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3518     ID3DXBaseEffect *base = This->base_effect;
3519
3520     TRACE("Forward iface %p, base %p\n", This, base);
3521
3522     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
3523 }
3524
3525 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n, UINT count)
3526 {
3527     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3528     ID3DXBaseEffect *base = This->base_effect;
3529
3530     TRACE("Forward iface %p, base %p\n", This, base);
3531
3532     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
3533 }
3534
3535 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT f)
3536 {
3537     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3538     ID3DXBaseEffect *base = This->base_effect;
3539
3540     TRACE("Forward iface %p, base %p\n", This, base);
3541
3542     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
3543 }
3544
3545 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f)
3546 {
3547     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3548     ID3DXBaseEffect *base = This->base_effect;
3549
3550     TRACE("Forward iface %p, base %p\n", This, base);
3551
3552     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
3553 }
3554
3555 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
3556 {
3557     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3558     ID3DXBaseEffect *base = This->base_effect;
3559
3560     TRACE("Forward iface %p, base %p\n", This, base);
3561
3562     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
3563 }
3564
3565 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
3566 {
3567     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3568     ID3DXBaseEffect *base = This->base_effect;
3569
3570     TRACE("Forward iface %p, base %p\n", This, base);
3571
3572     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
3573 }
3574
3575 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
3576 {
3577     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3578     ID3DXBaseEffect *base = This->base_effect;
3579
3580     TRACE("Forward iface %p, base %p\n", This, base);
3581
3582     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
3583 }
3584
3585 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3586 {
3587     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3588     ID3DXBaseEffect *base = This->base_effect;
3589
3590     TRACE("Forward iface %p, base %p\n", This, base);
3591
3592     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
3593 }
3594
3595 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
3596 {
3597     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3598     ID3DXBaseEffect *base = This->base_effect;
3599
3600     TRACE("Forward iface %p, base %p\n", This, base);
3601
3602     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
3603 }
3604
3605 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3606 {
3607     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3608     ID3DXBaseEffect *base = This->base_effect;
3609
3610     TRACE("Forward iface %p, base %p\n", This, base);
3611
3612     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
3613 }
3614
3615 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
3616 {
3617     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3618     ID3DXBaseEffect *base = This->base_effect;
3619
3620     TRACE("Forward iface %p, base %p\n", This, base);
3621
3622     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
3623 }
3624
3625 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3626 {
3627     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3628     ID3DXBaseEffect *base = This->base_effect;
3629
3630     TRACE("Forward iface %p, base %p\n", This, base);
3631
3632     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
3633 }
3634
3635 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
3636 {
3637     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3638     ID3DXBaseEffect *base = This->base_effect;
3639
3640     TRACE("Forward iface %p, base %p\n", This, base);
3641
3642     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
3643 }
3644
3645 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3646 {
3647     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3648     ID3DXBaseEffect *base = This->base_effect;
3649
3650     TRACE("Forward iface %p, base %p\n", This, base);
3651
3652     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
3653 }
3654
3655 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
3656 {
3657     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3658     ID3DXBaseEffect *base = This->base_effect;
3659
3660     TRACE("Forward iface %p, base %p\n", This, base);
3661
3662     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
3663 }
3664
3665 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3666 {
3667     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3668     ID3DXBaseEffect *base = This->base_effect;
3669
3670     TRACE("Forward iface %p, base %p\n", This, base);
3671
3672     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
3673 }
3674
3675 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
3676 {
3677     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3678     ID3DXBaseEffect *base = This->base_effect;
3679
3680     TRACE("Forward iface %p, base %p\n", This, base);
3681
3682     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
3683 }
3684
3685 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3686 {
3687     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3688     ID3DXBaseEffect *base = This->base_effect;
3689
3690     TRACE("Forward iface %p, base %p\n", This, base);
3691
3692     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
3693 }
3694
3695 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
3696 {
3697     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3698     ID3DXBaseEffect *base = This->base_effect;
3699
3700     TRACE("Forward iface %p, base %p\n", This, base);
3701
3702     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
3703 }
3704
3705 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3706 {
3707     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3708     ID3DXBaseEffect *base = This->base_effect;
3709
3710     TRACE("Forward iface %p, base %p\n", This, base);
3711
3712     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
3713 }
3714
3715 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
3716 {
3717     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3718     ID3DXBaseEffect *base = This->base_effect;
3719
3720     TRACE("Forward iface %p, base %p\n", This, base);
3721
3722     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
3723 }
3724
3725 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3726 {
3727     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3728     ID3DXBaseEffect *base = This->base_effect;
3729
3730     TRACE("Forward iface %p, base %p\n", This, base);
3731
3732     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
3733 }
3734
3735 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR string)
3736 {
3737     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3738     ID3DXBaseEffect *base = This->base_effect;
3739
3740     TRACE("Forward iface %p, base %p\n", This, base);
3741
3742     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
3743 }
3744
3745 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR *string)
3746 {
3747     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3748     ID3DXBaseEffect *base = This->base_effect;
3749
3750     TRACE("Forward iface %p, base %p\n", This, base);
3751
3752     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
3753 }
3754
3755 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
3756 {
3757     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3758     ID3DXBaseEffect *base = This->base_effect;
3759
3760     TRACE("Forward iface %p, base %p\n", This, base);
3761
3762     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
3763 }
3764
3765 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
3766 {
3767     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3768     ID3DXBaseEffect *base = This->base_effect;
3769
3770     TRACE("Forward iface %p, base %p\n", This, base);
3771
3772     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
3773 }
3774
3775 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
3776 {
3777     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3778     ID3DXBaseEffect *base = This->base_effect;
3779
3780     TRACE("Forward iface %p, base %p\n", This, base);
3781
3782     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
3783 }
3784
3785 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
3786 {
3787     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3788     ID3DXBaseEffect *base = This->base_effect;
3789
3790     TRACE("Forward iface %p, base %p\n", This, base);
3791
3792     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
3793 }
3794
3795 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT start, UINT end)
3796 {
3797     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3798     ID3DXBaseEffect *base = This->base_effect;
3799
3800     TRACE("Forward iface %p, base %p\n", This, base);
3801
3802     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
3803 }
3804
3805 /*** ID3DXEffectCompiler methods ***/
3806 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
3807 {
3808     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3809
3810     FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
3811
3812     return E_NOTIMPL;
3813 }
3814
3815 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
3816 {
3817     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3818
3819     FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
3820
3821     return E_NOTIMPL;
3822 }
3823
3824 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
3825         LPD3DXBUFFER *effect, LPD3DXBUFFER *error_msgs)
3826 {
3827     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3828
3829     FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
3830
3831     return E_NOTIMPL;
3832 }
3833
3834 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
3835         LPCSTR target, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *error_msgs, LPD3DXCONSTANTTABLE *constant_table)
3836 {
3837     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3838
3839     FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
3840             This, function, target, flags, shader, error_msgs, constant_table);
3841
3842     return E_NOTIMPL;
3843 }
3844
3845 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
3846 {
3847     /*** IUnknown methods ***/
3848     ID3DXEffectCompilerImpl_QueryInterface,
3849     ID3DXEffectCompilerImpl_AddRef,
3850     ID3DXEffectCompilerImpl_Release,
3851     /*** ID3DXBaseEffect methods ***/
3852     ID3DXEffectCompilerImpl_GetDesc,
3853     ID3DXEffectCompilerImpl_GetParameterDesc,
3854     ID3DXEffectCompilerImpl_GetTechniqueDesc,
3855     ID3DXEffectCompilerImpl_GetPassDesc,
3856     ID3DXEffectCompilerImpl_GetFunctionDesc,
3857     ID3DXEffectCompilerImpl_GetParameter,
3858     ID3DXEffectCompilerImpl_GetParameterByName,
3859     ID3DXEffectCompilerImpl_GetParameterBySemantic,
3860     ID3DXEffectCompilerImpl_GetParameterElement,
3861     ID3DXEffectCompilerImpl_GetTechnique,
3862     ID3DXEffectCompilerImpl_GetTechniqueByName,
3863     ID3DXEffectCompilerImpl_GetPass,
3864     ID3DXEffectCompilerImpl_GetPassByName,
3865     ID3DXEffectCompilerImpl_GetFunction,
3866     ID3DXEffectCompilerImpl_GetFunctionByName,
3867     ID3DXEffectCompilerImpl_GetAnnotation,
3868     ID3DXEffectCompilerImpl_GetAnnotationByName,
3869     ID3DXEffectCompilerImpl_SetValue,
3870     ID3DXEffectCompilerImpl_GetValue,
3871     ID3DXEffectCompilerImpl_SetBool,
3872     ID3DXEffectCompilerImpl_GetBool,
3873     ID3DXEffectCompilerImpl_SetBoolArray,
3874     ID3DXEffectCompilerImpl_GetBoolArray,
3875     ID3DXEffectCompilerImpl_SetInt,
3876     ID3DXEffectCompilerImpl_GetInt,
3877     ID3DXEffectCompilerImpl_SetIntArray,
3878     ID3DXEffectCompilerImpl_GetIntArray,
3879     ID3DXEffectCompilerImpl_SetFloat,
3880     ID3DXEffectCompilerImpl_GetFloat,
3881     ID3DXEffectCompilerImpl_SetFloatArray,
3882     ID3DXEffectCompilerImpl_GetFloatArray,
3883     ID3DXEffectCompilerImpl_SetVector,
3884     ID3DXEffectCompilerImpl_GetVector,
3885     ID3DXEffectCompilerImpl_SetVectorArray,
3886     ID3DXEffectCompilerImpl_GetVectorArray,
3887     ID3DXEffectCompilerImpl_SetMatrix,
3888     ID3DXEffectCompilerImpl_GetMatrix,
3889     ID3DXEffectCompilerImpl_SetMatrixArray,
3890     ID3DXEffectCompilerImpl_GetMatrixArray,
3891     ID3DXEffectCompilerImpl_SetMatrixPointerArray,
3892     ID3DXEffectCompilerImpl_GetMatrixPointerArray,
3893     ID3DXEffectCompilerImpl_SetMatrixTranspose,
3894     ID3DXEffectCompilerImpl_GetMatrixTranspose,
3895     ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
3896     ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
3897     ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
3898     ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
3899     ID3DXEffectCompilerImpl_SetString,
3900     ID3DXEffectCompilerImpl_GetString,
3901     ID3DXEffectCompilerImpl_SetTexture,
3902     ID3DXEffectCompilerImpl_GetTexture,
3903     ID3DXEffectCompilerImpl_GetPixelShader,
3904     ID3DXEffectCompilerImpl_GetVertexShader,
3905     ID3DXEffectCompilerImpl_SetArrayRange,
3906     /*** ID3DXEffectCompiler methods ***/
3907     ID3DXEffectCompilerImpl_SetLiteral,
3908     ID3DXEffectCompilerImpl_GetLiteral,
3909     ID3DXEffectCompilerImpl_CompileEffect,
3910     ID3DXEffectCompilerImpl_CompileShader,
3911 };
3912
3913 static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *data, const char **ptr, D3DXHANDLE *objects)
3914 {
3915     HRESULT hr;
3916     UINT i;
3917     struct d3dx_state *states;
3918
3919     read_dword(ptr, &sampler->state_count);
3920     TRACE("Count: %u\n", sampler->state_count);
3921
3922     states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * sampler->state_count);
3923     if (!states)
3924     {
3925         ERR("Out of memory\n");
3926         return E_OUTOFMEMORY;
3927     }
3928
3929     for (i = 0; i < sampler->state_count; ++i)
3930     {
3931         hr = d3dx9_parse_state(&states[i], data, ptr, objects);
3932         if (hr != D3D_OK)
3933         {
3934             WARN("Failed to parse state\n");
3935             goto err_out;
3936         }
3937     }
3938
3939     sampler->states = states;
3940
3941     return D3D_OK;
3942
3943 err_out:
3944
3945     for (i = 0; i < sampler->state_count; ++i)
3946     {
3947         free_state(&states[i]);
3948     }
3949
3950     HeapFree(GetProcessHeap(), 0, states);
3951
3952     return hr;
3953 }
3954
3955 static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char *data, const char **ptr, D3DXHANDLE *objects)
3956 {
3957     unsigned int i;
3958     HRESULT hr;
3959     UINT old_size = 0;
3960     DWORD id;
3961
3962     if (param->element_count)
3963     {
3964         param->data = value;
3965
3966         for (i = 0; i < param->element_count; ++i)
3967         {
3968             struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
3969
3970             hr = d3dx9_parse_value(member, value ? (char *)value + old_size : NULL, data, ptr, objects);
3971             if (hr != D3D_OK)
3972             {
3973                 WARN("Failed to parse value\n");
3974                 return hr;
3975             }
3976
3977             old_size += member->bytes;
3978         }
3979
3980         return D3D_OK;
3981     }
3982
3983     switch(param->class)
3984     {
3985         case D3DXPC_SCALAR:
3986         case D3DXPC_VECTOR:
3987         case D3DXPC_MATRIX_ROWS:
3988         case D3DXPC_MATRIX_COLUMNS:
3989             param->data = value;
3990             break;
3991
3992         case D3DXPC_STRUCT:
3993             param->data = value;
3994
3995             for (i = 0; i < param->member_count; ++i)
3996             {
3997                 struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
3998
3999                 hr = d3dx9_parse_value(member, (char *)value + old_size, data, ptr, objects);
4000                 if (hr != D3D_OK)
4001                 {
4002                     WARN("Failed to parse value\n");
4003                     return hr;
4004                 }
4005
4006                 old_size += member->bytes;
4007             }
4008             break;
4009
4010         case D3DXPC_OBJECT:
4011             switch (param->type)
4012             {
4013                 case D3DXPT_STRING:
4014                 case D3DXPT_TEXTURE:
4015                 case D3DXPT_TEXTURE1D:
4016                 case D3DXPT_TEXTURE2D:
4017                 case D3DXPT_TEXTURE3D:
4018                 case D3DXPT_TEXTURECUBE:
4019                 case D3DXPT_PIXELSHADER:
4020                 case D3DXPT_VERTEXSHADER:
4021                     read_dword(ptr, &id);
4022                     TRACE("Id: %u\n", id);
4023                     objects[id] = get_parameter_handle(param);
4024                     param->data = value;
4025                     break;
4026
4027                 case D3DXPT_SAMPLER:
4028                 case D3DXPT_SAMPLER1D:
4029                 case D3DXPT_SAMPLER2D:
4030                 case D3DXPT_SAMPLER3D:
4031                 case D3DXPT_SAMPLERCUBE:
4032                 {
4033                     struct d3dx_sampler *sampler;
4034
4035                     sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
4036                     if (!sampler)
4037                     {
4038                         ERR("Out of memory\n");
4039                         return E_OUTOFMEMORY;
4040                     }
4041
4042                     hr = d3dx9_parse_sampler(sampler, data, ptr, objects);
4043                     if (hr != D3D_OK)
4044                     {
4045                         HeapFree(GetProcessHeap(), 0, sampler);
4046                         WARN("Failed to parse sampler\n");
4047                         return hr;
4048                     }
4049
4050                     param->data = sampler;
4051                     break;
4052                 }
4053
4054                 default:
4055                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4056                     break;
4057             }
4058             break;
4059
4060         default:
4061             FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4062             break;
4063     }
4064
4065     return D3D_OK;
4066 }
4067
4068 static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *data, const char *ptr, D3DXHANDLE *objects)
4069 {
4070     UINT size = param->bytes;
4071     HRESULT hr;
4072     void *value = NULL;
4073
4074     TRACE("param size: %u\n", size);
4075
4076     if (size)
4077     {
4078         value = HeapAlloc(GetProcessHeap(), 0, size);
4079         if (!value)
4080         {
4081             ERR("Failed to allocate data memory.\n");
4082             return E_OUTOFMEMORY;
4083         }
4084
4085         TRACE("Data: %s.\n", debugstr_an(ptr, size));
4086         memcpy(value, ptr, size);
4087     }
4088
4089     hr = d3dx9_parse_value(param, value, data, &ptr, objects);
4090     if (hr != D3D_OK)
4091     {
4092         WARN("Failed to parse value\n");
4093         HeapFree(GetProcessHeap(), 0, value);
4094         return hr;
4095     }
4096
4097     return D3D_OK;
4098 }
4099
4100 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
4101 {
4102     DWORD size;
4103
4104     read_dword(&ptr, &size);
4105     TRACE("Name size: %#x\n", size);
4106
4107     if (!size)
4108     {
4109         return D3D_OK;
4110     }
4111
4112     *name = HeapAlloc(GetProcessHeap(), 0, size);
4113     if (!*name)
4114     {
4115         ERR("Failed to allocate name memory.\n");
4116         return E_OUTOFMEMORY;
4117     }
4118
4119     TRACE("Name: %s.\n", debugstr_an(ptr, size));
4120     memcpy(*name, ptr, size);
4121
4122     return D3D_OK;
4123 }
4124
4125 static HRESULT d3dx9_copy_data(char **str, const char **ptr)
4126 {
4127     DWORD size;
4128
4129     read_dword(ptr, &size);
4130     TRACE("Data size: %#x\n", size);
4131
4132     *str = HeapAlloc(GetProcessHeap(), 0, size);
4133     if (!*str)
4134     {
4135         ERR("Failed to allocate name memory.\n");
4136         return E_OUTOFMEMORY;
4137     }
4138
4139     TRACE("Data: %s.\n", debugstr_an(*ptr, size));
4140     memcpy(*str, *ptr, size);
4141
4142     *ptr += ((size + 3) & ~3);
4143
4144     return D3D_OK;
4145 }
4146
4147 static HRESULT d3dx9_parse_data(struct d3dx_parameter *param, const char **ptr, LPDIRECT3DDEVICE9 device)
4148 {
4149     DWORD size;
4150     HRESULT hr;
4151
4152     TRACE("Parse data for parameter %s, type %s\n", debugstr_a(param->name), debug_d3dxparameter_type(param->type));
4153
4154     read_dword(ptr, &size);
4155     TRACE("Data size: %#x\n", size);
4156
4157     if (!size)
4158     {
4159         TRACE("Size is 0\n");
4160         *(void **)param->data = NULL;
4161         return D3D_OK;
4162     }
4163
4164     switch (param->type)
4165     {
4166         case D3DXPT_STRING:
4167             /* re-read with size (sizeof(DWORD) = 4) */
4168             hr = d3dx9_parse_name((LPSTR *)param->data, *ptr - 4);
4169             if (hr != D3D_OK)
4170             {
4171                 WARN("Failed to parse string data\n");
4172                 return hr;
4173             }
4174             break;
4175
4176         case D3DXPT_VERTEXSHADER:
4177             hr = IDirect3DDevice9_CreateVertexShader(device, (DWORD *)*ptr, (LPDIRECT3DVERTEXSHADER9 *)param->data);
4178             if (hr != D3D_OK)
4179             {
4180                 WARN("Failed to create vertex shader\n");
4181                 return hr;
4182             }
4183             break;
4184
4185         case D3DXPT_PIXELSHADER:
4186             hr = IDirect3DDevice9_CreatePixelShader(device, (DWORD *)*ptr, (LPDIRECT3DPIXELSHADER9 *)param->data);
4187             if (hr != D3D_OK)
4188             {
4189                 WARN("Failed to create pixel shader\n");
4190                 return hr;
4191             }
4192             break;
4193
4194         default:
4195             FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4196             break;
4197     }
4198
4199
4200     *ptr += ((size + 3) & ~3);
4201
4202     return D3D_OK;
4203 }
4204
4205 static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
4206         struct d3dx_parameter *parent, UINT flags)
4207 {
4208     DWORD offset;
4209     HRESULT hr;
4210     D3DXHANDLE *member_handles = NULL;
4211     UINT i;
4212
4213     param->flags = flags;
4214
4215     if (!parent)
4216     {
4217         read_dword(ptr, &param->type);
4218         TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
4219
4220         read_dword(ptr, &param->class);
4221         TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
4222
4223         read_dword(ptr, &offset);
4224         TRACE("Type name offset: %#x\n", offset);
4225         hr = d3dx9_parse_name(&param->name, data + offset);
4226         if (hr != D3D_OK)
4227         {
4228             WARN("Failed to parse name\n");
4229             goto err_out;
4230         }
4231
4232         read_dword(ptr, &offset);
4233         TRACE("Type semantic offset: %#x\n", offset);
4234         hr = d3dx9_parse_name(&param->semantic, data + offset);
4235         if (hr != D3D_OK)
4236         {
4237             WARN("Failed to parse semantic\n");
4238             goto err_out;
4239         }
4240
4241         read_dword(ptr, &param->element_count);
4242         TRACE("Elements: %u\n", param->element_count);
4243
4244         switch (param->class)
4245         {
4246             case D3DXPC_VECTOR:
4247                 read_dword(ptr, &param->columns);
4248                 TRACE("Columns: %u\n", param->columns);
4249
4250                 read_dword(ptr, &param->rows);
4251                 TRACE("Rows: %u\n", param->rows);
4252
4253                 /* sizeof(DWORD) * rows * columns */
4254                 param->bytes = 4 * param->rows * param->columns;
4255                 break;
4256
4257             case D3DXPC_SCALAR:
4258             case D3DXPC_MATRIX_ROWS:
4259             case D3DXPC_MATRIX_COLUMNS:
4260                 read_dword(ptr, &param->rows);
4261                 TRACE("Rows: %u\n", param->rows);
4262
4263                 read_dword(ptr, &param->columns);
4264                 TRACE("Columns: %u\n", param->columns);
4265
4266                 /* sizeof(DWORD) * rows * columns */
4267                 param->bytes = 4 * param->rows * param->columns;
4268                 break;
4269
4270             case D3DXPC_STRUCT:
4271                 read_dword(ptr, &param->member_count);
4272                 TRACE("Members: %u\n", param->member_count);
4273                 break;
4274
4275             case D3DXPC_OBJECT:
4276                 switch (param->type)
4277                 {
4278                     case D3DXPT_STRING:
4279                         param->bytes = sizeof(LPCSTR);
4280                         break;
4281
4282                     case D3DXPT_PIXELSHADER:
4283                         param->bytes = sizeof(LPDIRECT3DPIXELSHADER9);
4284                         break;
4285
4286                     case D3DXPT_VERTEXSHADER:
4287                         param->bytes = sizeof(LPDIRECT3DVERTEXSHADER9);
4288                         break;
4289
4290                     case D3DXPT_TEXTURE:
4291                     case D3DXPT_TEXTURE1D:
4292                     case D3DXPT_TEXTURE2D:
4293                     case D3DXPT_TEXTURE3D:
4294                     case D3DXPT_TEXTURECUBE:
4295                         param->bytes = sizeof(LPDIRECT3DBASETEXTURE9);
4296                         break;
4297
4298                     case D3DXPT_SAMPLER:
4299                     case D3DXPT_SAMPLER1D:
4300                     case D3DXPT_SAMPLER2D:
4301                     case D3DXPT_SAMPLER3D:
4302                     case D3DXPT_SAMPLERCUBE:
4303                         param->bytes = 0;
4304                         break;
4305
4306                     default:
4307                         FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4308                         break;
4309                 }
4310                 break;
4311
4312             default:
4313                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4314                 break;
4315         }
4316     }
4317     else
4318     {
4319         /* elements */
4320         param->type = parent->type;
4321         param->class = parent->class;
4322         param->name = parent->name;
4323         param->semantic = parent->semantic;
4324         param->element_count = 0;
4325         param->annotation_count = 0;
4326         param->member_count = parent->member_count;
4327         param->bytes = parent->bytes;
4328         param->rows = parent->rows;
4329         param->columns = parent->columns;
4330     }
4331
4332     if (param->element_count)
4333     {
4334         unsigned int param_bytes = 0;
4335         const char *save_ptr = *ptr;
4336
4337         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->element_count);
4338         if (!member_handles)
4339         {
4340             ERR("Out of memory\n");
4341             hr = E_OUTOFMEMORY;
4342             goto err_out;
4343         }
4344
4345         for (i = 0; i < param->element_count; ++i)
4346         {
4347             struct d3dx_parameter *member;
4348             *ptr = save_ptr;
4349
4350             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4351             if (!member)
4352             {
4353                 ERR("Out of memory\n");
4354                 hr = E_OUTOFMEMORY;
4355                 goto err_out;
4356             }
4357
4358             member_handles[i] = get_parameter_handle(member);
4359
4360             hr = d3dx9_parse_effect_typedef(member, data, ptr, param, flags);
4361             if (hr != D3D_OK)
4362             {
4363                 WARN("Failed to parse member\n");
4364                 goto err_out;
4365             }
4366
4367             param_bytes += member->bytes;
4368         }
4369
4370         param->bytes = param_bytes;
4371     }
4372     else if (param->member_count)
4373     {
4374         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->member_count);
4375         if (!member_handles)
4376         {
4377             ERR("Out of memory\n");
4378             hr = E_OUTOFMEMORY;
4379             goto err_out;
4380         }
4381
4382         for (i = 0; i < param->member_count; ++i)
4383         {
4384             struct d3dx_parameter *member;
4385
4386             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4387             if (!member)
4388             {
4389                 ERR("Out of memory\n");
4390                 hr = E_OUTOFMEMORY;
4391                 goto err_out;
4392             }
4393
4394             member_handles[i] = get_parameter_handle(member);
4395
4396             hr = d3dx9_parse_effect_typedef(member, data, ptr, NULL, flags);
4397             if (hr != D3D_OK)
4398             {
4399                 WARN("Failed to parse member\n");
4400                 goto err_out;
4401             }
4402
4403             param->bytes += member->bytes;
4404         }
4405     }
4406
4407     param->member_handles = member_handles;
4408
4409     return D3D_OK;
4410
4411 err_out:
4412
4413     if (member_handles)
4414     {
4415         unsigned int count;
4416
4417         if (param->element_count) count = param->element_count;
4418         else count = param->member_count;
4419
4420         for (i = 0; i < count; ++i)
4421         {
4422             free_parameter(member_handles[i], param->element_count != 0, TRUE);
4423         }
4424         HeapFree(GetProcessHeap(), 0, member_handles);
4425     }
4426
4427     if (!parent)
4428     {
4429         HeapFree(GetProcessHeap(), 0, param->name);
4430         HeapFree(GetProcessHeap(), 0, param->semantic);
4431     }
4432     param->name = NULL;
4433     param->semantic = NULL;
4434
4435     return hr;
4436 }
4437
4438 static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data, const char **ptr, D3DXHANDLE *objects)
4439 {
4440     DWORD offset;
4441     const char *ptr2;
4442     HRESULT hr;
4443
4444     anno->flags = D3DX_PARAMETER_ANNOTATION;
4445
4446     read_dword(ptr, &offset);
4447     TRACE("Typedef offset: %#x\n", offset);
4448     ptr2 = data + offset;
4449     hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
4450     if (hr != D3D_OK)
4451     {
4452         WARN("Failed to parse type definition\n");
4453         return hr;
4454     }
4455
4456     read_dword(ptr, &offset);
4457     TRACE("Value offset: %#x\n", offset);
4458     hr = d3dx9_parse_init_value(anno, data, data + offset, objects);
4459     if (hr != D3D_OK)
4460     {
4461         WARN("Failed to parse value\n");
4462         return hr;
4463     }
4464
4465     return D3D_OK;
4466 }
4467
4468 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects)
4469 {
4470     DWORD offset;
4471     const char *ptr2;
4472     HRESULT hr;
4473     struct d3dx_parameter *parameter;
4474
4475     parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
4476     if (!parameter)
4477     {
4478         ERR("Out of memory\n");
4479         return E_OUTOFMEMORY;
4480     }
4481
4482     state->type = ST_CONSTANT;
4483
4484     read_dword(ptr, &state->operation);
4485     TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
4486
4487     read_dword(ptr, &state->index);
4488     TRACE("Index: %#x\n", state->index);
4489
4490     read_dword(ptr, &offset);
4491     TRACE("Typedef offset: %#x\n", offset);
4492     ptr2 = data + offset;
4493     hr = d3dx9_parse_effect_typedef(parameter, data, &ptr2, NULL, 0);
4494     if (hr != D3D_OK)
4495     {
4496         WARN("Failed to parse type definition\n");
4497         goto err_out;
4498     }
4499
4500     read_dword(ptr, &offset);
4501     TRACE("Value offset: %#x\n", offset);
4502     hr = d3dx9_parse_init_value(parameter, data, data + offset, objects);
4503     if (hr != D3D_OK)
4504     {
4505         WARN("Failed to parse value\n");
4506         goto err_out;
4507     }
4508
4509     state->parameter = get_parameter_handle(parameter);
4510
4511     return D3D_OK;
4512
4513 err_out:
4514
4515     free_parameter(get_parameter_handle(parameter), FALSE, FALSE);
4516
4517     return hr;
4518 }
4519
4520 static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data, const char **ptr, D3DXHANDLE *objects)
4521 {
4522     DWORD offset;
4523     HRESULT hr;
4524     unsigned int i;
4525     D3DXHANDLE *annotation_handles = NULL;
4526     const char *ptr2;
4527
4528     read_dword(ptr, &offset);
4529     TRACE("Typedef offset: %#x\n", offset);
4530     ptr2 = data + offset;
4531
4532     read_dword(ptr, &offset);
4533     TRACE("Value offset: %#x\n", offset);
4534
4535     read_dword(ptr, &param->flags);
4536     TRACE("Flags: %#x\n", param->flags);
4537
4538     read_dword(ptr, &param->annotation_count);
4539     TRACE("Annotation count: %u\n", param->annotation_count);
4540
4541     hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
4542     if (hr != D3D_OK)
4543     {
4544         WARN("Failed to parse type definition\n");
4545         return hr;
4546     }
4547
4548     hr = d3dx9_parse_init_value(param, data, data + offset, objects);
4549     if (hr != D3D_OK)
4550     {
4551         WARN("Failed to parse value\n");
4552         return hr;
4553     }
4554
4555     if (param->annotation_count)
4556     {
4557         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * param->annotation_count);
4558         if (!annotation_handles)
4559         {
4560             ERR("Out of memory\n");
4561             hr = E_OUTOFMEMORY;
4562             goto err_out;
4563         }
4564
4565         for (i = 0; i < param->annotation_count; ++i)
4566         {
4567             struct d3dx_parameter *annotation;
4568
4569             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
4570             if (!annotation)
4571             {
4572                 ERR("Out of memory\n");
4573                 hr = E_OUTOFMEMORY;
4574                 goto err_out;
4575             }
4576
4577             annotation_handles[i] = get_parameter_handle(annotation);
4578
4579             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
4580             if (hr != D3D_OK)
4581             {
4582                 WARN("Failed to parse annotation\n");
4583                 goto err_out;
4584             }
4585         }
4586     }
4587
4588     param->annotation_handles = annotation_handles;
4589
4590     return D3D_OK;
4591
4592 err_out:
4593
4594     if (annotation_handles)
4595     {
4596         for (i = 0; i < param->annotation_count; ++i)
4597         {
4598             free_parameter(annotation_handles[i], FALSE, FALSE);
4599         }
4600         HeapFree(GetProcessHeap(), 0, annotation_handles);
4601     }
4602
4603     return hr;
4604 }
4605
4606 static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr, D3DXHANDLE *objects)
4607 {
4608     DWORD offset;
4609     HRESULT hr;
4610     unsigned int i;
4611     D3DXHANDLE *annotation_handles = NULL;
4612     struct d3dx_state *states = NULL;
4613     char *name = NULL;
4614
4615     read_dword(ptr, &offset);
4616     TRACE("Pass name offset: %#x\n", offset);
4617     hr = d3dx9_parse_name(&name, data + offset);
4618     if (hr != D3D_OK)
4619     {
4620         WARN("Failed to parse name\n");
4621         goto err_out;
4622     }
4623
4624     read_dword(ptr, &pass->annotation_count);
4625     TRACE("Annotation count: %u\n", pass->annotation_count);
4626
4627     read_dword(ptr, &pass->state_count);
4628     TRACE("State count: %u\n", pass->state_count);
4629
4630     if (pass->annotation_count)
4631     {
4632         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count);
4633         if (!annotation_handles)
4634         {
4635             ERR("Out of memory\n");
4636             hr = E_OUTOFMEMORY;
4637             goto err_out;
4638         }
4639
4640         for (i = 0; i < pass->annotation_count; ++i)
4641         {
4642             struct d3dx_parameter *annotation;
4643
4644             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
4645             if (!annotation)
4646             {
4647                 ERR("Out of memory\n");
4648                 hr = E_OUTOFMEMORY;
4649                 goto err_out;
4650             }
4651
4652             annotation_handles[i] = get_parameter_handle(annotation);
4653
4654             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
4655             if (hr != D3D_OK)
4656             {
4657                 WARN("Failed to parse annotations\n");
4658                 goto err_out;
4659             }
4660         }
4661     }
4662
4663     if (pass->state_count)
4664     {
4665         states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
4666         if (!states)
4667         {
4668             ERR("Out of memory\n");
4669             hr = E_OUTOFMEMORY;
4670             goto err_out;
4671         }
4672
4673         for (i = 0; i < pass->state_count; ++i)
4674         {
4675             hr = d3dx9_parse_state(&states[i], data, ptr, objects);
4676             if (hr != D3D_OK)
4677             {
4678                 WARN("Failed to parse annotations\n");
4679                 goto err_out;
4680             }
4681         }
4682     }
4683
4684     pass->name = name;
4685     pass->annotation_handles = annotation_handles;
4686     pass->states = states;
4687
4688     return D3D_OK;
4689
4690 err_out:
4691
4692     if (annotation_handles)
4693     {
4694         for (i = 0; i < pass->annotation_count; ++i)
4695         {
4696             free_parameter(annotation_handles[i], FALSE, FALSE);
4697         }
4698         HeapFree(GetProcessHeap(), 0, annotation_handles);
4699     }
4700
4701     if (states)
4702     {
4703         for (i = 0; i < pass->state_count; ++i)
4704         {
4705             free_state(&states[i]);
4706         }
4707         HeapFree(GetProcessHeap(), 0, states);
4708     }
4709
4710     HeapFree(GetProcessHeap(), 0, name);
4711
4712     return hr;
4713 }
4714
4715 static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr, D3DXHANDLE *objects)
4716 {
4717     DWORD offset;
4718     HRESULT hr;
4719     unsigned int i;
4720     D3DXHANDLE *annotation_handles = NULL;
4721     D3DXHANDLE *pass_handles = NULL;
4722     char *name = NULL;
4723
4724     read_dword(ptr, &offset);
4725     TRACE("Technique name offset: %#x\n", offset);
4726     hr = d3dx9_parse_name(&name, data + offset);
4727     if (hr != D3D_OK)
4728     {
4729         WARN("Failed to parse name\n");
4730         goto err_out;
4731     }
4732
4733     read_dword(ptr, &technique->annotation_count);
4734     TRACE("Annotation count: %u\n", technique->annotation_count);
4735
4736     read_dword(ptr, &technique->pass_count);
4737     TRACE("Pass count: %u\n", technique->pass_count);
4738
4739     if (technique->annotation_count)
4740     {
4741         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count);
4742         if (!annotation_handles)
4743         {
4744             ERR("Out of memory\n");
4745             hr = E_OUTOFMEMORY;
4746             goto err_out;
4747         }
4748
4749         for (i = 0; i < technique->annotation_count; ++i)
4750         {
4751             struct d3dx_parameter *annotation;
4752
4753             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
4754             if (!annotation)
4755             {
4756                 ERR("Out of memory\n");
4757                 hr = E_OUTOFMEMORY;
4758                 goto err_out;
4759             }
4760
4761             annotation_handles[i] = get_parameter_handle(annotation);
4762
4763             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
4764             if (hr != D3D_OK)
4765             {
4766                 WARN("Failed to parse annotations\n");
4767                 goto err_out;
4768             }
4769         }
4770     }
4771
4772     if (technique->pass_count)
4773     {
4774         pass_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count);
4775         if (!pass_handles)
4776         {
4777             ERR("Out of memory\n");
4778             hr = E_OUTOFMEMORY;
4779             goto err_out;
4780         }
4781
4782         for (i = 0; i < technique->pass_count; ++i)
4783         {
4784             struct d3dx_pass *pass;
4785
4786             pass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass));
4787             if (!pass)
4788             {
4789                 ERR("Out of memory\n");
4790                 hr = E_OUTOFMEMORY;
4791                 goto err_out;
4792             }
4793
4794             pass_handles[i] = get_pass_handle(pass);
4795
4796             hr = d3dx9_parse_effect_pass(pass, data, ptr, objects);
4797             if (hr != D3D_OK)
4798             {
4799                 WARN("Failed to parse passes\n");
4800                 goto err_out;
4801             }
4802         }
4803     }
4804
4805     technique->name = name;
4806     technique->pass_handles = pass_handles;
4807     technique->annotation_handles = annotation_handles;
4808
4809     return D3D_OK;
4810
4811 err_out:
4812
4813     if (pass_handles)
4814     {
4815         for (i = 0; i < technique->pass_count; ++i)
4816         {
4817             free_pass(pass_handles[i]);
4818         }
4819         HeapFree(GetProcessHeap(), 0, pass_handles);
4820     }
4821
4822     if (annotation_handles)
4823     {
4824         for (i = 0; i < technique->annotation_count; ++i)
4825         {
4826             free_parameter(annotation_handles[i], FALSE, FALSE);
4827         }
4828         HeapFree(GetProcessHeap(), 0, annotation_handles);
4829     }
4830
4831     HeapFree(GetProcessHeap(), 0, name);
4832
4833     return hr;
4834 }
4835
4836 static HRESULT d3dx9_parse_resource(struct ID3DXBaseEffectImpl *base, const char *data, const char **ptr)
4837 {
4838     DWORD technique_index;
4839     DWORD index, state_index, usage, element_index;
4840     struct d3dx_state *state;
4841     struct d3dx_parameter *param;
4842     HRESULT hr = E_FAIL;
4843
4844     read_dword(ptr, &technique_index);
4845     TRACE("techn: %u\n", technique_index);
4846
4847     read_dword(ptr, &index);
4848     TRACE("index: %u\n", index);
4849
4850     read_dword(ptr, &element_index);
4851     TRACE("element_index: %u\n", element_index);
4852
4853     read_dword(ptr, &state_index);
4854     TRACE("state_index: %u\n", state_index);
4855
4856     read_dword(ptr, &usage);
4857     TRACE("usage: %u\n", usage);
4858
4859     if (technique_index == 0xffffffff)
4860     {
4861         struct d3dx_parameter *parameter;
4862         struct d3dx_sampler *sampler;
4863
4864         if (index >= base->parameter_count)
4865         {
4866             FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
4867             return E_FAIL;
4868         }
4869
4870         parameter = get_parameter_struct(base->parameter_handles[index]);
4871         if (element_index != 0xffffffff)
4872         {
4873             if (element_index >= parameter->element_count && parameter->element_count != 0)
4874             {
4875                 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
4876                 return E_FAIL;
4877             }
4878
4879             if (parameter->element_count != 0) parameter = get_parameter_struct(parameter->member_handles[element_index]);
4880         }
4881
4882         sampler = parameter->data;
4883         if (state_index >= sampler->state_count)
4884         {
4885             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
4886             return E_FAIL;
4887         }
4888
4889         state = &sampler->states[state_index];
4890     }
4891     else
4892     {
4893         struct d3dx_technique *technique;
4894         struct d3dx_pass *pass;
4895
4896         if (technique_index >= base->technique_count)
4897         {
4898             FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
4899             return E_FAIL;
4900         }
4901
4902         technique = get_technique_struct(base->technique_handles[technique_index]);
4903         if (index >= technique->pass_count)
4904         {
4905             FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
4906             return E_FAIL;
4907         }
4908
4909         pass = get_pass_struct(technique->pass_handles[index]);
4910         if (state_index >= pass->state_count)
4911         {
4912             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
4913             return E_FAIL;
4914         }
4915
4916         state = &pass->states[state_index];
4917     }
4918
4919     param = get_parameter_struct(state->parameter);
4920
4921     switch (usage)
4922     {
4923         case 0:
4924             TRACE("usage 0: type %s\n", debug_d3dxparameter_type(param->type));
4925             switch (param->type)
4926             {
4927                 case D3DXPT_VERTEXSHADER:
4928                 case D3DXPT_PIXELSHADER:
4929                     state->type = ST_CONSTANT;
4930                     hr = d3dx9_parse_data(param, ptr, base->effect->device);
4931                     break;
4932
4933                 case D3DXPT_BOOL:
4934                 case D3DXPT_INT:
4935                 case D3DXPT_FLOAT:
4936                 case D3DXPT_STRING:
4937                     state->type = ST_FXLC;
4938                     hr = d3dx9_copy_data(param->data, ptr);
4939                     break;
4940
4941                 default:
4942                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4943                     break;
4944             }
4945             break;
4946
4947         case 1:
4948             state->type = ST_PARAMETER;
4949             hr = d3dx9_copy_data(param->data, ptr);
4950             if (hr == D3D_OK)
4951             {
4952                 TRACE("Mapping to parameter %s\n", *(char **)param->data);
4953             }
4954             break;
4955
4956         default:
4957             FIXME("Unknown usage %x\n", usage);
4958             break;
4959     }
4960
4961     return hr;
4962 }
4963
4964 static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start)
4965 {
4966     const char *ptr = data + start;
4967     D3DXHANDLE *parameter_handles = NULL;
4968     D3DXHANDLE *technique_handles = NULL;
4969     D3DXHANDLE *objects = NULL;
4970     UINT stringcount, objectcount, resourcecount;
4971     HRESULT hr;
4972     UINT i;
4973
4974     read_dword(&ptr, &base->parameter_count);
4975     TRACE("Parameter count: %u\n", base->parameter_count);
4976
4977     read_dword(&ptr, &base->technique_count);
4978     TRACE("Technique count: %u\n", base->technique_count);
4979
4980     skip_dword_unknown(&ptr, 1);
4981
4982     read_dword(&ptr, &objectcount);
4983     TRACE("Object count: %u\n", objectcount);
4984
4985     objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*objects) * objectcount);
4986     if (!objects)
4987     {
4988         ERR("Out of memory\n");
4989         hr = E_OUTOFMEMORY;
4990         goto err_out;
4991     }
4992
4993     if (base->parameter_count)
4994     {
4995         parameter_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter_handles) * base->parameter_count);
4996         if (!parameter_handles)
4997         {
4998             ERR("Out of memory\n");
4999             hr = E_OUTOFMEMORY;
5000             goto err_out;
5001         }
5002
5003         for (i = 0; i < base->parameter_count; ++i)
5004         {
5005             struct d3dx_parameter *parameter;
5006
5007             parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
5008             if (!parameter)
5009             {
5010                 ERR("Out of memory\n");
5011                 hr = E_OUTOFMEMORY;
5012                 goto err_out;
5013             }
5014
5015             parameter_handles[i] = get_parameter_handle(parameter);
5016
5017             hr = d3dx9_parse_effect_parameter(parameter, data, &ptr, objects);
5018             if (hr != D3D_OK)
5019             {
5020                 WARN("Failed to parse parameter\n");
5021                 goto err_out;
5022             }
5023         }
5024     }
5025
5026     if (base->technique_count)
5027     {
5028         technique_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count);
5029         if (!technique_handles)
5030         {
5031             ERR("Out of memory\n");
5032             hr = E_OUTOFMEMORY;
5033             goto err_out;
5034         }
5035
5036         for (i = 0; i < base->technique_count; ++i)
5037         {
5038             struct d3dx_technique *technique;
5039
5040             technique = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique));
5041             if (!technique)
5042             {
5043                 ERR("Out of memory\n");
5044                 hr = E_OUTOFMEMORY;
5045                 goto err_out;
5046             }
5047
5048             technique_handles[i] = get_technique_handle(technique);
5049
5050             hr = d3dx9_parse_effect_technique(technique, data, &ptr, objects);
5051             if (hr != D3D_OK)
5052             {
5053                 WARN("Failed to parse technique\n");
5054                 goto err_out;
5055             }
5056         }
5057     }
5058
5059     /* needed for further parsing */
5060     base->technique_handles = technique_handles;
5061     base->parameter_handles = parameter_handles;
5062
5063     read_dword(&ptr, &stringcount);
5064     TRACE("String count: %u\n", stringcount);
5065
5066     read_dword(&ptr, &resourcecount);
5067     TRACE("Resource count: %u\n", resourcecount);
5068
5069     for (i = 0; i < stringcount; ++i)
5070     {
5071         DWORD id;
5072         struct d3dx_parameter *param;
5073
5074         read_dword(&ptr, &id);
5075         TRACE("Id: %u\n", id);
5076
5077         param = get_parameter_struct(objects[id]);
5078
5079         hr = d3dx9_parse_data(param, &ptr, base->effect->device);
5080         if (hr != D3D_OK)
5081         {
5082             WARN("Failed to parse data\n");
5083             goto err_out;
5084         }
5085     }
5086
5087     for (i = 0; i < resourcecount; ++i)
5088     {
5089         TRACE("parse resource %u\n", i);
5090
5091         hr = d3dx9_parse_resource(base, data, &ptr);
5092         if (hr != D3D_OK)
5093         {
5094             WARN("Failed to parse data\n");
5095             goto err_out;
5096         }
5097     }
5098
5099     HeapFree(GetProcessHeap(), 0, objects);
5100
5101     return D3D_OK;
5102
5103 err_out:
5104
5105     if (technique_handles)
5106     {
5107         for (i = 0; i < base->technique_count; ++i)
5108         {
5109             free_technique(technique_handles[i]);
5110         }
5111         HeapFree(GetProcessHeap(), 0, technique_handles);
5112     }
5113
5114     if (parameter_handles)
5115     {
5116         for (i = 0; i < base->parameter_count; ++i)
5117         {
5118             free_parameter(parameter_handles[i], FALSE, FALSE);
5119         }
5120         HeapFree(GetProcessHeap(), 0, parameter_handles);
5121     }
5122
5123     base->technique_handles = NULL;
5124     base->parameter_handles = NULL;
5125
5126     HeapFree(GetProcessHeap(), 0, objects);
5127
5128     return hr;
5129 }
5130
5131 static HRESULT d3dx9_base_effect_init(struct ID3DXBaseEffectImpl *base,
5132         const char *data, SIZE_T data_size, struct ID3DXEffectImpl *effect)
5133 {
5134     DWORD tag, offset;
5135     const char *ptr = data;
5136     HRESULT hr;
5137
5138     TRACE("base %p, data %p, data_size %lu, effect %p\n", base, data, data_size, effect);
5139
5140     base->ID3DXBaseEffect_iface.lpVtbl = &ID3DXBaseEffect_Vtbl;
5141     base->ref = 1;
5142     base->effect = effect;
5143
5144     read_dword(&ptr, &tag);
5145     TRACE("Tag: %x\n", tag);
5146
5147     if (tag != d3dx9_effect_version(9, 1))
5148     {
5149         /* todo: compile hlsl ascii code */
5150         FIXME("HLSL ascii effects not supported, yet\n");
5151
5152         /* Show the start of the shader for debugging info. */
5153         TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
5154     }
5155     else
5156     {
5157         read_dword(&ptr, &offset);
5158         TRACE("Offset: %x\n", offset);
5159
5160         hr = d3dx9_parse_effect(base, ptr, data_size, offset);
5161         if (hr != D3D_OK)
5162         {
5163             FIXME("Failed to parse effect.\n");
5164             return hr;
5165         }
5166     }
5167
5168     return D3D_OK;
5169 }
5170
5171 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
5172         const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
5173 {
5174     HRESULT hr;
5175     struct ID3DXBaseEffectImpl *object = NULL;
5176
5177     TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
5178
5179     effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
5180     effect->ref = 1;
5181
5182     if (pool) pool->lpVtbl->AddRef(pool);
5183     effect->pool = pool;
5184
5185     IDirect3DDevice9_AddRef(device);
5186     effect->device = device;
5187
5188     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5189     if (!object)
5190     {
5191         ERR("Out of memory\n");
5192         hr = E_OUTOFMEMORY;
5193         goto err_out;
5194     }
5195
5196     hr = d3dx9_base_effect_init(object, data, data_size, effect);
5197     if (hr != D3D_OK)
5198     {
5199         FIXME("Failed to parse effect.\n");
5200         goto err_out;
5201     }
5202
5203     effect->base_effect = &object->ID3DXBaseEffect_iface;
5204
5205     /* initialize defaults - check because of unsupported ascii effects */
5206     if (object->technique_handles)
5207     {
5208         effect->active_technique = object->technique_handles[0];
5209         effect->active_pass = NULL;
5210     }
5211
5212     return D3D_OK;
5213
5214 err_out:
5215
5216     HeapFree(GetProcessHeap(), 0, object);
5217     free_effect(effect);
5218
5219     return hr;
5220 }
5221
5222 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
5223                                   LPCVOID srcdata,
5224                                   UINT srcdatalen,
5225                                   CONST D3DXMACRO* defines,
5226                                   LPD3DXINCLUDE include,
5227                                   LPCSTR skip_constants,
5228                                   DWORD flags,
5229                                   LPD3DXEFFECTPOOL pool,
5230                                   LPD3DXEFFECT* effect,
5231                                   LPD3DXBUFFER* compilation_errors)
5232 {
5233     struct ID3DXEffectImpl *object;
5234     HRESULT hr;
5235
5236     FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
5237         skip_constants, flags, pool, effect, compilation_errors);
5238
5239     if (!device || !srcdata)
5240         return D3DERR_INVALIDCALL;
5241
5242     if (!srcdatalen)
5243         return E_FAIL;
5244
5245     /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
5246     if (!effect)
5247         return D3D_OK;
5248
5249     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5250     if (!object)
5251     {
5252         ERR("Out of memory\n");
5253         return E_OUTOFMEMORY;
5254     }
5255
5256     hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, pool);
5257     if (FAILED(hr))
5258     {
5259         WARN("Failed to initialize shader reflection\n");
5260         HeapFree(GetProcessHeap(), 0, object);
5261         return hr;
5262     }
5263
5264     *effect = &object->ID3DXEffect_iface;
5265
5266     TRACE("Created ID3DXEffect %p\n", object);
5267
5268     return D3D_OK;
5269 }
5270
5271 HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
5272                                 LPCVOID srcdata,
5273                                 UINT srcdatalen,
5274                                 CONST D3DXMACRO* defines,
5275                                 LPD3DXINCLUDE include,
5276                                 DWORD flags,
5277                                 LPD3DXEFFECTPOOL pool,
5278                                 LPD3DXEFFECT* effect,
5279                                 LPD3DXBUFFER* compilation_errors)
5280 {
5281     TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
5282         include, flags, pool, effect, compilation_errors);
5283
5284     return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
5285 }
5286
5287 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, const char *data, SIZE_T data_size)
5288 {
5289     HRESULT hr;
5290     struct ID3DXBaseEffectImpl *object = NULL;
5291
5292     TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
5293
5294     compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
5295     compiler->ref = 1;
5296
5297     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5298     if (!object)
5299     {
5300         ERR("Out of memory\n");
5301         hr = E_OUTOFMEMORY;
5302         goto err_out;
5303     }
5304
5305     hr = d3dx9_base_effect_init(object, data, data_size, NULL);
5306     if (hr != D3D_OK)
5307     {
5308         FIXME("Failed to parse effect.\n");
5309         goto err_out;
5310     }
5311
5312     compiler->base_effect = &object->ID3DXBaseEffect_iface;
5313
5314     return D3D_OK;
5315
5316 err_out:
5317
5318     HeapFree(GetProcessHeap(), 0, object);
5319     free_effect_compiler(compiler);
5320
5321     return hr;
5322 }
5323
5324 HRESULT WINAPI D3DXCreateEffectCompiler(LPCSTR srcdata,
5325                                         UINT srcdatalen,
5326                                         CONST D3DXMACRO *defines,
5327                                         LPD3DXINCLUDE include,
5328                                         DWORD flags,
5329                                         LPD3DXEFFECTCOMPILER *compiler,
5330                                         LPD3DXBUFFER *parse_errors)
5331 {
5332     struct ID3DXEffectCompilerImpl *object;
5333     HRESULT hr;
5334
5335     TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
5336             srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
5337
5338     if (!srcdata || !compiler)
5339     {
5340         WARN("Invalid arguments supplied\n");
5341         return D3DERR_INVALIDCALL;
5342     }
5343
5344     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5345     if (!object)
5346     {
5347         ERR("Out of memory\n");
5348         return E_OUTOFMEMORY;
5349     }
5350
5351     hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen);
5352     if (FAILED(hr))
5353     {
5354         WARN("Failed to initialize effect compiler\n");
5355         HeapFree(GetProcessHeap(), 0, object);
5356         return hr;
5357     }
5358
5359     *compiler = &object->ID3DXEffectCompiler_iface;
5360
5361     TRACE("Created ID3DXEffectCompiler %p\n", object);
5362
5363     return D3D_OK;
5364 }
5365
5366 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl;
5367
5368 struct ID3DXEffectPoolImpl
5369 {
5370     ID3DXEffectPool ID3DXEffectPool_iface;
5371     LONG ref;
5372 };
5373
5374 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
5375 {
5376     return CONTAINING_RECORD(iface, struct ID3DXEffectPoolImpl, ID3DXEffectPool_iface);
5377 }
5378
5379 /*** IUnknown methods ***/
5380 static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
5381 {
5382     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5383
5384     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
5385
5386     if (IsEqualGUID(riid, &IID_IUnknown) ||
5387         IsEqualGUID(riid, &IID_ID3DXEffectPool))
5388     {
5389         This->ID3DXEffectPool_iface.lpVtbl->AddRef(iface);
5390         *object = This;
5391         return S_OK;
5392     }
5393
5394     WARN("Interface %s not found\n", debugstr_guid(riid));
5395
5396     return E_NOINTERFACE;
5397 }
5398
5399 static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool *iface)
5400 {
5401     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5402
5403     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
5404
5405     return InterlockedIncrement(&This->ref);
5406 }
5407
5408 static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool *iface)
5409 {
5410     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5411     ULONG ref = InterlockedDecrement(&This->ref);
5412
5413     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
5414
5415     if (!ref)
5416         HeapFree(GetProcessHeap(), 0, This);
5417
5418     return ref;
5419 }
5420
5421 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
5422 {
5423     /*** IUnknown methods ***/
5424     ID3DXEffectPoolImpl_QueryInterface,
5425     ID3DXEffectPoolImpl_AddRef,
5426     ID3DXEffectPoolImpl_Release
5427 };
5428
5429 HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL *pool)
5430 {
5431     struct ID3DXEffectPoolImpl *object;
5432
5433     TRACE("(%p)\n", pool);
5434
5435     if (!pool)
5436         return D3DERR_INVALIDCALL;
5437
5438     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5439     if (!object)
5440     {
5441         ERR("Out of memory\n");
5442         return E_OUTOFMEMORY;
5443     }
5444
5445     object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
5446     object->ref = 1;
5447
5448     *pool = &object->ID3DXEffectPool_iface;
5449
5450     return S_OK;
5451 }
5452
5453 HRESULT WINAPI D3DXCreateEffectFromFileExW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
5454     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5455     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5456 {
5457     LPVOID buffer;
5458     HRESULT ret;
5459     DWORD size;
5460
5461     TRACE("(%s): relay\n", debugstr_w(srcfile));
5462
5463     if (!device || !srcfile)
5464         return D3DERR_INVALIDCALL;
5465
5466     ret = map_view_of_file(srcfile, &buffer, &size);
5467
5468     if (FAILED(ret))
5469         return D3DXERR_INVALIDDATA;
5470
5471     ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5472     UnmapViewOfFile(buffer);
5473
5474     return ret;
5475 }
5476
5477 HRESULT WINAPI D3DXCreateEffectFromFileExA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
5478     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5479     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5480 {
5481     LPWSTR srcfileW;
5482     HRESULT ret;
5483     DWORD len;
5484
5485     TRACE("(void): relay\n");
5486
5487     if (!srcfile)
5488         return D3DERR_INVALIDCALL;
5489
5490     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
5491     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
5492     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
5493
5494     ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5495     HeapFree(GetProcessHeap(), 0, srcfileW);
5496
5497     return ret;
5498 }
5499
5500 HRESULT WINAPI D3DXCreateEffectFromFileW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
5501     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5502     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5503 {
5504     TRACE("(void): relay\n");
5505     return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
5506 }
5507
5508 HRESULT WINAPI D3DXCreateEffectFromFileA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
5509     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5510     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5511 {
5512     TRACE("(void): relay\n");
5513     return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
5514 }
5515
5516 HRESULT WINAPI D3DXCreateEffectFromResourceExW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
5517     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5518     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5519 {
5520     HRSRC resinfo;
5521
5522     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
5523
5524     if (!device)
5525         return D3DERR_INVALIDCALL;
5526
5527     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
5528
5529     if (resinfo)
5530     {
5531         LPVOID buffer;
5532         HRESULT ret;
5533         DWORD size;
5534
5535         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5536
5537         if (FAILED(ret))
5538             return D3DXERR_INVALIDDATA;
5539
5540         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5541     }
5542
5543     return D3DXERR_INVALIDDATA;
5544 }
5545
5546 HRESULT WINAPI D3DXCreateEffectFromResourceExA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
5547     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5548     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5549 {
5550     HRSRC resinfo;
5551
5552     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
5553
5554     if (!device)
5555         return D3DERR_INVALIDCALL;
5556
5557     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
5558
5559     if (resinfo)
5560     {
5561         LPVOID buffer;
5562         HRESULT ret;
5563         DWORD size;
5564
5565         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5566
5567         if (FAILED(ret))
5568             return D3DXERR_INVALIDDATA;
5569
5570         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5571     }
5572
5573     return D3DXERR_INVALIDDATA;
5574 }
5575
5576 HRESULT WINAPI D3DXCreateEffectFromResourceW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
5577     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5578     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5579 {
5580     TRACE("(void): relay\n");
5581     return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
5582 }
5583
5584 HRESULT WINAPI D3DXCreateEffectFromResourceA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
5585     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5586     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5587 {
5588     TRACE("(void): relay\n");
5589     return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
5590 }
5591
5592 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(LPCWSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
5593     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5594 {
5595     LPVOID buffer;
5596     HRESULT ret;
5597     DWORD size;
5598
5599     TRACE("(%s): relay\n", debugstr_w(srcfile));
5600
5601     if (!srcfile)
5602         return D3DERR_INVALIDCALL;
5603
5604     ret = map_view_of_file(srcfile, &buffer, &size);
5605
5606     if (FAILED(ret))
5607         return D3DXERR_INVALIDDATA;
5608
5609     ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
5610     UnmapViewOfFile(buffer);
5611
5612     return ret;
5613 }
5614
5615 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
5616     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5617 {
5618     LPWSTR srcfileW;
5619     HRESULT ret;
5620     DWORD len;
5621
5622     TRACE("(void): relay\n");
5623
5624     if (!srcfile)
5625         return D3DERR_INVALIDCALL;
5626
5627     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
5628     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
5629     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
5630
5631     ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
5632     HeapFree(GetProcessHeap(), 0, srcfileW);
5633
5634     return ret;
5635 }
5636
5637 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, LPCSTR srcresource, const D3DXMACRO *defines,
5638     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5639 {
5640     HRSRC resinfo;
5641
5642     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
5643
5644     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
5645
5646     if (resinfo)
5647     {
5648         LPVOID buffer;
5649         HRESULT ret;
5650         DWORD size;
5651
5652         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5653
5654         if (FAILED(ret))
5655             return D3DXERR_INVALIDDATA;
5656
5657         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
5658     }
5659
5660     return D3DXERR_INVALIDDATA;
5661 }
5662
5663 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, LPCWSTR srcresource, const D3DXMACRO *defines,
5664     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5665 {
5666     HRSRC resinfo;
5667
5668     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
5669
5670     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
5671
5672     if (resinfo)
5673     {
5674         LPVOID buffer;
5675         HRESULT ret;
5676         DWORD size;
5677
5678         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5679
5680         if (FAILED(ret))
5681             return D3DXERR_INVALIDDATA;
5682
5683         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
5684     }
5685
5686     return D3DXERR_INVALIDDATA;
5687 }