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