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