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