d3dx9: Parse elements in d3dx9_parse_resource().
[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
1992     FIXME("iface %p, parameter %p, texture %p stub\n", This, parameter, texture);
1993
1994     return E_NOTIMPL;
1995 }
1996
1997 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
1998 {
1999     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2000     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
2001
2002     TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
2003
2004     if (texture && param && !param->element_count &&
2005             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2006             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
2007             || param->type == D3DXPT_TEXTURECUBE))
2008     {
2009         *texture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
2010         if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2011         TRACE("Returning %p\n", *texture);
2012         return D3D_OK;
2013     }
2014
2015     WARN("Invalid argument specified\n");
2016
2017     return D3DERR_INVALIDCALL;
2018 }
2019
2020 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPixelShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
2021 {
2022     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2023     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
2024
2025     TRACE("iface %p, parameter %p, pshader %p\n", This, parameter, pshader);
2026
2027     if (!param) param = get_parameter_by_name(This, NULL, parameter);
2028
2029     if (pshader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2030     {
2031         *pshader = *(LPDIRECT3DPIXELSHADER9 *)param->data;
2032         if (*pshader) IDirect3DPixelShader9_AddRef(*pshader);
2033         TRACE("Returning %p\n", *pshader);
2034         return D3D_OK;
2035     }
2036
2037     WARN("Invalid argument specified\n");
2038
2039     return D3DERR_INVALIDCALL;
2040 }
2041
2042 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVertexShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
2043 {
2044     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2045     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
2046
2047     TRACE("iface %p, parameter %p, vshader %p\n", This, parameter, vshader);
2048
2049     if (!param) param = get_parameter_by_name(This, NULL, parameter);
2050
2051     if (vshader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2052     {
2053         *vshader = *(LPDIRECT3DVERTEXSHADER9 *)param->data;
2054         if (*vshader) IDirect3DVertexShader9_AddRef(*vshader);
2055         TRACE("Returning %p\n", *vshader);
2056         return D3D_OK;
2057     }
2058
2059     WARN("Invalid argument specified\n");
2060
2061     return D3DERR_INVALIDCALL;
2062 }
2063
2064 static HRESULT WINAPI ID3DXBaseEffectImpl_SetArrayRange(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
2065 {
2066     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2067
2068     FIXME("iface %p, parameter %p, start %u, end %u stub\n", This, parameter, start, end);
2069
2070     return E_NOTIMPL;
2071 }
2072
2073 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl =
2074 {
2075     /*** IUnknown methods ***/
2076     ID3DXBaseEffectImpl_QueryInterface,
2077     ID3DXBaseEffectImpl_AddRef,
2078     ID3DXBaseEffectImpl_Release,
2079     /*** ID3DXBaseEffect methods ***/
2080     ID3DXBaseEffectImpl_GetDesc,
2081     ID3DXBaseEffectImpl_GetParameterDesc,
2082     ID3DXBaseEffectImpl_GetTechniqueDesc,
2083     ID3DXBaseEffectImpl_GetPassDesc,
2084     ID3DXBaseEffectImpl_GetFunctionDesc,
2085     ID3DXBaseEffectImpl_GetParameter,
2086     ID3DXBaseEffectImpl_GetParameterByName,
2087     ID3DXBaseEffectImpl_GetParameterBySemantic,
2088     ID3DXBaseEffectImpl_GetParameterElement,
2089     ID3DXBaseEffectImpl_GetTechnique,
2090     ID3DXBaseEffectImpl_GetTechniqueByName,
2091     ID3DXBaseEffectImpl_GetPass,
2092     ID3DXBaseEffectImpl_GetPassByName,
2093     ID3DXBaseEffectImpl_GetFunction,
2094     ID3DXBaseEffectImpl_GetFunctionByName,
2095     ID3DXBaseEffectImpl_GetAnnotation,
2096     ID3DXBaseEffectImpl_GetAnnotationByName,
2097     ID3DXBaseEffectImpl_SetValue,
2098     ID3DXBaseEffectImpl_GetValue,
2099     ID3DXBaseEffectImpl_SetBool,
2100     ID3DXBaseEffectImpl_GetBool,
2101     ID3DXBaseEffectImpl_SetBoolArray,
2102     ID3DXBaseEffectImpl_GetBoolArray,
2103     ID3DXBaseEffectImpl_SetInt,
2104     ID3DXBaseEffectImpl_GetInt,
2105     ID3DXBaseEffectImpl_SetIntArray,
2106     ID3DXBaseEffectImpl_GetIntArray,
2107     ID3DXBaseEffectImpl_SetFloat,
2108     ID3DXBaseEffectImpl_GetFloat,
2109     ID3DXBaseEffectImpl_SetFloatArray,
2110     ID3DXBaseEffectImpl_GetFloatArray,
2111     ID3DXBaseEffectImpl_SetVector,
2112     ID3DXBaseEffectImpl_GetVector,
2113     ID3DXBaseEffectImpl_SetVectorArray,
2114     ID3DXBaseEffectImpl_GetVectorArray,
2115     ID3DXBaseEffectImpl_SetMatrix,
2116     ID3DXBaseEffectImpl_GetMatrix,
2117     ID3DXBaseEffectImpl_SetMatrixArray,
2118     ID3DXBaseEffectImpl_GetMatrixArray,
2119     ID3DXBaseEffectImpl_SetMatrixPointerArray,
2120     ID3DXBaseEffectImpl_GetMatrixPointerArray,
2121     ID3DXBaseEffectImpl_SetMatrixTranspose,
2122     ID3DXBaseEffectImpl_GetMatrixTranspose,
2123     ID3DXBaseEffectImpl_SetMatrixTransposeArray,
2124     ID3DXBaseEffectImpl_GetMatrixTransposeArray,
2125     ID3DXBaseEffectImpl_SetMatrixTransposePointerArray,
2126     ID3DXBaseEffectImpl_GetMatrixTransposePointerArray,
2127     ID3DXBaseEffectImpl_SetString,
2128     ID3DXBaseEffectImpl_GetString,
2129     ID3DXBaseEffectImpl_SetTexture,
2130     ID3DXBaseEffectImpl_GetTexture,
2131     ID3DXBaseEffectImpl_GetPixelShader,
2132     ID3DXBaseEffectImpl_GetVertexShader,
2133     ID3DXBaseEffectImpl_SetArrayRange,
2134 };
2135
2136 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
2137 {
2138     return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
2139 }
2140
2141 /*** IUnknown methods ***/
2142 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
2143 {
2144     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2145
2146     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
2147
2148     if (IsEqualGUID(riid, &IID_IUnknown) ||
2149         IsEqualGUID(riid, &IID_ID3DXEffect))
2150     {
2151         This->ID3DXEffect_iface.lpVtbl->AddRef(iface);
2152         *object = This;
2153         return S_OK;
2154     }
2155
2156     ERR("Interface %s not found\n", debugstr_guid(riid));
2157
2158     return E_NOINTERFACE;
2159 }
2160
2161 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
2162 {
2163     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2164
2165     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
2166
2167     return InterlockedIncrement(&This->ref);
2168 }
2169
2170 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
2171 {
2172     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2173     ULONG ref = InterlockedDecrement(&This->ref);
2174
2175     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
2176
2177     if (!ref)
2178     {
2179         free_effect(This);
2180         HeapFree(GetProcessHeap(), 0, This);
2181     }
2182
2183     return ref;
2184 }
2185
2186 /*** ID3DXBaseEffect methods ***/
2187 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
2188 {
2189     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2190     ID3DXBaseEffect *base = This->base_effect;
2191
2192     TRACE("Forward iface %p, base %p\n", This, base);
2193
2194     return ID3DXBaseEffectImpl_GetDesc(base, desc);
2195 }
2196
2197 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
2198 {
2199     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2200     ID3DXBaseEffect *base = This->base_effect;
2201
2202     TRACE("Forward iface %p, base %p\n", This, base);
2203
2204     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
2205 }
2206
2207 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_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_GetTechniqueDesc(base, technique, desc);
2215 }
2216
2217 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_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_GetPassDesc(base, pass, desc);
2225 }
2226
2227 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_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_GetFunctionDesc(base, shader, desc);
2235 }
2236
2237 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
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_GetParameter(base, parameter, index);
2245 }
2246
2247 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR name)
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_GetParameterByName(base, parameter, name);
2255 }
2256
2257 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
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_GetParameterBySemantic(base, parameter, semantic);
2265 }
2266
2267 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
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_GetParameterElement(base, parameter, index);
2275 }
2276
2277 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
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_GetTechnique(base, index);
2285 }
2286
2287 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, LPCSTR name)
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_GetTechniqueByName(base, name);
2295 }
2296
2297 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, 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_GetPass(base, technique, index);
2305 }
2306
2307 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, 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_GetPassByName(base, technique, name);
2315 }
2316
2317 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, 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_GetFunction(base, index);
2325 }
2326
2327 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, 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_GetFunctionByName(base, name);
2335 }
2336
2337 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, 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_GetAnnotation(base, object, index);
2345 }
2346
2347 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object, 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_GetAnnotationByName(base, object, name);
2355 }
2356
2357 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
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_SetValue(base, parameter, data, bytes);
2365 }
2366
2367 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
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_GetValue(base, parameter, data, bytes);
2375 }
2376
2377 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
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_SetBool(base, parameter, b);
2385 }
2386
2387 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
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_GetBool(base, parameter, b);
2395 }
2396
2397 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
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_SetBoolArray(base, parameter, b, count);
2405 }
2406
2407 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
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_GetBoolArray(base, parameter, b, count);
2415 }
2416
2417 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
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_SetInt(base, parameter, n);
2425 }
2426
2427 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
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_GetInt(base, parameter, n);
2435 }
2436
2437 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
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_SetIntArray(base, parameter, n, count);
2445 }
2446
2447 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
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_GetIntArray(base, parameter, n, count);
2455 }
2456
2457 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT f)
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_SetFloat(base, parameter, f);
2465 }
2466
2467 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f)
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_GetFloat(base, parameter, f);
2475 }
2476
2477 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
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_SetFloatArray(base, parameter, f, count);
2485 }
2486
2487 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
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_GetFloatArray(base, parameter, f, count);
2495 }
2496
2497 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
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_SetVector(base, parameter, vector);
2505 }
2506
2507 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
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_GetVector(base, parameter, vector);
2515 }
2516
2517 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
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_SetVectorArray(base, parameter, vector, count);
2525 }
2526
2527 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
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_GetVectorArray(base, parameter, vector, count);
2535 }
2536
2537 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
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_SetMatrix(base, parameter, matrix);
2545 }
2546
2547 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
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_GetMatrix(base, parameter, matrix);
2555 }
2556
2557 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
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_SetMatrixArray(base, parameter, matrix, count);
2565 }
2566
2567 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
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_GetMatrixArray(base, parameter, matrix, count);
2575 }
2576
2577 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(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_SetMatrixPointerArray(base, parameter, matrix, count);
2585 }
2586
2587 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(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_GetMatrixPointerArray(base, parameter, matrix, count);
2595 }
2596
2597 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
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_SetMatrixTranspose(base, parameter, matrix);
2605 }
2606
2607 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
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_GetMatrixTranspose(base, parameter, matrix);
2615 }
2616
2617 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
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_SetMatrixTransposeArray(base, parameter, matrix, count);
2625 }
2626
2627 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
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_GetMatrixTransposeArray(base, parameter, matrix, count);
2635 }
2636
2637 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(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_SetMatrixTransposePointerArray(base, parameter, matrix, count);
2645 }
2646
2647 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(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_GetMatrixTransposePointerArray(base, parameter, matrix, count);
2655 }
2656
2657 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR string)
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_SetString(base, parameter, string);
2665 }
2666
2667 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
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_GetString(base, parameter, string);
2675 }
2676
2677 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
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_SetTexture(base, parameter, texture);
2685 }
2686
2687 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
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_GetTexture(base, parameter, texture);
2695 }
2696
2697 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
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_GetPixelShader(base, parameter, pshader);
2705 }
2706
2707 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
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_GetVertexShader(base, parameter, vshader);
2715 }
2716
2717 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
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_SetArrayRange(base, parameter, start, end);
2725 }
2726
2727 /*** ID3DXEffect methods ***/
2728 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, LPD3DXEFFECTPOOL *pool)
2729 {
2730     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2731
2732     TRACE("iface %p, pool %p\n", This, pool);
2733
2734     if (!pool)
2735     {
2736         WARN("Invalid argument supplied.\n");
2737         return D3DERR_INVALIDCALL;
2738     }
2739
2740     if (This->pool)
2741     {
2742         This->pool->lpVtbl->AddRef(This->pool);
2743     }
2744
2745     *pool = This->pool;
2746
2747     TRACE("Returning pool %p\n", *pool);
2748
2749     return S_OK;
2750 }
2751
2752 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
2753 {
2754     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2755     struct ID3DXBaseEffectImpl *base = impl_from_ID3DXBaseEffect(This->base_effect);
2756     struct d3dx_technique *tech = is_valid_technique(base, technique);
2757
2758     TRACE("iface %p, technique %p\n", This, technique);
2759
2760     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
2761
2762     if (tech)
2763     {
2764         UINT i;
2765
2766         for (i = 0; i < base->technique_count; ++i)
2767         {
2768             struct d3dx_technique *t = get_technique_struct(base->technique_handles[i]);
2769
2770             if (tech == t)
2771             {
2772                 This->active_technique = get_technique_handle(t);
2773                 TRACE("Technique %u (%p)\n", i, tech);
2774                 return D3D_OK;
2775             }
2776         }
2777     }
2778
2779     WARN("Invalid argument supplied.\n");
2780
2781     return D3DERR_INVALIDCALL;
2782 }
2783
2784 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
2785 {
2786     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2787
2788     TRACE("iface %p\n", This);
2789
2790     return This->active_technique;
2791 }
2792
2793 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
2794 {
2795     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2796
2797     FIXME("(%p)->(%p): stub\n", This, technique);
2798
2799     return D3D_OK;
2800 }
2801
2802 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
2803 {
2804     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2805
2806     FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
2807
2808     return E_NOTIMPL;
2809 }
2810
2811 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
2812 {
2813     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2814
2815     FIXME("(%p)->(%p, %p): stub\n", This, parameter, technique);
2816
2817     return FALSE;
2818 }
2819
2820 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
2821 {
2822     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2823     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
2824
2825     FIXME("iface %p, passes %p, flags %#x partial stub\n", This, passes, flags);
2826
2827     if (passes && technique)
2828     {
2829         if (This->manager || flags & D3DXFX_DONOTSAVESTATE)
2830         {
2831             TRACE("State capturing disabled.\n");
2832         }
2833         else
2834         {
2835             FIXME("State capturing not supported, yet!\n");
2836         }
2837
2838         *passes = technique->pass_count;
2839
2840         return D3D_OK;
2841     }
2842
2843     WARN("Invalid argument supplied.\n");
2844
2845     return D3DERR_INVALIDCALL;
2846 }
2847
2848 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
2849 {
2850     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2851     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
2852
2853     TRACE("iface %p, pass %u\n", This, pass);
2854
2855     if (technique && pass < technique->pass_count && !This->active_pass)
2856     {
2857         This->active_pass = technique->pass_handles[pass];
2858
2859         FIXME("No states applied, yet!\n");
2860
2861         return D3D_OK;
2862     }
2863
2864     WARN("Invalid argument supplied.\n");
2865
2866     return D3DERR_INVALIDCALL;
2867 }
2868
2869 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect* iface)
2870 {
2871     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2872
2873     FIXME("(%p)->(): stub\n", This);
2874
2875     return E_NOTIMPL;
2876 }
2877
2878 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
2879 {
2880     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2881
2882     TRACE("iface %p\n", This);
2883
2884     if (This->active_pass)
2885     {
2886          This->active_pass = NULL;
2887          return D3D_OK;
2888     }
2889
2890     WARN("Invalid call.\n");
2891
2892     return D3DERR_INVALIDCALL;
2893 }
2894
2895 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect* iface)
2896 {
2897     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2898
2899     FIXME("(%p)->(): stub\n", This);
2900
2901     return E_NOTIMPL;
2902 }
2903
2904 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, LPDIRECT3DDEVICE9 *device)
2905 {
2906     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2907
2908     TRACE("iface %p, device %p\n", This, device);
2909
2910     if (!device)
2911     {
2912         WARN("Invalid argument supplied.\n");
2913         return D3DERR_INVALIDCALL;
2914     }
2915
2916     IDirect3DDevice9_AddRef(This->device);
2917
2918     *device = This->device;
2919
2920     TRACE("Returning device %p\n", *device);
2921
2922     return S_OK;
2923 }
2924
2925 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
2926 {
2927     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2928
2929     FIXME("(%p)->(): stub\n", This);
2930
2931     return E_NOTIMPL;
2932 }
2933
2934 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
2935 {
2936     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2937
2938     FIXME("(%p)->(): stub\n", This);
2939
2940     return E_NOTIMPL;
2941 }
2942
2943 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER manager)
2944 {
2945     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2946
2947     TRACE("iface %p, manager %p\n", This, manager);
2948
2949     if (manager) IUnknown_AddRef(manager);
2950     if (This->manager) IUnknown_Release(This->manager);    
2951
2952     This->manager = manager;
2953
2954     return D3D_OK;
2955 }
2956
2957 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER *manager)
2958 {
2959     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2960
2961     TRACE("iface %p, manager %p\n", This, manager);
2962
2963     if (!manager)
2964     {
2965         WARN("Invalid argument supplied.\n");
2966         return D3DERR_INVALIDCALL;
2967     }
2968
2969     if (This->manager) IUnknown_AddRef(This->manager);
2970     *manager = This->manager;
2971
2972     return D3D_OK;
2973 }
2974
2975 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
2976 {
2977     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2978
2979     FIXME("(%p)->(): stub\n", This);
2980
2981     return E_NOTIMPL;
2982 }
2983
2984 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
2985 {
2986     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2987
2988     FIXME("(%p)->(): stub\n", This);
2989
2990     return NULL;
2991 }
2992
2993 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
2994 {
2995     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2996
2997     FIXME("(%p)->(%p): stub\n", This, parameter_block);
2998
2999     return E_NOTIMPL;
3000 }
3001
3002 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
3003 {
3004     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3005
3006     FIXME("(%p)->(%p): stub\n", This, parameter_block);
3007
3008     return E_NOTIMPL;
3009 }
3010
3011 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect* iface, LPDIRECT3DDEVICE9 device, LPD3DXEFFECT* effect)
3012 {
3013     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3014
3015     FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
3016
3017     return E_NOTIMPL;
3018 }
3019
3020 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect* iface, D3DXHANDLE parameter, LPCVOID data, UINT byte_offset, UINT bytes)
3021 {
3022     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3023
3024     FIXME("(%p)->(%p, %p, %u, %u): stub\n", This, parameter, data, byte_offset, bytes);
3025
3026     return E_NOTIMPL;
3027 }
3028
3029 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
3030 {
3031     /*** IUnknown methods ***/
3032     ID3DXEffectImpl_QueryInterface,
3033     ID3DXEffectImpl_AddRef,
3034     ID3DXEffectImpl_Release,
3035     /*** ID3DXBaseEffect methods ***/
3036     ID3DXEffectImpl_GetDesc,
3037     ID3DXEffectImpl_GetParameterDesc,
3038     ID3DXEffectImpl_GetTechniqueDesc,
3039     ID3DXEffectImpl_GetPassDesc,
3040     ID3DXEffectImpl_GetFunctionDesc,
3041     ID3DXEffectImpl_GetParameter,
3042     ID3DXEffectImpl_GetParameterByName,
3043     ID3DXEffectImpl_GetParameterBySemantic,
3044     ID3DXEffectImpl_GetParameterElement,
3045     ID3DXEffectImpl_GetTechnique,
3046     ID3DXEffectImpl_GetTechniqueByName,
3047     ID3DXEffectImpl_GetPass,
3048     ID3DXEffectImpl_GetPassByName,
3049     ID3DXEffectImpl_GetFunction,
3050     ID3DXEffectImpl_GetFunctionByName,
3051     ID3DXEffectImpl_GetAnnotation,
3052     ID3DXEffectImpl_GetAnnotationByName,
3053     ID3DXEffectImpl_SetValue,
3054     ID3DXEffectImpl_GetValue,
3055     ID3DXEffectImpl_SetBool,
3056     ID3DXEffectImpl_GetBool,
3057     ID3DXEffectImpl_SetBoolArray,
3058     ID3DXEffectImpl_GetBoolArray,
3059     ID3DXEffectImpl_SetInt,
3060     ID3DXEffectImpl_GetInt,
3061     ID3DXEffectImpl_SetIntArray,
3062     ID3DXEffectImpl_GetIntArray,
3063     ID3DXEffectImpl_SetFloat,
3064     ID3DXEffectImpl_GetFloat,
3065     ID3DXEffectImpl_SetFloatArray,
3066     ID3DXEffectImpl_GetFloatArray,
3067     ID3DXEffectImpl_SetVector,
3068     ID3DXEffectImpl_GetVector,
3069     ID3DXEffectImpl_SetVectorArray,
3070     ID3DXEffectImpl_GetVectorArray,
3071     ID3DXEffectImpl_SetMatrix,
3072     ID3DXEffectImpl_GetMatrix,
3073     ID3DXEffectImpl_SetMatrixArray,
3074     ID3DXEffectImpl_GetMatrixArray,
3075     ID3DXEffectImpl_SetMatrixPointerArray,
3076     ID3DXEffectImpl_GetMatrixPointerArray,
3077     ID3DXEffectImpl_SetMatrixTranspose,
3078     ID3DXEffectImpl_GetMatrixTranspose,
3079     ID3DXEffectImpl_SetMatrixTransposeArray,
3080     ID3DXEffectImpl_GetMatrixTransposeArray,
3081     ID3DXEffectImpl_SetMatrixTransposePointerArray,
3082     ID3DXEffectImpl_GetMatrixTransposePointerArray,
3083     ID3DXEffectImpl_SetString,
3084     ID3DXEffectImpl_GetString,
3085     ID3DXEffectImpl_SetTexture,
3086     ID3DXEffectImpl_GetTexture,
3087     ID3DXEffectImpl_GetPixelShader,
3088     ID3DXEffectImpl_GetVertexShader,
3089     ID3DXEffectImpl_SetArrayRange,
3090     /*** ID3DXEffect methods ***/
3091     ID3DXEffectImpl_GetPool,
3092     ID3DXEffectImpl_SetTechnique,
3093     ID3DXEffectImpl_GetCurrentTechnique,
3094     ID3DXEffectImpl_ValidateTechnique,
3095     ID3DXEffectImpl_FindNextValidTechnique,
3096     ID3DXEffectImpl_IsParameterUsed,
3097     ID3DXEffectImpl_Begin,
3098     ID3DXEffectImpl_BeginPass,
3099     ID3DXEffectImpl_CommitChanges,
3100     ID3DXEffectImpl_EndPass,
3101     ID3DXEffectImpl_End,
3102     ID3DXEffectImpl_GetDevice,
3103     ID3DXEffectImpl_OnLostDevice,
3104     ID3DXEffectImpl_OnResetDevice,
3105     ID3DXEffectImpl_SetStateManager,
3106     ID3DXEffectImpl_GetStateManager,
3107     ID3DXEffectImpl_BeginParameterBlock,
3108     ID3DXEffectImpl_EndParameterBlock,
3109     ID3DXEffectImpl_ApplyParameterBlock,
3110     ID3DXEffectImpl_DeleteParameterBlock,
3111     ID3DXEffectImpl_CloneEffect,
3112     ID3DXEffectImpl_SetRawValue
3113 };
3114
3115 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
3116 {
3117     return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
3118 }
3119
3120 /*** IUnknown methods ***/
3121 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
3122 {
3123     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3124
3125     TRACE("iface %p, riid %s, object %p\n", This, debugstr_guid(riid), object);
3126
3127     if (IsEqualGUID(riid, &IID_IUnknown) ||
3128         IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
3129     {
3130         This->ID3DXEffectCompiler_iface.lpVtbl->AddRef(iface);
3131         *object = This;
3132         return S_OK;
3133     }
3134
3135     ERR("Interface %s not found\n", debugstr_guid(riid));
3136
3137     return E_NOINTERFACE;
3138 }
3139
3140 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
3141 {
3142     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3143
3144     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
3145
3146     return InterlockedIncrement(&This->ref);
3147 }
3148
3149 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
3150 {
3151     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3152     ULONG ref = InterlockedDecrement(&This->ref);
3153
3154     TRACE("iface %p: Release from %u\n", iface, ref + 1);
3155
3156     if (!ref)
3157     {
3158         free_effect_compiler(This);
3159         HeapFree(GetProcessHeap(), 0, This);
3160     }
3161
3162     return ref;
3163 }
3164
3165 /*** ID3DXBaseEffect methods ***/
3166 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
3167 {
3168     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3169     ID3DXBaseEffect *base = This->base_effect;
3170
3171     TRACE("Forward iface %p, base %p\n", This, base);
3172
3173     return ID3DXBaseEffectImpl_GetDesc(base, desc);
3174 }
3175
3176 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3177 {
3178     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3179     ID3DXBaseEffect *base = This->base_effect;
3180
3181     TRACE("Forward iface %p, base %p\n", This, base);
3182
3183     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
3184 }
3185
3186 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, D3DXHANDLE technique, D3DXTECHNIQUE_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_GetTechniqueDesc(base, technique, desc);
3194 }
3195
3196 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, D3DXHANDLE pass, D3DXPASS_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_GetPassDesc(base, pass, desc);
3204 }
3205
3206 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, D3DXHANDLE shader, D3DXFUNCTION_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_GetFunctionDesc(base, shader, desc);
3214 }
3215
3216 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
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_GetParameter(base, parameter, index);
3224 }
3225
3226 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR name)
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_GetParameterByName(base, parameter, name);
3234 }
3235
3236 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR semantic)
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_GetParameterBySemantic(base, parameter, semantic);
3244 }
3245
3246 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
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_GetParameterElement(base, parameter, index);
3254 }
3255
3256 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
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_GetTechnique(base, index);
3264 }
3265
3266 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, LPCSTR name)
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_GetTechniqueByName(base, name);
3274 }
3275
3276 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, 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_GetPass(base, technique, index);
3284 }
3285
3286 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, D3DXHANDLE technique, 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_GetPassByName(base, technique, name);
3294 }
3295
3296 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, 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_GetFunction(base, index);
3304 }
3305
3306 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, 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_GetFunctionByName(base, name);
3314 }
3315
3316 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, D3DXHANDLE object, 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_GetAnnotation(base, object, index);
3324 }
3325
3326 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, D3DXHANDLE object, 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_GetAnnotationByName(base, object, name);
3334 }
3335
3336 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
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_SetValue(base, parameter, data, bytes);
3344 }
3345
3346 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
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_GetValue(base, parameter, data, bytes);
3354 }
3355
3356 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
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_SetBool(base, parameter, b);
3364 }
3365
3366 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
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_GetBool(base, parameter, b);
3374 }
3375
3376 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
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_SetBoolArray(base, parameter, b, count);
3384 }
3385
3386 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
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_GetBoolArray(base, parameter, b, count);
3394 }
3395
3396 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
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_SetInt(base, parameter, n);
3404 }
3405
3406 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
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_GetInt(base, parameter, n);
3414 }
3415
3416 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
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_SetIntArray(base, parameter, n, count);
3424 }
3425
3426 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n, UINT count)
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_GetIntArray(base, parameter, n, count);
3434 }
3435
3436 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT f)
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_SetFloat(base, parameter, f);
3444 }
3445
3446 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f)
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_GetFloat(base, parameter, f);
3454 }
3455
3456 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
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_SetFloatArray(base, parameter, f, count);
3464 }
3465
3466 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
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_GetFloatArray(base, parameter, f, count);
3474 }
3475
3476 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
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_SetVector(base, parameter, vector);
3484 }
3485
3486 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
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_GetVector(base, parameter, vector);
3494 }
3495
3496 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
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_SetVectorArray(base, parameter, vector, count);
3504 }
3505
3506 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
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_GetVectorArray(base, parameter, vector, count);
3514 }
3515
3516 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
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_SetMatrix(base, parameter, matrix);
3524 }
3525
3526 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
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_GetMatrix(base, parameter, matrix);
3534 }
3535
3536 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
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_SetMatrixArray(base, parameter, matrix, count);
3544 }
3545
3546 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
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_GetMatrixArray(base, parameter, matrix, count);
3554 }
3555
3556 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(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_SetMatrixPointerArray(base, parameter, matrix, count);
3564 }
3565
3566 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(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_GetMatrixPointerArray(base, parameter, matrix, count);
3574 }
3575
3576 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
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_SetMatrixTranspose(base, parameter, matrix);
3584 }
3585
3586 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
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_GetMatrixTranspose(base, parameter, matrix);
3594 }
3595
3596 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
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_SetMatrixTransposeArray(base, parameter, matrix, count);
3604 }
3605
3606 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
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_GetMatrixTransposeArray(base, parameter, matrix, count);
3614 }
3615
3616 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(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_SetMatrixTransposePointerArray(base, parameter, matrix, count);
3624 }
3625
3626 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(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_GetMatrixTransposePointerArray(base, parameter, matrix, count);
3634 }
3635
3636 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR string)
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_SetString(base, parameter, string);
3644 }
3645
3646 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR *string)
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_GetString(base, parameter, string);
3654 }
3655
3656 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
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_SetTexture(base, parameter, texture);
3664 }
3665
3666 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
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_GetTexture(base, parameter, texture);
3674 }
3675
3676 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
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_GetPixelShader(base, parameter, pshader);
3684 }
3685
3686 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
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_GetVertexShader(base, parameter, vshader);
3694 }
3695
3696 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT start, UINT end)
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_SetArrayRange(base, parameter, start, end);
3704 }
3705
3706 /*** ID3DXEffectCompiler methods ***/
3707 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
3708 {
3709     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3710
3711     FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
3712
3713     return E_NOTIMPL;
3714 }
3715
3716 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
3717 {
3718     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3719
3720     FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
3721
3722     return E_NOTIMPL;
3723 }
3724
3725 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
3726         LPD3DXBUFFER *effect, LPD3DXBUFFER *error_msgs)
3727 {
3728     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3729
3730     FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
3731
3732     return E_NOTIMPL;
3733 }
3734
3735 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
3736         LPCSTR target, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *error_msgs, LPD3DXCONSTANTTABLE *constant_table)
3737 {
3738     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3739
3740     FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
3741             This, function, target, flags, shader, error_msgs, constant_table);
3742
3743     return E_NOTIMPL;
3744 }
3745
3746 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
3747 {
3748     /*** IUnknown methods ***/
3749     ID3DXEffectCompilerImpl_QueryInterface,
3750     ID3DXEffectCompilerImpl_AddRef,
3751     ID3DXEffectCompilerImpl_Release,
3752     /*** ID3DXBaseEffect methods ***/
3753     ID3DXEffectCompilerImpl_GetDesc,
3754     ID3DXEffectCompilerImpl_GetParameterDesc,
3755     ID3DXEffectCompilerImpl_GetTechniqueDesc,
3756     ID3DXEffectCompilerImpl_GetPassDesc,
3757     ID3DXEffectCompilerImpl_GetFunctionDesc,
3758     ID3DXEffectCompilerImpl_GetParameter,
3759     ID3DXEffectCompilerImpl_GetParameterByName,
3760     ID3DXEffectCompilerImpl_GetParameterBySemantic,
3761     ID3DXEffectCompilerImpl_GetParameterElement,
3762     ID3DXEffectCompilerImpl_GetTechnique,
3763     ID3DXEffectCompilerImpl_GetTechniqueByName,
3764     ID3DXEffectCompilerImpl_GetPass,
3765     ID3DXEffectCompilerImpl_GetPassByName,
3766     ID3DXEffectCompilerImpl_GetFunction,
3767     ID3DXEffectCompilerImpl_GetFunctionByName,
3768     ID3DXEffectCompilerImpl_GetAnnotation,
3769     ID3DXEffectCompilerImpl_GetAnnotationByName,
3770     ID3DXEffectCompilerImpl_SetValue,
3771     ID3DXEffectCompilerImpl_GetValue,
3772     ID3DXEffectCompilerImpl_SetBool,
3773     ID3DXEffectCompilerImpl_GetBool,
3774     ID3DXEffectCompilerImpl_SetBoolArray,
3775     ID3DXEffectCompilerImpl_GetBoolArray,
3776     ID3DXEffectCompilerImpl_SetInt,
3777     ID3DXEffectCompilerImpl_GetInt,
3778     ID3DXEffectCompilerImpl_SetIntArray,
3779     ID3DXEffectCompilerImpl_GetIntArray,
3780     ID3DXEffectCompilerImpl_SetFloat,
3781     ID3DXEffectCompilerImpl_GetFloat,
3782     ID3DXEffectCompilerImpl_SetFloatArray,
3783     ID3DXEffectCompilerImpl_GetFloatArray,
3784     ID3DXEffectCompilerImpl_SetVector,
3785     ID3DXEffectCompilerImpl_GetVector,
3786     ID3DXEffectCompilerImpl_SetVectorArray,
3787     ID3DXEffectCompilerImpl_GetVectorArray,
3788     ID3DXEffectCompilerImpl_SetMatrix,
3789     ID3DXEffectCompilerImpl_GetMatrix,
3790     ID3DXEffectCompilerImpl_SetMatrixArray,
3791     ID3DXEffectCompilerImpl_GetMatrixArray,
3792     ID3DXEffectCompilerImpl_SetMatrixPointerArray,
3793     ID3DXEffectCompilerImpl_GetMatrixPointerArray,
3794     ID3DXEffectCompilerImpl_SetMatrixTranspose,
3795     ID3DXEffectCompilerImpl_GetMatrixTranspose,
3796     ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
3797     ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
3798     ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
3799     ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
3800     ID3DXEffectCompilerImpl_SetString,
3801     ID3DXEffectCompilerImpl_GetString,
3802     ID3DXEffectCompilerImpl_SetTexture,
3803     ID3DXEffectCompilerImpl_GetTexture,
3804     ID3DXEffectCompilerImpl_GetPixelShader,
3805     ID3DXEffectCompilerImpl_GetVertexShader,
3806     ID3DXEffectCompilerImpl_SetArrayRange,
3807     /*** ID3DXEffectCompiler methods ***/
3808     ID3DXEffectCompilerImpl_SetLiteral,
3809     ID3DXEffectCompilerImpl_GetLiteral,
3810     ID3DXEffectCompilerImpl_CompileEffect,
3811     ID3DXEffectCompilerImpl_CompileShader,
3812 };
3813
3814 static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *data, const char **ptr, D3DXHANDLE *objects)
3815 {
3816     HRESULT hr;
3817     UINT i;
3818     struct d3dx_state *states;
3819
3820     read_dword(ptr, &sampler->state_count);
3821     TRACE("Count: %u\n", sampler->state_count);
3822
3823     states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * sampler->state_count);
3824     if (!states)
3825     {
3826         ERR("Out of memory\n");
3827         return E_OUTOFMEMORY;
3828     }
3829
3830     for (i = 0; i < sampler->state_count; ++i)
3831     {
3832         hr = d3dx9_parse_state(&states[i], data, ptr, objects);
3833         if (hr != D3D_OK)
3834         {
3835             WARN("Failed to parse state\n");
3836             goto err_out;
3837         }
3838     }
3839
3840     sampler->states = states;
3841
3842     return D3D_OK;
3843
3844 err_out:
3845
3846     for (i = 0; i < sampler->state_count; ++i)
3847     {
3848         free_state(&states[i]);
3849     }
3850
3851     HeapFree(GetProcessHeap(), 0, states);
3852
3853     return hr;
3854 }
3855
3856 static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char *data, const char **ptr, D3DXHANDLE *objects)
3857 {
3858     unsigned int i;
3859     HRESULT hr;
3860     UINT old_size = 0;
3861     DWORD id;
3862
3863     if (param->element_count)
3864     {
3865         param->data = value;
3866
3867         for (i = 0; i < param->element_count; ++i)
3868         {
3869             struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
3870
3871             hr = d3dx9_parse_value(member, value ? (char *)value + old_size : NULL, data, ptr, objects);
3872             if (hr != D3D_OK)
3873             {
3874                 WARN("Failed to parse value\n");
3875                 return hr;
3876             }
3877
3878             old_size += member->bytes;
3879         }
3880
3881         return D3D_OK;
3882     }
3883
3884     switch(param->class)
3885     {
3886         case D3DXPC_SCALAR:
3887         case D3DXPC_VECTOR:
3888         case D3DXPC_MATRIX_ROWS:
3889         case D3DXPC_MATRIX_COLUMNS:
3890             param->data = value;
3891             break;
3892
3893         case D3DXPC_STRUCT:
3894             param->data = value;
3895
3896             for (i = 0; i < param->member_count; ++i)
3897             {
3898                 struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
3899
3900                 hr = d3dx9_parse_value(member, (char *)value + old_size, data, ptr, objects);
3901                 if (hr != D3D_OK)
3902                 {
3903                     WARN("Failed to parse value\n");
3904                     return hr;
3905                 }
3906
3907                 old_size += member->bytes;
3908             }
3909             break;
3910
3911         case D3DXPC_OBJECT:
3912             switch (param->type)
3913             {
3914                 case D3DXPT_STRING:
3915                 case D3DXPT_TEXTURE:
3916                 case D3DXPT_TEXTURE1D:
3917                 case D3DXPT_TEXTURE2D:
3918                 case D3DXPT_TEXTURE3D:
3919                 case D3DXPT_TEXTURECUBE:
3920                 case D3DXPT_PIXELSHADER:
3921                 case D3DXPT_VERTEXSHADER:
3922                     read_dword(ptr, &id);
3923                     TRACE("Id: %u\n", id);
3924                     objects[id] = get_parameter_handle(param);
3925                     param->data = value;
3926                     break;
3927
3928                 case D3DXPT_SAMPLER:
3929                 case D3DXPT_SAMPLER1D:
3930                 case D3DXPT_SAMPLER2D:
3931                 case D3DXPT_SAMPLER3D:
3932                 case D3DXPT_SAMPLERCUBE:
3933                 {
3934                     struct d3dx_sampler *sampler;
3935
3936                     sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
3937                     if (!sampler)
3938                     {
3939                         ERR("Out of memory\n");
3940                         return E_OUTOFMEMORY;
3941                     }
3942
3943                     hr = d3dx9_parse_sampler(sampler, data, ptr, objects);
3944                     if (hr != D3D_OK)
3945                     {
3946                         HeapFree(GetProcessHeap(), 0, sampler);
3947                         WARN("Failed to parse sampler\n");
3948                         return hr;
3949                     }
3950
3951                     param->data = sampler;
3952                     break;
3953                 }
3954
3955                 default:
3956                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
3957                     break;
3958             }
3959             break;
3960
3961         default:
3962             FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
3963             break;
3964     }
3965
3966     return D3D_OK;
3967 }
3968
3969 static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *data, const char *ptr, D3DXHANDLE *objects)
3970 {
3971     UINT size = param->bytes;
3972     HRESULT hr;
3973     void *value = NULL;
3974
3975     TRACE("param size: %u\n", size);
3976
3977     if (size)
3978     {
3979         value = HeapAlloc(GetProcessHeap(), 0, size);
3980         if (!value)
3981         {
3982             ERR("Failed to allocate data memory.\n");
3983             return E_OUTOFMEMORY;
3984         }
3985
3986         TRACE("Data: %s.\n", debugstr_an(ptr, size));
3987         memcpy(value, ptr, size);
3988     }
3989
3990     hr = d3dx9_parse_value(param, value, data, &ptr, objects);
3991     if (hr != D3D_OK)
3992     {
3993         WARN("Failed to parse value\n");
3994         HeapFree(GetProcessHeap(), 0, value);
3995         return hr;
3996     }
3997
3998     return D3D_OK;
3999 }
4000
4001 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
4002 {
4003     DWORD size;
4004
4005     read_dword(&ptr, &size);
4006     TRACE("Name size: %#x\n", size);
4007
4008     if (!size)
4009     {
4010         return D3D_OK;
4011     }
4012
4013     *name = HeapAlloc(GetProcessHeap(), 0, size);
4014     if (!*name)
4015     {
4016         ERR("Failed to allocate name memory.\n");
4017         return E_OUTOFMEMORY;
4018     }
4019
4020     TRACE("Name: %s.\n", debugstr_an(ptr, size));
4021     memcpy(*name, ptr, size);
4022
4023     return D3D_OK;
4024 }
4025
4026 static HRESULT d3dx9_copy_data(char **str, const char **ptr)
4027 {
4028     DWORD size;
4029
4030     read_dword(ptr, &size);
4031     TRACE("Data size: %#x\n", size);
4032
4033     *str = HeapAlloc(GetProcessHeap(), 0, size);
4034     if (!*str)
4035     {
4036         ERR("Failed to allocate name memory.\n");
4037         return E_OUTOFMEMORY;
4038     }
4039
4040     TRACE("Data: %s.\n", debugstr_an(*ptr, size));
4041     memcpy(*str, *ptr, size);
4042
4043     *ptr += ((size + 3) & ~3);
4044
4045     return D3D_OK;
4046 }
4047
4048 static HRESULT d3dx9_parse_data(struct d3dx_parameter *param, const char **ptr, LPDIRECT3DDEVICE9 device)
4049 {
4050     DWORD size;
4051     HRESULT hr;
4052
4053     TRACE("Parse data for parameter %s, type %s\n", debugstr_a(param->name), debug_d3dxparameter_type(param->type));
4054
4055     read_dword(ptr, &size);
4056     TRACE("Data size: %#x\n", size);
4057
4058     if (!size)
4059     {
4060         TRACE("Size is 0\n");
4061         *(void **)param->data = NULL;
4062         return D3D_OK;
4063     }
4064
4065     switch (param->type)
4066     {
4067         case D3DXPT_STRING:
4068             /* re-read with size (sizeof(DWORD) = 4) */
4069             hr = d3dx9_parse_name((LPSTR *)param->data, *ptr - 4);
4070             if (hr != D3D_OK)
4071             {
4072                 WARN("Failed to parse string data\n");
4073                 return hr;
4074             }
4075             break;
4076
4077         case D3DXPT_VERTEXSHADER:
4078             hr = IDirect3DDevice9_CreateVertexShader(device, (DWORD *)*ptr, (LPDIRECT3DVERTEXSHADER9 *)param->data);
4079             if (hr != D3D_OK)
4080             {
4081                 WARN("Failed to create vertex shader\n");
4082                 return hr;
4083             }
4084             break;
4085
4086         case D3DXPT_PIXELSHADER:
4087             hr = IDirect3DDevice9_CreatePixelShader(device, (DWORD *)*ptr, (LPDIRECT3DPIXELSHADER9 *)param->data);
4088             if (hr != D3D_OK)
4089             {
4090                 WARN("Failed to create pixel shader\n");
4091                 return hr;
4092             }
4093             break;
4094
4095         default:
4096             FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4097             break;
4098     }
4099
4100
4101     *ptr += ((size + 3) & ~3);
4102
4103     return D3D_OK;
4104 }
4105
4106 static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
4107         struct d3dx_parameter *parent, UINT flags)
4108 {
4109     DWORD offset;
4110     HRESULT hr;
4111     D3DXHANDLE *member_handles = NULL;
4112     UINT i;
4113
4114     param->flags = flags;
4115
4116     if (!parent)
4117     {
4118         read_dword(ptr, &param->type);
4119         TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
4120
4121         read_dword(ptr, &param->class);
4122         TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
4123
4124         read_dword(ptr, &offset);
4125         TRACE("Type name offset: %#x\n", offset);
4126         hr = d3dx9_parse_name(&param->name, data + offset);
4127         if (hr != D3D_OK)
4128         {
4129             WARN("Failed to parse name\n");
4130             goto err_out;
4131         }
4132
4133         read_dword(ptr, &offset);
4134         TRACE("Type semantic offset: %#x\n", offset);
4135         hr = d3dx9_parse_name(&param->semantic, data + offset);
4136         if (hr != D3D_OK)
4137         {
4138             WARN("Failed to parse semantic\n");
4139             goto err_out;
4140         }
4141
4142         read_dword(ptr, &param->element_count);
4143         TRACE("Elements: %u\n", param->element_count);
4144
4145         switch (param->class)
4146         {
4147             case D3DXPC_VECTOR:
4148                 read_dword(ptr, &param->columns);
4149                 TRACE("Columns: %u\n", param->columns);
4150
4151                 read_dword(ptr, &param->rows);
4152                 TRACE("Rows: %u\n", param->rows);
4153
4154                 /* sizeof(DWORD) * rows * columns */
4155                 param->bytes = 4 * param->rows * param->columns;
4156                 break;
4157
4158             case D3DXPC_SCALAR:
4159             case D3DXPC_MATRIX_ROWS:
4160             case D3DXPC_MATRIX_COLUMNS:
4161                 read_dword(ptr, &param->rows);
4162                 TRACE("Rows: %u\n", param->rows);
4163
4164                 read_dword(ptr, &param->columns);
4165                 TRACE("Columns: %u\n", param->columns);
4166
4167                 /* sizeof(DWORD) * rows * columns */
4168                 param->bytes = 4 * param->rows * param->columns;
4169                 break;
4170
4171             case D3DXPC_STRUCT:
4172                 read_dword(ptr, &param->member_count);
4173                 TRACE("Members: %u\n", param->member_count);
4174                 break;
4175
4176             case D3DXPC_OBJECT:
4177                 switch (param->type)
4178                 {
4179                     case D3DXPT_STRING:
4180                         param->bytes = sizeof(LPCSTR);
4181                         break;
4182
4183                     case D3DXPT_PIXELSHADER:
4184                         param->bytes = sizeof(LPDIRECT3DPIXELSHADER9);
4185                         break;
4186
4187                     case D3DXPT_VERTEXSHADER:
4188                         param->bytes = sizeof(LPDIRECT3DVERTEXSHADER9);
4189                         break;
4190
4191                     case D3DXPT_TEXTURE:
4192                     case D3DXPT_TEXTURE1D:
4193                     case D3DXPT_TEXTURE2D:
4194                     case D3DXPT_TEXTURE3D:
4195                     case D3DXPT_TEXTURECUBE:
4196                         param->bytes = sizeof(LPDIRECT3DBASETEXTURE9);
4197                         break;
4198
4199                     case D3DXPT_SAMPLER:
4200                     case D3DXPT_SAMPLER1D:
4201                     case D3DXPT_SAMPLER2D:
4202                     case D3DXPT_SAMPLER3D:
4203                     case D3DXPT_SAMPLERCUBE:
4204                         param->bytes = 0;
4205                         break;
4206
4207                     default:
4208                         FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4209                         break;
4210                 }
4211                 break;
4212
4213             default:
4214                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4215                 break;
4216         }
4217     }
4218     else
4219     {
4220         /* elements */
4221         param->type = parent->type;
4222         param->class = parent->class;
4223         param->name = parent->name;
4224         param->semantic = parent->semantic;
4225         param->element_count = 0;
4226         param->annotation_count = 0;
4227         param->member_count = parent->member_count;
4228         param->bytes = parent->bytes;
4229         param->rows = parent->rows;
4230         param->columns = parent->columns;
4231     }
4232
4233     if (param->element_count)
4234     {
4235         unsigned int param_bytes = 0;
4236         const char *save_ptr = *ptr;
4237
4238         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->element_count);
4239         if (!member_handles)
4240         {
4241             ERR("Out of memory\n");
4242             hr = E_OUTOFMEMORY;
4243             goto err_out;
4244         }
4245
4246         for (i = 0; i < param->element_count; ++i)
4247         {
4248             struct d3dx_parameter *member;
4249             *ptr = save_ptr;
4250
4251             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4252             if (!member)
4253             {
4254                 ERR("Out of memory\n");
4255                 hr = E_OUTOFMEMORY;
4256                 goto err_out;
4257             }
4258
4259             member_handles[i] = get_parameter_handle(member);
4260
4261             hr = d3dx9_parse_effect_typedef(member, data, ptr, param, flags);
4262             if (hr != D3D_OK)
4263             {
4264                 WARN("Failed to parse member\n");
4265                 goto err_out;
4266             }
4267
4268             param_bytes += member->bytes;
4269         }
4270
4271         param->bytes = param_bytes;
4272     }
4273     else if (param->member_count)
4274     {
4275         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->member_count);
4276         if (!member_handles)
4277         {
4278             ERR("Out of memory\n");
4279             hr = E_OUTOFMEMORY;
4280             goto err_out;
4281         }
4282
4283         for (i = 0; i < param->member_count; ++i)
4284         {
4285             struct d3dx_parameter *member;
4286
4287             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4288             if (!member)
4289             {
4290                 ERR("Out of memory\n");
4291                 hr = E_OUTOFMEMORY;
4292                 goto err_out;
4293             }
4294
4295             member_handles[i] = get_parameter_handle(member);
4296
4297             hr = d3dx9_parse_effect_typedef(member, data, ptr, NULL, flags);
4298             if (hr != D3D_OK)
4299             {
4300                 WARN("Failed to parse member\n");
4301                 goto err_out;
4302             }
4303
4304             param->bytes += member->bytes;
4305         }
4306     }
4307
4308     param->member_handles = member_handles;
4309
4310     return D3D_OK;
4311
4312 err_out:
4313
4314     if (member_handles)
4315     {
4316         unsigned int count;
4317
4318         if (param->element_count) count = param->element_count;
4319         else count = param->member_count;
4320
4321         for (i = 0; i < count; ++i)
4322         {
4323             free_parameter(member_handles[i], param->element_count != 0, TRUE);
4324         }
4325         HeapFree(GetProcessHeap(), 0, member_handles);
4326     }
4327
4328     if (!parent)
4329     {
4330         HeapFree(GetProcessHeap(), 0, param->name);
4331         HeapFree(GetProcessHeap(), 0, param->semantic);
4332     }
4333     param->name = NULL;
4334     param->semantic = NULL;
4335
4336     return hr;
4337 }
4338
4339 static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data, const char **ptr, D3DXHANDLE *objects)
4340 {
4341     DWORD offset;
4342     const char *ptr2;
4343     HRESULT hr;
4344
4345     anno->flags = D3DX_PARAMETER_ANNOTATION;
4346
4347     read_dword(ptr, &offset);
4348     TRACE("Typedef offset: %#x\n", offset);
4349     ptr2 = data + offset;
4350     hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
4351     if (hr != D3D_OK)
4352     {
4353         WARN("Failed to parse type definition\n");
4354         return hr;
4355     }
4356
4357     read_dword(ptr, &offset);
4358     TRACE("Value offset: %#x\n", offset);
4359     hr = d3dx9_parse_init_value(anno, data, data + offset, objects);
4360     if (hr != D3D_OK)
4361     {
4362         WARN("Failed to parse value\n");
4363         return hr;
4364     }
4365
4366     return D3D_OK;
4367 }
4368
4369 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects)
4370 {
4371     DWORD offset;
4372     const char *ptr2;
4373     HRESULT hr;
4374     struct d3dx_parameter *parameter;
4375
4376     parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
4377     if (!parameter)
4378     {
4379         ERR("Out of memory\n");
4380         return E_OUTOFMEMORY;
4381     }
4382
4383     state->type = ST_CONSTANT;
4384
4385     read_dword(ptr, &state->operation);
4386     TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
4387
4388     read_dword(ptr, &state->index);
4389     TRACE("Index: %#x\n", state->index);
4390
4391     read_dword(ptr, &offset);
4392     TRACE("Typedef offset: %#x\n", offset);
4393     ptr2 = data + offset;
4394     hr = d3dx9_parse_effect_typedef(parameter, data, &ptr2, NULL, 0);
4395     if (hr != D3D_OK)
4396     {
4397         WARN("Failed to parse type definition\n");
4398         goto err_out;
4399     }
4400
4401     read_dword(ptr, &offset);
4402     TRACE("Value offset: %#x\n", offset);
4403     hr = d3dx9_parse_init_value(parameter, data, data + offset, objects);
4404     if (hr != D3D_OK)
4405     {
4406         WARN("Failed to parse value\n");
4407         goto err_out;
4408     }
4409
4410     state->parameter = get_parameter_handle(parameter);
4411
4412     return D3D_OK;
4413
4414 err_out:
4415
4416     free_parameter(get_parameter_handle(parameter), FALSE, FALSE);
4417
4418     return hr;
4419 }
4420
4421 static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data, const char **ptr, D3DXHANDLE *objects)
4422 {
4423     DWORD offset;
4424     HRESULT hr;
4425     unsigned int i;
4426     D3DXHANDLE *annotation_handles = NULL;
4427     const char *ptr2;
4428
4429     read_dword(ptr, &offset);
4430     TRACE("Typedef offset: %#x\n", offset);
4431     ptr2 = data + offset;
4432
4433     read_dword(ptr, &offset);
4434     TRACE("Value offset: %#x\n", offset);
4435
4436     read_dword(ptr, &param->flags);
4437     TRACE("Flags: %#x\n", param->flags);
4438
4439     read_dword(ptr, &param->annotation_count);
4440     TRACE("Annotation count: %u\n", param->annotation_count);
4441
4442     hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
4443     if (hr != D3D_OK)
4444     {
4445         WARN("Failed to parse type definition\n");
4446         return hr;
4447     }
4448
4449     hr = d3dx9_parse_init_value(param, data, data + offset, objects);
4450     if (hr != D3D_OK)
4451     {
4452         WARN("Failed to parse value\n");
4453         return hr;
4454     }
4455
4456     if (param->annotation_count)
4457     {
4458         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * param->annotation_count);
4459         if (!annotation_handles)
4460         {
4461             ERR("Out of memory\n");
4462             hr = E_OUTOFMEMORY;
4463             goto err_out;
4464         }
4465
4466         for (i = 0; i < param->annotation_count; ++i)
4467         {
4468             struct d3dx_parameter *annotation;
4469
4470             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
4471             if (!annotation)
4472             {
4473                 ERR("Out of memory\n");
4474                 hr = E_OUTOFMEMORY;
4475                 goto err_out;
4476             }
4477
4478             annotation_handles[i] = get_parameter_handle(annotation);
4479
4480             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
4481             if (hr != D3D_OK)
4482             {
4483                 WARN("Failed to parse annotation\n");
4484                 goto err_out;
4485             }
4486         }
4487     }
4488
4489     param->annotation_handles = annotation_handles;
4490
4491     return D3D_OK;
4492
4493 err_out:
4494
4495     if (annotation_handles)
4496     {
4497         for (i = 0; i < param->annotation_count; ++i)
4498         {
4499             free_parameter(annotation_handles[i], FALSE, FALSE);
4500         }
4501         HeapFree(GetProcessHeap(), 0, annotation_handles);
4502     }
4503
4504     return hr;
4505 }
4506
4507 static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr, D3DXHANDLE *objects)
4508 {
4509     DWORD offset;
4510     HRESULT hr;
4511     unsigned int i;
4512     D3DXHANDLE *annotation_handles = NULL;
4513     struct d3dx_state *states = NULL;
4514     char *name = NULL;
4515
4516     read_dword(ptr, &offset);
4517     TRACE("Pass name offset: %#x\n", offset);
4518     hr = d3dx9_parse_name(&name, data + offset);
4519     if (hr != D3D_OK)
4520     {
4521         WARN("Failed to parse name\n");
4522         goto err_out;
4523     }
4524
4525     read_dword(ptr, &pass->annotation_count);
4526     TRACE("Annotation count: %u\n", pass->annotation_count);
4527
4528     read_dword(ptr, &pass->state_count);
4529     TRACE("State count: %u\n", pass->state_count);
4530
4531     if (pass->annotation_count)
4532     {
4533         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count);
4534         if (!annotation_handles)
4535         {
4536             ERR("Out of memory\n");
4537             hr = E_OUTOFMEMORY;
4538             goto err_out;
4539         }
4540
4541         for (i = 0; i < pass->annotation_count; ++i)
4542         {
4543             struct d3dx_parameter *annotation;
4544
4545             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
4546             if (!annotation)
4547             {
4548                 ERR("Out of memory\n");
4549                 hr = E_OUTOFMEMORY;
4550                 goto err_out;
4551             }
4552
4553             annotation_handles[i] = get_parameter_handle(annotation);
4554
4555             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
4556             if (hr != D3D_OK)
4557             {
4558                 WARN("Failed to parse annotations\n");
4559                 goto err_out;
4560             }
4561         }
4562     }
4563
4564     if (pass->state_count)
4565     {
4566         states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
4567         if (!states)
4568         {
4569             ERR("Out of memory\n");
4570             hr = E_OUTOFMEMORY;
4571             goto err_out;
4572         }
4573
4574         for (i = 0; i < pass->state_count; ++i)
4575         {
4576             hr = d3dx9_parse_state(&states[i], data, ptr, objects);
4577             if (hr != D3D_OK)
4578             {
4579                 WARN("Failed to parse annotations\n");
4580                 goto err_out;
4581             }
4582         }
4583     }
4584
4585     pass->name = name;
4586     pass->annotation_handles = annotation_handles;
4587     pass->states = states;
4588
4589     return D3D_OK;
4590
4591 err_out:
4592
4593     if (annotation_handles)
4594     {
4595         for (i = 0; i < pass->annotation_count; ++i)
4596         {
4597             free_parameter(annotation_handles[i], FALSE, FALSE);
4598         }
4599         HeapFree(GetProcessHeap(), 0, annotation_handles);
4600     }
4601
4602     if (states)
4603     {
4604         for (i = 0; i < pass->state_count; ++i)
4605         {
4606             free_state(&states[i]);
4607         }
4608         HeapFree(GetProcessHeap(), 0, states);
4609     }
4610
4611     HeapFree(GetProcessHeap(), 0, name);
4612
4613     return hr;
4614 }
4615
4616 static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr, D3DXHANDLE *objects)
4617 {
4618     DWORD offset;
4619     HRESULT hr;
4620     unsigned int i;
4621     D3DXHANDLE *annotation_handles = NULL;
4622     D3DXHANDLE *pass_handles = NULL;
4623     char *name = NULL;
4624
4625     read_dword(ptr, &offset);
4626     TRACE("Technique name offset: %#x\n", offset);
4627     hr = d3dx9_parse_name(&name, data + offset);
4628     if (hr != D3D_OK)
4629     {
4630         WARN("Failed to parse name\n");
4631         goto err_out;
4632     }
4633
4634     read_dword(ptr, &technique->annotation_count);
4635     TRACE("Annotation count: %u\n", technique->annotation_count);
4636
4637     read_dword(ptr, &technique->pass_count);
4638     TRACE("Pass count: %u\n", technique->pass_count);
4639
4640     if (technique->annotation_count)
4641     {
4642         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count);
4643         if (!annotation_handles)
4644         {
4645             ERR("Out of memory\n");
4646             hr = E_OUTOFMEMORY;
4647             goto err_out;
4648         }
4649
4650         for (i = 0; i < technique->annotation_count; ++i)
4651         {
4652             struct d3dx_parameter *annotation;
4653
4654             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
4655             if (!annotation)
4656             {
4657                 ERR("Out of memory\n");
4658                 hr = E_OUTOFMEMORY;
4659                 goto err_out;
4660             }
4661
4662             annotation_handles[i] = get_parameter_handle(annotation);
4663
4664             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
4665             if (hr != D3D_OK)
4666             {
4667                 WARN("Failed to parse annotations\n");
4668                 goto err_out;
4669             }
4670         }
4671     }
4672
4673     if (technique->pass_count)
4674     {
4675         pass_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count);
4676         if (!pass_handles)
4677         {
4678             ERR("Out of memory\n");
4679             hr = E_OUTOFMEMORY;
4680             goto err_out;
4681         }
4682
4683         for (i = 0; i < technique->pass_count; ++i)
4684         {
4685             struct d3dx_pass *pass;
4686
4687             pass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass));
4688             if (!pass)
4689             {
4690                 ERR("Out of memory\n");
4691                 hr = E_OUTOFMEMORY;
4692                 goto err_out;
4693             }
4694
4695             pass_handles[i] = get_pass_handle(pass);
4696
4697             hr = d3dx9_parse_effect_pass(pass, data, ptr, objects);
4698             if (hr != D3D_OK)
4699             {
4700                 WARN("Failed to parse passes\n");
4701                 goto err_out;
4702             }
4703         }
4704     }
4705
4706     technique->name = name;
4707     technique->pass_handles = pass_handles;
4708     technique->annotation_handles = annotation_handles;
4709
4710     return D3D_OK;
4711
4712 err_out:
4713
4714     if (pass_handles)
4715     {
4716         for (i = 0; i < technique->pass_count; ++i)
4717         {
4718             free_pass(pass_handles[i]);
4719         }
4720         HeapFree(GetProcessHeap(), 0, pass_handles);
4721     }
4722
4723     if (annotation_handles)
4724     {
4725         for (i = 0; i < technique->annotation_count; ++i)
4726         {
4727             free_parameter(annotation_handles[i], FALSE, FALSE);
4728         }
4729         HeapFree(GetProcessHeap(), 0, annotation_handles);
4730     }
4731
4732     HeapFree(GetProcessHeap(), 0, name);
4733
4734     return hr;
4735 }
4736
4737 static HRESULT d3dx9_parse_resource(struct ID3DXBaseEffectImpl *base, const char *data, const char **ptr)
4738 {
4739     DWORD technique_index;
4740     DWORD index, state_index, usage, element_index;
4741     struct d3dx_state *state;
4742     struct d3dx_parameter *param;
4743     HRESULT hr = E_FAIL;
4744
4745     read_dword(ptr, &technique_index);
4746     TRACE("techn: %u\n", technique_index);
4747
4748     read_dword(ptr, &index);
4749     TRACE("index: %u\n", index);
4750
4751     read_dword(ptr, &element_index);
4752     TRACE("element_index: %u\n", element_index);
4753
4754     read_dword(ptr, &state_index);
4755     TRACE("state_index: %u\n", state_index);
4756
4757     read_dword(ptr, &usage);
4758     TRACE("usage: %u\n", usage);
4759
4760     if (technique_index == 0xffffffff)
4761     {
4762         struct d3dx_parameter *parameter;
4763         struct d3dx_sampler *sampler;
4764
4765         if (index >= base->parameter_count)
4766         {
4767             FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
4768             return E_FAIL;
4769         }
4770
4771         parameter = get_parameter_struct(base->parameter_handles[index]);
4772         if (element_index != 0xffffffff)
4773         {
4774             if (element_index >= parameter->element_count && parameter->element_count != 0)
4775             {
4776                 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
4777                 return E_FAIL;
4778             }
4779
4780             if (parameter->element_count != 0) parameter = get_parameter_struct(parameter->member_handles[element_index]);
4781         }
4782
4783         sampler = parameter->data;
4784         if (state_index >= sampler->state_count)
4785         {
4786             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
4787             return E_FAIL;
4788         }
4789
4790         state = &sampler->states[state_index];
4791     }
4792     else
4793     {
4794         struct d3dx_technique *technique;
4795         struct d3dx_pass *pass;
4796
4797         if (technique_index >= base->technique_count)
4798         {
4799             FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
4800             return E_FAIL;
4801         }
4802
4803         technique = get_technique_struct(base->technique_handles[technique_index]);
4804         if (index >= technique->pass_count)
4805         {
4806             FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
4807             return E_FAIL;
4808         }
4809
4810         pass = get_pass_struct(technique->pass_handles[index]);
4811         if (state_index >= pass->state_count)
4812         {
4813             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
4814             return E_FAIL;
4815         }
4816
4817         state = &pass->states[state_index];
4818     }
4819
4820     param = get_parameter_struct(state->parameter);
4821
4822     switch (usage)
4823     {
4824         case 0:
4825             TRACE("usage 0: type %s\n", debug_d3dxparameter_type(param->type));
4826             switch (param->type)
4827             {
4828                 case D3DXPT_VERTEXSHADER:
4829                 case D3DXPT_PIXELSHADER:
4830                     state->type = ST_CONSTANT;
4831                     hr = d3dx9_parse_data(param, ptr, base->effect->device);
4832                     break;
4833
4834                 case D3DXPT_BOOL:
4835                 case D3DXPT_INT:
4836                 case D3DXPT_FLOAT:
4837                 case D3DXPT_STRING:
4838                     state->type = ST_FXLC;
4839                     hr = d3dx9_copy_data(param->data, ptr);
4840                     break;
4841
4842                 default:
4843                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4844                     break;
4845             }
4846             break;
4847
4848         case 1:
4849             state->type = ST_PARAMETER;
4850             hr = d3dx9_copy_data(param->data, ptr);
4851             if (hr == D3D_OK)
4852             {
4853                 TRACE("Mapping to parameter %s\n", *(char **)param->data);
4854             }
4855             break;
4856
4857         default:
4858             FIXME("Unknown usage %x\n", usage);
4859             break;
4860     }
4861
4862     return hr;
4863 }
4864
4865 static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start)
4866 {
4867     const char *ptr = data + start;
4868     D3DXHANDLE *parameter_handles = NULL;
4869     D3DXHANDLE *technique_handles = NULL;
4870     D3DXHANDLE *objects = NULL;
4871     UINT stringcount, objectcount, resourcecount;
4872     HRESULT hr;
4873     UINT i;
4874
4875     read_dword(&ptr, &base->parameter_count);
4876     TRACE("Parameter count: %u\n", base->parameter_count);
4877
4878     read_dword(&ptr, &base->technique_count);
4879     TRACE("Technique count: %u\n", base->technique_count);
4880
4881     skip_dword_unknown(&ptr, 1);
4882
4883     read_dword(&ptr, &objectcount);
4884     TRACE("Object count: %u\n", objectcount);
4885
4886     objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*objects) * objectcount);
4887     if (!objects)
4888     {
4889         ERR("Out of memory\n");
4890         hr = E_OUTOFMEMORY;
4891         goto err_out;
4892     }
4893
4894     if (base->parameter_count)
4895     {
4896         parameter_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter_handles) * base->parameter_count);
4897         if (!parameter_handles)
4898         {
4899             ERR("Out of memory\n");
4900             hr = E_OUTOFMEMORY;
4901             goto err_out;
4902         }
4903
4904         for (i = 0; i < base->parameter_count; ++i)
4905         {
4906             struct d3dx_parameter *parameter;
4907
4908             parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
4909             if (!parameter)
4910             {
4911                 ERR("Out of memory\n");
4912                 hr = E_OUTOFMEMORY;
4913                 goto err_out;
4914             }
4915
4916             parameter_handles[i] = get_parameter_handle(parameter);
4917
4918             hr = d3dx9_parse_effect_parameter(parameter, data, &ptr, objects);
4919             if (hr != D3D_OK)
4920             {
4921                 WARN("Failed to parse parameter\n");
4922                 goto err_out;
4923             }
4924         }
4925     }
4926
4927     if (base->technique_count)
4928     {
4929         technique_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count);
4930         if (!technique_handles)
4931         {
4932             ERR("Out of memory\n");
4933             hr = E_OUTOFMEMORY;
4934             goto err_out;
4935         }
4936
4937         for (i = 0; i < base->technique_count; ++i)
4938         {
4939             struct d3dx_technique *technique;
4940
4941             technique = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique));
4942             if (!technique)
4943             {
4944                 ERR("Out of memory\n");
4945                 hr = E_OUTOFMEMORY;
4946                 goto err_out;
4947             }
4948
4949             technique_handles[i] = get_technique_handle(technique);
4950
4951             hr = d3dx9_parse_effect_technique(technique, data, &ptr, objects);
4952             if (hr != D3D_OK)
4953             {
4954                 WARN("Failed to parse technique\n");
4955                 goto err_out;
4956             }
4957         }
4958     }
4959
4960     /* needed for further parsing */
4961     base->technique_handles = technique_handles;
4962     base->parameter_handles = parameter_handles;
4963
4964     read_dword(&ptr, &stringcount);
4965     TRACE("String count: %u\n", stringcount);
4966
4967     read_dword(&ptr, &resourcecount);
4968     TRACE("Resource count: %u\n", resourcecount);
4969
4970     for (i = 0; i < stringcount; ++i)
4971     {
4972         DWORD id;
4973         struct d3dx_parameter *param;
4974
4975         read_dword(&ptr, &id);
4976         TRACE("Id: %u\n", id);
4977
4978         param = get_parameter_struct(objects[id]);
4979
4980         hr = d3dx9_parse_data(param, &ptr, base->effect->device);
4981         if (hr != D3D_OK)
4982         {
4983             WARN("Failed to parse data\n");
4984             goto err_out;
4985         }
4986     }
4987
4988     for (i = 0; i < resourcecount; ++i)
4989     {
4990         TRACE("parse resource %u\n", i);
4991
4992         hr = d3dx9_parse_resource(base, data, &ptr);
4993         if (hr != D3D_OK)
4994         {
4995             WARN("Failed to parse data\n");
4996             goto err_out;
4997         }
4998     }
4999
5000     HeapFree(GetProcessHeap(), 0, objects);
5001
5002     return D3D_OK;
5003
5004 err_out:
5005
5006     if (technique_handles)
5007     {
5008         for (i = 0; i < base->technique_count; ++i)
5009         {
5010             free_technique(technique_handles[i]);
5011         }
5012         HeapFree(GetProcessHeap(), 0, technique_handles);
5013     }
5014
5015     if (parameter_handles)
5016     {
5017         for (i = 0; i < base->parameter_count; ++i)
5018         {
5019             free_parameter(parameter_handles[i], FALSE, FALSE);
5020         }
5021         HeapFree(GetProcessHeap(), 0, parameter_handles);
5022     }
5023
5024     base->technique_handles = NULL;
5025     base->parameter_handles = NULL;
5026
5027     HeapFree(GetProcessHeap(), 0, objects);
5028
5029     return hr;
5030 }
5031
5032 static HRESULT d3dx9_base_effect_init(struct ID3DXBaseEffectImpl *base,
5033         const char *data, SIZE_T data_size, struct ID3DXEffectImpl *effect)
5034 {
5035     DWORD tag, offset;
5036     const char *ptr = data;
5037     HRESULT hr;
5038
5039     TRACE("base %p, data %p, data_size %lu, effect %p\n", base, data, data_size, effect);
5040
5041     base->ID3DXBaseEffect_iface.lpVtbl = &ID3DXBaseEffect_Vtbl;
5042     base->ref = 1;
5043     base->effect = effect;
5044
5045     read_dword(&ptr, &tag);
5046     TRACE("Tag: %x\n", tag);
5047
5048     if (tag != d3dx9_effect_version(9, 1))
5049     {
5050         /* todo: compile hlsl ascii code */
5051         FIXME("HLSL ascii effects not supported, yet\n");
5052
5053         /* Show the start of the shader for debugging info. */
5054         TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
5055     }
5056     else
5057     {
5058         read_dword(&ptr, &offset);
5059         TRACE("Offset: %x\n", offset);
5060
5061         hr = d3dx9_parse_effect(base, ptr, data_size, offset);
5062         if (hr != D3D_OK)
5063         {
5064             FIXME("Failed to parse effect.\n");
5065             return hr;
5066         }
5067     }
5068
5069     return D3D_OK;
5070 }
5071
5072 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
5073         const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
5074 {
5075     HRESULT hr;
5076     struct ID3DXBaseEffectImpl *object = NULL;
5077
5078     TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
5079
5080     effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
5081     effect->ref = 1;
5082
5083     if (pool) pool->lpVtbl->AddRef(pool);
5084     effect->pool = pool;
5085
5086     IDirect3DDevice9_AddRef(device);
5087     effect->device = device;
5088
5089     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5090     if (!object)
5091     {
5092         ERR("Out of memory\n");
5093         hr = E_OUTOFMEMORY;
5094         goto err_out;
5095     }
5096
5097     hr = d3dx9_base_effect_init(object, data, data_size, effect);
5098     if (hr != D3D_OK)
5099     {
5100         FIXME("Failed to parse effect.\n");
5101         goto err_out;
5102     }
5103
5104     effect->base_effect = &object->ID3DXBaseEffect_iface;
5105
5106     /* initialize defaults - check because of unsupported ascii effects */
5107     if (object->technique_handles)
5108     {
5109         effect->active_technique = object->technique_handles[0];
5110         effect->active_pass = NULL;
5111     }
5112
5113     return D3D_OK;
5114
5115 err_out:
5116
5117     HeapFree(GetProcessHeap(), 0, object);
5118     free_effect(effect);
5119
5120     return hr;
5121 }
5122
5123 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
5124                                   LPCVOID srcdata,
5125                                   UINT srcdatalen,
5126                                   CONST D3DXMACRO* defines,
5127                                   LPD3DXINCLUDE include,
5128                                   LPCSTR skip_constants,
5129                                   DWORD flags,
5130                                   LPD3DXEFFECTPOOL pool,
5131                                   LPD3DXEFFECT* effect,
5132                                   LPD3DXBUFFER* compilation_errors)
5133 {
5134     struct ID3DXEffectImpl *object;
5135     HRESULT hr;
5136
5137     FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
5138         skip_constants, flags, pool, effect, compilation_errors);
5139
5140     if (!device || !srcdata)
5141         return D3DERR_INVALIDCALL;
5142
5143     if (!srcdatalen)
5144         return E_FAIL;
5145
5146     /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
5147     if (!effect)
5148         return D3D_OK;
5149
5150     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5151     if (!object)
5152     {
5153         ERR("Out of memory\n");
5154         return E_OUTOFMEMORY;
5155     }
5156
5157     hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, pool);
5158     if (FAILED(hr))
5159     {
5160         WARN("Failed to initialize shader reflection\n");
5161         HeapFree(GetProcessHeap(), 0, object);
5162         return hr;
5163     }
5164
5165     *effect = &object->ID3DXEffect_iface;
5166
5167     TRACE("Created ID3DXEffect %p\n", object);
5168
5169     return D3D_OK;
5170 }
5171
5172 HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
5173                                 LPCVOID srcdata,
5174                                 UINT srcdatalen,
5175                                 CONST D3DXMACRO* defines,
5176                                 LPD3DXINCLUDE include,
5177                                 DWORD flags,
5178                                 LPD3DXEFFECTPOOL pool,
5179                                 LPD3DXEFFECT* effect,
5180                                 LPD3DXBUFFER* compilation_errors)
5181 {
5182     TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
5183         include, flags, pool, effect, compilation_errors);
5184
5185     return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
5186 }
5187
5188 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, const char *data, SIZE_T data_size)
5189 {
5190     HRESULT hr;
5191     struct ID3DXBaseEffectImpl *object = NULL;
5192
5193     TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
5194
5195     compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
5196     compiler->ref = 1;
5197
5198     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5199     if (!object)
5200     {
5201         ERR("Out of memory\n");
5202         hr = E_OUTOFMEMORY;
5203         goto err_out;
5204     }
5205
5206     hr = d3dx9_base_effect_init(object, data, data_size, NULL);
5207     if (hr != D3D_OK)
5208     {
5209         FIXME("Failed to parse effect.\n");
5210         goto err_out;
5211     }
5212
5213     compiler->base_effect = &object->ID3DXBaseEffect_iface;
5214
5215     return D3D_OK;
5216
5217 err_out:
5218
5219     HeapFree(GetProcessHeap(), 0, object);
5220     free_effect_compiler(compiler);
5221
5222     return hr;
5223 }
5224
5225 HRESULT WINAPI D3DXCreateEffectCompiler(LPCSTR srcdata,
5226                                         UINT srcdatalen,
5227                                         CONST D3DXMACRO *defines,
5228                                         LPD3DXINCLUDE include,
5229                                         DWORD flags,
5230                                         LPD3DXEFFECTCOMPILER *compiler,
5231                                         LPD3DXBUFFER *parse_errors)
5232 {
5233     struct ID3DXEffectCompilerImpl *object;
5234     HRESULT hr;
5235
5236     TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
5237             srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
5238
5239     if (!srcdata || !compiler)
5240     {
5241         WARN("Invalid arguments supplied\n");
5242         return D3DERR_INVALIDCALL;
5243     }
5244
5245     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5246     if (!object)
5247     {
5248         ERR("Out of memory\n");
5249         return E_OUTOFMEMORY;
5250     }
5251
5252     hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen);
5253     if (FAILED(hr))
5254     {
5255         WARN("Failed to initialize effect compiler\n");
5256         HeapFree(GetProcessHeap(), 0, object);
5257         return hr;
5258     }
5259
5260     *compiler = &object->ID3DXEffectCompiler_iface;
5261
5262     TRACE("Created ID3DXEffectCompiler %p\n", object);
5263
5264     return D3D_OK;
5265 }
5266
5267 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl;
5268
5269 struct ID3DXEffectPoolImpl
5270 {
5271     ID3DXEffectPool ID3DXEffectPool_iface;
5272     LONG ref;
5273 };
5274
5275 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
5276 {
5277     return CONTAINING_RECORD(iface, struct ID3DXEffectPoolImpl, ID3DXEffectPool_iface);
5278 }
5279
5280 /*** IUnknown methods ***/
5281 static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
5282 {
5283     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5284
5285     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
5286
5287     if (IsEqualGUID(riid, &IID_IUnknown) ||
5288         IsEqualGUID(riid, &IID_ID3DXEffectPool))
5289     {
5290         This->ID3DXEffectPool_iface.lpVtbl->AddRef(iface);
5291         *object = This;
5292         return S_OK;
5293     }
5294
5295     WARN("Interface %s not found\n", debugstr_guid(riid));
5296
5297     return E_NOINTERFACE;
5298 }
5299
5300 static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool *iface)
5301 {
5302     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5303
5304     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
5305
5306     return InterlockedIncrement(&This->ref);
5307 }
5308
5309 static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool *iface)
5310 {
5311     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5312     ULONG ref = InterlockedDecrement(&This->ref);
5313
5314     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
5315
5316     if (!ref)
5317         HeapFree(GetProcessHeap(), 0, This);
5318
5319     return ref;
5320 }
5321
5322 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
5323 {
5324     /*** IUnknown methods ***/
5325     ID3DXEffectPoolImpl_QueryInterface,
5326     ID3DXEffectPoolImpl_AddRef,
5327     ID3DXEffectPoolImpl_Release
5328 };
5329
5330 HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL *pool)
5331 {
5332     struct ID3DXEffectPoolImpl *object;
5333
5334     TRACE("(%p)\n", pool);
5335
5336     if (!pool)
5337         return D3DERR_INVALIDCALL;
5338
5339     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5340     if (!object)
5341     {
5342         ERR("Out of memory\n");
5343         return E_OUTOFMEMORY;
5344     }
5345
5346     object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
5347     object->ref = 1;
5348
5349     *pool = &object->ID3DXEffectPool_iface;
5350
5351     return S_OK;
5352 }
5353
5354 HRESULT WINAPI D3DXCreateEffectFromFileExW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
5355     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5356     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5357 {
5358     LPVOID buffer;
5359     HRESULT ret;
5360     DWORD size;
5361
5362     TRACE("(%s): relay\n", debugstr_w(srcfile));
5363
5364     if (!device || !srcfile)
5365         return D3DERR_INVALIDCALL;
5366
5367     ret = map_view_of_file(srcfile, &buffer, &size);
5368
5369     if (FAILED(ret))
5370         return D3DXERR_INVALIDDATA;
5371
5372     ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5373     UnmapViewOfFile(buffer);
5374
5375     return ret;
5376 }
5377
5378 HRESULT WINAPI D3DXCreateEffectFromFileExA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
5379     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5380     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5381 {
5382     LPWSTR srcfileW;
5383     HRESULT ret;
5384     DWORD len;
5385
5386     TRACE("(void): relay\n");
5387
5388     if (!srcfile)
5389         return D3DERR_INVALIDCALL;
5390
5391     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
5392     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
5393     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
5394
5395     ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5396     HeapFree(GetProcessHeap(), 0, srcfileW);
5397
5398     return ret;
5399 }
5400
5401 HRESULT WINAPI D3DXCreateEffectFromFileW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
5402     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5403     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5404 {
5405     TRACE("(void): relay\n");
5406     return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
5407 }
5408
5409 HRESULT WINAPI D3DXCreateEffectFromFileA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
5410     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5411     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5412 {
5413     TRACE("(void): relay\n");
5414     return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
5415 }
5416
5417 HRESULT WINAPI D3DXCreateEffectFromResourceExW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
5418     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5419     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5420 {
5421     HRSRC resinfo;
5422
5423     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
5424
5425     if (!device)
5426         return D3DERR_INVALIDCALL;
5427
5428     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
5429
5430     if (resinfo)
5431     {
5432         LPVOID buffer;
5433         HRESULT ret;
5434         DWORD size;
5435
5436         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5437
5438         if (FAILED(ret))
5439             return D3DXERR_INVALIDDATA;
5440
5441         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5442     }
5443
5444     return D3DXERR_INVALIDDATA;
5445 }
5446
5447 HRESULT WINAPI D3DXCreateEffectFromResourceExA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
5448     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5449     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5450 {
5451     HRSRC resinfo;
5452
5453     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
5454
5455     if (!device)
5456         return D3DERR_INVALIDCALL;
5457
5458     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
5459
5460     if (resinfo)
5461     {
5462         LPVOID buffer;
5463         HRESULT ret;
5464         DWORD size;
5465
5466         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5467
5468         if (FAILED(ret))
5469             return D3DXERR_INVALIDDATA;
5470
5471         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
5472     }
5473
5474     return D3DXERR_INVALIDDATA;
5475 }
5476
5477 HRESULT WINAPI D3DXCreateEffectFromResourceW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
5478     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5479     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5480 {
5481     TRACE("(void): relay\n");
5482     return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
5483 }
5484
5485 HRESULT WINAPI D3DXCreateEffectFromResourceA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
5486     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
5487     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5488 {
5489     TRACE("(void): relay\n");
5490     return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
5491 }
5492
5493 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(LPCWSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
5494     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5495 {
5496     LPVOID buffer;
5497     HRESULT ret;
5498     DWORD size;
5499
5500     TRACE("(%s): relay\n", debugstr_w(srcfile));
5501
5502     if (!srcfile)
5503         return D3DERR_INVALIDCALL;
5504
5505     ret = map_view_of_file(srcfile, &buffer, &size);
5506
5507     if (FAILED(ret))
5508         return D3DXERR_INVALIDDATA;
5509
5510     ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
5511     UnmapViewOfFile(buffer);
5512
5513     return ret;
5514 }
5515
5516 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
5517     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5518 {
5519     LPWSTR srcfileW;
5520     HRESULT ret;
5521     DWORD len;
5522
5523     TRACE("(void): relay\n");
5524
5525     if (!srcfile)
5526         return D3DERR_INVALIDCALL;
5527
5528     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
5529     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
5530     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
5531
5532     ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
5533     HeapFree(GetProcessHeap(), 0, srcfileW);
5534
5535     return ret;
5536 }
5537
5538 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, LPCSTR srcresource, const D3DXMACRO *defines,
5539     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5540 {
5541     HRSRC resinfo;
5542
5543     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
5544
5545     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
5546
5547     if (resinfo)
5548     {
5549         LPVOID buffer;
5550         HRESULT ret;
5551         DWORD size;
5552
5553         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5554
5555         if (FAILED(ret))
5556             return D3DXERR_INVALIDDATA;
5557
5558         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
5559     }
5560
5561     return D3DXERR_INVALIDDATA;
5562 }
5563
5564 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, LPCWSTR srcresource, const D3DXMACRO *defines,
5565     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
5566 {
5567     HRSRC resinfo;
5568
5569     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
5570
5571     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
5572
5573     if (resinfo)
5574     {
5575         LPVOID buffer;
5576         HRESULT ret;
5577         DWORD size;
5578
5579         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
5580
5581         if (FAILED(ret))
5582             return D3DXERR_INVALIDDATA;
5583
5584         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
5585     }
5586
5587     return D3DXERR_INVALIDDATA;
5588 }