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