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