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