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