d3dx9: Avoid LPDIRECT3DVERTEXBUFFER9.
[wine] / dlls / d3dx9_36 / effect.c
1 /*
2  * Copyright 2010 Christian Costa
3  * Copyright 2011 Rico Schüller
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "config.h"
21 #include "wine/port.h"
22 #define NONAMELESSUNION
23 #include "wine/debug.h"
24 #include "wine/unicode.h"
25
26 #include "windef.h"
27 #include "wingdi.h"
28 #include "d3dx9_36_private.h"
29
30 /* Constants for special INT/FLOAT conversation */
31 #define INT_FLOAT_MULTI 255.0f
32 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
33
34 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
35
36 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl;
37 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl;
38 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl;
39
40 enum STATE_CLASS
41 {
42     SC_LIGHTENABLE,
43     SC_FVF,
44     SC_LIGHT,
45     SC_MATERIAL,
46     SC_NPATCHMODE,
47     SC_PIXELSHADER,
48     SC_RENDERSTATE,
49     SC_SETSAMPLER,
50     SC_SAMPLERSTATE,
51     SC_TEXTURE,
52     SC_TEXTURESTAGE,
53     SC_TRANSFORM,
54     SC_VERTEXSHADER,
55     SC_SHADERCONST,
56     SC_UNKNOWN,
57 };
58
59 enum MATERIAL_TYPE
60 {
61     MT_DIFFUSE,
62     MT_AMBIENT,
63     MT_SPECULAR,
64     MT_EMISSIVE,
65     MT_POWER,
66 };
67
68 enum LIGHT_TYPE
69 {
70     LT_TYPE,
71     LT_DIFFUSE,
72     LT_SPECULAR,
73     LT_AMBIENT,
74     LT_POSITION,
75     LT_DIRECTION,
76     LT_RANGE,
77     LT_FALLOFF,
78     LT_ATTENUATION0,
79     LT_ATTENUATION1,
80     LT_ATTENUATION2,
81     LT_THETA,
82     LT_PHI,
83 };
84
85 enum SHADER_CONSTANT_TYPE
86 {
87     SCT_VSFLOAT,
88     SCT_VSBOOL,
89     SCT_VSINT,
90     SCT_PSFLOAT,
91     SCT_PSBOOL,
92     SCT_PSINT,
93 };
94
95 enum STATE_TYPE
96 {
97     ST_CONSTANT,
98     ST_PARAMETER,
99     ST_FXLC,
100 };
101
102 struct d3dx_parameter
103 {
104     char *name;
105     char *semantic;
106     void *data;
107     D3DXPARAMETER_CLASS class;
108     D3DXPARAMETER_TYPE  type;
109     UINT rows;
110     UINT columns;
111     UINT element_count;
112     UINT annotation_count;
113     UINT member_count;
114     DWORD flags;
115     UINT bytes;
116
117     D3DXHANDLE *annotation_handles;
118     D3DXHANDLE *member_handles;
119 };
120
121 struct d3dx_state
122 {
123     UINT operation;
124     UINT index;
125     enum STATE_TYPE type;
126     D3DXHANDLE parameter;
127 };
128
129 struct d3dx_sampler
130 {
131     UINT state_count;
132     struct d3dx_state *states;
133 };
134
135 struct d3dx_pass
136 {
137     char *name;
138     UINT state_count;
139     UINT annotation_count;
140
141     struct d3dx_state *states;
142     D3DXHANDLE *annotation_handles;
143 };
144
145 struct d3dx_technique
146 {
147     char *name;
148     UINT pass_count;
149     UINT annotation_count;
150
151     D3DXHANDLE *annotation_handles;
152     D3DXHANDLE *pass_handles;
153 };
154
155 struct ID3DXBaseEffectImpl
156 {
157     ID3DXBaseEffect ID3DXBaseEffect_iface;
158     LONG ref;
159
160     struct ID3DXEffectImpl *effect;
161
162     UINT parameter_count;
163     UINT technique_count;
164
165     D3DXHANDLE *parameter_handles;
166     D3DXHANDLE *technique_handles;
167 };
168
169 struct ID3DXEffectImpl
170 {
171     ID3DXEffect ID3DXEffect_iface;
172     LONG ref;
173
174     LPD3DXEFFECTSTATEMANAGER manager;
175     LPDIRECT3DDEVICE9 device;
176     LPD3DXEFFECTPOOL pool;
177     D3DXHANDLE active_technique;
178     D3DXHANDLE active_pass;
179
180     ID3DXBaseEffect *base_effect;
181 };
182
183 struct ID3DXEffectCompilerImpl
184 {
185     ID3DXEffectCompiler ID3DXEffectCompiler_iface;
186     LONG ref;
187
188     ID3DXBaseEffect *base_effect;
189 };
190
191 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
192         struct d3dx_parameter *parameter, LPCSTR name);
193 static struct d3dx_parameter *get_annotation_by_name(UINT handlecount, D3DXHANDLE *handles, LPCSTR name);
194 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects);
195 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st);
196
197 static const struct
198 {
199     enum STATE_CLASS class;
200     UINT op;
201     LPCSTR name;
202 }
203 state_table[] =
204 {
205     /* Render sates */
206     {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
207     {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
208     {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
209     {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
210     {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
211     {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
212     {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
213     {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
214     {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
215     {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
216     {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
217     {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
218     {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
219     {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
220     {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
221     {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
222     {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
223     {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
224     {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
225     {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
226     {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
227     {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
228     {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
229     {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
230     {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
231     {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
232     {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
233     {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
234     {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
235     {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
236     {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
237     {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
238     {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
239     {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
240     {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
241     {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
242     {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
243     {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
244     {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
245     {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
246     {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
247     {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
248     {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
249     {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
250     {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
251     {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
252     {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
253     {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
254     {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
255     {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
256     {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
257     {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
258     {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
259     {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
260     {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
261     {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
262     {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
263     {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
264     {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
265     {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
266     {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
267     {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
268     {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
269     {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
270     {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
271     {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
272     {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
273     {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
274     {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
275     {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
276     {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
277     {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
278     {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
279     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
280     {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
281     {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
282     {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
283     {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
284     {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
285     {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
286     {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
287     {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
288     {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
289     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
290     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
291     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
292     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
293     {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
294     {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
295     {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
296     {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
297     {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
298     {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
299     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
300     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
301     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
302     {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
303     {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
304     {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
305     {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
306     {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
307     {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
308     {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
309     /* Texture stages */
310     {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
311     {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
312     {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
313     {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
314     {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
315     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
316     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
317     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
318     {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
319     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
320     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
321     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
322     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
323     {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
324     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
325     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
326     {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
327     {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
328     /* NPatchMode */
329     {SC_NPATCHMODE, 0, "NPatchMode"},
330     /* FVF */
331     {SC_FVF, 0, "FVF"},
332     /* Transform */
333     {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
334     {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
335     {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
336     {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
337     /* Material */
338     {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
339     {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
340     {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
341     {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
342     {SC_MATERIAL, MT_POWER, "MaterialPower"},
343     /* Light */
344     {SC_LIGHT, LT_TYPE, "LightType"},
345     {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
346     {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
347     {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
348     {SC_LIGHT, LT_POSITION, "LightPosition"},
349     {SC_LIGHT, LT_DIRECTION, "LightDirection"},
350     {SC_LIGHT, LT_RANGE, "LightRange"},
351     {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
352     {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
353     {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
354     {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
355     {SC_LIGHT, LT_THETA, "LightTheta"},
356     {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
357     /* Ligthenable */
358     {SC_LIGHTENABLE, 0, "LightEnable"},
359     /* Vertexshader */
360     {SC_VERTEXSHADER, 0, "Vertexshader"},
361     /* Pixelshader */
362     {SC_PIXELSHADER, 0, "Pixelshader"},
363     /* Shader constants */
364     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
365     {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
366     {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
367     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
368     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
369     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
370     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
371     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
372     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
373     {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
374     {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
375     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
376     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
377     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
378     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
379     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
380     /* Texture */
381     {SC_TEXTURE, 0, "Texture"},
382     /* Sampler states */
383     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
384     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
385     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
386     {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
387     {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
388     {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
389     {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
390     {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
391     {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
392     {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
393     {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
394     {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
395     {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
396     /* Set sampler */
397     {SC_SETSAMPLER, 0, "Sampler"},
398 };
399
400 static inline void read_dword(const char **ptr, DWORD *d)
401 {
402     memcpy(d, *ptr, sizeof(*d));
403     *ptr += sizeof(*d);
404 }
405
406 static void skip_dword_unknown(const char **ptr, unsigned int count)
407 {
408     unsigned int i;
409     DWORD d;
410
411     FIXME("Skipping %u unknown DWORDs:\n", count);
412     for (i = 0; i < count; ++i)
413     {
414         read_dword(ptr, &d);
415         FIXME("\t0x%08x\n", d);
416     }
417 }
418
419 static inline struct d3dx_parameter *get_parameter_struct(D3DXHANDLE handle)
420 {
421     return (struct d3dx_parameter *) handle;
422 }
423
424 static inline struct d3dx_pass *get_pass_struct(D3DXHANDLE handle)
425 {
426     return (struct d3dx_pass *) handle;
427 }
428
429 static inline struct d3dx_technique *get_technique_struct(D3DXHANDLE handle)
430 {
431     return (struct d3dx_technique *) handle;
432 }
433
434 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
435 {
436     return (D3DXHANDLE) parameter;
437 }
438
439 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
440 {
441     return (D3DXHANDLE) technique;
442 }
443
444 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
445 {
446     return (D3DXHANDLE) pass;
447 }
448
449 static struct d3dx_technique *get_technique_by_name(struct ID3DXBaseEffectImpl *base, LPCSTR name)
450 {
451     UINT i;
452
453     if (!name) return NULL;
454
455     for (i = 0; i < base->technique_count; ++i)
456     {
457         struct d3dx_technique *tech = get_technique_struct(base->technique_handles[i]);
458
459         if (!strcmp(tech->name, name)) return tech;
460     }
461
462     return NULL;
463 }
464
465 static struct d3dx_technique *is_valid_technique(struct ID3DXBaseEffectImpl *base, D3DXHANDLE technique)
466 {
467     struct d3dx_technique *tech = NULL;
468     unsigned int i;
469
470     for (i = 0; i < base->technique_count; ++i)
471     {
472         if (base->technique_handles[i] == technique)
473         {
474             tech = get_technique_struct(technique);
475             break;
476         }
477     }
478
479     if (!tech) tech = get_technique_by_name(base, technique);
480
481     return tech;
482 }
483
484 static struct d3dx_pass *is_valid_pass(struct ID3DXBaseEffectImpl *base, D3DXHANDLE pass)
485 {
486     unsigned int i, k;
487
488     for (i = 0; i < base->technique_count; ++i)
489     {
490         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
491
492         for (k = 0; k < technique->pass_count; ++k)
493         {
494             if (technique->pass_handles[k] == pass)
495             {
496                 return get_pass_struct(pass);
497             }
498         }
499     }
500
501     return NULL;
502 }
503
504 static struct d3dx_parameter *is_valid_sub_parameter(struct d3dx_parameter *param, D3DXHANDLE parameter)
505 {
506     unsigned int i, count;
507     struct d3dx_parameter *p;
508
509     for (i = 0; i < param->annotation_count; ++i)
510     {
511         if (param->annotation_handles[i] == parameter)
512         {
513             return get_parameter_struct(parameter);
514         }
515
516         p = is_valid_sub_parameter(get_parameter_struct(param->annotation_handles[i]), parameter);
517         if (p) return p;
518     }
519
520     if (param->element_count) count = param->element_count;
521     else count = param->member_count;
522
523     for (i = 0; i < count; ++i)
524     {
525         if (param->member_handles[i] == parameter)
526         {
527             return get_parameter_struct(parameter);
528         }
529
530         p = is_valid_sub_parameter(get_parameter_struct(param->member_handles[i]), parameter);
531         if (p) return p;
532     }
533
534     return NULL;
535 }
536
537 static struct d3dx_parameter *is_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
538 {
539     unsigned int i, k, m;
540     struct d3dx_parameter *p;
541
542     for (i = 0; i < base->parameter_count; ++i)
543     {
544         if (base->parameter_handles[i] == parameter)
545         {
546             return get_parameter_struct(parameter);
547         }
548
549         p = is_valid_sub_parameter(get_parameter_struct(base->parameter_handles[i]), parameter);
550         if (p) return p;
551     }
552
553     for (i = 0; i < base->technique_count; ++i)
554     {
555         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
556
557         for (k = 0; k < technique->pass_count; ++k)
558         {
559             struct d3dx_pass *pass = get_pass_struct(technique->pass_handles[k]);
560
561             for (m = 0; m < pass->annotation_count; ++m)
562             {
563                 if (pass->annotation_handles[i] == parameter)
564                 {
565                     return get_parameter_struct(parameter);
566                 }
567
568                 p = is_valid_sub_parameter(get_parameter_struct(pass->annotation_handles[m]), parameter);
569                 if (p) return p;
570             }
571         }
572
573         for (k = 0; k < technique->annotation_count; ++k)
574         {
575             if (technique->annotation_handles[k] == parameter)
576             {
577                 return get_parameter_struct(parameter);
578             }
579
580             p = is_valid_sub_parameter(get_parameter_struct(technique->annotation_handles[k]), parameter);
581             if (p) return p;
582         }
583     }
584
585     return NULL;
586 }
587
588 static inline struct d3dx_parameter *get_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
589 {
590     struct d3dx_parameter *param = is_valid_parameter(base, parameter);
591
592     if (!param) param = get_parameter_by_name(base, NULL, parameter);
593
594     return param;
595 }
596
597 static void free_state(struct d3dx_state *state)
598 {
599     free_parameter_state(state->parameter, FALSE, FALSE, state->type);
600 }
601
602 static void free_sampler(struct d3dx_sampler *sampler)
603 {
604     UINT i;
605
606     for (i = 0; i < sampler->state_count; ++i)
607     {
608         free_state(&sampler->states[i]);
609     }
610     HeapFree(GetProcessHeap(), 0, sampler->states);
611 }
612
613 static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
614 {
615     free_parameter_state(handle, element, child, ST_CONSTANT);
616 }
617
618 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st)
619 {
620     unsigned int i;
621     struct d3dx_parameter *param = get_parameter_struct(handle);
622
623     TRACE("Free parameter %p, name %s, type %s, child %s, state_type %x\n", param, param->name,
624             debug_d3dxparameter_type(param->type), child ? "yes" : "no", st);
625
626     if (!param)
627     {
628         return;
629     }
630
631     if (param->annotation_handles)
632     {
633         for (i = 0; i < param->annotation_count; ++i)
634         {
635             free_parameter(param->annotation_handles[i], FALSE, FALSE);
636         }
637         HeapFree(GetProcessHeap(), 0, param->annotation_handles);
638     }
639
640     if (param->member_handles)
641     {
642         unsigned int count;
643
644         if (param->element_count) count = param->element_count;
645         else count = param->member_count;
646
647         for (i = 0; i < count; ++i)
648         {
649             free_parameter(param->member_handles[i], param->element_count != 0, TRUE);
650         }
651         HeapFree(GetProcessHeap(), 0, param->member_handles);
652     }
653
654     if (param->class == D3DXPC_OBJECT && !param->element_count)
655     {
656         switch (param->type)
657         {
658             case D3DXPT_STRING:
659                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
660                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
661                 break;
662
663             case D3DXPT_TEXTURE:
664             case D3DXPT_TEXTURE1D:
665             case D3DXPT_TEXTURE2D:
666             case D3DXPT_TEXTURE3D:
667             case D3DXPT_TEXTURECUBE:
668             case D3DXPT_PIXELSHADER:
669             case D3DXPT_VERTEXSHADER:
670                 if (st == ST_CONSTANT)
671                 {
672                     if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
673                 }
674                 else
675                 {
676                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
677                 }
678                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
679                 break;
680
681             case D3DXPT_SAMPLER:
682             case D3DXPT_SAMPLER1D:
683             case D3DXPT_SAMPLER2D:
684             case D3DXPT_SAMPLER3D:
685             case D3DXPT_SAMPLERCUBE:
686                 if (st == ST_CONSTANT)
687                 {
688                     free_sampler((struct d3dx_sampler *)param->data);
689                 }
690                 else
691                 {
692                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
693                 }
694                 /* samplers have always own data, so free that */
695                 HeapFree(GetProcessHeap(), 0, param->data);
696                 break;
697
698             default:
699                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
700                 break;
701         }
702     }
703     else
704     {
705         if (!child)
706         {
707             if (st != ST_CONSTANT)
708             {
709                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
710             }
711             HeapFree(GetProcessHeap(), 0, param->data);
712         }
713     }
714
715     /* only the parent has to release name and semantic */
716     if (!element)
717     {
718         HeapFree(GetProcessHeap(), 0, param->name);
719         HeapFree(GetProcessHeap(), 0, param->semantic);
720     }
721
722     HeapFree(GetProcessHeap(), 0, param);
723 }
724
725 static void free_pass(D3DXHANDLE handle)
726 {
727     unsigned int i;
728     struct d3dx_pass *pass = get_pass_struct(handle);
729
730     TRACE("Free pass %p\n", pass);
731
732     if (!pass)
733     {
734         return;
735     }
736
737     if (pass->annotation_handles)
738     {
739         for (i = 0; i < pass->annotation_count; ++i)
740         {
741             free_parameter(pass->annotation_handles[i], FALSE, FALSE);
742         }
743         HeapFree(GetProcessHeap(), 0, pass->annotation_handles);
744     }
745
746     if (pass->states)
747     {
748         for (i = 0; i < pass->state_count; ++i)
749         {
750             free_state(&pass->states[i]);
751         }
752         HeapFree(GetProcessHeap(), 0, pass->states);
753     }
754
755     HeapFree(GetProcessHeap(), 0, pass->name);
756     HeapFree(GetProcessHeap(), 0, pass);
757 }
758
759 static void free_technique(D3DXHANDLE handle)
760 {
761     unsigned int i;
762     struct d3dx_technique *technique = get_technique_struct(handle);
763
764     TRACE("Free technique %p\n", technique);
765
766     if (!technique)
767     {
768         return;
769     }
770
771     if (technique->annotation_handles)
772     {
773         for (i = 0; i < technique->annotation_count; ++i)
774         {
775             free_parameter(technique->annotation_handles[i], FALSE, FALSE);
776         }
777         HeapFree(GetProcessHeap(), 0, technique->annotation_handles);
778     }
779
780     if (technique->pass_handles)
781     {
782         for (i = 0; i < technique->pass_count; ++i)
783         {
784             free_pass(technique->pass_handles[i]);
785         }
786         HeapFree(GetProcessHeap(), 0, technique->pass_handles);
787     }
788
789     HeapFree(GetProcessHeap(), 0, technique->name);
790     HeapFree(GetProcessHeap(), 0, technique);
791 }
792
793 static void free_base_effect(struct ID3DXBaseEffectImpl *base)
794 {
795     unsigned int i;
796
797     TRACE("Free base effect %p\n", base);
798
799     if (base->parameter_handles)
800     {
801         for (i = 0; i < base->parameter_count; ++i)
802         {
803             free_parameter(base->parameter_handles[i], FALSE, FALSE);
804         }
805         HeapFree(GetProcessHeap(), 0, base->parameter_handles);
806     }
807
808     if (base->technique_handles)
809     {
810         for (i = 0; i < base->technique_count; ++i)
811         {
812             free_technique(base->technique_handles[i]);
813         }
814         HeapFree(GetProcessHeap(), 0, base->technique_handles);
815     }
816 }
817
818 static void free_effect(struct ID3DXEffectImpl *effect)
819 {
820     TRACE("Free effect %p\n", effect);
821
822     if (effect->base_effect)
823     {
824         effect->base_effect->lpVtbl->Release(effect->base_effect);
825     }
826
827     if (effect->pool)
828     {
829         effect->pool->lpVtbl->Release(effect->pool);
830     }
831
832     if (effect->manager)
833     {
834         IUnknown_Release(effect->manager);
835     }
836
837     IDirect3DDevice9_Release(effect->device);
838 }
839
840 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
841 {
842     TRACE("Free effect compiler %p\n", compiler);
843
844     if (compiler->base_effect)
845     {
846         compiler->base_effect->lpVtbl->Release(compiler->base_effect);
847     }
848 }
849
850 static 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, LPD3DXEFFECTPOOL *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, LPDIRECT3DDEVICE9 *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, LPD3DXEFFECTSTATEMANAGER 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, LPD3DXEFFECTSTATEMANAGER *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, LPDIRECT3DDEVICE9 device, LPD3DXEFFECT* effect)
3681 {
3682     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3683
3684     FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
3685
3686     return E_NOTIMPL;
3687 }
3688
3689 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect* iface, D3DXHANDLE parameter, LPCVOID data, UINT byte_offset, UINT bytes)
3690 {
3691     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3692
3693     FIXME("(%p)->(%p, %p, %u, %u): stub\n", This, parameter, data, byte_offset, bytes);
3694
3695     return E_NOTIMPL;
3696 }
3697
3698 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
3699 {
3700     /*** IUnknown methods ***/
3701     ID3DXEffectImpl_QueryInterface,
3702     ID3DXEffectImpl_AddRef,
3703     ID3DXEffectImpl_Release,
3704     /*** ID3DXBaseEffect methods ***/
3705     ID3DXEffectImpl_GetDesc,
3706     ID3DXEffectImpl_GetParameterDesc,
3707     ID3DXEffectImpl_GetTechniqueDesc,
3708     ID3DXEffectImpl_GetPassDesc,
3709     ID3DXEffectImpl_GetFunctionDesc,
3710     ID3DXEffectImpl_GetParameter,
3711     ID3DXEffectImpl_GetParameterByName,
3712     ID3DXEffectImpl_GetParameterBySemantic,
3713     ID3DXEffectImpl_GetParameterElement,
3714     ID3DXEffectImpl_GetTechnique,
3715     ID3DXEffectImpl_GetTechniqueByName,
3716     ID3DXEffectImpl_GetPass,
3717     ID3DXEffectImpl_GetPassByName,
3718     ID3DXEffectImpl_GetFunction,
3719     ID3DXEffectImpl_GetFunctionByName,
3720     ID3DXEffectImpl_GetAnnotation,
3721     ID3DXEffectImpl_GetAnnotationByName,
3722     ID3DXEffectImpl_SetValue,
3723     ID3DXEffectImpl_GetValue,
3724     ID3DXEffectImpl_SetBool,
3725     ID3DXEffectImpl_GetBool,
3726     ID3DXEffectImpl_SetBoolArray,
3727     ID3DXEffectImpl_GetBoolArray,
3728     ID3DXEffectImpl_SetInt,
3729     ID3DXEffectImpl_GetInt,
3730     ID3DXEffectImpl_SetIntArray,
3731     ID3DXEffectImpl_GetIntArray,
3732     ID3DXEffectImpl_SetFloat,
3733     ID3DXEffectImpl_GetFloat,
3734     ID3DXEffectImpl_SetFloatArray,
3735     ID3DXEffectImpl_GetFloatArray,
3736     ID3DXEffectImpl_SetVector,
3737     ID3DXEffectImpl_GetVector,
3738     ID3DXEffectImpl_SetVectorArray,
3739     ID3DXEffectImpl_GetVectorArray,
3740     ID3DXEffectImpl_SetMatrix,
3741     ID3DXEffectImpl_GetMatrix,
3742     ID3DXEffectImpl_SetMatrixArray,
3743     ID3DXEffectImpl_GetMatrixArray,
3744     ID3DXEffectImpl_SetMatrixPointerArray,
3745     ID3DXEffectImpl_GetMatrixPointerArray,
3746     ID3DXEffectImpl_SetMatrixTranspose,
3747     ID3DXEffectImpl_GetMatrixTranspose,
3748     ID3DXEffectImpl_SetMatrixTransposeArray,
3749     ID3DXEffectImpl_GetMatrixTransposeArray,
3750     ID3DXEffectImpl_SetMatrixTransposePointerArray,
3751     ID3DXEffectImpl_GetMatrixTransposePointerArray,
3752     ID3DXEffectImpl_SetString,
3753     ID3DXEffectImpl_GetString,
3754     ID3DXEffectImpl_SetTexture,
3755     ID3DXEffectImpl_GetTexture,
3756     ID3DXEffectImpl_GetPixelShader,
3757     ID3DXEffectImpl_GetVertexShader,
3758     ID3DXEffectImpl_SetArrayRange,
3759     /*** ID3DXEffect methods ***/
3760     ID3DXEffectImpl_GetPool,
3761     ID3DXEffectImpl_SetTechnique,
3762     ID3DXEffectImpl_GetCurrentTechnique,
3763     ID3DXEffectImpl_ValidateTechnique,
3764     ID3DXEffectImpl_FindNextValidTechnique,
3765     ID3DXEffectImpl_IsParameterUsed,
3766     ID3DXEffectImpl_Begin,
3767     ID3DXEffectImpl_BeginPass,
3768     ID3DXEffectImpl_CommitChanges,
3769     ID3DXEffectImpl_EndPass,
3770     ID3DXEffectImpl_End,
3771     ID3DXEffectImpl_GetDevice,
3772     ID3DXEffectImpl_OnLostDevice,
3773     ID3DXEffectImpl_OnResetDevice,
3774     ID3DXEffectImpl_SetStateManager,
3775     ID3DXEffectImpl_GetStateManager,
3776     ID3DXEffectImpl_BeginParameterBlock,
3777     ID3DXEffectImpl_EndParameterBlock,
3778     ID3DXEffectImpl_ApplyParameterBlock,
3779     ID3DXEffectImpl_DeleteParameterBlock,
3780     ID3DXEffectImpl_CloneEffect,
3781     ID3DXEffectImpl_SetRawValue
3782 };
3783
3784 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
3785 {
3786     return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
3787 }
3788
3789 /*** IUnknown methods ***/
3790 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
3791 {
3792     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
3793
3794     if (IsEqualGUID(riid, &IID_IUnknown) ||
3795         IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
3796     {
3797         iface->lpVtbl->AddRef(iface);
3798         *object = iface;
3799         return S_OK;
3800     }
3801
3802     ERR("Interface %s not found\n", debugstr_guid(riid));
3803
3804     return E_NOINTERFACE;
3805 }
3806
3807 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
3808 {
3809     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3810
3811     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
3812
3813     return InterlockedIncrement(&This->ref);
3814 }
3815
3816 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
3817 {
3818     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3819     ULONG ref = InterlockedDecrement(&This->ref);
3820
3821     TRACE("iface %p: Release from %u\n", iface, ref + 1);
3822
3823     if (!ref)
3824     {
3825         free_effect_compiler(This);
3826         HeapFree(GetProcessHeap(), 0, This);
3827     }
3828
3829     return ref;
3830 }
3831
3832 /*** ID3DXBaseEffect methods ***/
3833 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
3834 {
3835     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3836     ID3DXBaseEffect *base = This->base_effect;
3837
3838     TRACE("Forward iface %p, base %p\n", This, base);
3839
3840     return ID3DXBaseEffectImpl_GetDesc(base, desc);
3841 }
3842
3843 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3844 {
3845     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3846     ID3DXBaseEffect *base = This->base_effect;
3847
3848     TRACE("Forward iface %p, base %p\n", This, base);
3849
3850     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
3851 }
3852
3853 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3854 {
3855     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3856     ID3DXBaseEffect *base = This->base_effect;
3857
3858     TRACE("Forward iface %p, base %p\n", This, base);
3859
3860     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
3861 }
3862
3863 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3864 {
3865     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3866     ID3DXBaseEffect *base = This->base_effect;
3867
3868     TRACE("Forward iface %p, base %p\n", This, base);
3869
3870     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
3871 }
3872
3873 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3874 {
3875     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3876     ID3DXBaseEffect *base = This->base_effect;
3877
3878     TRACE("Forward iface %p, base %p\n", This, base);
3879
3880     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
3881 }
3882
3883 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
3884 {
3885     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3886     ID3DXBaseEffect *base = This->base_effect;
3887
3888     TRACE("Forward iface %p, base %p\n", This, base);
3889
3890     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
3891 }
3892
3893 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR name)
3894 {
3895     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3896     ID3DXBaseEffect *base = This->base_effect;
3897
3898     TRACE("Forward iface %p, base %p\n", This, base);
3899
3900     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
3901 }
3902
3903 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR semantic)
3904 {
3905     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3906     ID3DXBaseEffect *base = This->base_effect;
3907
3908     TRACE("Forward iface %p, base %p\n", This, base);
3909
3910     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
3911 }
3912
3913 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
3914 {
3915     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3916     ID3DXBaseEffect *base = This->base_effect;
3917
3918     TRACE("Forward iface %p, base %p\n", This, base);
3919
3920     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
3921 }
3922
3923 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
3924 {
3925     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3926     ID3DXBaseEffect *base = This->base_effect;
3927
3928     TRACE("Forward iface %p, base %p\n", This, base);
3929
3930     return ID3DXBaseEffectImpl_GetTechnique(base, index);
3931 }
3932
3933 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, LPCSTR name)
3934 {
3935     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3936     ID3DXBaseEffect *base = This->base_effect;
3937
3938     TRACE("Forward iface %p, base %p\n", This, base);
3939
3940     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
3941 }
3942
3943 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
3944 {
3945     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3946     ID3DXBaseEffect *base = This->base_effect;
3947
3948     TRACE("Forward iface %p, base %p\n", This, base);
3949
3950     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
3951 }
3952
3953 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, D3DXHANDLE technique, LPCSTR name)
3954 {
3955     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3956     ID3DXBaseEffect *base = This->base_effect;
3957
3958     TRACE("Forward iface %p, base %p\n", This, base);
3959
3960     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
3961 }
3962
3963 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
3964 {
3965     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3966     ID3DXBaseEffect *base = This->base_effect;
3967
3968     TRACE("Forward iface %p, base %p\n", This, base);
3969
3970     return ID3DXBaseEffectImpl_GetFunction(base, index);
3971 }
3972
3973 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, LPCSTR name)
3974 {
3975     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3976     ID3DXBaseEffect *base = This->base_effect;
3977
3978     TRACE("Forward iface %p, base %p\n", This, base);
3979
3980     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
3981 }
3982
3983 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, D3DXHANDLE object, UINT index)
3984 {
3985     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3986     ID3DXBaseEffect *base = This->base_effect;
3987
3988     TRACE("Forward iface %p, base %p\n", This, base);
3989
3990     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
3991 }
3992
3993 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, D3DXHANDLE object, LPCSTR name)
3994 {
3995     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3996     ID3DXBaseEffect *base = This->base_effect;
3997
3998     TRACE("Forward iface %p, base %p\n", This, base);
3999
4000     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
4001 }
4002
4003 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
4004 {
4005     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4006     ID3DXBaseEffect *base = This->base_effect;
4007
4008     TRACE("Forward iface %p, base %p\n", This, base);
4009
4010     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
4011 }
4012
4013 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
4014 {
4015     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4016     ID3DXBaseEffect *base = This->base_effect;
4017
4018     TRACE("Forward iface %p, base %p\n", This, base);
4019
4020     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
4021 }
4022
4023 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4024 {
4025     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4026     ID3DXBaseEffect *base = This->base_effect;
4027
4028     TRACE("Forward iface %p, base %p\n", This, base);
4029
4030     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
4031 }
4032
4033 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4034 {
4035     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4036     ID3DXBaseEffect *base = This->base_effect;
4037
4038     TRACE("Forward iface %p, base %p\n", This, base);
4039
4040     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
4041 }
4042
4043 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
4044 {
4045     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4046     ID3DXBaseEffect *base = This->base_effect;
4047
4048     TRACE("Forward iface %p, base %p\n", This, base);
4049
4050     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
4051 }
4052
4053 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
4054 {
4055     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4056     ID3DXBaseEffect *base = This->base_effect;
4057
4058     TRACE("Forward iface %p, base %p\n", This, base);
4059
4060     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
4061 }
4062
4063 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4064 {
4065     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4066     ID3DXBaseEffect *base = This->base_effect;
4067
4068     TRACE("Forward iface %p, base %p\n", This, base);
4069
4070     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
4071 }
4072
4073 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4074 {
4075     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4076     ID3DXBaseEffect *base = This->base_effect;
4077
4078     TRACE("Forward iface %p, base %p\n", This, base);
4079
4080     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
4081 }
4082
4083 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
4084 {
4085     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4086     ID3DXBaseEffect *base = This->base_effect;
4087
4088     TRACE("Forward iface %p, base %p\n", This, base);
4089
4090     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
4091 }
4092
4093 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n, UINT count)
4094 {
4095     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4096     ID3DXBaseEffect *base = This->base_effect;
4097
4098     TRACE("Forward iface %p, base %p\n", This, base);
4099
4100     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
4101 }
4102
4103 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT f)
4104 {
4105     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4106     ID3DXBaseEffect *base = This->base_effect;
4107
4108     TRACE("Forward iface %p, base %p\n", This, base);
4109
4110     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
4111 }
4112
4113 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f)
4114 {
4115     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4116     ID3DXBaseEffect *base = This->base_effect;
4117
4118     TRACE("Forward iface %p, base %p\n", This, base);
4119
4120     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
4121 }
4122
4123 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
4124 {
4125     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4126     ID3DXBaseEffect *base = This->base_effect;
4127
4128     TRACE("Forward iface %p, base %p\n", This, base);
4129
4130     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
4131 }
4132
4133 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
4134 {
4135     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4136     ID3DXBaseEffect *base = This->base_effect;
4137
4138     TRACE("Forward iface %p, base %p\n", This, base);
4139
4140     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
4141 }
4142
4143 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
4144 {
4145     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4146     ID3DXBaseEffect *base = This->base_effect;
4147
4148     TRACE("Forward iface %p, base %p\n", This, base);
4149
4150     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
4151 }
4152
4153 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4154 {
4155     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4156     ID3DXBaseEffect *base = This->base_effect;
4157
4158     TRACE("Forward iface %p, base %p\n", This, base);
4159
4160     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
4161 }
4162
4163 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
4164 {
4165     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4166     ID3DXBaseEffect *base = This->base_effect;
4167
4168     TRACE("Forward iface %p, base %p\n", This, base);
4169
4170     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
4171 }
4172
4173 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4174 {
4175     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4176     ID3DXBaseEffect *base = This->base_effect;
4177
4178     TRACE("Forward iface %p, base %p\n", This, base);
4179
4180     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
4181 }
4182
4183 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
4184 {
4185     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4186     ID3DXBaseEffect *base = This->base_effect;
4187
4188     TRACE("Forward iface %p, base %p\n", This, base);
4189
4190     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
4191 }
4192
4193 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
4194 {
4195     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4196     ID3DXBaseEffect *base = This->base_effect;
4197
4198     TRACE("Forward iface %p, base %p\n", This, base);
4199
4200     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
4201 }
4202
4203 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
4204 {
4205     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4206     ID3DXBaseEffect *base = This->base_effect;
4207
4208     TRACE("Forward iface %p, base %p\n", This, base);
4209
4210     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
4211 }
4212
4213 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4214 {
4215     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4216     ID3DXBaseEffect *base = This->base_effect;
4217
4218     TRACE("Forward iface %p, base %p\n", This, base);
4219
4220     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
4221 }
4222
4223 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
4224 {
4225     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4226     ID3DXBaseEffect *base = This->base_effect;
4227
4228     TRACE("Forward iface %p, base %p\n", This, base);
4229
4230     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
4231 }
4232
4233 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4234 {
4235     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4236     ID3DXBaseEffect *base = This->base_effect;
4237
4238     TRACE("Forward iface %p, base %p\n", This, base);
4239
4240     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
4241 }
4242
4243 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
4244 {
4245     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4246     ID3DXBaseEffect *base = This->base_effect;
4247
4248     TRACE("Forward iface %p, base %p\n", This, base);
4249
4250     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
4251 }
4252
4253 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
4254 {
4255     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4256     ID3DXBaseEffect *base = This->base_effect;
4257
4258     TRACE("Forward iface %p, base %p\n", This, base);
4259
4260     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
4261 }
4262
4263 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
4264 {
4265     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4266     ID3DXBaseEffect *base = This->base_effect;
4267
4268     TRACE("Forward iface %p, base %p\n", This, base);
4269
4270     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
4271 }
4272
4273 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4274 {
4275     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4276     ID3DXBaseEffect *base = This->base_effect;
4277
4278     TRACE("Forward iface %p, base %p\n", This, base);
4279
4280     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
4281 }
4282
4283 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
4284 {
4285     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4286     ID3DXBaseEffect *base = This->base_effect;
4287
4288     TRACE("Forward iface %p, base %p\n", This, base);
4289
4290     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
4291 }
4292
4293 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4294 {
4295     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4296     ID3DXBaseEffect *base = This->base_effect;
4297
4298     TRACE("Forward iface %p, base %p\n", This, base);
4299
4300     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
4301 }
4302
4303 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR string)
4304 {
4305     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4306     ID3DXBaseEffect *base = This->base_effect;
4307
4308     TRACE("Forward iface %p, base %p\n", This, base);
4309
4310     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
4311 }
4312
4313 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR *string)
4314 {
4315     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4316     ID3DXBaseEffect *base = This->base_effect;
4317
4318     TRACE("Forward iface %p, base %p\n", This, base);
4319
4320     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
4321 }
4322
4323 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
4324         D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
4325 {
4326     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4327     ID3DXBaseEffect *base = This->base_effect;
4328
4329     TRACE("Forward iface %p, base %p\n", This, base);
4330
4331     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
4332 }
4333
4334 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
4335         D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
4336 {
4337     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4338     ID3DXBaseEffect *base = This->base_effect;
4339
4340     TRACE("Forward iface %p, base %p\n", This, base);
4341
4342     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
4343 }
4344
4345 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
4346         D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
4347 {
4348     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4349     ID3DXBaseEffect *base = This->base_effect;
4350
4351     TRACE("Forward iface %p, base %p\n", This, base);
4352
4353     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, shader);
4354 }
4355
4356 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
4357         D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
4358 {
4359     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4360     ID3DXBaseEffect *base = This->base_effect;
4361
4362     TRACE("Forward iface %p, base %p\n", This, base);
4363
4364     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, shader);
4365 }
4366
4367 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT start, UINT end)
4368 {
4369     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4370     ID3DXBaseEffect *base = This->base_effect;
4371
4372     TRACE("Forward iface %p, base %p\n", This, base);
4373
4374     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
4375 }
4376
4377 /*** ID3DXEffectCompiler methods ***/
4378 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
4379 {
4380     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4381
4382     FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
4383
4384     return E_NOTIMPL;
4385 }
4386
4387 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
4388 {
4389     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4390
4391     FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
4392
4393     return E_NOTIMPL;
4394 }
4395
4396 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
4397         LPD3DXBUFFER *effect, LPD3DXBUFFER *error_msgs)
4398 {
4399     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4400
4401     FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
4402
4403     return E_NOTIMPL;
4404 }
4405
4406 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
4407         LPCSTR target, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *error_msgs, LPD3DXCONSTANTTABLE *constant_table)
4408 {
4409     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4410
4411     FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
4412             This, function, target, flags, shader, error_msgs, constant_table);
4413
4414     return E_NOTIMPL;
4415 }
4416
4417 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
4418 {
4419     /*** IUnknown methods ***/
4420     ID3DXEffectCompilerImpl_QueryInterface,
4421     ID3DXEffectCompilerImpl_AddRef,
4422     ID3DXEffectCompilerImpl_Release,
4423     /*** ID3DXBaseEffect methods ***/
4424     ID3DXEffectCompilerImpl_GetDesc,
4425     ID3DXEffectCompilerImpl_GetParameterDesc,
4426     ID3DXEffectCompilerImpl_GetTechniqueDesc,
4427     ID3DXEffectCompilerImpl_GetPassDesc,
4428     ID3DXEffectCompilerImpl_GetFunctionDesc,
4429     ID3DXEffectCompilerImpl_GetParameter,
4430     ID3DXEffectCompilerImpl_GetParameterByName,
4431     ID3DXEffectCompilerImpl_GetParameterBySemantic,
4432     ID3DXEffectCompilerImpl_GetParameterElement,
4433     ID3DXEffectCompilerImpl_GetTechnique,
4434     ID3DXEffectCompilerImpl_GetTechniqueByName,
4435     ID3DXEffectCompilerImpl_GetPass,
4436     ID3DXEffectCompilerImpl_GetPassByName,
4437     ID3DXEffectCompilerImpl_GetFunction,
4438     ID3DXEffectCompilerImpl_GetFunctionByName,
4439     ID3DXEffectCompilerImpl_GetAnnotation,
4440     ID3DXEffectCompilerImpl_GetAnnotationByName,
4441     ID3DXEffectCompilerImpl_SetValue,
4442     ID3DXEffectCompilerImpl_GetValue,
4443     ID3DXEffectCompilerImpl_SetBool,
4444     ID3DXEffectCompilerImpl_GetBool,
4445     ID3DXEffectCompilerImpl_SetBoolArray,
4446     ID3DXEffectCompilerImpl_GetBoolArray,
4447     ID3DXEffectCompilerImpl_SetInt,
4448     ID3DXEffectCompilerImpl_GetInt,
4449     ID3DXEffectCompilerImpl_SetIntArray,
4450     ID3DXEffectCompilerImpl_GetIntArray,
4451     ID3DXEffectCompilerImpl_SetFloat,
4452     ID3DXEffectCompilerImpl_GetFloat,
4453     ID3DXEffectCompilerImpl_SetFloatArray,
4454     ID3DXEffectCompilerImpl_GetFloatArray,
4455     ID3DXEffectCompilerImpl_SetVector,
4456     ID3DXEffectCompilerImpl_GetVector,
4457     ID3DXEffectCompilerImpl_SetVectorArray,
4458     ID3DXEffectCompilerImpl_GetVectorArray,
4459     ID3DXEffectCompilerImpl_SetMatrix,
4460     ID3DXEffectCompilerImpl_GetMatrix,
4461     ID3DXEffectCompilerImpl_SetMatrixArray,
4462     ID3DXEffectCompilerImpl_GetMatrixArray,
4463     ID3DXEffectCompilerImpl_SetMatrixPointerArray,
4464     ID3DXEffectCompilerImpl_GetMatrixPointerArray,
4465     ID3DXEffectCompilerImpl_SetMatrixTranspose,
4466     ID3DXEffectCompilerImpl_GetMatrixTranspose,
4467     ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
4468     ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
4469     ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
4470     ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
4471     ID3DXEffectCompilerImpl_SetString,
4472     ID3DXEffectCompilerImpl_GetString,
4473     ID3DXEffectCompilerImpl_SetTexture,
4474     ID3DXEffectCompilerImpl_GetTexture,
4475     ID3DXEffectCompilerImpl_GetPixelShader,
4476     ID3DXEffectCompilerImpl_GetVertexShader,
4477     ID3DXEffectCompilerImpl_SetArrayRange,
4478     /*** ID3DXEffectCompiler methods ***/
4479     ID3DXEffectCompilerImpl_SetLiteral,
4480     ID3DXEffectCompilerImpl_GetLiteral,
4481     ID3DXEffectCompilerImpl_CompileEffect,
4482     ID3DXEffectCompilerImpl_CompileShader,
4483 };
4484
4485 static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *data, const char **ptr, D3DXHANDLE *objects)
4486 {
4487     HRESULT hr;
4488     UINT i;
4489     struct d3dx_state *states;
4490
4491     read_dword(ptr, &sampler->state_count);
4492     TRACE("Count: %u\n", sampler->state_count);
4493
4494     states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * sampler->state_count);
4495     if (!states)
4496     {
4497         ERR("Out of memory\n");
4498         return E_OUTOFMEMORY;
4499     }
4500
4501     for (i = 0; i < sampler->state_count; ++i)
4502     {
4503         hr = d3dx9_parse_state(&states[i], data, ptr, objects);
4504         if (hr != D3D_OK)
4505         {
4506             WARN("Failed to parse state\n");
4507             goto err_out;
4508         }
4509     }
4510
4511     sampler->states = states;
4512
4513     return D3D_OK;
4514
4515 err_out:
4516
4517     for (i = 0; i < sampler->state_count; ++i)
4518     {
4519         free_state(&states[i]);
4520     }
4521
4522     HeapFree(GetProcessHeap(), 0, states);
4523
4524     return hr;
4525 }
4526
4527 static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char *data, const char **ptr, D3DXHANDLE *objects)
4528 {
4529     unsigned int i;
4530     HRESULT hr;
4531     UINT old_size = 0;
4532     DWORD id;
4533
4534     if (param->element_count)
4535     {
4536         param->data = value;
4537
4538         for (i = 0; i < param->element_count; ++i)
4539         {
4540             struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
4541
4542             hr = d3dx9_parse_value(member, value ? (char *)value + old_size : NULL, data, ptr, objects);
4543             if (hr != D3D_OK)
4544             {
4545                 WARN("Failed to parse value\n");
4546                 return hr;
4547             }
4548
4549             old_size += member->bytes;
4550         }
4551
4552         return D3D_OK;
4553     }
4554
4555     switch(param->class)
4556     {
4557         case D3DXPC_SCALAR:
4558         case D3DXPC_VECTOR:
4559         case D3DXPC_MATRIX_ROWS:
4560         case D3DXPC_MATRIX_COLUMNS:
4561             param->data = value;
4562             break;
4563
4564         case D3DXPC_STRUCT:
4565             param->data = value;
4566
4567             for (i = 0; i < param->member_count; ++i)
4568             {
4569                 struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
4570
4571                 hr = d3dx9_parse_value(member, (char *)value + old_size, data, ptr, objects);
4572                 if (hr != D3D_OK)
4573                 {
4574                     WARN("Failed to parse value\n");
4575                     return hr;
4576                 }
4577
4578                 old_size += member->bytes;
4579             }
4580             break;
4581
4582         case D3DXPC_OBJECT:
4583             switch (param->type)
4584             {
4585                 case D3DXPT_STRING:
4586                 case D3DXPT_TEXTURE:
4587                 case D3DXPT_TEXTURE1D:
4588                 case D3DXPT_TEXTURE2D:
4589                 case D3DXPT_TEXTURE3D:
4590                 case D3DXPT_TEXTURECUBE:
4591                 case D3DXPT_PIXELSHADER:
4592                 case D3DXPT_VERTEXSHADER:
4593                     read_dword(ptr, &id);
4594                     TRACE("Id: %u\n", id);
4595                     objects[id] = get_parameter_handle(param);
4596                     param->data = value;
4597                     break;
4598
4599                 case D3DXPT_SAMPLER:
4600                 case D3DXPT_SAMPLER1D:
4601                 case D3DXPT_SAMPLER2D:
4602                 case D3DXPT_SAMPLER3D:
4603                 case D3DXPT_SAMPLERCUBE:
4604                 {
4605                     struct d3dx_sampler *sampler;
4606
4607                     sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
4608                     if (!sampler)
4609                     {
4610                         ERR("Out of memory\n");
4611                         return E_OUTOFMEMORY;
4612                     }
4613
4614                     hr = d3dx9_parse_sampler(sampler, data, ptr, objects);
4615                     if (hr != D3D_OK)
4616                     {
4617                         HeapFree(GetProcessHeap(), 0, sampler);
4618                         WARN("Failed to parse sampler\n");
4619                         return hr;
4620                     }
4621
4622                     param->data = sampler;
4623                     break;
4624                 }
4625
4626                 default:
4627                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4628                     break;
4629             }
4630             break;
4631
4632         default:
4633             FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4634             break;
4635     }
4636
4637     return D3D_OK;
4638 }
4639
4640 static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *data, const char *ptr, D3DXHANDLE *objects)
4641 {
4642     UINT size = param->bytes;
4643     HRESULT hr;
4644     void *value = NULL;
4645
4646     TRACE("param size: %u\n", size);
4647
4648     if (size)
4649     {
4650         value = HeapAlloc(GetProcessHeap(), 0, size);
4651         if (!value)
4652         {
4653             ERR("Failed to allocate data memory.\n");
4654             return E_OUTOFMEMORY;
4655         }
4656
4657         TRACE("Data: %s.\n", debugstr_an(ptr, size));
4658         memcpy(value, ptr, size);
4659     }
4660
4661     hr = d3dx9_parse_value(param, value, data, &ptr, objects);
4662     if (hr != D3D_OK)
4663     {
4664         WARN("Failed to parse value\n");
4665         HeapFree(GetProcessHeap(), 0, value);
4666         return hr;
4667     }
4668
4669     return D3D_OK;
4670 }
4671
4672 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
4673 {
4674     DWORD size;
4675
4676     read_dword(&ptr, &size);
4677     TRACE("Name size: %#x\n", size);
4678
4679     if (!size)
4680     {
4681         return D3D_OK;
4682     }
4683
4684     *name = HeapAlloc(GetProcessHeap(), 0, size);
4685     if (!*name)
4686     {
4687         ERR("Failed to allocate name memory.\n");
4688         return E_OUTOFMEMORY;
4689     }
4690
4691     TRACE("Name: %s.\n", debugstr_an(ptr, size));
4692     memcpy(*name, ptr, size);
4693
4694     return D3D_OK;
4695 }
4696
4697 static HRESULT d3dx9_copy_data(char **str, const char **ptr)
4698 {
4699     DWORD size;
4700
4701     read_dword(ptr, &size);
4702     TRACE("Data size: %#x\n", size);
4703
4704     *str = HeapAlloc(GetProcessHeap(), 0, size);
4705     if (!*str)
4706     {
4707         ERR("Failed to allocate name memory.\n");
4708         return E_OUTOFMEMORY;
4709     }
4710
4711     TRACE("Data: %s.\n", debugstr_an(*ptr, size));
4712     memcpy(*str, *ptr, size);
4713
4714     *ptr += ((size + 3) & ~3);
4715
4716     return D3D_OK;
4717 }
4718
4719 static HRESULT d3dx9_parse_data(struct d3dx_parameter *param, const char **ptr, LPDIRECT3DDEVICE9 device)
4720 {
4721     DWORD size;
4722     HRESULT hr;
4723
4724     TRACE("Parse data for parameter %s, type %s\n", debugstr_a(param->name), debug_d3dxparameter_type(param->type));
4725
4726     read_dword(ptr, &size);
4727     TRACE("Data size: %#x\n", size);
4728
4729     if (!size)
4730     {
4731         TRACE("Size is 0\n");
4732         *(void **)param->data = NULL;
4733         return D3D_OK;
4734     }
4735
4736     switch (param->type)
4737     {
4738         case D3DXPT_STRING:
4739             /* re-read with size (sizeof(DWORD) = 4) */
4740             hr = d3dx9_parse_name((LPSTR *)param->data, *ptr - 4);
4741             if (hr != D3D_OK)
4742             {
4743                 WARN("Failed to parse string data\n");
4744                 return hr;
4745             }
4746             break;
4747
4748         case D3DXPT_VERTEXSHADER:
4749             if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, (DWORD *)*ptr, param->data)))
4750             {
4751                 WARN("Failed to create vertex shader\n");
4752                 return hr;
4753             }
4754             break;
4755
4756         case D3DXPT_PIXELSHADER:
4757             if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, (DWORD *)*ptr, param->data)))
4758             {
4759                 WARN("Failed to create pixel shader\n");
4760                 return hr;
4761             }
4762             break;
4763
4764         default:
4765             FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4766             break;
4767     }
4768
4769
4770     *ptr += ((size + 3) & ~3);
4771
4772     return D3D_OK;
4773 }
4774
4775 static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
4776         struct d3dx_parameter *parent, UINT flags)
4777 {
4778     DWORD offset;
4779     HRESULT hr;
4780     D3DXHANDLE *member_handles = NULL;
4781     UINT i;
4782
4783     param->flags = flags;
4784
4785     if (!parent)
4786     {
4787         read_dword(ptr, &param->type);
4788         TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
4789
4790         read_dword(ptr, &param->class);
4791         TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
4792
4793         read_dword(ptr, &offset);
4794         TRACE("Type name offset: %#x\n", offset);
4795         hr = d3dx9_parse_name(&param->name, data + offset);
4796         if (hr != D3D_OK)
4797         {
4798             WARN("Failed to parse name\n");
4799             goto err_out;
4800         }
4801
4802         read_dword(ptr, &offset);
4803         TRACE("Type semantic offset: %#x\n", offset);
4804         hr = d3dx9_parse_name(&param->semantic, data + offset);
4805         if (hr != D3D_OK)
4806         {
4807             WARN("Failed to parse semantic\n");
4808             goto err_out;
4809         }
4810
4811         read_dword(ptr, &param->element_count);
4812         TRACE("Elements: %u\n", param->element_count);
4813
4814         switch (param->class)
4815         {
4816             case D3DXPC_VECTOR:
4817                 read_dword(ptr, &param->columns);
4818                 TRACE("Columns: %u\n", param->columns);
4819
4820                 read_dword(ptr, &param->rows);
4821                 TRACE("Rows: %u\n", param->rows);
4822
4823                 /* sizeof(DWORD) * rows * columns */
4824                 param->bytes = 4 * param->rows * param->columns;
4825                 break;
4826
4827             case D3DXPC_SCALAR:
4828             case D3DXPC_MATRIX_ROWS:
4829             case D3DXPC_MATRIX_COLUMNS:
4830                 read_dword(ptr, &param->rows);
4831                 TRACE("Rows: %u\n", param->rows);
4832
4833                 read_dword(ptr, &param->columns);
4834                 TRACE("Columns: %u\n", param->columns);
4835
4836                 /* sizeof(DWORD) * rows * columns */
4837                 param->bytes = 4 * param->rows * param->columns;
4838                 break;
4839
4840             case D3DXPC_STRUCT:
4841                 read_dword(ptr, &param->member_count);
4842                 TRACE("Members: %u\n", param->member_count);
4843                 break;
4844
4845             case D3DXPC_OBJECT:
4846                 switch (param->type)
4847                 {
4848                     case D3DXPT_STRING:
4849                     case D3DXPT_PIXELSHADER:
4850                     case D3DXPT_VERTEXSHADER:
4851                     case D3DXPT_TEXTURE:
4852                     case D3DXPT_TEXTURE1D:
4853                     case D3DXPT_TEXTURE2D:
4854                     case D3DXPT_TEXTURE3D:
4855                     case D3DXPT_TEXTURECUBE:
4856                         param->bytes = sizeof(void *);
4857                         break;
4858
4859                     case D3DXPT_SAMPLER:
4860                     case D3DXPT_SAMPLER1D:
4861                     case D3DXPT_SAMPLER2D:
4862                     case D3DXPT_SAMPLER3D:
4863                     case D3DXPT_SAMPLERCUBE:
4864                         param->bytes = 0;
4865                         break;
4866
4867                     default:
4868                         FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4869                         break;
4870                 }
4871                 break;
4872
4873             default:
4874                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4875                 break;
4876         }
4877     }
4878     else
4879     {
4880         /* elements */
4881         param->type = parent->type;
4882         param->class = parent->class;
4883         param->name = parent->name;
4884         param->semantic = parent->semantic;
4885         param->element_count = 0;
4886         param->annotation_count = 0;
4887         param->member_count = parent->member_count;
4888         param->bytes = parent->bytes;
4889         param->rows = parent->rows;
4890         param->columns = parent->columns;
4891     }
4892
4893     if (param->element_count)
4894     {
4895         unsigned int param_bytes = 0;
4896         const char *save_ptr = *ptr;
4897
4898         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->element_count);
4899         if (!member_handles)
4900         {
4901             ERR("Out of memory\n");
4902             hr = E_OUTOFMEMORY;
4903             goto err_out;
4904         }
4905
4906         for (i = 0; i < param->element_count; ++i)
4907         {
4908             struct d3dx_parameter *member;
4909             *ptr = save_ptr;
4910
4911             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4912             if (!member)
4913             {
4914                 ERR("Out of memory\n");
4915                 hr = E_OUTOFMEMORY;
4916                 goto err_out;
4917             }
4918
4919             member_handles[i] = get_parameter_handle(member);
4920
4921             hr = d3dx9_parse_effect_typedef(member, data, ptr, param, flags);
4922             if (hr != D3D_OK)
4923             {
4924                 WARN("Failed to parse member\n");
4925                 goto err_out;
4926             }
4927
4928             param_bytes += member->bytes;
4929         }
4930
4931         param->bytes = param_bytes;
4932     }
4933     else if (param->member_count)
4934     {
4935         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->member_count);
4936         if (!member_handles)
4937         {
4938             ERR("Out of memory\n");
4939             hr = E_OUTOFMEMORY;
4940             goto err_out;
4941         }
4942
4943         for (i = 0; i < param->member_count; ++i)
4944         {
4945             struct d3dx_parameter *member;
4946
4947             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4948             if (!member)
4949             {
4950                 ERR("Out of memory\n");
4951                 hr = E_OUTOFMEMORY;
4952                 goto err_out;
4953             }
4954
4955             member_handles[i] = get_parameter_handle(member);
4956
4957             hr = d3dx9_parse_effect_typedef(member, data, ptr, NULL, flags);
4958             if (hr != D3D_OK)
4959             {
4960                 WARN("Failed to parse member\n");
4961                 goto err_out;
4962             }
4963
4964             param->bytes += member->bytes;
4965         }
4966     }
4967
4968     param->member_handles = member_handles;
4969
4970     return D3D_OK;
4971
4972 err_out:
4973
4974     if (member_handles)
4975     {
4976         unsigned int count;
4977
4978         if (param->element_count) count = param->element_count;
4979         else count = param->member_count;
4980
4981         for (i = 0; i < count; ++i)
4982         {
4983             free_parameter(member_handles[i], param->element_count != 0, TRUE);
4984         }
4985         HeapFree(GetProcessHeap(), 0, member_handles);
4986     }
4987
4988     if (!parent)
4989     {
4990         HeapFree(GetProcessHeap(), 0, param->name);
4991         HeapFree(GetProcessHeap(), 0, param->semantic);
4992     }
4993     param->name = NULL;
4994     param->semantic = NULL;
4995
4996     return hr;
4997 }
4998
4999 static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data, const char **ptr, D3DXHANDLE *objects)
5000 {
5001     DWORD offset;
5002     const char *ptr2;
5003     HRESULT hr;
5004
5005     anno->flags = D3DX_PARAMETER_ANNOTATION;
5006
5007     read_dword(ptr, &offset);
5008     TRACE("Typedef offset: %#x\n", offset);
5009     ptr2 = data + offset;
5010     hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5011     if (hr != D3D_OK)
5012     {
5013         WARN("Failed to parse type definition\n");
5014         return hr;
5015     }
5016
5017     read_dword(ptr, &offset);
5018     TRACE("Value offset: %#x\n", offset);
5019     hr = d3dx9_parse_init_value(anno, data, data + offset, objects);
5020     if (hr != D3D_OK)
5021     {
5022         WARN("Failed to parse value\n");
5023         return hr;
5024     }
5025
5026     return D3D_OK;
5027 }
5028
5029 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects)
5030 {
5031     DWORD offset;
5032     const char *ptr2;
5033     HRESULT hr;
5034     struct d3dx_parameter *parameter;
5035
5036     parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
5037     if (!parameter)
5038     {
5039         ERR("Out of memory\n");
5040         return E_OUTOFMEMORY;
5041     }
5042
5043     state->type = ST_CONSTANT;
5044
5045     read_dword(ptr, &state->operation);
5046     TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5047
5048     read_dword(ptr, &state->index);
5049     TRACE("Index: %#x\n", state->index);
5050
5051     read_dword(ptr, &offset);
5052     TRACE("Typedef offset: %#x\n", offset);
5053     ptr2 = data + offset;
5054     hr = d3dx9_parse_effect_typedef(parameter, data, &ptr2, NULL, 0);
5055     if (hr != D3D_OK)
5056     {
5057         WARN("Failed to parse type definition\n");
5058         goto err_out;
5059     }
5060
5061     read_dword(ptr, &offset);
5062     TRACE("Value offset: %#x\n", offset);
5063     hr = d3dx9_parse_init_value(parameter, data, data + offset, objects);
5064     if (hr != D3D_OK)
5065     {
5066         WARN("Failed to parse value\n");
5067         goto err_out;
5068     }
5069
5070     state->parameter = get_parameter_handle(parameter);
5071
5072     return D3D_OK;
5073
5074 err_out:
5075
5076     free_parameter(get_parameter_handle(parameter), FALSE, FALSE);
5077
5078     return hr;
5079 }
5080
5081 static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data, const char **ptr, D3DXHANDLE *objects)
5082 {
5083     DWORD offset;
5084     HRESULT hr;
5085     unsigned int i;
5086     D3DXHANDLE *annotation_handles = NULL;
5087     const char *ptr2;
5088
5089     read_dword(ptr, &offset);
5090     TRACE("Typedef offset: %#x\n", offset);
5091     ptr2 = data + offset;
5092
5093     read_dword(ptr, &offset);
5094     TRACE("Value offset: %#x\n", offset);
5095
5096     read_dword(ptr, &param->flags);
5097     TRACE("Flags: %#x\n", param->flags);
5098
5099     read_dword(ptr, &param->annotation_count);
5100     TRACE("Annotation count: %u\n", param->annotation_count);
5101
5102     hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
5103     if (hr != D3D_OK)
5104     {
5105         WARN("Failed to parse type definition\n");
5106         return hr;
5107     }
5108
5109     hr = d3dx9_parse_init_value(param, data, data + offset, objects);
5110     if (hr != D3D_OK)
5111     {
5112         WARN("Failed to parse value\n");
5113         return hr;
5114     }
5115
5116     if (param->annotation_count)
5117     {
5118         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * param->annotation_count);
5119         if (!annotation_handles)
5120         {
5121             ERR("Out of memory\n");
5122             hr = E_OUTOFMEMORY;
5123             goto err_out;
5124         }
5125
5126         for (i = 0; i < param->annotation_count; ++i)
5127         {
5128             struct d3dx_parameter *annotation;
5129
5130             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
5131             if (!annotation)
5132             {
5133                 ERR("Out of memory\n");
5134                 hr = E_OUTOFMEMORY;
5135                 goto err_out;
5136             }
5137
5138             annotation_handles[i] = get_parameter_handle(annotation);
5139
5140             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
5141             if (hr != D3D_OK)
5142             {
5143                 WARN("Failed to parse annotation\n");
5144                 goto err_out;
5145             }
5146         }
5147     }
5148
5149     param->annotation_handles = annotation_handles;
5150
5151     return D3D_OK;
5152
5153 err_out:
5154
5155     if (annotation_handles)
5156     {
5157         for (i = 0; i < param->annotation_count; ++i)
5158         {
5159             free_parameter(annotation_handles[i], FALSE, FALSE);
5160         }
5161         HeapFree(GetProcessHeap(), 0, annotation_handles);
5162     }
5163
5164     return hr;
5165 }
5166
5167 static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr, D3DXHANDLE *objects)
5168 {
5169     DWORD offset;
5170     HRESULT hr;
5171     unsigned int i;
5172     D3DXHANDLE *annotation_handles = NULL;
5173     struct d3dx_state *states = NULL;
5174     char *name = NULL;
5175
5176     read_dword(ptr, &offset);
5177     TRACE("Pass name offset: %#x\n", offset);
5178     hr = d3dx9_parse_name(&name, data + offset);
5179     if (hr != D3D_OK)
5180     {
5181         WARN("Failed to parse name\n");
5182         goto err_out;
5183     }
5184
5185     read_dword(ptr, &pass->annotation_count);
5186     TRACE("Annotation count: %u\n", pass->annotation_count);
5187
5188     read_dword(ptr, &pass->state_count);
5189     TRACE("State count: %u\n", pass->state_count);
5190
5191     if (pass->annotation_count)
5192     {
5193         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count);
5194         if (!annotation_handles)
5195         {
5196             ERR("Out of memory\n");
5197             hr = E_OUTOFMEMORY;
5198             goto err_out;
5199         }
5200
5201         for (i = 0; i < pass->annotation_count; ++i)
5202         {
5203             struct d3dx_parameter *annotation;
5204
5205             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
5206             if (!annotation)
5207             {
5208                 ERR("Out of memory\n");
5209                 hr = E_OUTOFMEMORY;
5210                 goto err_out;
5211             }
5212
5213             annotation_handles[i] = get_parameter_handle(annotation);
5214
5215             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
5216             if (hr != D3D_OK)
5217             {
5218                 WARN("Failed to parse annotations\n");
5219                 goto err_out;
5220             }
5221         }
5222     }
5223
5224     if (pass->state_count)
5225     {
5226         states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5227         if (!states)
5228         {
5229             ERR("Out of memory\n");
5230             hr = E_OUTOFMEMORY;
5231             goto err_out;
5232         }
5233
5234         for (i = 0; i < pass->state_count; ++i)
5235         {
5236             hr = d3dx9_parse_state(&states[i], data, ptr, objects);
5237             if (hr != D3D_OK)
5238             {
5239                 WARN("Failed to parse annotations\n");
5240                 goto err_out;
5241             }
5242         }
5243     }
5244
5245     pass->name = name;
5246     pass->annotation_handles = annotation_handles;
5247     pass->states = states;
5248
5249     return D3D_OK;
5250
5251 err_out:
5252
5253     if (annotation_handles)
5254     {
5255         for (i = 0; i < pass->annotation_count; ++i)
5256         {
5257             free_parameter(annotation_handles[i], FALSE, FALSE);
5258         }
5259         HeapFree(GetProcessHeap(), 0, annotation_handles);
5260     }
5261
5262     if (states)
5263     {
5264         for (i = 0; i < pass->state_count; ++i)
5265         {
5266             free_state(&states[i]);
5267         }
5268         HeapFree(GetProcessHeap(), 0, states);
5269     }
5270
5271     HeapFree(GetProcessHeap(), 0, name);
5272
5273     return hr;
5274 }
5275
5276 static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr, D3DXHANDLE *objects)
5277 {
5278     DWORD offset;
5279     HRESULT hr;
5280     unsigned int i;
5281     D3DXHANDLE *annotation_handles = NULL;
5282     D3DXHANDLE *pass_handles = NULL;
5283     char *name = NULL;
5284
5285     read_dword(ptr, &offset);
5286     TRACE("Technique name offset: %#x\n", offset);
5287     hr = d3dx9_parse_name(&name, data + offset);
5288     if (hr != D3D_OK)
5289     {
5290         WARN("Failed to parse name\n");
5291         goto err_out;
5292     }
5293
5294     read_dword(ptr, &technique->annotation_count);
5295     TRACE("Annotation count: %u\n", technique->annotation_count);
5296
5297     read_dword(ptr, &technique->pass_count);
5298     TRACE("Pass count: %u\n", technique->pass_count);
5299
5300     if (technique->annotation_count)
5301     {
5302         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count);
5303         if (!annotation_handles)
5304         {
5305             ERR("Out of memory\n");
5306             hr = E_OUTOFMEMORY;
5307             goto err_out;
5308         }
5309
5310         for (i = 0; i < technique->annotation_count; ++i)
5311         {
5312             struct d3dx_parameter *annotation;
5313
5314             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
5315             if (!annotation)
5316             {
5317                 ERR("Out of memory\n");
5318                 hr = E_OUTOFMEMORY;
5319                 goto err_out;
5320             }
5321
5322             annotation_handles[i] = get_parameter_handle(annotation);
5323
5324             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
5325             if (hr != D3D_OK)
5326             {
5327                 WARN("Failed to parse annotations\n");
5328                 goto err_out;
5329             }
5330         }
5331     }
5332
5333     if (technique->pass_count)
5334     {
5335         pass_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count);
5336         if (!pass_handles)
5337         {
5338             ERR("Out of memory\n");
5339             hr = E_OUTOFMEMORY;
5340             goto err_out;
5341         }
5342
5343         for (i = 0; i < technique->pass_count; ++i)
5344         {
5345             struct d3dx_pass *pass;
5346
5347             pass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass));
5348             if (!pass)
5349             {
5350                 ERR("Out of memory\n");
5351                 hr = E_OUTOFMEMORY;
5352                 goto err_out;
5353             }
5354
5355             pass_handles[i] = get_pass_handle(pass);
5356
5357             hr = d3dx9_parse_effect_pass(pass, data, ptr, objects);
5358             if (hr != D3D_OK)
5359             {
5360                 WARN("Failed to parse passes\n");
5361                 goto err_out;
5362             }
5363         }
5364     }
5365
5366     technique->name = name;
5367     technique->pass_handles = pass_handles;
5368     technique->annotation_handles = annotation_handles;
5369
5370     return D3D_OK;
5371
5372 err_out:
5373
5374     if (pass_handles)
5375     {
5376         for (i = 0; i < technique->pass_count; ++i)
5377         {
5378             free_pass(pass_handles[i]);
5379         }
5380         HeapFree(GetProcessHeap(), 0, pass_handles);
5381     }
5382
5383     if (annotation_handles)
5384     {
5385         for (i = 0; i < technique->annotation_count; ++i)
5386         {
5387             free_parameter(annotation_handles[i], FALSE, FALSE);
5388         }
5389         HeapFree(GetProcessHeap(), 0, annotation_handles);
5390     }
5391
5392     HeapFree(GetProcessHeap(), 0, name);
5393
5394     return hr;
5395 }
5396
5397 static HRESULT d3dx9_parse_resource(struct ID3DXBaseEffectImpl *base, const char *data, const char **ptr)
5398 {
5399     DWORD technique_index;
5400     DWORD index, state_index, usage, element_index;
5401     struct d3dx_state *state;
5402     struct d3dx_parameter *param;
5403     HRESULT hr = E_FAIL;
5404
5405     read_dword(ptr, &technique_index);
5406     TRACE("techn: %u\n", technique_index);
5407
5408     read_dword(ptr, &index);
5409     TRACE("index: %u\n", index);
5410
5411     read_dword(ptr, &element_index);
5412     TRACE("element_index: %u\n", element_index);
5413
5414     read_dword(ptr, &state_index);
5415     TRACE("state_index: %u\n", state_index);
5416
5417     read_dword(ptr, &usage);
5418     TRACE("usage: %u\n", usage);
5419
5420     if (technique_index == 0xffffffff)
5421     {
5422         struct d3dx_parameter *parameter;
5423         struct d3dx_sampler *sampler;
5424
5425         if (index >= base->parameter_count)
5426         {
5427             FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
5428             return E_FAIL;
5429         }
5430
5431         parameter = get_parameter_struct(base->parameter_handles[index]);
5432         if (element_index != 0xffffffff)
5433         {
5434             if (element_index >= parameter->element_count && parameter->element_count != 0)
5435             {
5436                 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
5437                 return E_FAIL;
5438             }
5439
5440             if (parameter->element_count != 0) parameter = get_parameter_struct(parameter->member_handles[element_index]);
5441         }
5442
5443         sampler = parameter->data;
5444         if (state_index >= sampler->state_count)
5445         {
5446             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
5447             return E_FAIL;
5448         }
5449
5450         state = &sampler->states[state_index];
5451     }
5452     else
5453     {
5454         struct d3dx_technique *technique;
5455         struct d3dx_pass *pass;
5456
5457         if (technique_index >= base->technique_count)
5458         {
5459             FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
5460             return E_FAIL;
5461         }
5462
5463         technique = get_technique_struct(base->technique_handles[technique_index]);
5464         if (index >= technique->pass_count)
5465         {
5466             FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
5467             return E_FAIL;
5468         }
5469
5470         pass = get_pass_struct(technique->pass_handles[index]);
5471         if (state_index >= pass->state_count)
5472         {
5473             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
5474             return E_FAIL;
5475         }
5476
5477         state = &pass->states[state_index];
5478     }
5479
5480     param = get_parameter_struct(state->parameter);
5481
5482     switch (usage)
5483     {
5484         case 0:
5485             TRACE("usage 0: type %s\n", debug_d3dxparameter_type(param->type));
5486             switch (param->type)
5487             {
5488                 case D3DXPT_VERTEXSHADER:
5489                 case D3DXPT_PIXELSHADER:
5490                     state->type = ST_CONSTANT;
5491                     hr = d3dx9_parse_data(param, ptr, base->effect->device);
5492                     break;
5493
5494                 case D3DXPT_BOOL:
5495                 case D3DXPT_INT:
5496                 case D3DXPT_FLOAT:
5497                 case D3DXPT_STRING:
5498                     state->type = ST_FXLC;
5499                     hr = d3dx9_copy_data(param->data, ptr);
5500                     break;
5501
5502                 default:
5503                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5504                     break;
5505             }
5506             break;
5507
5508         case 1:
5509             state->type = ST_PARAMETER;
5510             hr = d3dx9_copy_data(param->data, ptr);
5511             if (hr == D3D_OK)
5512             {
5513                 TRACE("Mapping to parameter %s\n", *(char **)param->data);
5514             }
5515             break;
5516
5517         default:
5518             FIXME("Unknown usage %x\n", usage);
5519             break;
5520     }
5521
5522     return hr;
5523 }
5524
5525 static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start)
5526 {
5527     const char *ptr = data + start;
5528     D3DXHANDLE *parameter_handles = NULL;
5529     D3DXHANDLE *technique_handles = NULL;
5530     D3DXHANDLE *objects = NULL;
5531     UINT stringcount, objectcount, resourcecount;
5532     HRESULT hr;
5533     UINT i;
5534
5535     read_dword(&ptr, &base->parameter_count);
5536     TRACE("Parameter count: %u\n", base->parameter_count);
5537
5538     read_dword(&ptr, &base->technique_count);
5539     TRACE("Technique count: %u\n", base->technique_count);
5540
5541     skip_dword_unknown(&ptr, 1);
5542
5543     read_dword(&ptr, &objectcount);
5544     TRACE("Object count: %u\n", objectcount);
5545
5546     objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*objects) * objectcount);
5547     if (!objects)
5548     {
5549         ERR("Out of memory\n");
5550         hr = E_OUTOFMEMORY;
5551         goto err_out;
5552     }
5553
5554     if (base->parameter_count)
5555     {
5556         parameter_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter_handles) * base->parameter_count);
5557         if (!parameter_handles)
5558         {
5559             ERR("Out of memory\n");
5560             hr = E_OUTOFMEMORY;
5561             goto err_out;
5562         }
5563
5564         for (i = 0; i < base->parameter_count; ++i)
5565         {
5566             struct d3dx_parameter *parameter;
5567
5568             parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
5569             if (!parameter)
5570             {
5571                 ERR("Out of memory\n");
5572                 hr = E_OUTOFMEMORY;
5573                 goto err_out;
5574             }
5575
5576             parameter_handles[i] = get_parameter_handle(parameter);
5577
5578             hr = d3dx9_parse_effect_parameter(parameter, data, &ptr, objects);
5579             if (hr != D3D_OK)
5580             {
5581                 WARN("Failed to parse parameter\n");
5582                 goto err_out;
5583             }
5584         }
5585     }
5586
5587     if (base->technique_count)
5588     {
5589         technique_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count);
5590         if (!technique_handles)
5591         {
5592             ERR("Out of memory\n");
5593             hr = E_OUTOFMEMORY;
5594             goto err_out;
5595         }
5596
5597         for (i = 0; i < base->technique_count; ++i)
5598         {
5599             struct d3dx_technique *technique;
5600
5601             technique = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique));
5602             if (!technique)
5603             {
5604                 ERR("Out of memory\n");
5605                 hr = E_OUTOFMEMORY;
5606                 goto err_out;
5607             }
5608
5609             technique_handles[i] = get_technique_handle(technique);
5610
5611             hr = d3dx9_parse_effect_technique(technique, data, &ptr, objects);
5612             if (hr != D3D_OK)
5613             {
5614                 WARN("Failed to parse technique\n");
5615                 goto err_out;
5616             }
5617         }
5618     }
5619
5620     /* needed for further parsing */
5621     base->technique_handles = technique_handles;
5622     base->parameter_handles = parameter_handles;
5623
5624     read_dword(&ptr, &stringcount);
5625     TRACE("String count: %u\n", stringcount);
5626
5627     read_dword(&ptr, &resourcecount);
5628     TRACE("Resource count: %u\n", resourcecount);
5629
5630     for (i = 0; i < stringcount; ++i)
5631     {
5632         DWORD id;
5633         struct d3dx_parameter *param;
5634
5635         read_dword(&ptr, &id);
5636         TRACE("Id: %u\n", id);
5637
5638         param = get_parameter_struct(objects[id]);
5639
5640         hr = d3dx9_parse_data(param, &ptr, base->effect->device);
5641         if (hr != D3D_OK)
5642         {
5643             WARN("Failed to parse data\n");
5644             goto err_out;
5645         }
5646     }
5647
5648     for (i = 0; i < resourcecount; ++i)
5649     {
5650         TRACE("parse resource %u\n", i);
5651
5652         hr = d3dx9_parse_resource(base, data, &ptr);
5653         if (hr != D3D_OK)
5654         {
5655             WARN("Failed to parse data\n");
5656             goto err_out;
5657         }
5658     }
5659
5660     HeapFree(GetProcessHeap(), 0, objects);
5661
5662     return D3D_OK;
5663
5664 err_out:
5665
5666     if (technique_handles)
5667     {
5668         for (i = 0; i < base->technique_count; ++i)
5669         {
5670             free_technique(technique_handles[i]);
5671         }
5672         HeapFree(GetProcessHeap(), 0, technique_handles);
5673     }
5674
5675     if (parameter_handles)
5676     {
5677         for (i = 0; i < base->parameter_count; ++i)
5678         {
5679             free_parameter(parameter_handles[i], FALSE, FALSE);
5680         }
5681         HeapFree(GetProcessHeap(), 0, parameter_handles);
5682     }
5683
5684     base->technique_handles = NULL;
5685     base->parameter_handles = NULL;
5686
5687     HeapFree(GetProcessHeap(), 0, objects);
5688
5689     return hr;
5690 }
5691
5692 static HRESULT d3dx9_base_effect_init(struct ID3DXBaseEffectImpl *base,
5693         const char *data, SIZE_T data_size, struct ID3DXEffectImpl *effect)
5694 {
5695     DWORD tag, offset;
5696     const char *ptr = data;
5697     HRESULT hr;
5698
5699     TRACE("base %p, data %p, data_size %lu, effect %p\n", base, data, data_size, effect);
5700
5701     base->ID3DXBaseEffect_iface.lpVtbl = &ID3DXBaseEffect_Vtbl;
5702     base->ref = 1;
5703     base->effect = effect;
5704
5705     read_dword(&ptr, &tag);
5706     TRACE("Tag: %x\n", tag);
5707
5708     if (tag != d3dx9_effect_version(9, 1))
5709     {
5710         /* todo: compile hlsl ascii code */
5711         FIXME("HLSL ascii effects not supported, yet\n");
5712
5713         /* Show the start of the shader for debugging info. */
5714         TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
5715     }
5716     else
5717     {
5718         read_dword(&ptr, &offset);
5719         TRACE("Offset: %x\n", offset);
5720
5721         hr = d3dx9_parse_effect(base, ptr, data_size, offset);
5722         if (hr != D3D_OK)
5723         {
5724             FIXME("Failed to parse effect.\n");
5725             return hr;
5726         }
5727     }
5728
5729     return D3D_OK;
5730 }
5731
5732 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
5733         const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
5734 {
5735     HRESULT hr;
5736     struct ID3DXBaseEffectImpl *object = NULL;
5737
5738     TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
5739
5740     effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
5741     effect->ref = 1;
5742
5743     if (pool) pool->lpVtbl->AddRef(pool);
5744     effect->pool = pool;
5745
5746     IDirect3DDevice9_AddRef(device);
5747     effect->device = device;
5748
5749     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5750     if (!object)
5751     {
5752         ERR("Out of memory\n");
5753         hr = E_OUTOFMEMORY;
5754         goto err_out;
5755     }
5756
5757     hr = d3dx9_base_effect_init(object, data, data_size, effect);
5758     if (hr != D3D_OK)
5759     {
5760         FIXME("Failed to parse effect.\n");
5761         goto err_out;
5762     }
5763
5764     effect->base_effect = &object->ID3DXBaseEffect_iface;
5765
5766     /* initialize defaults - check because of unsupported ascii effects */
5767     if (object->technique_handles)
5768     {
5769         effect->active_technique = object->technique_handles[0];
5770         effect->active_pass = NULL;
5771     }
5772
5773     return D3D_OK;
5774
5775 err_out:
5776
5777     HeapFree(GetProcessHeap(), 0, object);
5778     free_effect(effect);
5779
5780     return hr;
5781 }
5782
5783 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
5784                                   LPCVOID srcdata,
5785                                   UINT srcdatalen,
5786                                   CONST D3DXMACRO* defines,
5787                                   LPD3DXINCLUDE include,
5788                                   LPCSTR skip_constants,
5789                                   DWORD flags,
5790                                   LPD3DXEFFECTPOOL pool,
5791                                   LPD3DXEFFECT* effect,
5792                                   LPD3DXBUFFER* compilation_errors)
5793 {
5794     struct ID3DXEffectImpl *object;
5795     HRESULT hr;
5796
5797     FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
5798         skip_constants, flags, pool, effect, compilation_errors);
5799
5800     if (!device || !srcdata)
5801         return D3DERR_INVALIDCALL;
5802
5803     if (!srcdatalen)
5804         return E_FAIL;
5805
5806     /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
5807     if (!effect)
5808         return D3D_OK;
5809
5810     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5811     if (!object)
5812     {
5813         ERR("Out of memory\n");
5814         return E_OUTOFMEMORY;
5815     }
5816
5817     hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, pool);
5818     if (FAILED(hr))
5819     {
5820         WARN("Failed to initialize shader reflection\n");
5821         HeapFree(GetProcessHeap(), 0, object);
5822         return hr;
5823     }
5824
5825     *effect = &object->ID3DXEffect_iface;
5826
5827     TRACE("Created ID3DXEffect %p\n", object);
5828
5829     return D3D_OK;
5830 }
5831
5832 HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
5833                                 LPCVOID srcdata,
5834                                 UINT srcdatalen,
5835                                 CONST D3DXMACRO* defines,
5836                                 LPD3DXINCLUDE include,
5837                                 DWORD flags,
5838                                 LPD3DXEFFECTPOOL pool,
5839                                 LPD3DXEFFECT* effect,
5840                                 LPD3DXBUFFER* compilation_errors)
5841 {
5842     TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
5843         include, flags, pool, effect, compilation_errors);
5844
5845     return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
5846 }
5847
5848 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, const char *data, SIZE_T data_size)
5849 {
5850     HRESULT hr;
5851     struct ID3DXBaseEffectImpl *object = NULL;
5852
5853     TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
5854
5855     compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
5856     compiler->ref = 1;
5857
5858     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5859     if (!object)
5860     {
5861         ERR("Out of memory\n");
5862         hr = E_OUTOFMEMORY;
5863         goto err_out;
5864     }
5865
5866     hr = d3dx9_base_effect_init(object, data, data_size, NULL);
5867     if (hr != D3D_OK)
5868     {
5869         FIXME("Failed to parse effect.\n");
5870         goto err_out;
5871     }
5872
5873     compiler->base_effect = &object->ID3DXBaseEffect_iface;
5874
5875     return D3D_OK;
5876
5877 err_out:
5878
5879     HeapFree(GetProcessHeap(), 0, object);
5880     free_effect_compiler(compiler);
5881
5882     return hr;
5883 }
5884
5885 HRESULT WINAPI D3DXCreateEffectCompiler(LPCSTR srcdata,
5886                                         UINT srcdatalen,
5887                                         CONST D3DXMACRO *defines,
5888                                         LPD3DXINCLUDE include,
5889                                         DWORD flags,
5890                                         LPD3DXEFFECTCOMPILER *compiler,
5891                                         LPD3DXBUFFER *parse_errors)
5892 {
5893     struct ID3DXEffectCompilerImpl *object;
5894     HRESULT hr;
5895
5896     TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
5897             srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
5898
5899     if (!srcdata || !compiler)
5900     {
5901         WARN("Invalid arguments supplied\n");
5902         return D3DERR_INVALIDCALL;
5903     }
5904
5905     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5906     if (!object)
5907     {
5908         ERR("Out of memory\n");
5909         return E_OUTOFMEMORY;
5910     }
5911
5912     hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen);
5913     if (FAILED(hr))
5914     {
5915         WARN("Failed to initialize effect compiler\n");
5916         HeapFree(GetProcessHeap(), 0, object);
5917         return hr;
5918     }
5919
5920     *compiler = &object->ID3DXEffectCompiler_iface;
5921
5922     TRACE("Created ID3DXEffectCompiler %p\n", object);
5923
5924     return D3D_OK;
5925 }
5926
5927 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl;
5928
5929 struct ID3DXEffectPoolImpl
5930 {
5931     ID3DXEffectPool ID3DXEffectPool_iface;
5932     LONG ref;
5933 };
5934
5935 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
5936 {
5937     return CONTAINING_RECORD(iface, struct ID3DXEffectPoolImpl, ID3DXEffectPool_iface);
5938 }
5939
5940 /*** IUnknown methods ***/
5941 static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
5942 {
5943     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
5944
5945     if (IsEqualGUID(riid, &IID_IUnknown) ||
5946         IsEqualGUID(riid, &IID_ID3DXEffectPool))
5947     {
5948         iface->lpVtbl->AddRef(iface);
5949         *object = iface;
5950         return S_OK;
5951     }
5952
5953     WARN("Interface %s not found\n", debugstr_guid(riid));
5954
5955     return E_NOINTERFACE;
5956 }
5957
5958 static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool *iface)
5959 {
5960     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5961
5962     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
5963
5964     return InterlockedIncrement(&This->ref);
5965 }
5966
5967 static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool *iface)
5968 {
5969     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5970     ULONG ref = InterlockedDecrement(&This->ref);
5971
5972     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
5973
5974     if (!ref)
5975         HeapFree(GetProcessHeap(), 0, This);
5976
5977     return ref;
5978 }
5979
5980 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
5981 {
5982     /*** IUnknown methods ***/
5983     ID3DXEffectPoolImpl_QueryInterface,
5984     ID3DXEffectPoolImpl_AddRef,
5985     ID3DXEffectPoolImpl_Release
5986 };
5987
5988 HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL *pool)
5989 {
5990     struct ID3DXEffectPoolImpl *object;
5991
5992     TRACE("(%p)\n", pool);
5993
5994     if (!pool)
5995         return D3DERR_INVALIDCALL;
5996
5997     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5998     if (!object)
5999     {
6000         ERR("Out of memory\n");
6001         return E_OUTOFMEMORY;
6002     }
6003
6004     object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6005     object->ref = 1;
6006
6007     *pool = &object->ID3DXEffectPool_iface;
6008
6009     return S_OK;
6010 }
6011
6012 HRESULT WINAPI D3DXCreateEffectFromFileExW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
6013     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6014     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6015 {
6016     LPVOID buffer;
6017     HRESULT ret;
6018     DWORD size;
6019
6020     TRACE("(%s): relay\n", debugstr_w(srcfile));
6021
6022     if (!device || !srcfile)
6023         return D3DERR_INVALIDCALL;
6024
6025     ret = map_view_of_file(srcfile, &buffer, &size);
6026
6027     if (FAILED(ret))
6028         return D3DXERR_INVALIDDATA;
6029
6030     ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6031     UnmapViewOfFile(buffer);
6032
6033     return ret;
6034 }
6035
6036 HRESULT WINAPI D3DXCreateEffectFromFileExA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
6037     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6038     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6039 {
6040     LPWSTR srcfileW;
6041     HRESULT ret;
6042     DWORD len;
6043
6044     TRACE("(void): relay\n");
6045
6046     if (!srcfile)
6047         return D3DERR_INVALIDCALL;
6048
6049     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6050     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6051     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6052
6053     ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6054     HeapFree(GetProcessHeap(), 0, srcfileW);
6055
6056     return ret;
6057 }
6058
6059 HRESULT WINAPI D3DXCreateEffectFromFileW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
6060     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6061     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6062 {
6063     TRACE("(void): relay\n");
6064     return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6065 }
6066
6067 HRESULT WINAPI D3DXCreateEffectFromFileA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
6068     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6069     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6070 {
6071     TRACE("(void): relay\n");
6072     return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6073 }
6074
6075 HRESULT WINAPI D3DXCreateEffectFromResourceExW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
6076     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6077     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6078 {
6079     HRSRC resinfo;
6080
6081     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
6082
6083     if (!device)
6084         return D3DERR_INVALIDCALL;
6085
6086     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
6087
6088     if (resinfo)
6089     {
6090         LPVOID buffer;
6091         HRESULT ret;
6092         DWORD size;
6093
6094         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6095
6096         if (FAILED(ret))
6097             return D3DXERR_INVALIDDATA;
6098
6099         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6100     }
6101
6102     return D3DXERR_INVALIDDATA;
6103 }
6104
6105 HRESULT WINAPI D3DXCreateEffectFromResourceExA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
6106     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6107     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6108 {
6109     HRSRC resinfo;
6110
6111     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
6112
6113     if (!device)
6114         return D3DERR_INVALIDCALL;
6115
6116     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
6117
6118     if (resinfo)
6119     {
6120         LPVOID buffer;
6121         HRESULT ret;
6122         DWORD size;
6123
6124         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6125
6126         if (FAILED(ret))
6127             return D3DXERR_INVALIDDATA;
6128
6129         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6130     }
6131
6132     return D3DXERR_INVALIDDATA;
6133 }
6134
6135 HRESULT WINAPI D3DXCreateEffectFromResourceW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
6136     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6137     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6138 {
6139     TRACE("(void): relay\n");
6140     return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6141 }
6142
6143 HRESULT WINAPI D3DXCreateEffectFromResourceA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
6144     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6145     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6146 {
6147     TRACE("(void): relay\n");
6148     return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6149 }
6150
6151 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(LPCWSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
6152     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6153 {
6154     LPVOID buffer;
6155     HRESULT ret;
6156     DWORD size;
6157
6158     TRACE("(%s): relay\n", debugstr_w(srcfile));
6159
6160     if (!srcfile)
6161         return D3DERR_INVALIDCALL;
6162
6163     ret = map_view_of_file(srcfile, &buffer, &size);
6164
6165     if (FAILED(ret))
6166         return D3DXERR_INVALIDDATA;
6167
6168     ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6169     UnmapViewOfFile(buffer);
6170
6171     return ret;
6172 }
6173
6174 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
6175     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6176 {
6177     LPWSTR srcfileW;
6178     HRESULT ret;
6179     DWORD len;
6180
6181     TRACE("(void): relay\n");
6182
6183     if (!srcfile)
6184         return D3DERR_INVALIDCALL;
6185
6186     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6187     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6188     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6189
6190     ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
6191     HeapFree(GetProcessHeap(), 0, srcfileW);
6192
6193     return ret;
6194 }
6195
6196 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, LPCSTR srcresource, const D3DXMACRO *defines,
6197     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6198 {
6199     HRSRC resinfo;
6200
6201     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
6202
6203     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
6204
6205     if (resinfo)
6206     {
6207         LPVOID buffer;
6208         HRESULT ret;
6209         DWORD size;
6210
6211         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6212
6213         if (FAILED(ret))
6214             return D3DXERR_INVALIDDATA;
6215
6216         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6217     }
6218
6219     return D3DXERR_INVALIDDATA;
6220 }
6221
6222 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, LPCWSTR srcresource, const D3DXMACRO *defines,
6223     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6224 {
6225     HRSRC resinfo;
6226
6227     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
6228
6229     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
6230
6231     if (resinfo)
6232     {
6233         LPVOID buffer;
6234         HRESULT ret;
6235         DWORD size;
6236
6237         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6238
6239         if (FAILED(ret))
6240             return D3DXERR_INVALIDDATA;
6241
6242         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6243     }
6244
6245     return D3DXERR_INVALIDDATA;
6246 }