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