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