wined3d: Unroll SM4+ pixel shader inputs.
[wine.git] / dlls / d3dx9_36 / effect.c
blobce2e5d86e5f0cc8c6421e7fd849449ac1886ce62
1 /*
2 * Copyright 2010 Christian Costa
3 * Copyright 2011 Rico Schüller
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.
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.
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
20 #include "config.h"
21 #include "wine/port.h"
23 #include "d3dx9_private.h"
24 #include "d3dcompiler.h"
26 /* Constants for special INT/FLOAT conversation */
27 #define INT_FLOAT_MULTI 255.0f
28 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
30 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
32 #define PARAMETER_FLAG_SHARED 1
34 #define INITIAL_POOL_SIZE 16
36 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
38 enum STATE_CLASS
40 SC_LIGHTENABLE,
41 SC_FVF,
42 SC_LIGHT,
43 SC_MATERIAL,
44 SC_NPATCHMODE,
45 SC_PIXELSHADER,
46 SC_RENDERSTATE,
47 SC_SETSAMPLER,
48 SC_SAMPLERSTATE,
49 SC_TEXTURE,
50 SC_TEXTURESTAGE,
51 SC_TRANSFORM,
52 SC_VERTEXSHADER,
53 SC_SHADERCONST,
54 SC_UNKNOWN,
57 enum MATERIAL_TYPE
59 MT_DIFFUSE,
60 MT_AMBIENT,
61 MT_SPECULAR,
62 MT_EMISSIVE,
63 MT_POWER,
66 enum LIGHT_TYPE
68 LT_TYPE,
69 LT_DIFFUSE,
70 LT_SPECULAR,
71 LT_AMBIENT,
72 LT_POSITION,
73 LT_DIRECTION,
74 LT_RANGE,
75 LT_FALLOFF,
76 LT_ATTENUATION0,
77 LT_ATTENUATION1,
78 LT_ATTENUATION2,
79 LT_THETA,
80 LT_PHI,
83 enum SHADER_CONSTANT_TYPE
85 SCT_VSFLOAT,
86 SCT_VSBOOL,
87 SCT_VSINT,
88 SCT_PSFLOAT,
89 SCT_PSBOOL,
90 SCT_PSINT,
93 enum STATE_TYPE
95 ST_CONSTANT,
96 ST_PARAMETER,
97 ST_FXLC,
98 ST_ARRAY_SELECTOR,
101 struct d3dx_object
103 UINT size;
104 void *data;
105 struct d3dx_parameter *param;
106 BOOL creation_failed;
109 struct d3dx_state
111 UINT operation;
112 UINT index;
113 enum STATE_TYPE type;
114 struct d3dx_parameter parameter;
115 struct d3dx_parameter *referenced_param;
118 struct d3dx_sampler
120 UINT state_count;
121 struct d3dx_state *states;
124 struct d3dx_pass
126 char *name;
127 UINT state_count;
128 UINT annotation_count;
130 struct d3dx_state *states;
131 struct d3dx_parameter *annotations;
133 ULONG64 update_version;
136 struct d3dx_technique
138 char *name;
139 UINT pass_count;
140 UINT annotation_count;
142 struct d3dx_parameter *annotations;
143 struct d3dx_pass *passes;
145 struct IDirect3DStateBlock9 *saved_state;
148 struct d3dx9_base_effect
150 struct ID3DXEffectImpl *effect;
152 UINT parameter_count;
153 UINT technique_count;
154 UINT object_count;
156 struct d3dx_top_level_parameter *parameters;
157 struct d3dx_technique *techniques;
158 struct d3dx_object *objects;
160 struct d3dx_effect_pool *pool;
161 DWORD flags;
163 ULONG64 version_counter;
166 struct ID3DXEffectImpl
168 ID3DXEffect ID3DXEffect_iface;
169 LONG ref;
171 struct d3dx9_base_effect base_effect;
173 struct ID3DXEffectStateManager *manager;
174 struct IDirect3DDevice9 *device;
175 struct ID3DXEffectPool *pool;
176 struct d3dx_technique *active_technique;
177 struct d3dx_pass *active_pass;
178 BOOL started;
179 DWORD begin_flags;
181 D3DLIGHT9 current_light[8];
182 unsigned int light_updated;
183 D3DMATERIAL9 current_material;
184 BOOL material_updated;
187 #define INITIAL_SHARED_DATA_SIZE 4
189 struct d3dx_effect_pool
191 ID3DXEffectPool ID3DXEffectPool_iface;
192 LONG refcount;
194 struct d3dx_shared_data *shared_data;
195 unsigned int size;
197 ULONG64 version_counter;
200 struct ID3DXEffectCompilerImpl
202 ID3DXEffectCompiler ID3DXEffectCompiler_iface;
203 LONG ref;
205 struct d3dx9_base_effect base_effect;
208 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *parameters,
209 const char *name);
210 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
211 const char *data, const char **ptr, struct d3dx_object *objects);
212 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
214 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param);
216 static const struct
218 enum STATE_CLASS class;
219 UINT op;
220 const char *name;
222 state_table[] =
224 /* Render states */
225 {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
226 {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
227 {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
228 {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
229 {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
230 {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
231 {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
232 {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
233 {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
234 {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
235 {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
236 {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
237 {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
238 {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
239 {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
240 {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
241 {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
242 {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
243 {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
244 {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
245 {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
246 {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
247 {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
248 {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
249 {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
250 {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
251 {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
252 {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
253 {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
254 {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
255 {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
256 {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
257 {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
258 {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
259 {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
260 {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
261 {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
262 {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
263 {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
264 {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
265 {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
266 {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
267 {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
268 {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
269 {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
270 {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
271 {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
272 {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
273 {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
274 {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
275 {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
276 {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
277 {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
278 {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
279 {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
280 {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
281 {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
282 {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
283 {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
284 {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
285 {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
286 {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
287 {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
288 {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
289 {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
290 {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
291 {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
292 {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
293 {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
294 {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
295 {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
296 {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
297 {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
298 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
299 {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
300 {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
301 {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
302 {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
303 {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
304 {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
305 {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
306 {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
307 {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
308 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
309 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
310 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
311 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
312 {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
313 {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
314 {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
315 {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
316 {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
317 {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
318 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
319 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
320 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
321 {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
322 {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
323 {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
324 {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
325 {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
326 {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
327 {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
328 /* Texture stages */
329 {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
330 {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
331 {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
332 {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
333 {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
334 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
335 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
336 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
337 {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
338 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
339 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
340 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
341 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
342 {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
343 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
344 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
345 {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
346 {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
347 /* NPatchMode */
348 {SC_NPATCHMODE, 0, "NPatchMode"},
349 /* FVF */
350 {SC_FVF, 0, "FVF"},
351 /* Transform */
352 {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
353 {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
354 {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
355 {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
356 /* Material */
357 {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
358 {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
359 {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
360 {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
361 {SC_MATERIAL, MT_POWER, "MaterialPower"},
362 /* Light */
363 {SC_LIGHT, LT_TYPE, "LightType"},
364 {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
365 {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
366 {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
367 {SC_LIGHT, LT_POSITION, "LightPosition"},
368 {SC_LIGHT, LT_DIRECTION, "LightDirection"},
369 {SC_LIGHT, LT_RANGE, "LightRange"},
370 {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
371 {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
372 {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
373 {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
374 {SC_LIGHT, LT_THETA, "LightTheta"},
375 {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
376 /* Lightenable */
377 {SC_LIGHTENABLE, 0, "LightEnable"},
378 /* Vertexshader */
379 {SC_VERTEXSHADER, 0, "Vertexshader"},
380 /* Pixelshader */
381 {SC_PIXELSHADER, 0, "Pixelshader"},
382 /* Shader constants */
383 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
384 {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
385 {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
386 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
387 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
388 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
389 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
390 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
391 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
392 {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
393 {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
394 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
395 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
396 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
397 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
398 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
399 /* Texture */
400 {SC_TEXTURE, 0, "Texture"},
401 /* Sampler states */
402 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
403 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
404 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
405 {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
406 {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
407 {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
408 {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
409 {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
410 {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
411 {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
412 {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
413 {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
414 {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
415 /* Set sampler */
416 {SC_SETSAMPLER, 0, "Sampler"},
419 static inline void read_dword(const char **ptr, DWORD *d)
421 memcpy(d, *ptr, sizeof(*d));
422 *ptr += sizeof(*d);
425 static void skip_dword_unknown(const char **ptr, unsigned int count)
427 unsigned int i;
428 DWORD d;
430 WARN("Skipping %u unknown DWORDs:\n", count);
431 for (i = 0; i < count; ++i)
433 read_dword(ptr, &d);
434 WARN("\t0x%08x\n", d);
438 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
440 return (D3DXHANDLE)parameter;
443 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
445 return (D3DXHANDLE)technique;
448 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
450 return (D3DXHANDLE)pass;
453 static struct d3dx_technique *get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
455 UINT i;
457 if (!name) return NULL;
459 for (i = 0; i < base->technique_count; ++i)
461 if (!strcmp(base->techniques[i].name, name))
462 return &base->techniques[i];
465 return NULL;
468 static struct d3dx_technique *get_valid_technique(struct d3dx9_base_effect *base, D3DXHANDLE technique)
470 unsigned int i;
472 for (i = 0; i < base->technique_count; ++i)
474 if (get_technique_handle(&base->techniques[i]) == technique)
475 return &base->techniques[i];
478 return get_technique_by_name(base, technique);
481 static struct d3dx_pass *get_valid_pass(struct d3dx9_base_effect *base, D3DXHANDLE pass)
483 unsigned int i, k;
485 for (i = 0; i < base->technique_count; ++i)
487 struct d3dx_technique *technique = &base->techniques[i];
489 for (k = 0; k < technique->pass_count; ++k)
491 if (get_pass_handle(&technique->passes[k]) == pass)
492 return &technique->passes[k];
496 return NULL;
499 static struct d3dx_parameter *get_valid_parameter(struct d3dx9_base_effect *base, D3DXHANDLE parameter)
501 struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter;
503 if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string,
504 sizeof(parameter_magic_string)))
505 return handle_param;
507 return base->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(base, NULL, parameter);
510 static void free_state(struct d3dx_state *state)
512 free_parameter(&state->parameter, FALSE, FALSE);
515 static void free_object(struct d3dx_object *object)
517 HeapFree(GetProcessHeap(), 0, object->data);
520 static void free_sampler(struct d3dx_sampler *sampler)
522 UINT i;
524 for (i = 0; i < sampler->state_count; ++i)
526 free_state(&sampler->states[i]);
528 HeapFree(GetProcessHeap(), 0, sampler->states);
531 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param);
533 static void free_parameter_data(struct d3dx_parameter *param, BOOL child)
535 if (!param->data)
536 return;
537 if (param->class == D3DXPC_OBJECT && !param->element_count)
539 switch (param->type)
541 case D3DXPT_STRING:
542 HeapFree(GetProcessHeap(), 0, *(char **)param->data);
543 break;
545 case D3DXPT_TEXTURE:
546 case D3DXPT_TEXTURE1D:
547 case D3DXPT_TEXTURE2D:
548 case D3DXPT_TEXTURE3D:
549 case D3DXPT_TEXTURECUBE:
550 case D3DXPT_PIXELSHADER:
551 case D3DXPT_VERTEXSHADER:
552 if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
553 break;
555 case D3DXPT_SAMPLER:
556 case D3DXPT_SAMPLER1D:
557 case D3DXPT_SAMPLER2D:
558 case D3DXPT_SAMPLER3D:
559 case D3DXPT_SAMPLERCUBE:
560 free_sampler((struct d3dx_sampler *)param->data);
561 break;
563 default:
564 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
565 break;
568 if (!child)
569 HeapFree(GetProcessHeap(), 0, param->data);
572 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child)
574 unsigned int i;
576 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name,
577 debug_d3dxparameter_type(param->type), element, child);
579 if (param->param_eval)
580 d3dx_free_param_eval(param->param_eval);
582 if (param->members)
584 unsigned int count = param->element_count ? param->element_count : param->member_count;
586 for (i = 0; i < count; ++i)
587 free_parameter(&param->members[i], param->element_count != 0, TRUE);
588 HeapFree(GetProcessHeap(), 0, param->members);
591 free_parameter_data(param, child);
593 /* only the parent has to release name and semantic */
594 if (!element)
596 HeapFree(GetProcessHeap(), 0, param->name);
597 HeapFree(GetProcessHeap(), 0, param->semantic);
601 static void free_top_level_parameter(struct d3dx_top_level_parameter *param)
603 if (param->annotations)
605 unsigned int i;
607 for (i = 0; i < param->annotation_count; ++i)
608 free_parameter(&param->annotations[i], FALSE, FALSE);
609 HeapFree(GetProcessHeap(), 0, param->annotations);
611 d3dx_pool_release_shared_parameter(param);
612 free_parameter(&param->param, FALSE, FALSE);
615 static void free_pass(struct d3dx_pass *pass)
617 unsigned int i;
619 TRACE("Free pass %p\n", pass);
621 if (!pass)
622 return;
624 if (pass->annotations)
626 for (i = 0; i < pass->annotation_count; ++i)
627 free_parameter(&pass->annotations[i], FALSE, FALSE);
628 HeapFree(GetProcessHeap(), 0, pass->annotations);
629 pass->annotations = NULL;
632 if (pass->states)
634 for (i = 0; i < pass->state_count; ++i)
635 free_state(&pass->states[i]);
636 HeapFree(GetProcessHeap(), 0, pass->states);
637 pass->states = NULL;
640 HeapFree(GetProcessHeap(), 0, pass->name);
641 pass->name = NULL;
644 static void free_technique(struct d3dx_technique *technique)
646 unsigned int i;
648 TRACE("Free technique %p\n", technique);
650 if (!technique)
651 return;
653 if (technique->saved_state)
655 IDirect3DStateBlock9_Release(technique->saved_state);
656 technique->saved_state = NULL;
659 if (technique->annotations)
661 for (i = 0; i < technique->annotation_count; ++i)
662 free_parameter(&technique->annotations[i], FALSE, FALSE);
663 HeapFree(GetProcessHeap(), 0, technique->annotations);
664 technique->annotations = NULL;
667 if (technique->passes)
669 for (i = 0; i < technique->pass_count; ++i)
670 free_pass(&technique->passes[i]);
671 HeapFree(GetProcessHeap(), 0, technique->passes);
672 technique->passes = NULL;
675 HeapFree(GetProcessHeap(), 0, technique->name);
676 technique->name = NULL;
679 static void d3dx9_base_effect_cleanup(struct d3dx9_base_effect *base)
681 unsigned int i;
683 TRACE("base %p.\n", base);
685 if (base->parameters)
687 for (i = 0; i < base->parameter_count; ++i)
688 free_top_level_parameter(&base->parameters[i]);
689 HeapFree(GetProcessHeap(), 0, base->parameters);
690 base->parameters = NULL;
693 if (base->techniques)
695 for (i = 0; i < base->technique_count; ++i)
696 free_technique(&base->techniques[i]);
697 HeapFree(GetProcessHeap(), 0, base->techniques);
698 base->techniques = NULL;
701 if (base->objects)
703 for (i = 0; i < base->object_count; ++i)
705 free_object(&base->objects[i]);
707 HeapFree(GetProcessHeap(), 0, base->objects);
708 base->objects = NULL;
712 static void free_effect(struct ID3DXEffectImpl *effect)
714 TRACE("Free effect %p\n", effect);
716 d3dx9_base_effect_cleanup(&effect->base_effect);
718 if (effect->pool)
720 effect->pool->lpVtbl->Release(effect->pool);
723 if (effect->manager)
725 IUnknown_Release(effect->manager);
728 IDirect3DDevice9_Release(effect->device);
731 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
733 TRACE("Free effect compiler %p\n", compiler);
735 d3dx9_base_effect_cleanup(&compiler->base_effect);
738 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
740 UINT i;
742 for (i = 0; i < 4; ++i)
744 if (i < param->columns)
745 set_number((FLOAT *)vector + i, D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
746 else
747 ((FLOAT *)vector)[i] = 0.0f;
751 static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector)
753 UINT i;
755 for (i = 0; i < param->columns; ++i)
757 set_number((FLOAT *)param->data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
761 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
763 UINT i, k;
765 for (i = 0; i < 4; ++i)
767 for (k = 0; k < 4; ++k)
769 FLOAT *tmp = transpose ? (FLOAT *)&matrix->u.m[k][i] : (FLOAT *)&matrix->u.m[i][k];
771 if ((i < param->rows) && (k < param->columns))
772 set_number(tmp, D3DXPT_FLOAT, (DWORD *)param->data + i * param->columns + k, param->type);
773 else
774 *tmp = 0.0f;
779 static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix)
781 UINT i, k;
783 if (param->type == D3DXPT_FLOAT)
785 if (param->columns == 4)
786 memcpy(param->data, matrix->u.m, param->rows * 4 * sizeof(float));
787 else
788 for (i = 0; i < param->rows; ++i)
789 memcpy((float *)param->data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float));
790 return;
793 for (i = 0; i < param->rows; ++i)
795 for (k = 0; k < param->columns; ++k)
797 set_number((FLOAT *)param->data + i * param->columns + k, param->type,
798 &matrix->u.m[i][k], D3DXPT_FLOAT);
803 static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix)
805 UINT i, k;
807 for (i = 0; i < param->rows; ++i)
809 for (k = 0; k < param->columns; ++k)
811 set_number((FLOAT *)param->data + i * param->columns + k, param->type,
812 &matrix->u.m[k][i], D3DXPT_FLOAT);
817 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_parameter *parameter, const char *name)
819 UINT element;
820 struct d3dx_parameter *temp_parameter;
821 const char *part;
823 TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
825 if (!name || !*name) return NULL;
827 element = atoi(name);
828 part = strchr(name, ']') + 1;
830 /* check for empty [] && element range */
831 if ((part - name) > 1 && parameter->element_count > element)
833 temp_parameter = &parameter->members[element];
835 switch (*part++)
837 case '.':
838 return get_parameter_by_name(NULL, temp_parameter, part);
840 case '\0':
841 TRACE("Returning parameter %p\n", temp_parameter);
842 return temp_parameter;
844 default:
845 FIXME("Unhandled case \"%c\"\n", *--part);
846 break;
850 TRACE("Parameter not found\n");
851 return NULL;
854 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *annotations,
855 const char *name)
857 UINT i, length;
858 struct d3dx_parameter *temp_parameter;
859 const char *part;
861 TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name));
863 if (!name || !*name) return NULL;
865 length = strcspn( name, "[.@" );
866 part = name + length;
868 for (i = 0; i < count; ++i)
870 temp_parameter = &annotations[i];
872 if (!strcmp(temp_parameter->name, name))
874 TRACE("Returning annotation %p\n", temp_parameter);
875 return temp_parameter;
877 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
879 switch (*part++)
881 case '.':
882 return get_parameter_by_name(NULL, temp_parameter, part);
884 case '[':
885 return get_parameter_element_by_name(temp_parameter, part);
887 default:
888 FIXME("Unhandled case \"%c\"\n", *--part);
889 break;
894 TRACE("Annotation not found\n");
895 return NULL;
898 struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
899 struct d3dx_parameter *parameter, const char *name)
901 UINT i, count, length;
902 struct d3dx_parameter *temp_parameter;
903 const char *part;
905 TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
907 if (!name || !*name) return NULL;
909 count = parameter ? parameter->member_count : base->parameter_count;
910 length = strcspn( name, "[.@" );
911 part = name + length;
913 for (i = 0; i < count; i++)
915 temp_parameter = !parameter ? &base->parameters[i].param
916 : &parameter->members[i];
918 if (!strcmp(temp_parameter->name, name))
920 TRACE("Returning parameter %p\n", temp_parameter);
921 return temp_parameter;
923 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
925 switch (*part++)
927 case '.':
928 return get_parameter_by_name(NULL, temp_parameter, part);
930 case '@':
932 struct d3dx_top_level_parameter *top_param
933 = top_level_parameter_from_parameter(temp_parameter);
935 return parameter ? NULL : get_annotation_by_name(top_param->annotation_count,
936 top_param->annotations, part);
938 case '[':
939 return get_parameter_element_by_name(temp_parameter, part);
941 default:
942 FIXME("Unhandled case \"%c\"\n", *--part);
943 break;
948 TRACE("Parameter not found\n");
949 return NULL;
952 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
954 return (0xfeff0000 | ((major) << 8) | (minor));
957 static HRESULT d3dx9_base_effect_get_desc(struct d3dx9_base_effect *base, D3DXEFFECT_DESC *desc)
959 if (!desc)
961 WARN("Invalid argument specified.\n");
962 return D3DERR_INVALIDCALL;
965 FIXME("partial stub!\n");
967 /* TODO: add creator and function count. */
968 desc->Creator = NULL;
969 desc->Functions = 0;
970 desc->Parameters = base->parameter_count;
971 desc->Techniques = base->technique_count;
973 return D3D_OK;
976 static HRESULT d3dx9_base_effect_get_parameter_desc(struct d3dx9_base_effect *base,
977 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
979 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
981 if (!desc || !param)
983 WARN("Invalid argument specified.\n");
984 return D3DERR_INVALIDCALL;
987 desc->Name = param->name;
988 desc->Semantic = param->semantic;
989 desc->Class = param->class;
990 desc->Type = param->type;
991 desc->Rows = param->rows;
992 desc->Columns = param->columns;
993 desc->Elements = param->element_count;
994 desc->Annotations = is_top_level_parameter(param)
995 ? top_level_parameter_from_parameter(param)->annotation_count : 0;
996 desc->StructMembers = param->member_count;
997 desc->Flags = param->flags;
998 desc->Bytes = param->bytes;
1000 return D3D_OK;
1003 static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *base,
1004 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1006 struct d3dx_technique *tech = technique ? get_valid_technique(base, technique) : &base->techniques[0];
1008 if (!desc || !tech)
1010 WARN("Invalid argument specified.\n");
1011 return D3DERR_INVALIDCALL;
1014 desc->Name = tech->name;
1015 desc->Passes = tech->pass_count;
1016 desc->Annotations = tech->annotation_count;
1018 return D3D_OK;
1021 static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
1022 void **param_value, struct d3dx_parameter **out_param,
1023 BOOL update_all, BOOL *param_dirty)
1025 struct d3dx_parameter *param = &state->parameter;
1027 *param_value = NULL;
1028 *out_param = NULL;
1029 *param_dirty = FALSE;
1031 switch (state->type)
1033 case ST_PARAMETER:
1034 param = state->referenced_param;
1035 *param_dirty = is_param_dirty(param, pass->update_version);
1036 /* fallthrough */
1037 case ST_CONSTANT:
1038 *out_param = param;
1039 *param_value = param->data;
1040 return D3D_OK;
1041 case ST_ARRAY_SELECTOR:
1043 unsigned int array_idx;
1044 static const struct d3dx_parameter array_idx_param =
1045 {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)};
1046 HRESULT hr;
1047 struct d3dx_parameter *ref_param, *selected_param;
1049 if (!param->param_eval)
1051 FIXME("Preshader structure is null.\n");
1052 return D3DERR_INVALIDCALL;
1054 /* We override with the update_version of the pass because we want
1055 * to force index recomputation and check for out of bounds. */
1056 if (is_param_eval_input_dirty(param->param_eval, pass->update_version))
1058 if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
1059 return hr;
1061 else
1063 array_idx = state->index;
1065 ref_param = state->referenced_param;
1066 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
1067 ref_param->element_count);
1068 /* According to the tests, native d3dx handles the case of array index evaluated to -1
1069 * in a specific way, always selecting first array element and not returning error. */
1070 if (array_idx == ~0u)
1072 WARN("Array index is -1, setting to 0.\n");
1073 array_idx = 0;
1076 if (array_idx >= ref_param->element_count)
1078 WARN("Computed array index %u is larger than array size %u.\n",
1079 array_idx, ref_param->element_count);
1080 return E_FAIL;
1082 selected_param = &ref_param->members[array_idx];
1083 *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
1084 state->index = array_idx;
1086 *param_value = selected_param->data;
1087 *out_param = selected_param;
1088 return D3D_OK;
1090 case ST_FXLC:
1091 if (param->param_eval)
1093 *out_param = param;
1094 *param_value = param->data;
1095 /* We check with the update_version of the pass because the
1096 * same preshader might be used by both the vertex and the
1097 * pixel shader (that can happen e.g. for sampler states). */
1098 if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version))
1100 *param_dirty = TRUE;
1101 return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
1103 else
1104 return D3D_OK;
1106 else
1108 FIXME("No preshader for FXLC parameter.\n");
1109 return D3DERR_INVALIDCALL;
1112 return E_NOTIMPL;
1115 static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
1116 D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
1118 struct d3dx_pass *pass = get_valid_pass(base, pass_handle);
1119 unsigned int i;
1121 if (!desc || !pass)
1123 WARN("Invalid argument specified.\n");
1124 return D3DERR_INVALIDCALL;
1127 desc->Name = pass->name;
1128 desc->Annotations = pass->annotation_count;
1130 desc->pVertexShaderFunction = NULL;
1131 desc->pPixelShaderFunction = NULL;
1133 if (base->flags & D3DXFX_NOT_CLONEABLE)
1134 return D3D_OK;
1136 for (i = 0; i < pass->state_count; ++i)
1138 struct d3dx_state *state = &pass->states[i];
1140 if (state_table[state->operation].class == SC_VERTEXSHADER
1141 || state_table[state->operation].class == SC_PIXELSHADER)
1143 struct d3dx_parameter *param;
1144 void *param_value;
1145 BOOL param_dirty;
1146 HRESULT hr;
1147 void *data;
1149 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
1150 FALSE, &param_dirty)))
1151 return hr;
1153 data = param->object_id ? base->objects[param->object_id].data : NULL;
1154 if (state_table[state->operation].class == SC_VERTEXSHADER)
1155 desc->pVertexShaderFunction = data;
1156 else
1157 desc->pPixelShaderFunction = data;
1161 return D3D_OK;
1164 static HRESULT d3dx9_base_effect_get_function_desc(struct d3dx9_base_effect *base,
1165 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
1167 FIXME("stub!\n");
1169 return E_NOTIMPL;
1172 static D3DXHANDLE d3dx9_base_effect_get_parameter(struct d3dx9_base_effect *base,
1173 D3DXHANDLE parameter, UINT index)
1175 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1177 if (!parameter)
1179 if (index < base->parameter_count)
1181 TRACE("Returning parameter %p.\n", &base->parameters[index]);
1182 return get_parameter_handle(&base->parameters[index].param);
1185 else
1187 if (param && !param->element_count && index < param->member_count)
1189 TRACE("Returning parameter %p.\n", &param->members[index]);
1190 return get_parameter_handle(&param->members[index]);
1194 WARN("Parameter not found.\n");
1196 return NULL;
1199 static D3DXHANDLE d3dx9_base_effect_get_parameter_by_name(struct d3dx9_base_effect *base,
1200 D3DXHANDLE parameter, const char *name)
1202 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1203 D3DXHANDLE handle;
1205 if (!name)
1207 handle = get_parameter_handle(param);
1208 TRACE("Returning parameter %p.\n", handle);
1209 return handle;
1212 handle = get_parameter_handle(get_parameter_by_name(base, param, name));
1213 TRACE("Returning parameter %p.\n", handle);
1215 return handle;
1218 static D3DXHANDLE d3dx9_base_effect_get_parameter_by_semantic(struct d3dx9_base_effect *base,
1219 D3DXHANDLE parameter, const char *semantic)
1221 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1222 struct d3dx_parameter *temp_param;
1223 UINT i;
1225 if (!parameter)
1227 for (i = 0; i < base->parameter_count; ++i)
1229 temp_param = &base->parameters[i].param;
1231 if (!temp_param->semantic)
1233 if (!semantic)
1235 TRACE("Returning parameter %p\n", temp_param);
1236 return get_parameter_handle(temp_param);
1238 continue;
1241 if (!strcasecmp(temp_param->semantic, semantic))
1243 TRACE("Returning parameter %p\n", temp_param);
1244 return get_parameter_handle(temp_param);
1248 else if (param)
1250 for (i = 0; i < param->member_count; ++i)
1252 temp_param = &param->members[i];
1254 if (!temp_param->semantic)
1256 if (!semantic)
1258 TRACE("Returning parameter %p\n", temp_param);
1259 return get_parameter_handle(temp_param);
1261 continue;
1264 if (!strcasecmp(temp_param->semantic, semantic))
1266 TRACE("Returning parameter %p\n", temp_param);
1267 return get_parameter_handle(temp_param);
1272 WARN("Parameter not found.\n");
1274 return NULL;
1277 static D3DXHANDLE d3dx9_base_effect_get_parameter_element(struct d3dx9_base_effect *base,
1278 D3DXHANDLE parameter, UINT index)
1280 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1282 if (!param)
1284 if (index < base->parameter_count)
1286 TRACE("Returning parameter %p.\n", &base->parameters[index]);
1287 return get_parameter_handle(&base->parameters[index].param);
1290 else
1292 if (index < param->element_count)
1294 TRACE("Returning parameter %p.\n", &param->members[index]);
1295 return get_parameter_handle(&param->members[index]);
1299 WARN("Parameter not found.\n");
1301 return NULL;
1304 static D3DXHANDLE d3dx9_base_effect_get_technique(struct d3dx9_base_effect *base, UINT index)
1306 if (index >= base->technique_count)
1308 WARN("Invalid argument specified.\n");
1309 return NULL;
1312 TRACE("Returning technique %p.\n", &base->techniques[index]);
1314 return get_technique_handle(&base->techniques[index]);
1317 static D3DXHANDLE d3dx9_base_effect_get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
1319 struct d3dx_technique *tech = get_technique_by_name(base, name);
1321 if (tech)
1323 D3DXHANDLE t = get_technique_handle(tech);
1324 TRACE("Returning technique %p\n", t);
1325 return t;
1328 WARN("Technique not found.\n");
1330 return NULL;
1333 static D3DXHANDLE d3dx9_base_effect_get_pass(struct d3dx9_base_effect *base,
1334 D3DXHANDLE technique, UINT index)
1336 struct d3dx_technique *tech = get_valid_technique(base, technique);
1338 if (tech && index < tech->pass_count)
1340 TRACE("Returning pass %p\n", &tech->passes[index]);
1341 return get_pass_handle(&tech->passes[index]);
1344 WARN("Pass not found.\n");
1346 return NULL;
1349 static D3DXHANDLE d3dx9_base_effect_get_pass_by_name(struct d3dx9_base_effect *base,
1350 D3DXHANDLE technique, const char *name)
1352 struct d3dx_technique *tech = get_valid_technique(base, technique);
1354 if (tech && name)
1356 unsigned int i;
1358 for (i = 0; i < tech->pass_count; ++i)
1360 struct d3dx_pass *pass = &tech->passes[i];
1362 if (!strcmp(pass->name, name))
1364 TRACE("Returning pass %p\n", pass);
1365 return get_pass_handle(pass);
1370 WARN("Pass not found.\n");
1372 return NULL;
1375 static D3DXHANDLE d3dx9_base_effect_get_function(struct d3dx9_base_effect *base, UINT index)
1377 FIXME("stub!\n");
1379 return NULL;
1382 static D3DXHANDLE d3dx9_base_effect_get_function_by_name(struct d3dx9_base_effect *base, const char *name)
1384 FIXME("stub!\n");
1386 return NULL;
1389 static UINT get_annotation_from_object(struct d3dx9_base_effect *base,
1390 D3DXHANDLE object, struct d3dx_parameter **annotations)
1392 struct d3dx_parameter *param = get_valid_parameter(base, object);
1393 struct d3dx_pass *pass = get_valid_pass(base, object);
1394 struct d3dx_technique *technique = get_valid_technique(base, object);
1396 if (pass)
1398 *annotations = pass->annotations;
1399 return pass->annotation_count;
1401 else if (technique)
1403 *annotations = technique->annotations;
1404 return technique->annotation_count;
1406 else if (param)
1408 if (is_top_level_parameter(param))
1410 struct d3dx_top_level_parameter *top_param
1411 = top_level_parameter_from_parameter(param);
1413 *annotations = top_param->annotations;
1414 return top_param->annotation_count;
1416 else
1418 *annotations = NULL;
1419 return 0;
1422 else
1424 FIXME("Functions are not handled, yet!\n");
1425 return 0;
1429 static D3DXHANDLE d3dx9_base_effect_get_annotation(struct d3dx9_base_effect *base,
1430 D3DXHANDLE object, UINT index)
1432 struct d3dx_parameter *annotations = NULL;
1433 UINT annotation_count = 0;
1435 annotation_count = get_annotation_from_object(base, object, &annotations);
1437 if (index < annotation_count)
1439 TRACE("Returning parameter %p\n", &annotations[index]);
1440 return get_parameter_handle(&annotations[index]);
1443 WARN("Annotation not found.\n");
1445 return NULL;
1448 static D3DXHANDLE d3dx9_base_effect_get_annotation_by_name(struct d3dx9_base_effect *base,
1449 D3DXHANDLE object, const char *name)
1451 struct d3dx_parameter *annotation = NULL;
1452 struct d3dx_parameter *annotations = NULL;
1453 UINT annotation_count = 0;
1455 if (!name)
1457 WARN("Invalid argument specified\n");
1458 return NULL;
1461 annotation_count = get_annotation_from_object(base, object, &annotations);
1463 annotation = get_annotation_by_name(annotation_count, annotations, name);
1464 if (annotation)
1466 TRACE("Returning parameter %p\n", annotation);
1467 return get_parameter_handle(annotation);
1470 WARN("Annotation not found.\n");
1472 return NULL;
1475 static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
1476 void *data)
1478 unsigned int i;
1479 unsigned int member_count;
1481 if (param_func(data, param))
1482 return TRUE;
1484 member_count = param->element_count ? param->element_count : param->member_count;
1485 for (i = 0; i < member_count; ++i)
1487 if (walk_parameter_tree(&param->members[i], param_func, data))
1488 return TRUE;
1490 return FALSE;
1493 static ULONG64 *get_version_counter_ptr(struct d3dx9_base_effect *base)
1495 return base->pool ? &base->pool->version_counter : &base->version_counter;
1498 static ULONG64 next_effect_update_version(struct d3dx9_base_effect *base)
1500 return next_update_version(get_version_counter_ptr(base));
1503 static void set_dirty(struct d3dx_parameter *param)
1505 struct d3dx_shared_data *shared_data;
1506 struct d3dx_top_level_parameter *top_param = param->top_level_param;
1507 ULONG64 new_update_version = next_update_version(top_param->version_counter);
1509 if ((shared_data = top_param->shared_data))
1510 shared_data->update_version = new_update_version;
1511 else
1512 top_param->update_version = new_update_version;
1515 static HRESULT set_string(char **param_data, const char *string)
1517 HeapFree(GetProcessHeap(), 0, *param_data);
1518 *param_data = HeapAlloc(GetProcessHeap(), 0, strlen(string) + 1);
1519 if (!*param_data)
1521 ERR("Out of memory.\n");
1522 return E_OUTOFMEMORY;
1524 strcpy(*param_data, string);
1525 return D3D_OK;
1528 static HRESULT d3dx9_base_effect_set_value(struct d3dx9_base_effect *base,
1529 D3DXHANDLE parameter, const void *data, UINT bytes)
1531 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1532 unsigned int i;
1534 if (!param)
1536 WARN("Invalid parameter %p specified\n", parameter);
1537 return D3DERR_INVALIDCALL;
1540 /* samplers don't touch data */
1541 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1543 TRACE("Sampler: returning E_FAIL\n");
1544 return E_FAIL;
1547 if (data && param->bytes <= bytes)
1549 switch (param->type)
1551 case D3DXPT_TEXTURE:
1552 case D3DXPT_TEXTURE1D:
1553 case D3DXPT_TEXTURE2D:
1554 case D3DXPT_TEXTURE3D:
1555 case D3DXPT_TEXTURECUBE:
1556 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1558 IUnknown *unk = ((IUnknown **)data)[i];
1559 if (unk)
1560 IUnknown_AddRef(unk);
1562 unk = ((IUnknown **)param->data)[i];
1563 if (unk)
1564 IUnknown_Release(unk);
1566 /* fallthrough */
1567 case D3DXPT_VOID:
1568 case D3DXPT_BOOL:
1569 case D3DXPT_INT:
1570 case D3DXPT_FLOAT:
1571 TRACE("Copy %u bytes.\n", param->bytes);
1572 memcpy(param->data, data, param->bytes);
1573 set_dirty(param);
1574 break;
1576 case D3DXPT_STRING:
1578 HRESULT hr;
1580 set_dirty(param);
1581 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1583 if (FAILED(hr = set_string(&((char **)param->data)[i], ((const char **)data)[i])))
1584 return hr;
1586 break;
1589 default:
1590 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
1591 break;
1594 return D3D_OK;
1597 WARN("Invalid argument specified\n");
1599 return D3DERR_INVALIDCALL;
1602 static HRESULT d3dx9_base_effect_get_value(struct d3dx9_base_effect *base,
1603 D3DXHANDLE parameter, void *data, UINT bytes)
1605 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1607 if (!param)
1609 WARN("Invalid parameter %p specified\n", parameter);
1610 return D3DERR_INVALIDCALL;
1613 /* samplers don't touch data */
1614 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1616 TRACE("Sampler: returning E_FAIL\n");
1617 return E_FAIL;
1620 if (data && param->bytes <= bytes)
1622 TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1624 switch (param->type)
1626 case D3DXPT_VOID:
1627 case D3DXPT_BOOL:
1628 case D3DXPT_INT:
1629 case D3DXPT_FLOAT:
1630 case D3DXPT_STRING:
1631 break;
1633 case D3DXPT_VERTEXSHADER:
1634 case D3DXPT_PIXELSHADER:
1635 case D3DXPT_TEXTURE:
1636 case D3DXPT_TEXTURE1D:
1637 case D3DXPT_TEXTURE2D:
1638 case D3DXPT_TEXTURE3D:
1639 case D3DXPT_TEXTURECUBE:
1641 UINT i;
1643 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1645 IUnknown *unk = ((IUnknown **)param->data)[i];
1646 if (unk) IUnknown_AddRef(unk);
1648 break;
1651 default:
1652 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1653 break;
1656 TRACE("Copy %u bytes\n", param->bytes);
1657 memcpy(data, param->data, param->bytes);
1658 return D3D_OK;
1661 WARN("Parameter not found.\n");
1663 return D3DERR_INVALIDCALL;
1666 static HRESULT d3dx9_base_effect_set_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL b)
1668 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1670 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1672 set_number(param->data, param->type, &b, D3DXPT_BOOL);
1673 set_dirty(param);
1674 return D3D_OK;
1677 WARN("Parameter not found.\n");
1679 return D3DERR_INVALIDCALL;
1682 static HRESULT d3dx9_base_effect_get_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL *b)
1684 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1686 if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
1688 set_number(b, D3DXPT_BOOL, param->data, param->type);
1689 TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1690 return D3D_OK;
1693 WARN("Parameter not found.\n");
1695 return D3DERR_INVALIDCALL;
1698 static HRESULT d3dx9_base_effect_set_bool_array(struct d3dx9_base_effect *base,
1699 D3DXHANDLE parameter, const BOOL *b, UINT count)
1701 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1703 if (param)
1705 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1707 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1709 switch (param->class)
1711 case D3DXPC_SCALAR:
1712 case D3DXPC_VECTOR:
1713 case D3DXPC_MATRIX_ROWS:
1714 for (i = 0; i < size; ++i)
1716 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
1717 set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
1719 set_dirty(param);
1720 return D3D_OK;
1722 case D3DXPC_OBJECT:
1723 case D3DXPC_STRUCT:
1724 break;
1726 default:
1727 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1728 break;
1732 WARN("Parameter not found.\n");
1734 return D3DERR_INVALIDCALL;
1737 static HRESULT d3dx9_base_effect_get_bool_array(struct d3dx9_base_effect *base,
1738 D3DXHANDLE parameter, BOOL *b, UINT count)
1740 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1742 if (b && param && (param->class == D3DXPC_SCALAR
1743 || param->class == D3DXPC_VECTOR
1744 || param->class == D3DXPC_MATRIX_ROWS
1745 || param->class == D3DXPC_MATRIX_COLUMNS))
1747 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1749 for (i = 0; i < size; ++i)
1751 set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
1753 return D3D_OK;
1756 WARN("Parameter not found.\n");
1758 return D3DERR_INVALIDCALL;
1761 static HRESULT d3dx9_base_effect_set_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT n)
1763 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1765 if (param && !param->element_count)
1767 if (param->rows == 1 && param->columns == 1)
1769 DWORD value;
1771 set_number(&value, param->type, &n, D3DXPT_INT);
1772 if (value != *(DWORD *)param->data)
1773 set_dirty(param);
1774 *(DWORD *)param->data = value;
1775 return D3D_OK;
1779 * Split the value, if parameter is a vector with dimension 3 or 4.
1781 if (param->type == D3DXPT_FLOAT &&
1782 ((param->class == D3DXPC_VECTOR && param->columns != 2) ||
1783 (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1785 TRACE("Vector fixup\n");
1787 *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
1788 ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
1789 ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
1790 if (param->rows * param->columns > 3)
1792 ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
1794 set_dirty(param);
1795 return D3D_OK;
1799 WARN("Parameter not found.\n");
1801 return D3DERR_INVALIDCALL;
1804 static HRESULT d3dx9_base_effect_get_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT *n)
1806 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1808 if (n && param && !param->element_count)
1810 if (param->columns == 1 && param->rows == 1)
1812 set_number(n, D3DXPT_INT, param->data, param->type);
1813 TRACE("Returning %i\n", *n);
1814 return D3D_OK;
1817 if (param->type == D3DXPT_FLOAT &&
1818 ((param->class == D3DXPC_VECTOR && param->columns != 2)
1819 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1821 TRACE("Vector fixup\n");
1823 /* all components (3,4) are clamped (0,255) and put in the INT */
1824 *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
1825 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
1826 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
1827 if (param->columns * param->rows > 3)
1829 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
1832 TRACE("Returning %i\n", *n);
1833 return D3D_OK;
1837 WARN("Parameter not found.\n");
1839 return D3DERR_INVALIDCALL;
1842 static HRESULT d3dx9_base_effect_set_int_array(struct d3dx9_base_effect *base,
1843 D3DXHANDLE parameter, const INT *n, UINT count)
1845 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1847 if (param)
1849 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1851 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1853 switch (param->class)
1855 case D3DXPC_SCALAR:
1856 case D3DXPC_VECTOR:
1857 case D3DXPC_MATRIX_ROWS:
1858 for (i = 0; i < size; ++i)
1860 set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
1862 set_dirty(param);
1863 return D3D_OK;
1865 case D3DXPC_OBJECT:
1866 case D3DXPC_STRUCT:
1867 break;
1869 default:
1870 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1871 break;
1875 WARN("Parameter not found.\n");
1877 return D3DERR_INVALIDCALL;
1880 static HRESULT d3dx9_base_effect_get_int_array(struct d3dx9_base_effect *base,
1881 D3DXHANDLE parameter, INT *n, UINT count)
1883 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1885 if (n && param && (param->class == D3DXPC_SCALAR
1886 || param->class == D3DXPC_VECTOR
1887 || param->class == D3DXPC_MATRIX_ROWS
1888 || param->class == D3DXPC_MATRIX_COLUMNS))
1890 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1892 for (i = 0; i < size; ++i)
1894 set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
1896 return D3D_OK;
1899 WARN("Parameter not found.\n");
1901 return D3DERR_INVALIDCALL;
1904 static HRESULT d3dx9_base_effect_set_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float f)
1906 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1908 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1910 DWORD value;
1912 set_number(&value, param->type, &f, D3DXPT_FLOAT);
1913 if (value != *(DWORD *)param->data)
1914 set_dirty(param);
1915 *(DWORD *)param->data = value;
1916 return D3D_OK;
1919 WARN("Parameter not found.\n");
1921 return D3DERR_INVALIDCALL;
1924 static HRESULT d3dx9_base_effect_get_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float *f)
1926 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1928 if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
1930 set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
1931 TRACE("Returning %f\n", *f);
1932 return D3D_OK;
1935 WARN("Parameter not found.\n");
1937 return D3DERR_INVALIDCALL;
1940 static HRESULT d3dx9_base_effect_set_float_array(struct d3dx9_base_effect *base,
1941 D3DXHANDLE parameter, const float *f, UINT count)
1943 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1945 if (param)
1947 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1949 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1951 switch (param->class)
1953 case D3DXPC_SCALAR:
1954 case D3DXPC_VECTOR:
1955 case D3DXPC_MATRIX_ROWS:
1956 for (i = 0; i < size; ++i)
1958 set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
1960 set_dirty(param);
1961 return D3D_OK;
1963 case D3DXPC_OBJECT:
1964 case D3DXPC_STRUCT:
1965 break;
1967 default:
1968 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1969 break;
1973 WARN("Parameter not found.\n");
1975 return D3DERR_INVALIDCALL;
1978 static HRESULT d3dx9_base_effect_get_float_array(struct d3dx9_base_effect *base,
1979 D3DXHANDLE parameter, float *f, UINT count)
1981 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1983 if (f && param && (param->class == D3DXPC_SCALAR
1984 || param->class == D3DXPC_VECTOR
1985 || param->class == D3DXPC_MATRIX_ROWS
1986 || param->class == D3DXPC_MATRIX_COLUMNS))
1988 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1990 for (i = 0; i < size; ++i)
1992 set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
1994 return D3D_OK;
1997 WARN("Parameter not found.\n");
1999 return D3DERR_INVALIDCALL;
2002 static HRESULT d3dx9_base_effect_set_vector(struct d3dx9_base_effect *base,
2003 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2005 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2007 if (param && !param->element_count)
2009 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2011 switch (param->class)
2013 case D3DXPC_SCALAR:
2014 case D3DXPC_VECTOR:
2015 set_dirty(param);
2016 if (param->type == D3DXPT_INT && param->bytes == 4)
2018 DWORD tmp;
2020 TRACE("INT fixup\n");
2021 tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
2022 tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2023 tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2024 tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2026 *(INT *)param->data = tmp;
2027 return D3D_OK;
2029 if (param->type == D3DXPT_FLOAT)
2031 memcpy(param->data, vector, param->columns * sizeof(float));
2032 return D3D_OK;
2035 set_vector(param, vector);
2036 return D3D_OK;
2038 case D3DXPC_MATRIX_ROWS:
2039 case D3DXPC_OBJECT:
2040 case D3DXPC_STRUCT:
2041 break;
2043 default:
2044 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2045 break;
2049 WARN("Parameter not found.\n");
2051 return D3DERR_INVALIDCALL;
2054 static HRESULT d3dx9_base_effect_get_vector(struct d3dx9_base_effect *base,
2055 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2057 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2059 if (vector && param && !param->element_count)
2061 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2063 switch (param->class)
2065 case D3DXPC_SCALAR:
2066 case D3DXPC_VECTOR:
2067 if (param->type == D3DXPT_INT && param->bytes == 4)
2069 TRACE("INT fixup\n");
2070 vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2071 vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2072 vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2073 vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2074 return D3D_OK;
2076 get_vector(param, vector);
2077 return D3D_OK;
2079 case D3DXPC_MATRIX_ROWS:
2080 case D3DXPC_OBJECT:
2081 case D3DXPC_STRUCT:
2082 break;
2084 default:
2085 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2086 break;
2090 WARN("Parameter not found.\n");
2092 return D3DERR_INVALIDCALL;
2095 static HRESULT d3dx9_base_effect_set_vector_array(struct d3dx9_base_effect *base,
2096 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
2098 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2100 if (param && param->element_count && param->element_count >= count)
2102 UINT i;
2104 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2106 switch (param->class)
2108 case D3DXPC_VECTOR:
2109 set_dirty(param);
2110 if (param->type == D3DXPT_FLOAT)
2112 if (param->columns == 4)
2113 memcpy(param->data, vector, count * 4 * sizeof(float));
2114 else
2115 for (i = 0; i < count; ++i)
2116 memcpy((float *)param->data + param->columns * i, vector + i,
2117 param->columns * sizeof(float));
2118 return D3D_OK;
2121 for (i = 0; i < count; ++i)
2123 set_vector(&param->members[i], &vector[i]);
2125 return D3D_OK;
2127 case D3DXPC_SCALAR:
2128 case D3DXPC_MATRIX_ROWS:
2129 case D3DXPC_OBJECT:
2130 case D3DXPC_STRUCT:
2131 break;
2133 default:
2134 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2135 break;
2139 WARN("Parameter not found.\n");
2141 return D3DERR_INVALIDCALL;
2144 static HRESULT d3dx9_base_effect_get_vector_array(struct d3dx9_base_effect *base,
2145 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2147 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2149 if (!count) return D3D_OK;
2151 if (vector && param && count <= param->element_count)
2153 UINT i;
2155 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2157 switch (param->class)
2159 case D3DXPC_VECTOR:
2160 for (i = 0; i < count; ++i)
2162 get_vector(&param->members[i], &vector[i]);
2164 return D3D_OK;
2166 case D3DXPC_SCALAR:
2167 case D3DXPC_MATRIX_ROWS:
2168 case D3DXPC_OBJECT:
2169 case D3DXPC_STRUCT:
2170 break;
2172 default:
2173 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2174 break;
2178 WARN("Parameter not found.\n");
2180 return D3DERR_INVALIDCALL;
2183 static HRESULT d3dx9_base_effect_set_matrix(struct d3dx9_base_effect *base,
2184 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2186 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2188 if (param && !param->element_count)
2190 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2192 switch (param->class)
2194 case D3DXPC_MATRIX_ROWS:
2195 set_matrix(param, matrix);
2196 set_dirty(param);
2197 return D3D_OK;
2199 case D3DXPC_SCALAR:
2200 case D3DXPC_VECTOR:
2201 case D3DXPC_OBJECT:
2202 case D3DXPC_STRUCT:
2203 break;
2205 default:
2206 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2207 break;
2211 WARN("Parameter not found.\n");
2213 return D3DERR_INVALIDCALL;
2216 static HRESULT d3dx9_base_effect_get_matrix(struct d3dx9_base_effect *base,
2217 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2219 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2221 if (matrix && param && !param->element_count)
2223 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2225 switch (param->class)
2227 case D3DXPC_MATRIX_ROWS:
2228 get_matrix(param, matrix, FALSE);
2229 return D3D_OK;
2231 case D3DXPC_SCALAR:
2232 case D3DXPC_VECTOR:
2233 case D3DXPC_OBJECT:
2234 case D3DXPC_STRUCT:
2235 break;
2237 default:
2238 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2239 break;
2243 WARN("Parameter not found.\n");
2245 return D3DERR_INVALIDCALL;
2248 static HRESULT d3dx9_base_effect_set_matrix_array(struct d3dx9_base_effect *base,
2249 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2251 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2253 if (param && param->element_count >= count)
2255 UINT i;
2257 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2259 switch (param->class)
2261 case D3DXPC_MATRIX_ROWS:
2262 set_dirty(param);
2263 for (i = 0; i < count; ++i)
2265 set_matrix(&param->members[i], &matrix[i]);
2267 return D3D_OK;
2269 case D3DXPC_SCALAR:
2270 case D3DXPC_VECTOR:
2271 case D3DXPC_OBJECT:
2272 case D3DXPC_STRUCT:
2273 break;
2275 default:
2276 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2277 break;
2281 WARN("Parameter not found.\n");
2283 return D3DERR_INVALIDCALL;
2286 static HRESULT d3dx9_base_effect_get_matrix_array(struct d3dx9_base_effect *base,
2287 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2289 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2291 if (!count) return D3D_OK;
2293 if (matrix && param && count <= param->element_count)
2295 UINT i;
2297 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2299 switch (param->class)
2301 case D3DXPC_MATRIX_ROWS:
2302 for (i = 0; i < count; ++i)
2304 get_matrix(&param->members[i], &matrix[i], FALSE);
2306 return D3D_OK;
2308 case D3DXPC_SCALAR:
2309 case D3DXPC_VECTOR:
2310 case D3DXPC_OBJECT:
2311 case D3DXPC_STRUCT:
2312 break;
2314 default:
2315 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2316 break;
2320 WARN("Parameter not found.\n");
2322 return D3DERR_INVALIDCALL;
2325 static HRESULT d3dx9_base_effect_set_matrix_pointer_array(struct d3dx9_base_effect *base,
2326 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2328 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2330 if (param && count <= param->element_count)
2332 UINT i;
2334 switch (param->class)
2336 case D3DXPC_MATRIX_ROWS:
2337 set_dirty(param);
2338 for (i = 0; i < count; ++i)
2340 set_matrix(&param->members[i], matrix[i]);
2342 return D3D_OK;
2344 case D3DXPC_SCALAR:
2345 case D3DXPC_VECTOR:
2346 case D3DXPC_OBJECT:
2347 break;
2349 default:
2350 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2351 break;
2355 WARN("Parameter not found.\n");
2357 return D3DERR_INVALIDCALL;
2360 static HRESULT d3dx9_base_effect_get_matrix_pointer_array(struct d3dx9_base_effect *base,
2361 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2363 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2365 if (!count) return D3D_OK;
2367 if (param && matrix && count <= param->element_count)
2369 UINT i;
2371 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2373 switch (param->class)
2375 case D3DXPC_MATRIX_ROWS:
2376 for (i = 0; i < count; ++i)
2378 get_matrix(&param->members[i], matrix[i], FALSE);
2380 return D3D_OK;
2382 case D3DXPC_SCALAR:
2383 case D3DXPC_VECTOR:
2384 case D3DXPC_OBJECT:
2385 break;
2387 default:
2388 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2389 break;
2393 WARN("Parameter not found.\n");
2395 return D3DERR_INVALIDCALL;
2398 static HRESULT d3dx9_base_effect_set_matrix_transpose(struct d3dx9_base_effect *base,
2399 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2401 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2403 if (param && !param->element_count)
2405 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2407 switch (param->class)
2409 case D3DXPC_MATRIX_ROWS:
2410 set_dirty(param);
2411 set_matrix_transpose(param, matrix);
2412 return D3D_OK;
2414 case D3DXPC_SCALAR:
2415 case D3DXPC_VECTOR:
2416 case D3DXPC_OBJECT:
2417 case D3DXPC_STRUCT:
2418 break;
2420 default:
2421 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2422 break;
2426 WARN("Parameter not found.\n");
2428 return D3DERR_INVALIDCALL;
2431 static HRESULT d3dx9_base_effect_get_matrix_transpose(struct d3dx9_base_effect *base,
2432 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2434 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2436 if (matrix && param && !param->element_count)
2438 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2440 switch (param->class)
2442 case D3DXPC_SCALAR:
2443 case D3DXPC_VECTOR:
2444 get_matrix(param, matrix, FALSE);
2445 return D3D_OK;
2447 case D3DXPC_MATRIX_ROWS:
2448 get_matrix(param, matrix, TRUE);
2449 return D3D_OK;
2451 case D3DXPC_OBJECT:
2452 case D3DXPC_STRUCT:
2453 break;
2455 default:
2456 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2457 break;
2461 WARN("Parameter not found.\n");
2463 return D3DERR_INVALIDCALL;
2466 static HRESULT d3dx9_base_effect_set_matrix_transpose_array(struct d3dx9_base_effect *base,
2467 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2469 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2471 if (param && param->element_count >= count)
2473 UINT i;
2475 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2477 switch (param->class)
2479 case D3DXPC_MATRIX_ROWS:
2480 set_dirty(param);
2481 for (i = 0; i < count; ++i)
2483 set_matrix_transpose(&param->members[i], &matrix[i]);
2485 return D3D_OK;
2487 case D3DXPC_SCALAR:
2488 case D3DXPC_VECTOR:
2489 case D3DXPC_OBJECT:
2490 case D3DXPC_STRUCT:
2491 break;
2493 default:
2494 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2495 break;
2499 WARN("Parameter not found.\n");
2501 return D3DERR_INVALIDCALL;
2504 static HRESULT d3dx9_base_effect_get_matrix_transpose_array(struct d3dx9_base_effect *base,
2505 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2507 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2509 if (!count) return D3D_OK;
2511 if (matrix && param && count <= param->element_count)
2513 UINT i;
2515 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2517 switch (param->class)
2519 case D3DXPC_MATRIX_ROWS:
2520 for (i = 0; i < count; ++i)
2522 get_matrix(&param->members[i], &matrix[i], TRUE);
2524 return D3D_OK;
2526 case D3DXPC_SCALAR:
2527 case D3DXPC_VECTOR:
2528 case D3DXPC_OBJECT:
2529 case D3DXPC_STRUCT:
2530 break;
2532 default:
2533 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2534 break;
2538 WARN("Parameter not found.\n");
2540 return D3DERR_INVALIDCALL;
2543 static HRESULT d3dx9_base_effect_set_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2544 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2546 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2548 if (param && count <= param->element_count)
2550 UINT i;
2552 switch (param->class)
2554 case D3DXPC_MATRIX_ROWS:
2555 set_dirty(param);
2556 for (i = 0; i < count; ++i)
2558 set_matrix_transpose(&param->members[i], matrix[i]);
2560 return D3D_OK;
2562 case D3DXPC_SCALAR:
2563 case D3DXPC_VECTOR:
2564 case D3DXPC_OBJECT:
2565 break;
2567 default:
2568 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2569 break;
2573 WARN("Parameter not found.\n");
2575 return D3DERR_INVALIDCALL;
2578 static HRESULT d3dx9_base_effect_get_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2579 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2581 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2583 if (!count) return D3D_OK;
2585 if (matrix && param && count <= param->element_count)
2587 UINT i;
2589 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2591 switch (param->class)
2593 case D3DXPC_MATRIX_ROWS:
2594 for (i = 0; i < count; ++i)
2596 get_matrix(&param->members[i], matrix[i], TRUE);
2598 return D3D_OK;
2600 case D3DXPC_SCALAR:
2601 case D3DXPC_VECTOR:
2602 case D3DXPC_OBJECT:
2603 break;
2605 default:
2606 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2607 break;
2611 WARN("Parameter not found.\n");
2613 return D3DERR_INVALIDCALL;
2616 static HRESULT d3dx9_base_effect_set_string(struct d3dx9_base_effect *base,
2617 D3DXHANDLE parameter, const char *string)
2619 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2621 if (param && param->type == D3DXPT_STRING)
2623 set_dirty(param);
2624 return set_string(param->data, string);
2627 WARN("Parameter not found.\n");
2629 return D3DERR_INVALIDCALL;
2632 static HRESULT d3dx9_base_effect_get_string(struct d3dx9_base_effect *base,
2633 D3DXHANDLE parameter, const char **string)
2635 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2637 if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2639 *string = *(const char **)param->data;
2640 TRACE("Returning %s.\n", debugstr_a(*string));
2641 return D3D_OK;
2644 WARN("Parameter not found.\n");
2646 return D3DERR_INVALIDCALL;
2649 static HRESULT d3dx9_base_effect_set_texture(struct d3dx9_base_effect *base,
2650 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
2652 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2654 if (param && !param->element_count &&
2655 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2656 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2657 || param->type == D3DXPT_TEXTURECUBE))
2659 struct IDirect3DBaseTexture9 *oltexture = *(struct IDirect3DBaseTexture9 **)param->data;
2661 if (texture == oltexture)
2662 return D3D_OK;
2664 if (texture) IDirect3DBaseTexture9_AddRef(texture);
2665 if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2667 *(struct IDirect3DBaseTexture9 **)param->data = texture;
2668 set_dirty(param);
2670 return D3D_OK;
2673 WARN("Parameter not found.\n");
2675 return D3DERR_INVALIDCALL;
2678 static HRESULT d3dx9_base_effect_get_texture(struct d3dx9_base_effect *base,
2679 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
2681 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2683 if (texture && param && !param->element_count &&
2684 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2685 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2686 || param->type == D3DXPT_TEXTURECUBE))
2688 *texture = *(struct IDirect3DBaseTexture9 **)param->data;
2689 if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2690 TRACE("Returning %p\n", *texture);
2691 return D3D_OK;
2694 WARN("Parameter not found.\n");
2696 return D3DERR_INVALIDCALL;
2699 static HRESULT d3dx9_base_effect_get_pixel_shader(struct d3dx9_base_effect *base,
2700 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
2702 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2704 if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2706 if ((*shader = *(struct IDirect3DPixelShader9 **)param->data))
2707 IDirect3DPixelShader9_AddRef(*shader);
2708 TRACE("Returning %p.\n", *shader);
2709 return D3D_OK;
2712 WARN("Parameter not found.\n");
2714 return D3DERR_INVALIDCALL;
2717 static HRESULT d3dx9_base_effect_get_vertex_shader(struct d3dx9_base_effect *base,
2718 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
2720 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2722 if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2724 if ((*shader = *(struct IDirect3DVertexShader9 **)param->data))
2725 IDirect3DVertexShader9_AddRef(*shader);
2726 TRACE("Returning %p.\n", *shader);
2727 return D3D_OK;
2730 WARN("Parameter not found.\n");
2732 return D3DERR_INVALIDCALL;
2735 static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base,
2736 D3DXHANDLE parameter, UINT start, UINT end)
2738 FIXME("stub!\n");
2740 return E_NOTIMPL;
2743 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
2745 static const struct
2747 unsigned int offset;
2748 const char *name;
2750 light_tbl[] =
2752 {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
2753 {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
2754 {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
2755 {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
2756 {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
2757 {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
2758 {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
2759 {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
2760 {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
2761 {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
2762 {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
2763 {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
2764 {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
2766 switch (op)
2768 case LT_TYPE:
2769 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
2770 light->Type = *(D3DLIGHTTYPE *)value;
2771 break;
2772 case LT_DIFFUSE:
2773 case LT_SPECULAR:
2774 case LT_AMBIENT:
2776 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2778 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
2779 *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
2780 break;
2782 case LT_POSITION:
2783 case LT_DIRECTION:
2785 D3DVECTOR v = *(D3DVECTOR *)value;
2787 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
2788 *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
2789 break;
2791 case LT_RANGE:
2792 case LT_FALLOFF:
2793 case LT_ATTENUATION0:
2794 case LT_ATTENUATION1:
2795 case LT_ATTENUATION2:
2796 case LT_THETA:
2797 case LT_PHI:
2799 float v = *(float *)value;
2800 TRACE("%s %.8e.\n", light_tbl[op].name, v);
2801 *(float *)((BYTE *)light + light_tbl[op].offset) = v;
2802 break;
2804 default:
2805 WARN("Unknown light parameter %u.\n", op);
2806 break;
2810 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
2812 static const struct
2814 unsigned int offset;
2815 const char *name;
2817 material_tbl[] =
2819 {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
2820 {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
2821 {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
2822 {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
2823 {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
2826 switch (op)
2828 case MT_POWER:
2830 float v = *(float *)value;
2832 TRACE("%s %.8e.\n", material_tbl[op].name, v);
2833 material->Power = v;
2834 break;
2836 case MT_DIFFUSE:
2837 case MT_AMBIENT:
2838 case MT_SPECULAR:
2839 case MT_EMISSIVE:
2841 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2843 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
2844 *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
2845 break;
2847 default:
2848 WARN("Unknown material parameter %u.\n", op);
2849 break;
2853 static HRESULT d3dx_set_shader_const_state(struct ID3DXEffectImpl *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
2854 struct d3dx_parameter *param, void *value_ptr)
2856 static const struct
2858 D3DXPARAMETER_TYPE type;
2859 UINT elem_size;
2860 const char *name;
2862 const_tbl[] =
2864 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
2865 {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
2866 {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
2867 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
2868 {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
2869 {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
2871 unsigned int element_count;
2873 if (op < 0 || op > SCT_PSINT)
2875 FIXME("Unknown op %u.\n", op);
2876 return D3DERR_INVALIDCALL;
2878 element_count = param->bytes / const_tbl[op].elem_size;
2879 TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
2880 if (param->type != const_tbl[op].type)
2882 FIXME("Unexpected param type %u.\n", param->type);
2883 return D3DERR_INVALIDCALL;
2885 if (param->bytes % const_tbl[op].elem_size != 0)
2887 FIXME("Unexpected param size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
2888 return D3DERR_INVALIDCALL;
2891 switch (op)
2893 case SCT_VSFLOAT:
2894 return SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)value_ptr, element_count);
2895 case SCT_VSBOOL:
2896 return SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2897 case SCT_VSINT:
2898 return SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)value_ptr, element_count);
2899 case SCT_PSFLOAT:
2900 return SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)value_ptr, element_count);
2901 case SCT_PSBOOL:
2902 return SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2903 case SCT_PSINT:
2904 return SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)value_ptr, element_count);
2906 return D3D_OK;
2909 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2910 struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
2912 static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2913 struct d3dx_parameter *param, BOOL vs, BOOL update_all)
2915 HRESULT hr, ret;
2916 struct d3dx_parameter **params;
2917 D3DXCONSTANT_DESC *cdesc;
2918 unsigned int parameters_count;
2919 unsigned int i, j;
2921 if (!param->param_eval)
2923 FIXME("param_eval structure is null.\n");
2924 return D3DERR_INVALIDCALL;
2926 if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
2927 param->param_eval, update_all)))
2928 return hr;
2929 params = param->param_eval->shader_inputs.inputs_param;
2930 cdesc = param->param_eval->shader_inputs.inputs;
2931 parameters_count = param->param_eval->shader_inputs.input_count;
2932 ret = D3D_OK;
2933 for (i = 0; i < parameters_count; ++i)
2935 if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
2937 struct d3dx_sampler *sampler;
2938 unsigned int sampler_idx;
2940 for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
2942 sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
2943 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
2944 cdesc[i].RegisterIndex, sampler->state_count);
2945 for (j = 0; j < sampler->state_count; ++j)
2947 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
2948 cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
2949 update_all)))
2950 ret = hr;
2955 return ret;
2958 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2959 struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
2961 struct d3dx_parameter *param;
2962 void *param_value;
2963 BOOL param_dirty;
2964 HRESULT hr;
2966 TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
2968 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
2969 update_all, &param_dirty)))
2971 if (!update_all && hr == E_FAIL)
2973 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
2974 * out of bounds array access and does not touch the affected
2975 * states. */
2976 WARN("Returning D3D_OK on out of bounds array access.\n");
2977 return D3D_OK;
2979 return hr;
2982 if (!(update_all || param_dirty
2983 || state_table[state->operation].class == SC_VERTEXSHADER
2984 || state_table[state->operation].class == SC_PIXELSHADER
2985 || state_table[state->operation].class == SC_SETSAMPLER))
2986 return D3D_OK;
2988 switch (state_table[state->operation].class)
2990 case SC_RENDERSTATE:
2991 TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
2992 state_table[state->operation].op, *(DWORD *)param_value);
2993 return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
2994 case SC_FVF:
2995 TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
2996 return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
2997 case SC_TEXTURE:
2999 UINT unit;
3001 unit = parent_index == ~0u ? state->index : parent_index;
3002 TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
3003 *(IDirect3DBaseTexture9 **)param_value);
3004 return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
3006 case SC_TEXTURESTAGE:
3007 TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
3008 return SET_D3D_STATE(effect, SetTextureStageState, state->index,
3009 state_table[state->operation].op, *(DWORD *)param_value);
3010 case SC_SETSAMPLER:
3012 struct d3dx_sampler *sampler;
3013 HRESULT ret, hr;
3014 unsigned int i;
3016 sampler = (struct d3dx_sampler *)param_value;
3017 TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
3018 sampler->state_count);
3019 ret = D3D_OK;
3020 for (i = 0; i < sampler->state_count; i++)
3022 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
3023 ret = hr;
3025 return ret;
3027 case SC_SAMPLERSTATE:
3029 UINT sampler;
3031 sampler = parent_index == ~0u ? state->index : parent_index;
3032 TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
3033 return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
3034 *(DWORD *)param_value);
3036 case SC_VERTEXSHADER:
3037 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
3038 if ((update_all || param_dirty)
3039 && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
3040 *(IDirect3DVertexShader9 **)param_value)))
3041 ERR("Could not set vertex shader, hr %#x.\n", hr);
3042 else if (*(IDirect3DVertexShader9 **)param_value)
3043 hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
3044 return hr;
3045 case SC_PIXELSHADER:
3046 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
3047 if ((update_all || param_dirty)
3048 && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
3049 *(IDirect3DPixelShader9 **)param_value)))
3050 ERR("Could not set pixel shader, hr %#x.\n", hr);
3051 else if (*(IDirect3DPixelShader9 **)param_value)
3052 hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
3053 return hr;
3054 case SC_TRANSFORM:
3055 TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
3056 return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
3057 (D3DMATRIX *)param_value);
3058 case SC_LIGHTENABLE:
3059 TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
3060 return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
3061 case SC_LIGHT:
3063 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3064 state_table[state->operation].op);
3065 d3dx9_set_light_parameter(state_table[state->operation].op,
3066 &effect->current_light[state->index], param_value);
3067 effect->light_updated |= 1u << state->index;
3068 return D3D_OK;
3070 case SC_MATERIAL:
3072 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3073 state_table[state->operation].op);
3074 d3dx9_set_material_parameter(state_table[state->operation].op,
3075 &effect->current_material, param_value);
3076 effect->material_updated = TRUE;
3077 return D3D_OK;
3079 case SC_NPATCHMODE:
3080 TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
3081 return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
3082 case SC_SHADERCONST:
3083 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3084 state_table[state->operation].op);
3085 return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
3086 param, param_value);
3087 default:
3088 FIXME("%s not handled.\n", state_table[state->operation].name);
3089 break;
3091 return D3D_OK;
3094 static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass, BOOL update_all)
3096 unsigned int i;
3097 HRESULT ret;
3098 HRESULT hr;
3099 ULONG64 new_update_version = next_effect_update_version(&effect->base_effect);
3101 TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
3103 ret = D3D_OK;
3104 for (i = 0; i < pass->state_count; ++i)
3106 if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
3108 WARN("Error applying state, hr %#x.\n", hr);
3109 ret = hr;
3113 if (effect->light_updated)
3115 for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
3117 if ((effect->light_updated & (1u << i))
3118 && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
3120 WARN("Error setting light, hr %#x.\n", hr);
3121 ret = hr;
3124 effect->light_updated = 0;
3127 if (effect->material_updated
3128 && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
3130 WARN("Error setting material, hr %#x.\n", hr);
3131 ret = hr;
3133 effect->material_updated = FALSE;
3135 pass->update_version = new_update_version;
3136 return ret;
3139 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
3141 unsigned char *member_data = data;
3142 unsigned int i, count;
3144 count = param->element_count ? param->element_count : param->member_count;
3145 for (i = 0; i < count; ++i)
3147 param_set_data_pointer(&param->members[i], member_data, TRUE, free_data);
3148 if (data)
3149 member_data += param->members[i].bytes;
3151 if (free_data)
3152 free_parameter_data(param, child);
3153 param->data = data;
3156 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
3158 struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
3159 BOOL matches;
3160 unsigned int i, member_count;
3162 matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
3163 && param1->type == param2->type && param1->rows == param2->rows
3164 && param1->columns == param2->columns && param1->element_count == param2->element_count
3165 && param1->member_count == param2->member_count;
3167 member_count = param1->element_count ? param1->element_count : param1->member_count;
3169 if (!matches || !member_count)
3170 return matches;
3172 for (i = 0; i < member_count; ++i)
3174 if (!is_same_parameter(&param1->members[i], &param2->members[i]))
3175 return FALSE;
3177 return TRUE;
3180 static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param)
3182 unsigned int i, free_entry_index;
3183 unsigned int new_size, new_count;
3185 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
3186 return D3D_OK;
3188 free_entry_index = pool->size;
3189 for (i = 0; i < pool->size; ++i)
3191 if (!pool->shared_data[i].count)
3192 free_entry_index = i;
3193 else if (is_same_parameter(&param->param, &pool->shared_data[i].parameters[0]->param))
3194 break;
3196 if (i == pool->size)
3198 i = free_entry_index;
3199 if (i == pool->size)
3201 struct d3dx_shared_data *new_alloc;
3203 if (!pool->size)
3205 new_size = INITIAL_POOL_SIZE;
3206 new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3207 sizeof(*pool->shared_data) * new_size);
3208 if (!new_alloc)
3210 ERR("Out of memory.\n");
3211 return E_OUTOFMEMORY;
3214 else
3216 new_size = pool->size * 2;
3217 new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
3218 sizeof(*pool->shared_data) * new_size);
3219 if (!new_alloc)
3221 ERR("Out of memory.\n");
3222 return E_OUTOFMEMORY;
3224 if (new_alloc != pool->shared_data)
3226 unsigned int j, k;
3228 for (j = 0; j < pool->size; ++j)
3229 for (k = 0; k < new_alloc[j].count; ++k)
3230 new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
3233 pool->shared_data = new_alloc;
3234 pool->size = new_size;
3236 pool->shared_data[i].data = param->param.data;
3238 else
3240 param_set_data_pointer(&param->param, pool->shared_data[i].data, FALSE, TRUE);
3242 new_count = ++pool->shared_data[i].count;
3243 if (new_count >= pool->shared_data[i].size)
3245 if (!pool->shared_data[i].size)
3247 new_size = INITIAL_SHARED_DATA_SIZE;
3248 pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3249 sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
3251 else
3253 new_size = pool->shared_data[i].size * 2;
3254 pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3255 pool->shared_data[i].parameters,
3256 sizeof(*pool->shared_data[i].parameters) * new_size);
3258 pool->shared_data[i].size = new_size;
3261 param->shared_data = &pool->shared_data[i];
3262 pool->shared_data[i].parameters[new_count - 1] = param;
3264 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
3265 new_count);
3267 return D3D_OK;
3270 static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param)
3272 param->data = NULL;
3273 return FALSE;
3276 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param)
3278 unsigned int new_count;
3280 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
3281 return;
3282 new_count = --param->shared_data->count;
3284 TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
3286 if (new_count)
3288 unsigned int i;
3290 for (i = 0; i < new_count; ++i)
3292 if (param->shared_data->parameters[i] == param)
3294 memmove(&param->shared_data->parameters[i],
3295 &param->shared_data->parameters[i + 1],
3296 sizeof(param->shared_data->parameters[i]) * (new_count - i));
3297 break;
3300 walk_parameter_tree(&param->param, param_zero_data_func, NULL);
3302 else
3304 HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
3305 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
3306 param->shared_data->size = 0;
3307 param->shared_data = NULL;
3311 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
3313 return CONTAINING_RECORD(iface, struct d3dx_effect_pool, ID3DXEffectPool_iface);
3316 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
3318 return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
3321 /*** IUnknown methods ***/
3322 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
3324 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
3326 if (IsEqualGUID(riid, &IID_IUnknown) ||
3327 IsEqualGUID(riid, &IID_ID3DXEffect))
3329 iface->lpVtbl->AddRef(iface);
3330 *object = iface;
3331 return S_OK;
3334 ERR("Interface %s not found\n", debugstr_guid(riid));
3336 return E_NOINTERFACE;
3339 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
3341 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3343 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
3345 return InterlockedIncrement(&This->ref);
3348 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
3350 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3351 ULONG ref = InterlockedDecrement(&This->ref);
3353 TRACE("(%p)->(): Release from %u\n", This, ref + 1);
3355 if (!ref)
3357 free_effect(This);
3358 HeapFree(GetProcessHeap(), 0, This);
3361 return ref;
3364 /*** ID3DXBaseEffect methods ***/
3365 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
3367 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3369 TRACE("iface %p, desc %p.\n", iface, desc);
3371 return d3dx9_base_effect_get_desc(&effect->base_effect, desc);
3374 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface,
3375 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3377 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3379 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
3381 return d3dx9_base_effect_get_parameter_desc(&effect->base_effect, parameter, desc);
3384 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface,
3385 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3387 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3389 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
3391 return d3dx9_base_effect_get_technique_desc(&effect->base_effect, technique, desc);
3394 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3396 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3398 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
3400 return d3dx9_base_effect_get_pass_desc(&effect->base_effect, pass, desc);
3403 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3405 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3407 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
3409 return d3dx9_base_effect_get_function_desc(&effect->base_effect, shader, desc);
3412 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3414 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3416 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3418 return d3dx9_base_effect_get_parameter(&effect->base_effect, parameter, index);
3421 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface,
3422 D3DXHANDLE parameter, const char *name)
3424 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3426 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
3428 return d3dx9_base_effect_get_parameter_by_name(&effect->base_effect, parameter, name);
3431 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface,
3432 D3DXHANDLE parameter, const char *semantic)
3434 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3436 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
3438 return d3dx9_base_effect_get_parameter_by_semantic(&effect->base_effect, parameter, semantic);
3441 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3443 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3445 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3447 return d3dx9_base_effect_get_parameter_element(&effect->base_effect, parameter, index);
3450 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
3452 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3454 TRACE("iface %p, index %u.\n", iface, index);
3456 return d3dx9_base_effect_get_technique(&effect->base_effect, index);
3459 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, const char *name)
3461 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3463 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3465 return d3dx9_base_effect_get_technique_by_name(&effect->base_effect, name);
3468 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
3470 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3472 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
3474 return d3dx9_base_effect_get_pass(&effect->base_effect, technique, index);
3477 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface,
3478 D3DXHANDLE technique, const char *name)
3480 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3482 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
3484 return d3dx9_base_effect_get_pass_by_name(&effect->base_effect, technique, name);
3487 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
3489 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3491 TRACE("iface %p, index %u.\n", iface, index);
3493 return d3dx9_base_effect_get_function(&effect->base_effect, index);
3496 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, const char *name)
3498 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3500 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3502 return d3dx9_base_effect_get_function_by_name(&effect->base_effect, name);
3505 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
3507 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3509 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
3511 return d3dx9_base_effect_get_annotation(&effect->base_effect, object, index);
3514 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface,
3515 D3DXHANDLE object, const char *name)
3517 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3519 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
3521 return d3dx9_base_effect_get_annotation_by_name(&effect->base_effect, object, name);
3524 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface,
3525 D3DXHANDLE parameter, const void *data, UINT bytes)
3527 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3529 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3531 return d3dx9_base_effect_set_value(&effect->base_effect, parameter, data, bytes);
3534 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface,
3535 D3DXHANDLE parameter, void *data, UINT bytes)
3537 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3539 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3541 return d3dx9_base_effect_get_value(&effect->base_effect, parameter, data, bytes);
3544 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
3546 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3548 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
3550 return d3dx9_base_effect_set_bool(&effect->base_effect, parameter, b);
3553 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
3555 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3557 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
3559 return d3dx9_base_effect_get_bool(&effect->base_effect, parameter, b);
3562 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface,
3563 D3DXHANDLE parameter, const BOOL *b, UINT count)
3565 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3567 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3569 return d3dx9_base_effect_set_bool_array(&effect->base_effect, parameter, b, count);
3572 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface,
3573 D3DXHANDLE parameter, BOOL *b, UINT count)
3575 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3577 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3579 return d3dx9_base_effect_get_bool_array(&effect->base_effect, parameter, b, count);
3582 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
3584 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3586 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
3588 return d3dx9_base_effect_set_int(&effect->base_effect, parameter, n);
3591 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
3593 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3595 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
3597 return d3dx9_base_effect_get_int(&effect->base_effect, parameter, n);
3600 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface,
3601 D3DXHANDLE parameter, const INT *n, UINT count)
3603 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3605 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3607 return d3dx9_base_effect_set_int_array(&effect->base_effect, parameter, n, count);
3610 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface,
3611 D3DXHANDLE parameter, INT *n, UINT count)
3613 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3615 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3617 return d3dx9_base_effect_get_int_array(&effect->base_effect, parameter, n, count);
3620 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
3622 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3624 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
3626 return d3dx9_base_effect_set_float(&effect->base_effect, parameter, f);
3629 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
3631 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3633 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
3635 return d3dx9_base_effect_get_float(&effect->base_effect, parameter, f);
3638 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface,
3639 D3DXHANDLE parameter, const float *f, UINT count)
3641 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3643 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3645 return d3dx9_base_effect_set_float_array(&effect->base_effect, parameter, f, count);
3648 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface,
3649 D3DXHANDLE parameter, float *f, UINT count)
3651 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3653 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3655 return d3dx9_base_effect_get_float_array(&effect->base_effect, parameter, f, count);
3658 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface,
3659 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
3661 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3663 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3665 return d3dx9_base_effect_set_vector(&effect->base_effect, parameter, vector);
3668 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface,
3669 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3671 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3673 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3675 return d3dx9_base_effect_get_vector(&effect->base_effect, parameter, vector);
3678 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface,
3679 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
3681 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3683 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3685 return d3dx9_base_effect_set_vector_array(&effect->base_effect, parameter, vector, count);
3688 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface,
3689 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3691 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3693 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3695 return d3dx9_base_effect_get_vector_array(&effect->base_effect, parameter, vector, count);
3698 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface,
3699 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3701 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3703 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3705 return d3dx9_base_effect_set_matrix(&effect->base_effect, parameter, matrix);
3708 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface,
3709 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3711 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3713 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3715 return d3dx9_base_effect_get_matrix(&effect->base_effect, parameter, matrix);
3718 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface,
3719 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3721 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3723 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3725 return d3dx9_base_effect_set_matrix_array(&effect->base_effect, parameter, matrix, count);
3728 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface,
3729 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3731 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3733 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3735 return d3dx9_base_effect_get_matrix_array(&effect->base_effect, parameter, matrix, count);
3738 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface,
3739 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3741 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3743 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3745 return d3dx9_base_effect_set_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3748 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface,
3749 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3751 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3753 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3755 return d3dx9_base_effect_get_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3758 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface,
3759 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3761 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3763 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3765 return d3dx9_base_effect_set_matrix_transpose(&effect->base_effect, parameter, matrix);
3768 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface,
3769 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3771 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3773 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3775 return d3dx9_base_effect_get_matrix_transpose(&effect->base_effect, parameter, matrix);
3778 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface,
3779 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3781 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3783 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3785 return d3dx9_base_effect_set_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3788 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface,
3789 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3791 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3793 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3795 return d3dx9_base_effect_get_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3798 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface,
3799 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3801 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3803 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3805 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3808 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface,
3809 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3811 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3813 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3815 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3818 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char *string)
3820 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3822 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
3824 return d3dx9_base_effect_set_string(&effect->base_effect, parameter, string);
3827 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char **string)
3829 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3831 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
3833 return d3dx9_base_effect_get_string(&effect->base_effect, parameter, string);
3836 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(struct ID3DXEffect *iface,
3837 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
3839 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3841 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3843 return d3dx9_base_effect_set_texture(&effect->base_effect, parameter, texture);
3846 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(struct ID3DXEffect *iface,
3847 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
3849 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3851 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3853 return d3dx9_base_effect_get_texture(&effect->base_effect, parameter, texture);
3856 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface,
3857 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
3859 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3861 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3863 return d3dx9_base_effect_get_pixel_shader(&effect->base_effect, parameter, shader);
3866 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(struct ID3DXEffect *iface,
3867 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
3869 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3871 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3873 return d3dx9_base_effect_get_vertex_shader(&effect->base_effect, parameter, shader);
3876 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3878 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3880 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
3882 return d3dx9_base_effect_set_array_range(&effect->base_effect, parameter, start, end);
3885 /*** ID3DXEffect methods ***/
3886 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, ID3DXEffectPool **pool)
3888 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3890 TRACE("iface %p, pool %p\n", This, pool);
3892 if (!pool)
3894 WARN("Invalid argument supplied.\n");
3895 return D3DERR_INVALIDCALL;
3898 if (This->pool)
3900 This->pool->lpVtbl->AddRef(This->pool);
3903 *pool = This->pool;
3905 TRACE("Returning pool %p\n", *pool);
3907 return S_OK;
3910 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3912 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3913 struct d3dx9_base_effect *base = &This->base_effect;
3914 struct d3dx_technique *tech = get_valid_technique(base, technique);
3916 TRACE("iface %p, technique %p\n", This, technique);
3918 if (tech)
3920 This->active_technique = tech;
3921 TRACE("Technique %p\n", tech);
3922 return D3D_OK;
3925 WARN("Technique not found.\n");
3927 return D3DERR_INVALIDCALL;
3930 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
3932 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3934 TRACE("iface %p\n", This);
3936 return get_technique_handle(This->active_technique);
3939 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
3941 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3942 struct d3dx9_base_effect *base = &effect->base_effect;
3943 struct d3dx_technique *tech = get_valid_technique(base, technique);
3944 HRESULT ret = D3D_OK;
3945 unsigned int i, j;
3947 FIXME("iface %p, technique %p semi-stub.\n", iface, technique);
3949 if (!tech)
3951 ret = D3DERR_INVALIDCALL;
3952 goto done;
3954 for (i = 0; i < tech->pass_count; ++i)
3956 struct d3dx_pass *pass = &tech->passes[i];
3958 for (j = 0; j < pass->state_count; ++j)
3960 struct d3dx_state *state = &pass->states[j];
3962 if (state_table[state->operation].class == SC_VERTEXSHADER
3963 || state_table[state->operation].class == SC_PIXELSHADER)
3965 struct d3dx_parameter *param;
3966 void *param_value;
3967 BOOL param_dirty;
3968 HRESULT hr;
3970 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[j], &param_value, &param,
3971 FALSE, &param_dirty)))
3972 return hr;
3974 if (param->object_id && base->objects[param->object_id].creation_failed)
3976 ret = E_FAIL;
3977 goto done;
3982 done:
3983 TRACE("Returning %#x.\n", ret);
3984 return ret;
3987 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
3989 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3991 FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
3993 return E_NOTIMPL;
3996 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
3997 void *data);
3999 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func,
4000 void *data)
4002 struct d3dx_parameter **params;
4003 unsigned int i, param_count;
4005 if (!param_eval)
4006 return FALSE;
4008 params = param_eval->shader_inputs.inputs_param;
4009 param_count = param_eval->shader_inputs.input_count;
4010 for (i = 0; i < param_count; ++i)
4012 if (walk_parameter_dep(params[i], param_func, data))
4013 return TRUE;
4016 params = param_eval->pres.inputs.inputs_param;
4017 param_count = param_eval->pres.inputs.input_count;
4018 for (i = 0; i < param_count; ++i)
4020 if (walk_parameter_dep(params[i], param_func, data))
4021 return TRUE;
4023 return FALSE;
4026 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func,
4027 void *data)
4029 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type))
4031 if (walk_parameter_dep(&state->parameter, param_func, data))
4032 return TRUE;
4034 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER)
4036 if (walk_parameter_dep(state->referenced_param, param_func, data))
4037 return TRUE;
4039 return walk_param_eval_dep(state->parameter.param_eval, param_func, data);
4042 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
4043 void *data)
4045 unsigned int i;
4046 unsigned int member_count;
4048 param = &param->top_level_param->param;
4049 if (param_func(data, param))
4050 return TRUE;
4052 if (walk_param_eval_dep(param->param_eval, param_func, data))
4053 return TRUE;
4055 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
4057 struct d3dx_sampler *sampler;
4058 unsigned int sampler_idx;
4059 unsigned int samplers_count = max(param->element_count, 1);
4061 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx)
4063 sampler = param->element_count ? param->members[sampler_idx].data : param->data;
4064 for (i = 0; i < sampler->state_count; ++i)
4066 if (walk_state_dep(&sampler->states[i], param_func, data))
4067 return TRUE;
4070 return FALSE;
4073 member_count = param->element_count ? param->element_count : param->member_count;
4074 for (i = 0; i < member_count; ++i)
4076 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data))
4077 return TRUE;
4080 return FALSE;
4083 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech)
4085 unsigned int i, j;
4086 struct d3dx_pass *pass;
4088 if (!tech || !param)
4089 return FALSE;
4091 for (i = 0; i < tech->pass_count; ++i)
4093 pass = &tech->passes[i];
4094 for (j = 0; j < pass->state_count; ++j)
4096 if (walk_state_dep(&pass->states[j], is_same_parameter, param))
4097 return TRUE;
4100 return FALSE;
4103 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
4105 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4106 struct d3dx_parameter *param = get_valid_parameter(&effect->base_effect, parameter);
4107 struct d3dx_technique *tech = get_valid_technique(&effect->base_effect, technique);
4108 BOOL ret;
4110 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique);
4111 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech);
4113 ret = is_parameter_used(param, tech);
4114 TRACE("Returning %#x.\n", ret);
4115 return ret;
4118 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
4120 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4121 struct d3dx_technique *technique = effect->active_technique;
4123 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags);
4125 if (passes && technique)
4127 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE))
4128 WARN("Invalid flags (%#x) specified.\n", flags);
4130 if (flags & D3DXFX_DONOTSAVESTATE)
4132 TRACE("State capturing disabled.\n");
4134 else
4136 HRESULT hr;
4137 unsigned int i;
4139 if (!technique->saved_state)
4141 ID3DXEffectStateManager *manager;
4143 manager = effect->manager;
4144 effect->manager = NULL;
4145 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
4146 ERR("BeginStateBlock failed, hr %#x.\n", hr);
4147 for (i = 0; i < technique->pass_count; i++)
4148 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE);
4149 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
4150 ERR("EndStateBlock failed, hr %#x.\n", hr);
4151 effect->manager = manager;
4153 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
4154 ERR("StateBlock Capture failed, hr %#x.\n", hr);
4157 *passes = technique->pass_count;
4158 effect->started = TRUE;
4159 effect->begin_flags = flags;
4161 return D3D_OK;
4164 WARN("Invalid argument supplied.\n");
4166 return D3DERR_INVALIDCALL;
4169 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
4171 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4172 struct d3dx_technique *technique = effect->active_technique;
4174 TRACE("iface %p, pass %u\n", effect, pass);
4176 if (technique && pass < technique->pass_count && !effect->active_pass)
4178 HRESULT hr;
4180 memset(effect->current_light, 0, sizeof(effect->current_light));
4181 memset(&effect->current_material, 0, sizeof(effect->current_material));
4183 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE)))
4184 effect->active_pass = &technique->passes[pass];
4185 return hr;
4188 WARN("Invalid argument supplied.\n");
4190 return D3DERR_INVALIDCALL;
4193 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect *iface)
4195 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4197 TRACE("iface %p.\n", iface);
4199 if (!effect->active_pass)
4201 WARN("Called without an active pass.\n");
4202 return D3D_OK;
4204 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE);
4207 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
4209 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4211 TRACE("iface %p\n", This);
4213 if (This->active_pass)
4215 This->active_pass = NULL;
4216 return D3D_OK;
4219 WARN("Invalid call.\n");
4221 return D3DERR_INVALIDCALL;
4224 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect *iface)
4226 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4227 struct d3dx_technique *technique = effect->active_technique;
4229 TRACE("iface %p.\n", iface);
4231 if (!effect->started)
4232 return D3D_OK;
4234 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE)
4236 TRACE("State restoring disabled.\n");
4238 else
4240 HRESULT hr;
4242 if (technique && technique->saved_state)
4244 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
4245 ERR("State block apply failed, hr %#x.\n", hr);
4247 else
4248 ERR("No saved state.\n");
4251 effect->started = FALSE;
4253 return D3D_OK;
4256 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device)
4258 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4260 TRACE("iface %p, device %p\n", This, device);
4262 if (!device)
4264 WARN("Invalid argument supplied.\n");
4265 return D3DERR_INVALIDCALL;
4268 IDirect3DDevice9_AddRef(This->device);
4270 *device = This->device;
4272 TRACE("Returning device %p\n", *device);
4274 return S_OK;
4277 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
4279 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4281 FIXME("(%p)->(): stub\n", This);
4283 return E_NOTIMPL;
4286 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
4288 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4290 FIXME("(%p)->(): stub\n", This);
4292 return E_NOTIMPL;
4295 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager)
4297 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4299 TRACE("iface %p, manager %p\n", This, manager);
4301 if (manager) IUnknown_AddRef(manager);
4302 if (This->manager) IUnknown_Release(This->manager);
4304 This->manager = manager;
4306 return D3D_OK;
4309 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager)
4311 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4313 TRACE("iface %p, manager %p\n", This, manager);
4315 if (!manager)
4317 WARN("Invalid argument supplied.\n");
4318 return D3DERR_INVALIDCALL;
4321 if (This->manager) IUnknown_AddRef(This->manager);
4322 *manager = This->manager;
4324 return D3D_OK;
4327 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
4329 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4331 FIXME("(%p)->(): stub\n", This);
4333 return E_NOTIMPL;
4336 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
4338 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4340 FIXME("(%p)->(): stub\n", This);
4342 return NULL;
4345 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4347 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4349 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4351 return E_NOTIMPL;
4354 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4356 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4358 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4360 return E_NOTIMPL;
4363 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
4364 struct IDirect3DDevice9 *device, struct ID3DXEffect **effect)
4366 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4368 FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
4370 return E_NOTIMPL;
4373 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface,
4374 D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes)
4376 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4377 iface, parameter, data, byte_offset, bytes);
4379 return E_NOTIMPL;
4382 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
4384 /*** IUnknown methods ***/
4385 ID3DXEffectImpl_QueryInterface,
4386 ID3DXEffectImpl_AddRef,
4387 ID3DXEffectImpl_Release,
4388 /*** ID3DXBaseEffect methods ***/
4389 ID3DXEffectImpl_GetDesc,
4390 ID3DXEffectImpl_GetParameterDesc,
4391 ID3DXEffectImpl_GetTechniqueDesc,
4392 ID3DXEffectImpl_GetPassDesc,
4393 ID3DXEffectImpl_GetFunctionDesc,
4394 ID3DXEffectImpl_GetParameter,
4395 ID3DXEffectImpl_GetParameterByName,
4396 ID3DXEffectImpl_GetParameterBySemantic,
4397 ID3DXEffectImpl_GetParameterElement,
4398 ID3DXEffectImpl_GetTechnique,
4399 ID3DXEffectImpl_GetTechniqueByName,
4400 ID3DXEffectImpl_GetPass,
4401 ID3DXEffectImpl_GetPassByName,
4402 ID3DXEffectImpl_GetFunction,
4403 ID3DXEffectImpl_GetFunctionByName,
4404 ID3DXEffectImpl_GetAnnotation,
4405 ID3DXEffectImpl_GetAnnotationByName,
4406 ID3DXEffectImpl_SetValue,
4407 ID3DXEffectImpl_GetValue,
4408 ID3DXEffectImpl_SetBool,
4409 ID3DXEffectImpl_GetBool,
4410 ID3DXEffectImpl_SetBoolArray,
4411 ID3DXEffectImpl_GetBoolArray,
4412 ID3DXEffectImpl_SetInt,
4413 ID3DXEffectImpl_GetInt,
4414 ID3DXEffectImpl_SetIntArray,
4415 ID3DXEffectImpl_GetIntArray,
4416 ID3DXEffectImpl_SetFloat,
4417 ID3DXEffectImpl_GetFloat,
4418 ID3DXEffectImpl_SetFloatArray,
4419 ID3DXEffectImpl_GetFloatArray,
4420 ID3DXEffectImpl_SetVector,
4421 ID3DXEffectImpl_GetVector,
4422 ID3DXEffectImpl_SetVectorArray,
4423 ID3DXEffectImpl_GetVectorArray,
4424 ID3DXEffectImpl_SetMatrix,
4425 ID3DXEffectImpl_GetMatrix,
4426 ID3DXEffectImpl_SetMatrixArray,
4427 ID3DXEffectImpl_GetMatrixArray,
4428 ID3DXEffectImpl_SetMatrixPointerArray,
4429 ID3DXEffectImpl_GetMatrixPointerArray,
4430 ID3DXEffectImpl_SetMatrixTranspose,
4431 ID3DXEffectImpl_GetMatrixTranspose,
4432 ID3DXEffectImpl_SetMatrixTransposeArray,
4433 ID3DXEffectImpl_GetMatrixTransposeArray,
4434 ID3DXEffectImpl_SetMatrixTransposePointerArray,
4435 ID3DXEffectImpl_GetMatrixTransposePointerArray,
4436 ID3DXEffectImpl_SetString,
4437 ID3DXEffectImpl_GetString,
4438 ID3DXEffectImpl_SetTexture,
4439 ID3DXEffectImpl_GetTexture,
4440 ID3DXEffectImpl_GetPixelShader,
4441 ID3DXEffectImpl_GetVertexShader,
4442 ID3DXEffectImpl_SetArrayRange,
4443 /*** ID3DXEffect methods ***/
4444 ID3DXEffectImpl_GetPool,
4445 ID3DXEffectImpl_SetTechnique,
4446 ID3DXEffectImpl_GetCurrentTechnique,
4447 ID3DXEffectImpl_ValidateTechnique,
4448 ID3DXEffectImpl_FindNextValidTechnique,
4449 ID3DXEffectImpl_IsParameterUsed,
4450 ID3DXEffectImpl_Begin,
4451 ID3DXEffectImpl_BeginPass,
4452 ID3DXEffectImpl_CommitChanges,
4453 ID3DXEffectImpl_EndPass,
4454 ID3DXEffectImpl_End,
4455 ID3DXEffectImpl_GetDevice,
4456 ID3DXEffectImpl_OnLostDevice,
4457 ID3DXEffectImpl_OnResetDevice,
4458 ID3DXEffectImpl_SetStateManager,
4459 ID3DXEffectImpl_GetStateManager,
4460 ID3DXEffectImpl_BeginParameterBlock,
4461 ID3DXEffectImpl_EndParameterBlock,
4462 ID3DXEffectImpl_ApplyParameterBlock,
4463 ID3DXEffectImpl_DeleteParameterBlock,
4464 ID3DXEffectImpl_CloneEffect,
4465 ID3DXEffectImpl_SetRawValue
4468 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
4470 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
4473 /*** IUnknown methods ***/
4474 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
4476 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
4478 if (IsEqualGUID(riid, &IID_IUnknown) ||
4479 IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
4481 iface->lpVtbl->AddRef(iface);
4482 *object = iface;
4483 return S_OK;
4486 ERR("Interface %s not found\n", debugstr_guid(riid));
4488 return E_NOINTERFACE;
4491 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
4493 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4495 TRACE("iface %p: AddRef from %u\n", iface, This->ref);
4497 return InterlockedIncrement(&This->ref);
4500 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
4502 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4503 ULONG ref = InterlockedDecrement(&This->ref);
4505 TRACE("iface %p: Release from %u\n", iface, ref + 1);
4507 if (!ref)
4509 free_effect_compiler(This);
4510 HeapFree(GetProcessHeap(), 0, This);
4513 return ref;
4516 /*** ID3DXBaseEffect methods ***/
4517 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
4519 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4521 TRACE("iface %p, desc %p.\n", iface, desc);
4523 return d3dx9_base_effect_get_desc(&compiler->base_effect, desc);
4526 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface,
4527 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
4529 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4531 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
4533 return d3dx9_base_effect_get_parameter_desc(&compiler->base_effect, parameter, desc);
4536 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface,
4537 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
4539 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4541 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
4543 return d3dx9_base_effect_get_technique_desc(&compiler->base_effect, technique, desc);
4546 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface,
4547 D3DXHANDLE pass, D3DXPASS_DESC *desc)
4549 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4551 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
4553 return d3dx9_base_effect_get_pass_desc(&compiler->base_effect, pass, desc);
4556 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface,
4557 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
4559 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4561 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
4563 return d3dx9_base_effect_get_function_desc(&compiler->base_effect, shader, desc);
4566 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface,
4567 D3DXHANDLE parameter, UINT index)
4569 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4571 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
4573 return d3dx9_base_effect_get_parameter(&compiler->base_effect, parameter, index);
4576 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface,
4577 D3DXHANDLE parameter, const char *name)
4579 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4581 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
4583 return d3dx9_base_effect_get_parameter_by_name(&compiler->base_effect, parameter, name);
4586 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface,
4587 D3DXHANDLE parameter, const char *semantic)
4589 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4591 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
4593 return d3dx9_base_effect_get_parameter_by_semantic(&compiler->base_effect, parameter, semantic);
4596 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface,
4597 D3DXHANDLE parameter, UINT index)
4599 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4601 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
4603 return d3dx9_base_effect_get_parameter_element(&compiler->base_effect, parameter, index);
4606 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
4608 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4610 TRACE("iface %p, index %u.\n", iface, index);
4612 return d3dx9_base_effect_get_technique(&compiler->base_effect, index);
4615 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name)
4617 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4619 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
4621 return d3dx9_base_effect_get_technique_by_name(&compiler->base_effect, name);
4624 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
4626 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4628 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
4630 return d3dx9_base_effect_get_pass(&compiler->base_effect, technique, index);
4633 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface,
4634 D3DXHANDLE technique, const char *name)
4636 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4638 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
4640 return d3dx9_base_effect_get_pass_by_name(&compiler->base_effect, technique, name);
4643 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
4645 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4647 TRACE("iface %p, index %u.\n", iface, index);
4649 return d3dx9_base_effect_get_function(&compiler->base_effect, index);
4652 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name)
4654 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4656 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
4658 return d3dx9_base_effect_get_function_by_name(&compiler->base_effect, name);
4661 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface,
4662 D3DXHANDLE object, UINT index)
4664 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4666 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
4668 return d3dx9_base_effect_get_annotation(&compiler->base_effect, object, index);
4671 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface,
4672 D3DXHANDLE object, const char *name)
4674 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4676 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
4678 return d3dx9_base_effect_get_annotation_by_name(&compiler->base_effect, object, name);
4681 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface,
4682 D3DXHANDLE parameter, const void *data, UINT bytes)
4684 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4686 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
4688 return d3dx9_base_effect_set_value(&compiler->base_effect, parameter, data, bytes);
4691 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface,
4692 D3DXHANDLE parameter, void *data, UINT bytes)
4694 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4696 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
4698 return d3dx9_base_effect_get_value(&compiler->base_effect, parameter, data, bytes);
4701 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4703 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4705 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
4707 return d3dx9_base_effect_set_bool(&compiler->base_effect, parameter, b);
4710 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4712 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4714 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
4716 return d3dx9_base_effect_get_bool(&compiler->base_effect, parameter, b);
4719 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface,
4720 D3DXHANDLE parameter, const BOOL *b, UINT count)
4722 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4724 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
4726 return d3dx9_base_effect_set_bool_array(&compiler->base_effect, parameter, b, count);
4729 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface,
4730 D3DXHANDLE parameter, BOOL *b, UINT count)
4732 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4734 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
4736 return d3dx9_base_effect_get_bool_array(&compiler->base_effect, parameter, b, count);
4739 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4741 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4743 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
4745 return d3dx9_base_effect_set_int(&compiler->base_effect, parameter, n);
4748 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4750 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4752 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
4754 return d3dx9_base_effect_get_int(&compiler->base_effect, parameter, n);
4757 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface,
4758 D3DXHANDLE parameter, const INT *n, UINT count)
4760 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4762 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
4764 return d3dx9_base_effect_set_int_array(&compiler->base_effect, parameter, n, count);
4767 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface,
4768 D3DXHANDLE parameter, INT *n, UINT count)
4770 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4772 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
4774 return d3dx9_base_effect_get_int_array(&compiler->base_effect, parameter, n, count);
4777 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f)
4779 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4781 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
4783 return d3dx9_base_effect_set_float(&compiler->base_effect, parameter, f);
4786 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f)
4788 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4790 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
4792 return d3dx9_base_effect_get_float(&compiler->base_effect, parameter, f);
4795 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface,
4796 D3DXHANDLE parameter, const float *f, UINT count)
4798 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4800 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
4802 return d3dx9_base_effect_set_float_array(&compiler->base_effect, parameter, f, count);
4805 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface,
4806 D3DXHANDLE parameter, float *f, UINT count)
4808 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4810 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
4812 return d3dx9_base_effect_get_float_array(&compiler->base_effect, parameter, f, count);
4815 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface,
4816 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
4818 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4820 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
4822 return d3dx9_base_effect_set_vector(&compiler->base_effect, parameter, vector);
4825 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface,
4826 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4828 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4830 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
4832 return d3dx9_base_effect_get_vector(&compiler->base_effect, parameter, vector);
4835 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface,
4836 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
4838 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4840 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
4842 return d3dx9_base_effect_set_vector_array(&compiler->base_effect, parameter, vector, count);
4845 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface,
4846 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4848 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4850 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
4852 return d3dx9_base_effect_get_vector_array(&compiler->base_effect, parameter, vector, count);
4855 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface,
4856 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4858 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4860 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4862 return d3dx9_base_effect_set_matrix(&compiler->base_effect, parameter, matrix);
4865 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface,
4866 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4868 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4870 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4872 return d3dx9_base_effect_get_matrix(&compiler->base_effect, parameter, matrix);
4875 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface,
4876 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4878 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4880 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4882 return d3dx9_base_effect_set_matrix_array(&compiler->base_effect, parameter, matrix, count);
4885 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface,
4886 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4888 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4890 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4892 return d3dx9_base_effect_get_matrix_array(&compiler->base_effect, parameter, matrix, count);
4895 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface,
4896 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4898 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4900 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4902 return d3dx9_base_effect_set_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count);
4905 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface,
4906 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4908 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4910 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4912 return d3dx9_base_effect_get_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count);
4915 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface,
4916 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4918 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4920 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4922 return d3dx9_base_effect_set_matrix_transpose(&compiler->base_effect, parameter, matrix);
4925 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface,
4926 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4928 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4930 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4932 return d3dx9_base_effect_get_matrix_transpose(&compiler->base_effect, parameter, matrix);
4935 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4936 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4938 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4940 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4942 return d3dx9_base_effect_set_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count);
4945 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4946 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4948 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4950 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4952 return d3dx9_base_effect_get_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count);
4955 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4956 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4958 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4960 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4962 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count);
4965 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4966 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4968 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4970 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4972 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count);
4975 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface,
4976 D3DXHANDLE parameter, const char *string)
4978 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4980 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
4982 return d3dx9_base_effect_set_string(&compiler->base_effect, parameter, string);
4985 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface,
4986 D3DXHANDLE parameter, const char **string)
4988 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4990 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
4992 return d3dx9_base_effect_get_string(&compiler->base_effect, parameter, string);
4995 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
4996 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
4998 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5000 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
5002 return d3dx9_base_effect_set_texture(&compiler->base_effect, parameter, texture);
5005 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
5006 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
5008 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5010 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
5012 return d3dx9_base_effect_get_texture(&compiler->base_effect, parameter, texture);
5015 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
5016 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
5018 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5020 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
5022 return d3dx9_base_effect_get_pixel_shader(&compiler->base_effect, parameter, shader);
5025 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
5026 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
5028 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5030 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
5032 return d3dx9_base_effect_get_vertex_shader(&compiler->base_effect, parameter, shader);
5035 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface,
5036 D3DXHANDLE parameter, UINT start, UINT end)
5038 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5040 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
5042 return d3dx9_base_effect_set_array_range(&compiler->base_effect, parameter, start, end);
5045 /*** ID3DXEffectCompiler methods ***/
5046 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
5048 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5050 FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
5052 return E_NOTIMPL;
5055 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
5057 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5059 FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
5061 return E_NOTIMPL;
5064 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
5065 ID3DXBuffer **effect, ID3DXBuffer **error_msgs)
5067 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5069 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
5071 return E_NOTIMPL;
5074 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
5075 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs,
5076 ID3DXConstantTable **constant_table)
5078 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5080 FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
5081 This, function, target, flags, shader, error_msgs, constant_table);
5083 return E_NOTIMPL;
5086 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
5088 /*** IUnknown methods ***/
5089 ID3DXEffectCompilerImpl_QueryInterface,
5090 ID3DXEffectCompilerImpl_AddRef,
5091 ID3DXEffectCompilerImpl_Release,
5092 /*** ID3DXBaseEffect methods ***/
5093 ID3DXEffectCompilerImpl_GetDesc,
5094 ID3DXEffectCompilerImpl_GetParameterDesc,
5095 ID3DXEffectCompilerImpl_GetTechniqueDesc,
5096 ID3DXEffectCompilerImpl_GetPassDesc,
5097 ID3DXEffectCompilerImpl_GetFunctionDesc,
5098 ID3DXEffectCompilerImpl_GetParameter,
5099 ID3DXEffectCompilerImpl_GetParameterByName,
5100 ID3DXEffectCompilerImpl_GetParameterBySemantic,
5101 ID3DXEffectCompilerImpl_GetParameterElement,
5102 ID3DXEffectCompilerImpl_GetTechnique,
5103 ID3DXEffectCompilerImpl_GetTechniqueByName,
5104 ID3DXEffectCompilerImpl_GetPass,
5105 ID3DXEffectCompilerImpl_GetPassByName,
5106 ID3DXEffectCompilerImpl_GetFunction,
5107 ID3DXEffectCompilerImpl_GetFunctionByName,
5108 ID3DXEffectCompilerImpl_GetAnnotation,
5109 ID3DXEffectCompilerImpl_GetAnnotationByName,
5110 ID3DXEffectCompilerImpl_SetValue,
5111 ID3DXEffectCompilerImpl_GetValue,
5112 ID3DXEffectCompilerImpl_SetBool,
5113 ID3DXEffectCompilerImpl_GetBool,
5114 ID3DXEffectCompilerImpl_SetBoolArray,
5115 ID3DXEffectCompilerImpl_GetBoolArray,
5116 ID3DXEffectCompilerImpl_SetInt,
5117 ID3DXEffectCompilerImpl_GetInt,
5118 ID3DXEffectCompilerImpl_SetIntArray,
5119 ID3DXEffectCompilerImpl_GetIntArray,
5120 ID3DXEffectCompilerImpl_SetFloat,
5121 ID3DXEffectCompilerImpl_GetFloat,
5122 ID3DXEffectCompilerImpl_SetFloatArray,
5123 ID3DXEffectCompilerImpl_GetFloatArray,
5124 ID3DXEffectCompilerImpl_SetVector,
5125 ID3DXEffectCompilerImpl_GetVector,
5126 ID3DXEffectCompilerImpl_SetVectorArray,
5127 ID3DXEffectCompilerImpl_GetVectorArray,
5128 ID3DXEffectCompilerImpl_SetMatrix,
5129 ID3DXEffectCompilerImpl_GetMatrix,
5130 ID3DXEffectCompilerImpl_SetMatrixArray,
5131 ID3DXEffectCompilerImpl_GetMatrixArray,
5132 ID3DXEffectCompilerImpl_SetMatrixPointerArray,
5133 ID3DXEffectCompilerImpl_GetMatrixPointerArray,
5134 ID3DXEffectCompilerImpl_SetMatrixTranspose,
5135 ID3DXEffectCompilerImpl_GetMatrixTranspose,
5136 ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
5137 ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
5138 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
5139 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
5140 ID3DXEffectCompilerImpl_SetString,
5141 ID3DXEffectCompilerImpl_GetString,
5142 ID3DXEffectCompilerImpl_SetTexture,
5143 ID3DXEffectCompilerImpl_GetTexture,
5144 ID3DXEffectCompilerImpl_GetPixelShader,
5145 ID3DXEffectCompilerImpl_GetVertexShader,
5146 ID3DXEffectCompilerImpl_SetArrayRange,
5147 /*** ID3DXEffectCompiler methods ***/
5148 ID3DXEffectCompilerImpl_SetLiteral,
5149 ID3DXEffectCompilerImpl_GetLiteral,
5150 ID3DXEffectCompilerImpl_CompileEffect,
5151 ID3DXEffectCompilerImpl_CompileShader,
5154 static HRESULT d3dx9_parse_sampler(struct d3dx9_base_effect *base, struct d3dx_sampler *sampler,
5155 const char *data, const char **ptr, struct d3dx_object *objects)
5157 HRESULT hr;
5158 UINT i;
5160 read_dword(ptr, &sampler->state_count);
5161 TRACE("Count: %u\n", sampler->state_count);
5163 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count);
5164 if (!sampler->states)
5166 ERR("Out of memory\n");
5167 return E_OUTOFMEMORY;
5170 for (i = 0; i < sampler->state_count; ++i)
5172 hr = d3dx9_parse_state(base, &sampler->states[i], data, ptr, objects);
5173 if (hr != D3D_OK)
5175 WARN("Failed to parse state %u\n", i);
5176 goto err_out;
5180 return D3D_OK;
5182 err_out:
5184 for (i = 0; i < sampler->state_count; ++i)
5186 free_state(&sampler->states[i]);
5188 HeapFree(GetProcessHeap(), 0, sampler->states);
5189 sampler->states = NULL;
5191 return hr;
5194 static HRESULT d3dx9_parse_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5195 void *value, const char *data, const char **ptr, struct d3dx_object *objects)
5197 unsigned int i;
5198 HRESULT hr;
5199 UINT old_size = 0;
5201 if (param->element_count)
5203 param->data = value;
5205 for (i = 0; i < param->element_count; ++i)
5207 struct d3dx_parameter *member = &param->members[i];
5209 hr = d3dx9_parse_value(base, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
5210 if (hr != D3D_OK)
5212 WARN("Failed to parse value %u\n", i);
5213 return hr;
5216 old_size += member->bytes;
5219 return D3D_OK;
5222 switch(param->class)
5224 case D3DXPC_SCALAR:
5225 case D3DXPC_VECTOR:
5226 case D3DXPC_MATRIX_ROWS:
5227 case D3DXPC_MATRIX_COLUMNS:
5228 param->data = value;
5229 break;
5231 case D3DXPC_STRUCT:
5232 param->data = value;
5234 for (i = 0; i < param->member_count; ++i)
5236 struct d3dx_parameter *member = &param->members[i];
5238 hr = d3dx9_parse_value(base, member, (char *)value + old_size, data, ptr, objects);
5239 if (hr != D3D_OK)
5241 WARN("Failed to parse value %u\n", i);
5242 return hr;
5245 old_size += member->bytes;
5247 break;
5249 case D3DXPC_OBJECT:
5250 switch (param->type)
5252 case D3DXPT_STRING:
5253 case D3DXPT_TEXTURE:
5254 case D3DXPT_TEXTURE1D:
5255 case D3DXPT_TEXTURE2D:
5256 case D3DXPT_TEXTURE3D:
5257 case D3DXPT_TEXTURECUBE:
5258 case D3DXPT_PIXELSHADER:
5259 case D3DXPT_VERTEXSHADER:
5260 read_dword(ptr, &param->object_id);
5261 TRACE("Id: %u\n", param->object_id);
5262 objects[param->object_id].param = param;
5263 param->data = value;
5264 break;
5266 case D3DXPT_SAMPLER:
5267 case D3DXPT_SAMPLER1D:
5268 case D3DXPT_SAMPLER2D:
5269 case D3DXPT_SAMPLER3D:
5270 case D3DXPT_SAMPLERCUBE:
5272 struct d3dx_sampler *sampler;
5274 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
5275 if (!sampler)
5276 return E_OUTOFMEMORY;
5278 hr = d3dx9_parse_sampler(base, sampler, data, ptr, objects);
5279 if (hr != D3D_OK)
5281 HeapFree(GetProcessHeap(), 0, sampler);
5282 WARN("Failed to parse sampler\n");
5283 return hr;
5286 param->data = sampler;
5287 break;
5290 default:
5291 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5292 break;
5294 break;
5296 default:
5297 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5298 break;
5301 return D3D_OK;
5304 static HRESULT d3dx9_parse_init_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5305 const char *data, const char *ptr, struct d3dx_object *objects)
5307 UINT size = param->bytes;
5308 HRESULT hr;
5309 void *value = NULL;
5311 TRACE("param size: %u\n", size);
5313 if (size)
5315 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5316 if (!value)
5318 ERR("Failed to allocate data memory.\n");
5319 return E_OUTOFMEMORY;
5322 switch(param->class)
5324 case D3DXPC_OBJECT:
5325 break;
5327 case D3DXPC_SCALAR:
5328 case D3DXPC_VECTOR:
5329 case D3DXPC_MATRIX_ROWS:
5330 case D3DXPC_MATRIX_COLUMNS:
5331 case D3DXPC_STRUCT:
5332 TRACE("Data: %s.\n", debugstr_an(ptr, size));
5333 memcpy(value, ptr, size);
5334 break;
5336 default:
5337 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5338 break;
5342 hr = d3dx9_parse_value(base, param, value, data, &ptr, objects);
5343 if (hr != D3D_OK)
5345 WARN("Failed to parse value\n");
5346 HeapFree(GetProcessHeap(), 0, value);
5347 return hr;
5350 return D3D_OK;
5353 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
5355 DWORD size;
5357 read_dword(&ptr, &size);
5358 TRACE("Name size: %#x\n", size);
5360 if (!size)
5362 return D3D_OK;
5365 *name = HeapAlloc(GetProcessHeap(), 0, size);
5366 if (!*name)
5368 ERR("Failed to allocate name memory.\n");
5369 return E_OUTOFMEMORY;
5372 TRACE("Name: %s.\n", debugstr_an(ptr, size));
5373 memcpy(*name, ptr, size);
5375 return D3D_OK;
5378 static HRESULT d3dx9_copy_data(struct d3dx9_base_effect *base, unsigned int object_id, const char **ptr)
5380 struct d3dx_object *object = &base->objects[object_id];
5382 if (object->size || object->data)
5384 if (object_id)
5385 FIXME("Overwriting object id %u!\n", object_id);
5386 else
5387 TRACE("Overwriting object id 0.\n");
5389 HeapFree(GetProcessHeap(), 0, object->data);
5390 object->data = NULL;
5393 read_dword(ptr, &object->size);
5394 TRACE("Data size: %#x.\n", object->size);
5396 if (!object->size)
5397 return D3D_OK;
5399 object->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5400 if (!object->data)
5402 ERR("Failed to allocate object memory.\n");
5403 return E_OUTOFMEMORY;
5406 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size));
5407 memcpy(object->data, *ptr, object->size);
5409 *ptr += ((object->size + 3) & ~3);
5411 return D3D_OK;
5414 static void param_set_magic_number(struct d3dx_parameter *param)
5416 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string));
5419 static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5420 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
5422 DWORD offset;
5423 HRESULT hr;
5424 UINT i;
5426 param->flags = flags;
5428 if (!parent)
5430 read_dword(ptr, (DWORD *)&param->type);
5431 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
5433 read_dword(ptr, (DWORD *)&param->class);
5434 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
5436 read_dword(ptr, &offset);
5437 TRACE("Type name offset: %#x\n", offset);
5438 hr = d3dx9_parse_name(&param->name, data + offset);
5439 if (hr != D3D_OK)
5441 WARN("Failed to parse name\n");
5442 goto err_out;
5445 read_dword(ptr, &offset);
5446 TRACE("Type semantic offset: %#x\n", offset);
5447 hr = d3dx9_parse_name(&param->semantic, data + offset);
5448 if (hr != D3D_OK)
5450 WARN("Failed to parse semantic\n");
5451 goto err_out;
5454 read_dword(ptr, &param->element_count);
5455 TRACE("Elements: %u\n", param->element_count);
5457 switch (param->class)
5459 case D3DXPC_VECTOR:
5460 read_dword(ptr, &param->columns);
5461 TRACE("Columns: %u\n", param->columns);
5463 read_dword(ptr, &param->rows);
5464 TRACE("Rows: %u\n", param->rows);
5466 /* sizeof(DWORD) * rows * columns */
5467 param->bytes = 4 * param->rows * param->columns;
5468 break;
5470 case D3DXPC_SCALAR:
5471 case D3DXPC_MATRIX_ROWS:
5472 case D3DXPC_MATRIX_COLUMNS:
5473 read_dword(ptr, &param->rows);
5474 TRACE("Rows: %u\n", param->rows);
5476 read_dword(ptr, &param->columns);
5477 TRACE("Columns: %u\n", param->columns);
5479 /* sizeof(DWORD) * rows * columns */
5480 param->bytes = 4 * param->rows * param->columns;
5481 break;
5483 case D3DXPC_STRUCT:
5484 read_dword(ptr, &param->member_count);
5485 TRACE("Members: %u\n", param->member_count);
5486 break;
5488 case D3DXPC_OBJECT:
5489 switch (param->type)
5491 case D3DXPT_STRING:
5492 case D3DXPT_PIXELSHADER:
5493 case D3DXPT_VERTEXSHADER:
5494 case D3DXPT_TEXTURE:
5495 case D3DXPT_TEXTURE1D:
5496 case D3DXPT_TEXTURE2D:
5497 case D3DXPT_TEXTURE3D:
5498 case D3DXPT_TEXTURECUBE:
5499 param->bytes = sizeof(void *);
5500 break;
5502 case D3DXPT_SAMPLER:
5503 case D3DXPT_SAMPLER1D:
5504 case D3DXPT_SAMPLER2D:
5505 case D3DXPT_SAMPLER3D:
5506 case D3DXPT_SAMPLERCUBE:
5507 param->bytes = 0;
5508 break;
5510 default:
5511 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5512 break;
5514 break;
5516 default:
5517 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5518 break;
5521 else
5523 /* elements */
5524 param->type = parent->type;
5525 param->class = parent->class;
5526 param->name = parent->name;
5527 param->semantic = parent->semantic;
5528 param->element_count = 0;
5529 param->member_count = parent->member_count;
5530 param->bytes = parent->bytes;
5531 param->rows = parent->rows;
5532 param->columns = parent->columns;
5535 if (param->element_count)
5537 unsigned int param_bytes = 0;
5538 const char *save_ptr = *ptr;
5540 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count);
5541 if (!param->members)
5543 ERR("Out of memory\n");
5544 hr = E_OUTOFMEMORY;
5545 goto err_out;
5548 for (i = 0; i < param->element_count; ++i)
5550 *ptr = save_ptr;
5552 param_set_magic_number(&param->members[i]);
5553 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, param, flags);
5554 if (hr != D3D_OK)
5556 WARN("Failed to parse member %u\n", i);
5557 goto err_out;
5560 param_bytes += param->members[i].bytes;
5563 param->bytes = param_bytes;
5565 else if (param->member_count)
5567 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count);
5568 if (!param->members)
5570 ERR("Out of memory\n");
5571 hr = E_OUTOFMEMORY;
5572 goto err_out;
5575 for (i = 0; i < param->member_count; ++i)
5577 param_set_magic_number(&param->members[i]);
5578 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, NULL, flags);
5579 if (hr != D3D_OK)
5581 WARN("Failed to parse member %u\n", i);
5582 goto err_out;
5585 param->bytes += param->members[i].bytes;
5588 return D3D_OK;
5590 err_out:
5592 if (param->members)
5594 unsigned int count = param->element_count ? param->element_count : param->member_count;
5596 for (i = 0; i < count; ++i)
5597 free_parameter(&param->members[i], param->element_count != 0, TRUE);
5598 HeapFree(GetProcessHeap(), 0, param->members);
5599 param->members = NULL;
5602 if (!parent)
5604 HeapFree(GetProcessHeap(), 0, param->name);
5605 HeapFree(GetProcessHeap(), 0, param->semantic);
5607 param->name = NULL;
5608 param->semantic = NULL;
5610 return hr;
5613 static HRESULT d3dx9_parse_effect_annotation(struct d3dx9_base_effect *base, struct d3dx_parameter *anno,
5614 const char *data, const char **ptr, struct d3dx_object *objects)
5616 DWORD offset;
5617 const char *ptr2;
5618 HRESULT hr;
5620 anno->flags = D3DX_PARAMETER_ANNOTATION;
5622 read_dword(ptr, &offset);
5623 TRACE("Typedef offset: %#x\n", offset);
5624 ptr2 = data + offset;
5625 hr = d3dx9_parse_effect_typedef(base, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5626 if (hr != D3D_OK)
5628 WARN("Failed to parse type definition\n");
5629 return hr;
5632 read_dword(ptr, &offset);
5633 TRACE("Value offset: %#x\n", offset);
5634 hr = d3dx9_parse_init_value(base, anno, data, data + offset, objects);
5635 if (hr != D3D_OK)
5637 WARN("Failed to parse value\n");
5638 return hr;
5641 return D3D_OK;
5644 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
5645 const char *data, const char **ptr, struct d3dx_object *objects)
5647 DWORD offset;
5648 const char *ptr2;
5649 HRESULT hr;
5651 state->type = ST_CONSTANT;
5653 read_dword(ptr, &state->operation);
5654 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5656 read_dword(ptr, &state->index);
5657 TRACE("Index: %#x\n", state->index);
5659 read_dword(ptr, &offset);
5660 TRACE("Typedef offset: %#x\n", offset);
5661 ptr2 = data + offset;
5662 hr = d3dx9_parse_effect_typedef(base, &state->parameter, data, &ptr2, NULL, 0);
5663 if (hr != D3D_OK)
5665 WARN("Failed to parse type definition\n");
5666 goto err_out;
5669 read_dword(ptr, &offset);
5670 TRACE("Value offset: %#x\n", offset);
5671 hr = d3dx9_parse_init_value(base, &state->parameter, data, data + offset, objects);
5672 if (hr != D3D_OK)
5674 WARN("Failed to parse value\n");
5675 goto err_out;
5678 return D3D_OK;
5680 err_out:
5682 free_parameter(&state->parameter, FALSE, FALSE);
5684 return hr;
5687 static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_top_level_parameter *param,
5688 const char *data, const char **ptr, struct d3dx_object *objects)
5690 DWORD offset;
5691 HRESULT hr;
5692 unsigned int i;
5693 const char *ptr2;
5695 read_dword(ptr, &offset);
5696 TRACE("Typedef offset: %#x.\n", offset);
5697 ptr2 = data + offset;
5699 read_dword(ptr, &offset);
5700 TRACE("Value offset: %#x.\n", offset);
5702 read_dword(ptr, &param->param.flags);
5703 TRACE("Flags: %#x.\n", param->param.flags);
5705 read_dword(ptr, &param->annotation_count);
5706 TRACE("Annotation count: %u.\n", param->annotation_count);
5708 hr = d3dx9_parse_effect_typedef(base, &param->param, data, &ptr2, NULL, param->param.flags);
5709 if (hr != D3D_OK)
5711 WARN("Failed to parse type definition.\n");
5712 return hr;
5715 hr = d3dx9_parse_init_value(base, &param->param, data, data + offset, objects);
5716 if (hr != D3D_OK)
5718 WARN("Failed to parse value.\n");
5719 return hr;
5722 if (param->annotation_count)
5724 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5725 sizeof(*param->annotations) * param->annotation_count);
5726 if (!param->annotations)
5728 ERR("Out of memory.\n");
5729 hr = E_OUTOFMEMORY;
5730 goto err_out;
5733 for (i = 0; i < param->annotation_count; ++i)
5735 param_set_magic_number(&param->annotations[i]);
5736 hr = d3dx9_parse_effect_annotation(base, &param->annotations[i], data, ptr, objects);
5737 if (hr != D3D_OK)
5739 WARN("Failed to parse annotation.\n");
5740 goto err_out;
5745 return D3D_OK;
5747 err_out:
5749 if (param->annotations)
5751 for (i = 0; i < param->annotation_count; ++i)
5752 free_parameter(&param->annotations[i], FALSE, FALSE);
5753 HeapFree(GetProcessHeap(), 0, param->annotations);
5754 param->annotations = NULL;
5757 return hr;
5760 static HRESULT d3dx9_parse_effect_pass(struct d3dx9_base_effect *base, struct d3dx_pass *pass,
5761 const char *data, const char **ptr, struct d3dx_object *objects)
5763 DWORD offset;
5764 HRESULT hr;
5765 unsigned int i;
5766 struct d3dx_state *states = NULL;
5767 char *name = NULL;
5769 read_dword(ptr, &offset);
5770 TRACE("Pass name offset: %#x\n", offset);
5771 hr = d3dx9_parse_name(&name, data + offset);
5772 if (hr != D3D_OK)
5774 WARN("Failed to parse name\n");
5775 goto err_out;
5778 read_dword(ptr, &pass->annotation_count);
5779 TRACE("Annotation count: %u\n", pass->annotation_count);
5781 read_dword(ptr, &pass->state_count);
5782 TRACE("State count: %u\n", pass->state_count);
5784 if (pass->annotation_count)
5786 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5787 sizeof(*pass->annotations) * pass->annotation_count);
5788 if (!pass->annotations)
5790 ERR("Out of memory\n");
5791 hr = E_OUTOFMEMORY;
5792 goto err_out;
5795 for (i = 0; i < pass->annotation_count; ++i)
5797 param_set_magic_number(&pass->annotations[i]);
5798 hr = d3dx9_parse_effect_annotation(base, &pass->annotations[i], data, ptr, objects);
5799 if (hr != D3D_OK)
5801 WARN("Failed to parse annotation %u\n", i);
5802 goto err_out;
5807 if (pass->state_count)
5809 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5810 if (!states)
5812 ERR("Out of memory\n");
5813 hr = E_OUTOFMEMORY;
5814 goto err_out;
5817 for (i = 0; i < pass->state_count; ++i)
5819 hr = d3dx9_parse_state(base, &states[i], data, ptr, objects);
5820 if (hr != D3D_OK)
5822 WARN("Failed to parse annotation %u\n", i);
5823 goto err_out;
5828 pass->name = name;
5829 pass->states = states;
5831 return D3D_OK;
5833 err_out:
5835 if (pass->annotations)
5837 for (i = 0; i < pass->annotation_count; ++i)
5838 free_parameter(&pass->annotations[i], FALSE, FALSE);
5839 HeapFree(GetProcessHeap(), 0, pass->annotations);
5840 pass->annotations = NULL;
5843 if (states)
5845 for (i = 0; i < pass->state_count; ++i)
5847 free_state(&states[i]);
5849 HeapFree(GetProcessHeap(), 0, states);
5852 HeapFree(GetProcessHeap(), 0, name);
5854 return hr;
5857 static HRESULT d3dx9_parse_effect_technique(struct d3dx9_base_effect *base, struct d3dx_technique *technique,
5858 const char *data, const char **ptr, struct d3dx_object *objects)
5860 DWORD offset;
5861 HRESULT hr;
5862 unsigned int i;
5863 char *name = NULL;
5865 read_dword(ptr, &offset);
5866 TRACE("Technique name offset: %#x\n", offset);
5867 hr = d3dx9_parse_name(&name, data + offset);
5868 if (hr != D3D_OK)
5870 WARN("Failed to parse name\n");
5871 goto err_out;
5874 read_dword(ptr, &technique->annotation_count);
5875 TRACE("Annotation count: %u\n", technique->annotation_count);
5877 read_dword(ptr, &technique->pass_count);
5878 TRACE("Pass count: %u\n", technique->pass_count);
5880 if (technique->annotation_count)
5882 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5883 sizeof(*technique->annotations) * technique->annotation_count);
5884 if (!technique->annotations)
5886 ERR("Out of memory\n");
5887 hr = E_OUTOFMEMORY;
5888 goto err_out;
5891 for (i = 0; i < technique->annotation_count; ++i)
5893 param_set_magic_number(&technique->annotations[i]);
5894 hr = d3dx9_parse_effect_annotation(base, &technique->annotations[i], data, ptr, objects);
5895 if (hr != D3D_OK)
5897 WARN("Failed to parse annotation %u\n", i);
5898 goto err_out;
5903 if (technique->pass_count)
5905 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5906 sizeof(*technique->passes) * technique->pass_count);
5907 if (!technique->passes)
5909 ERR("Out of memory\n");
5910 hr = E_OUTOFMEMORY;
5911 goto err_out;
5914 for (i = 0; i < technique->pass_count; ++i)
5916 hr = d3dx9_parse_effect_pass(base, &technique->passes[i], data, ptr, objects);
5917 if (hr != D3D_OK)
5919 WARN("Failed to parse pass %u\n", i);
5920 goto err_out;
5925 technique->name = name;
5927 return D3D_OK;
5929 err_out:
5931 if (technique->passes)
5933 for (i = 0; i < technique->pass_count; ++i)
5934 free_pass(&technique->passes[i]);
5935 HeapFree(GetProcessHeap(), 0, technique->passes);
5936 technique->passes = NULL;
5939 if (technique->annotations)
5941 for (i = 0; i < technique->annotation_count; ++i)
5942 free_parameter(&technique->annotations[i], FALSE, FALSE);
5943 HeapFree(GetProcessHeap(), 0, technique->annotations);
5944 technique->annotations = NULL;
5947 HeapFree(GetProcessHeap(), 0, name);
5949 return hr;
5952 static HRESULT d3dx9_create_object(struct d3dx9_base_effect *base, struct d3dx_object *object)
5954 struct d3dx_parameter *param = object->param;
5955 struct IDirect3DDevice9 *device = base->effect->device;
5956 HRESULT hr;
5958 if (*(char **)param->data)
5959 ERR("Parameter data already allocated.\n");
5961 switch (param->type)
5963 case D3DXPT_STRING:
5964 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5965 if (!*(char **)param->data)
5967 ERR("Out of memory.\n");
5968 return E_OUTOFMEMORY;
5970 memcpy(*(char **)param->data, object->data, object->size);
5971 break;
5972 case D3DXPT_VERTEXSHADER:
5973 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data,
5974 (IDirect3DVertexShader9 **)param->data)))
5976 WARN("Failed to create vertex shader.\n");
5977 object->creation_failed = TRUE;
5979 break;
5980 case D3DXPT_PIXELSHADER:
5981 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data,
5982 (IDirect3DPixelShader9 **)param->data)))
5984 WARN("Failed to create pixel shader.\n");
5985 object->creation_failed = TRUE;
5987 break;
5988 default:
5989 break;
5991 return D3D_OK;
5994 static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct d3dx_state *state,
5995 const char **skip_constants, unsigned int skip_constants_count)
5997 DWORD string_size;
5998 struct d3dx_parameter *param = &state->parameter;
5999 struct d3dx_object *object = &base->objects[param->object_id];
6000 char *ptr = object->data;
6001 HRESULT ret;
6003 TRACE("Parsing array entry selection state for parameter %p.\n", param);
6005 string_size = *(DWORD *)ptr;
6006 state->referenced_param = get_parameter_by_name(base, NULL, ptr + 4);
6007 if (state->referenced_param)
6009 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
6011 else
6013 FIXME("Referenced parameter %s not found.\n", ptr + 4);
6014 return D3DXERR_INVALIDDATA;
6016 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
6018 if (string_size % sizeof(DWORD))
6019 FIXME("Unaligned string_size %u.\n", string_size);
6020 if (FAILED(ret = d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1,
6021 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, &param->param_eval,
6022 get_version_counter_ptr(base), NULL, 0)))
6023 return ret;
6024 ret = D3D_OK;
6025 param = state->referenced_param;
6026 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
6028 unsigned int i;
6030 for (i = 0; i < param->element_count; i++)
6032 if (param->members[i].type != param->type)
6034 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
6035 return D3DXERR_INVALIDDATA;
6037 if (!param->members[i].param_eval)
6039 TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
6040 object = &base->objects[param->members[i].object_id];
6041 if (FAILED(ret = d3dx_create_param_eval(base, object->data, object->size, param->type,
6042 &param->members[i].param_eval, get_version_counter_ptr(base),
6043 skip_constants, skip_constants_count)))
6044 break;
6048 return ret;
6051 static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr,
6052 const char **skip_constants, unsigned int skip_constants_count)
6054 DWORD technique_index;
6055 DWORD index, state_index, usage, element_index;
6056 struct d3dx_state *state;
6057 struct d3dx_parameter *param;
6058 struct d3dx_object *object;
6059 HRESULT hr = E_FAIL;
6061 read_dword(ptr, &technique_index);
6062 TRACE("technique_index: %u\n", technique_index);
6064 read_dword(ptr, &index);
6065 TRACE("index: %u\n", index);
6067 read_dword(ptr, &element_index);
6068 TRACE("element_index: %u\n", element_index);
6070 read_dword(ptr, &state_index);
6071 TRACE("state_index: %u\n", state_index);
6073 read_dword(ptr, &usage);
6074 TRACE("usage: %u\n", usage);
6076 if (technique_index == 0xffffffff)
6078 struct d3dx_parameter *parameter;
6079 struct d3dx_sampler *sampler;
6081 if (index >= base->parameter_count)
6083 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
6084 return E_FAIL;
6087 parameter = &base->parameters[index].param;
6088 if (element_index != 0xffffffff)
6090 if (element_index >= parameter->element_count && parameter->element_count != 0)
6092 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
6093 return E_FAIL;
6096 if (parameter->element_count)
6097 parameter = &parameter->members[element_index];
6100 sampler = parameter->data;
6101 if (state_index >= sampler->state_count)
6103 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
6104 return E_FAIL;
6107 state = &sampler->states[state_index];
6109 else
6111 struct d3dx_technique *technique;
6112 struct d3dx_pass *pass;
6114 if (technique_index >= base->technique_count)
6116 FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
6117 return E_FAIL;
6120 technique = &base->techniques[technique_index];
6121 if (index >= technique->pass_count)
6123 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
6124 return E_FAIL;
6127 pass = &technique->passes[index];
6128 if (state_index >= pass->state_count)
6130 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
6131 return E_FAIL;
6134 state = &pass->states[state_index];
6137 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name);
6138 param = &state->parameter;
6139 TRACE("Using object id %u.\n", param->object_id);
6140 object = &base->objects[param->object_id];
6142 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class),
6143 debug_d3dxparameter_type(param->type));
6144 switch (usage)
6146 case 0:
6147 switch (param->type)
6149 case D3DXPT_VERTEXSHADER:
6150 case D3DXPT_PIXELSHADER:
6151 state->type = ST_CONSTANT;
6152 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6153 return hr;
6155 if (object->data)
6157 if (FAILED(hr = d3dx9_create_object(base, object)))
6158 return hr;
6159 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6160 &param->param_eval, get_version_counter_ptr(base),
6161 skip_constants, skip_constants_count)))
6162 return hr;
6164 break;
6166 case D3DXPT_BOOL:
6167 case D3DXPT_INT:
6168 case D3DXPT_FLOAT:
6169 case D3DXPT_STRING:
6170 state->type = ST_FXLC;
6171 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6172 return hr;
6173 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6174 &param->param_eval, get_version_counter_ptr(base), NULL, 0)))
6175 return hr;
6176 break;
6178 default:
6179 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
6180 break;
6182 break;
6184 case 1:
6185 state->type = ST_PARAMETER;
6186 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6187 return hr;
6189 TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
6190 state->referenced_param = get_parameter_by_name(base, NULL, object->data);
6191 if (state->referenced_param)
6193 struct d3dx_parameter *refpar = state->referenced_param;
6195 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
6196 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
6198 struct d3dx_object *refobj = &base->objects[refpar->object_id];
6200 if (!refpar->param_eval)
6202 if (FAILED(hr = d3dx_create_param_eval(base, refobj->data, refobj->size,
6203 refpar->type, &refpar->param_eval, get_version_counter_ptr(base),
6204 skip_constants, skip_constants_count)))
6205 return hr;
6209 else
6211 FIXME("Referenced parameter %s not found.\n", (char *)object->data);
6212 return D3DXERR_INVALIDDATA;
6214 break;
6216 case 2:
6217 state->type = ST_ARRAY_SELECTOR;
6218 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6219 return hr;
6220 hr = d3dx9_parse_array_selector(base, state, skip_constants, skip_constants_count);
6221 break;
6223 default:
6224 FIXME("Unknown usage %x\n", usage);
6225 break;
6228 return hr;
6231 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param)
6233 param->top_level_param = top_level_param;
6234 return FALSE;
6237 static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *data, UINT data_size,
6238 DWORD start, const char **skip_constants, unsigned int skip_constants_count)
6240 const char *ptr = data + start;
6241 UINT stringcount, resourcecount;
6242 HRESULT hr;
6243 UINT i;
6245 read_dword(&ptr, &base->parameter_count);
6246 TRACE("Parameter count: %u.\n", base->parameter_count);
6248 read_dword(&ptr, &base->technique_count);
6249 TRACE("Technique count: %u.\n", base->technique_count);
6251 skip_dword_unknown(&ptr, 1);
6253 read_dword(&ptr, &base->object_count);
6254 TRACE("Object count: %u.\n", base->object_count);
6256 base->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base->objects) * base->object_count);
6257 if (!base->objects)
6259 ERR("Out of memory.\n");
6260 hr = E_OUTOFMEMORY;
6261 goto err_out;
6264 if (base->parameter_count)
6266 base->parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6267 sizeof(*base->parameters) * base->parameter_count);
6268 if (!base->parameters)
6270 ERR("Out of memory.\n");
6271 hr = E_OUTOFMEMORY;
6272 goto err_out;
6275 for (i = 0; i < base->parameter_count; ++i)
6277 param_set_magic_number(&base->parameters[i].param);
6278 hr = d3dx9_parse_effect_parameter(base, &base->parameters[i], data, &ptr, base->objects);
6279 if (hr != D3D_OK)
6281 WARN("Failed to parse parameter %u.\n", i);
6282 goto err_out;
6284 walk_parameter_tree(&base->parameters[i].param, param_set_top_level_param,
6285 &base->parameters[i]);
6289 if (base->technique_count)
6291 base->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6292 sizeof(*base->techniques) * base->technique_count);
6293 if (!base->techniques)
6295 ERR("Out of memory.\n");
6296 hr = E_OUTOFMEMORY;
6297 goto err_out;
6300 for (i = 0; i < base->technique_count; ++i)
6302 TRACE("Parsing technique %u.\n", i);
6303 hr = d3dx9_parse_effect_technique(base, &base->techniques[i], data, &ptr, base->objects);
6304 if (hr != D3D_OK)
6306 WARN("Failed to parse technique %u.\n", i);
6307 goto err_out;
6312 read_dword(&ptr, &stringcount);
6313 TRACE("String count: %u.\n", stringcount);
6315 read_dword(&ptr, &resourcecount);
6316 TRACE("Resource count: %u.\n", resourcecount);
6318 for (i = 0; i < stringcount; ++i)
6320 DWORD id;
6322 read_dword(&ptr, &id);
6323 TRACE("id: %u.\n", id);
6325 if (FAILED(hr = d3dx9_copy_data(base, id, &ptr)))
6326 goto err_out;
6328 if (base->objects[id].data)
6330 if (FAILED(hr = d3dx9_create_object(base, &base->objects[id])))
6331 goto err_out;
6335 for (i = 0; i < resourcecount; ++i)
6337 TRACE("parse resource %u.\n", i);
6339 hr = d3dx9_parse_resource(base, data, &ptr, skip_constants, skip_constants_count);
6340 if (hr != D3D_OK)
6342 WARN("Failed to parse resource %u.\n", i);
6343 goto err_out;
6347 for (i = 0; i < base->parameter_count; ++i)
6349 if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i])))
6350 goto err_out;
6351 base->parameters[i].version_counter = base->pool
6352 ? &base->pool->version_counter
6353 : &base->version_counter;
6354 set_dirty(&base->parameters[i].param);
6356 return D3D_OK;
6358 err_out:
6360 if (base->techniques)
6362 for (i = 0; i < base->technique_count; ++i)
6363 free_technique(&base->techniques[i]);
6364 HeapFree(GetProcessHeap(), 0, base->techniques);
6365 base->techniques = NULL;
6368 if (base->parameters)
6370 for (i = 0; i < base->parameter_count; ++i)
6372 free_top_level_parameter(&base->parameters[i]);
6374 HeapFree(GetProcessHeap(), 0, base->parameters);
6375 base->parameters = NULL;
6378 if (base->objects)
6380 for (i = 0; i < base->object_count; ++i)
6382 free_object(&base->objects[i]);
6384 HeapFree(GetProcessHeap(), 0, base->objects);
6385 base->objects = NULL;
6388 return hr;
6391 #define INITIAL_CONST_NAMES_SIZE 4
6393 static char *next_valid_constant_name(char **string)
6395 char *ret = *string;
6396 char *next;
6398 while (*ret && !isalpha(*ret) && *ret != '_')
6399 ++ret;
6400 if (!*ret)
6401 return NULL;
6403 next = ret + 1;
6404 while (isalpha(*next) || isdigit(*next) || *next == '_')
6405 ++next;
6406 if (*next)
6407 *next++ = 0;
6408 *string = next;
6409 return ret;
6412 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count)
6414 const char **names, **new_alloc;
6415 const char *name;
6416 char *s;
6417 unsigned int size = INITIAL_CONST_NAMES_SIZE;
6419 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size);
6420 if (!names)
6421 return NULL;
6423 *names_count = 0;
6424 s = skip_constants_string;
6425 while ((name = next_valid_constant_name(&s)))
6427 if (*names_count == size)
6429 size *= 2;
6430 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size);
6431 if (!new_alloc)
6433 HeapFree(GetProcessHeap(), 0, names);
6434 return NULL;
6436 names = new_alloc;
6438 names[(*names_count)++] = name;
6440 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names));
6441 if (!new_alloc)
6442 return names;
6443 return new_alloc;
6446 static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
6447 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6448 UINT eflags, ID3DBlob **errors, struct ID3DXEffectImpl *effect, struct d3dx_effect_pool *pool,
6449 const char *skip_constants_string)
6451 DWORD tag, offset;
6452 const char *ptr = data;
6453 HRESULT hr;
6454 ID3DBlob *bytecode = NULL, *temp_errors = NULL;
6455 char *skip_constants_buffer = NULL;
6456 const char **skip_constants = NULL;
6457 unsigned int skip_constants_count = 0;
6458 unsigned int i, j;
6460 TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n",
6461 base, data, data_size, effect, pool, debugstr_a(skip_constants_string));
6463 base->effect = effect;
6464 base->pool = pool;
6465 base->flags = eflags;
6467 read_dword(&ptr, &tag);
6468 TRACE("Tag: %x\n", tag);
6470 if (tag != d3dx9_effect_version(9, 1))
6472 TRACE("HLSL ASCII effect, trying to compile it.\n");
6473 hr = D3DCompile(data, data_size, NULL, defines, include,
6474 "main", "fx_2_0", 0, eflags, &bytecode, &temp_errors);
6475 if (FAILED(hr))
6477 WARN("Failed to compile ASCII effect.\n");
6478 if (bytecode)
6479 ID3D10Blob_Release(bytecode);
6480 if (temp_errors)
6482 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors);
6483 const char *string_ptr;
6485 while (*error_string)
6487 string_ptr = error_string;
6488 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r'
6489 && string_ptr - error_string < 80)
6490 ++string_ptr;
6491 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string));
6492 error_string = string_ptr;
6493 while (*error_string == '\n' || *error_string == '\r')
6494 ++error_string;
6497 if (errors)
6498 *errors = temp_errors;
6499 else if (temp_errors)
6500 ID3D10Blob_Release(temp_errors);
6501 return hr;
6503 if (!bytecode)
6505 FIXME("No output from effect compilation.\n");
6506 return D3DERR_INVALIDCALL;
6508 if (errors)
6509 *errors = temp_errors;
6510 else if (temp_errors)
6511 ID3D10Blob_Release(temp_errors);
6513 ptr = ID3D10Blob_GetBufferPointer(bytecode);
6514 read_dword(&ptr, &tag);
6515 TRACE("Tag: %x\n", tag);
6518 if (skip_constants_string)
6520 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0,
6521 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1));
6522 if (!skip_constants_buffer)
6524 if (bytecode)
6525 ID3D10Blob_Release(bytecode);
6526 return E_OUTOFMEMORY;
6528 strcpy(skip_constants_buffer, skip_constants_string);
6530 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count)))
6532 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6533 if (bytecode)
6534 ID3D10Blob_Release(bytecode);
6535 return E_OUTOFMEMORY;
6538 read_dword(&ptr, &offset);
6539 TRACE("Offset: %x\n", offset);
6541 hr = d3dx9_parse_effect(base, ptr, data_size, offset, skip_constants, skip_constants_count);
6542 if (bytecode)
6543 ID3D10Blob_Release(bytecode);
6544 if (hr != D3D_OK)
6546 FIXME("Failed to parse effect.\n");
6547 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6548 HeapFree(GetProcessHeap(), 0, skip_constants);
6549 return hr;
6552 for (i = 0; i < skip_constants_count; ++i)
6554 struct d3dx_parameter *param;
6555 param = get_parameter_by_name(base, NULL, skip_constants[i]);
6556 if (param)
6558 for (j = 0; j < base->technique_count; ++j)
6560 if (is_parameter_used(param, &base->techniques[j]))
6562 WARN("skip_constants parameter %s is used in technique %u.\n",
6563 debugstr_a(skip_constants[i]), j);
6564 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6565 HeapFree(GetProcessHeap(), 0, skip_constants);
6566 d3dx9_base_effect_cleanup(base);
6567 return D3DERR_INVALIDCALL;
6571 else
6573 TRACE("skip_constants parameter %s not found.\n",
6574 debugstr_a(skip_constants[i]));
6578 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6579 HeapFree(GetProcessHeap(), 0, skip_constants);
6581 return D3D_OK;
6584 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, struct IDirect3DDevice9 *device,
6585 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6586 UINT eflags, ID3DBlob **error_messages, struct ID3DXEffectPool *pool, const char *skip_constants)
6588 HRESULT hr;
6589 struct d3dx_effect_pool *pool_impl = NULL;
6591 TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
6593 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
6594 effect->ref = 1;
6596 if (pool)
6598 pool->lpVtbl->AddRef(pool);
6599 pool_impl = impl_from_ID3DXEffectPool(pool);
6601 effect->pool = pool;
6603 IDirect3DDevice9_AddRef(device);
6604 effect->device = device;
6606 if (FAILED(hr = d3dx9_base_effect_init(&effect->base_effect, data, data_size, defines, include,
6607 eflags, error_messages, effect, pool_impl, skip_constants)))
6609 FIXME("Failed to parse effect, hr %#x.\n", hr);
6610 free_effect(effect);
6611 return hr;
6614 /* initialize defaults - check because of unsupported ascii effects */
6615 if (effect->base_effect.techniques)
6617 effect->active_technique = &effect->base_effect.techniques[0];
6618 effect->active_pass = NULL;
6621 return D3D_OK;
6624 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6625 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags,
6626 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6628 struct ID3DXEffectImpl *object;
6629 HRESULT hr;
6631 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p,"
6632 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n",
6633 device, srcdata, srcdatalen, defines, include,
6634 skip_constants, flags, pool, effect, compilation_errors);
6636 if (compilation_errors)
6637 *compilation_errors = NULL;
6639 if (!device || !srcdata)
6640 return D3DERR_INVALIDCALL;
6642 if (!srcdatalen)
6643 return E_FAIL;
6645 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6646 if (!effect)
6647 return D3D_OK;
6649 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6650 if (!object)
6651 return E_OUTOFMEMORY;
6653 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6654 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants);
6655 if (FAILED(hr))
6657 WARN("Failed to create effect object.\n");
6658 HeapFree(GetProcessHeap(), 0, object);
6659 return hr;
6662 *effect = &object->ID3DXEffect_iface;
6664 TRACE("Created ID3DXEffect %p\n", object);
6666 return D3D_OK;
6669 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6670 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6671 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6673 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
6674 include, flags, pool, effect, compilation_errors);
6676 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
6679 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler,
6680 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6681 UINT eflags, ID3DBlob **error_messages)
6683 HRESULT hr;
6685 TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
6687 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
6688 compiler->ref = 1;
6690 if (FAILED(hr = d3dx9_base_effect_init(&compiler->base_effect, data, data_size, defines,
6691 include, eflags, error_messages, NULL, NULL, NULL)))
6693 FIXME("Failed to parse effect, hr %#x.\n", hr);
6694 free_effect_compiler(compiler);
6695 return hr;
6698 return D3D_OK;
6701 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines,
6702 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors)
6704 struct ID3DXEffectCompilerImpl *object;
6705 HRESULT hr;
6707 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
6708 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
6710 if (!srcdata || !compiler)
6712 WARN("Invalid arguments supplied\n");
6713 return D3DERR_INVALIDCALL;
6716 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6717 if (!object)
6718 return E_OUTOFMEMORY;
6720 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6721 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors);
6722 if (FAILED(hr))
6724 WARN("Failed to initialize effect compiler\n");
6725 HeapFree(GetProcessHeap(), 0, object);
6726 return hr;
6729 *compiler = &object->ID3DXEffectCompiler_iface;
6731 TRACE("Created ID3DXEffectCompiler %p\n", object);
6733 return D3D_OK;
6736 /*** IUnknown methods ***/
6737 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
6739 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
6741 if (IsEqualGUID(riid, &IID_IUnknown) ||
6742 IsEqualGUID(riid, &IID_ID3DXEffectPool))
6744 iface->lpVtbl->AddRef(iface);
6745 *object = iface;
6746 return S_OK;
6749 WARN("Interface %s not found\n", debugstr_guid(riid));
6751 return E_NOINTERFACE;
6754 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface)
6756 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6757 ULONG refcount = InterlockedIncrement(&pool->refcount);
6759 TRACE("%p increasing refcount to %u.\n", pool, refcount);
6761 return refcount;
6764 static void free_effect_pool(struct d3dx_effect_pool *pool)
6766 unsigned int i;
6768 for (i = 0; i < pool->size; ++i)
6770 if (pool->shared_data[i].count)
6772 unsigned int j;
6774 WARN("Releasing pool with referenced parameters.\n");
6776 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE);
6777 pool->shared_data[i].parameters[0]->shared_data = NULL;
6779 for (j = 1; j < pool->shared_data[i].count; ++j)
6781 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL);
6782 pool->shared_data[i].parameters[j]->shared_data = NULL;
6784 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);
6787 HeapFree(GetProcessHeap(), 0, pool->shared_data);
6788 HeapFree(GetProcessHeap(), 0, pool);
6791 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface)
6793 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6794 ULONG refcount = InterlockedDecrement(&pool->refcount);
6796 TRACE("%p decreasing refcount to %u.\n", pool, refcount);
6798 if (!refcount)
6799 free_effect_pool(pool);
6801 return refcount;
6804 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
6806 /*** IUnknown methods ***/
6807 d3dx_effect_pool_QueryInterface,
6808 d3dx_effect_pool_AddRef,
6809 d3dx_effect_pool_Release
6812 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool)
6814 struct d3dx_effect_pool *object;
6816 TRACE("pool %p.\n", pool);
6818 if (!pool)
6819 return D3DERR_INVALIDCALL;
6821 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6822 if (!object)
6823 return E_OUTOFMEMORY;
6825 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6826 object->refcount = 1;
6828 *pool = &object->ID3DXEffectPool_iface;
6830 return S_OK;
6833 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6834 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6835 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6837 void *buffer;
6838 HRESULT ret;
6839 DWORD size;
6841 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6842 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6843 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants),
6844 flags, pool, effect, compilationerrors);
6846 if (!device || !srcfile)
6847 return D3DERR_INVALIDCALL;
6849 ret = map_view_of_file(srcfile, &buffer, &size);
6851 if (FAILED(ret))
6852 return D3DXERR_INVALIDDATA;
6854 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6855 UnmapViewOfFile(buffer);
6857 return ret;
6860 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
6861 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6862 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6864 WCHAR *srcfileW;
6865 HRESULT ret;
6866 DWORD len;
6868 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6869 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6870 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants),
6871 flags, pool, effect, compilationerrors);
6873 if (!srcfile)
6874 return D3DERR_INVALIDCALL;
6876 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6877 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6878 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6880 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6881 HeapFree(GetProcessHeap(), 0, srcfileW);
6883 return ret;
6886 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6887 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6888 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6890 TRACE("(void): relay\n");
6891 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6894 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile,
6895 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6896 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6898 TRACE("(void): relay\n");
6899 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6902 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6903 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6904 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6906 HRSRC resinfo;
6907 void *buffer;
6908 DWORD size;
6910 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6911 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6912 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants),
6913 flags, pool, effect, compilationerrors);
6915 if (!device)
6916 return D3DERR_INVALIDCALL;
6918 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
6919 return D3DXERR_INVALIDDATA;
6921 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6922 return D3DXERR_INVALIDDATA;
6924 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6925 skipconstants, flags, pool, effect, compilationerrors);
6928 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6929 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6930 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6932 HRSRC resinfo;
6933 void *buffer;
6934 DWORD size;
6936 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6937 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6938 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants),
6939 flags, pool, effect, compilationerrors);
6941 if (!device)
6942 return D3DERR_INVALIDCALL;
6944 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6945 return D3DXERR_INVALIDDATA;
6947 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6948 return D3DXERR_INVALIDDATA;
6950 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6951 skipconstants, flags, pool, effect, compilationerrors);
6954 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6955 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6956 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6958 TRACE("(void): relay\n");
6959 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6962 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6963 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6964 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6966 TRACE("(void): relay\n");
6967 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6970 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines,
6971 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6973 void *buffer;
6974 HRESULT ret;
6975 DWORD size;
6977 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6978 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors);
6980 if (!srcfile)
6981 return D3DERR_INVALIDCALL;
6983 ret = map_view_of_file(srcfile, &buffer, &size);
6985 if (FAILED(ret))
6986 return D3DXERR_INVALIDDATA;
6988 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6989 UnmapViewOfFile(buffer);
6991 return ret;
6994 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines,
6995 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6997 WCHAR *srcfileW;
6998 HRESULT ret;
6999 DWORD len;
7001 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7002 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors);
7004 if (!srcfile)
7005 return D3DERR_INVALIDCALL;
7007 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
7008 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
7009 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
7011 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
7012 HeapFree(GetProcessHeap(), 0, srcfileW);
7014 return ret;
7017 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource,
7018 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
7019 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7021 HRSRC resinfo;
7022 void *buffer;
7023 DWORD size;
7025 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7026 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors);
7028 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
7029 return D3DXERR_INVALIDDATA;
7031 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7032 return D3DXERR_INVALIDDATA;
7034 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7037 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource,
7038 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
7039 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7041 HRSRC resinfo;
7042 void *buffer;
7043 DWORD size;
7045 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7046 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors);
7048 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
7049 return D3DXERR_INVALIDDATA;
7051 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7052 return D3DXERR_INVALIDDATA;
7054 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7057 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly)
7059 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly);
7061 return D3DXERR_INVALIDDATA;