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