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