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