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