d3dx9: Skip AddRef + Release if SetValue is called with the old texture.
[wine.git] / dlls / d3dx9_36 / effect.c
blob7f54e251a656f624862305e45392212ae01b6097
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 *old_texture = ((IUnknown **)param->data)[i];
1559 IUnknown *new_texture = ((IUnknown **)data)[i];
1561 if (new_texture == old_texture)
1562 continue;
1564 if (new_texture)
1565 IUnknown_AddRef(new_texture);
1566 if (old_texture)
1567 IUnknown_Release(old_texture);
1569 /* fallthrough */
1570 case D3DXPT_VOID:
1571 case D3DXPT_BOOL:
1572 case D3DXPT_INT:
1573 case D3DXPT_FLOAT:
1574 TRACE("Copy %u bytes.\n", param->bytes);
1575 memcpy(param->data, data, param->bytes);
1576 set_dirty(param);
1577 break;
1579 case D3DXPT_STRING:
1581 HRESULT hr;
1583 set_dirty(param);
1584 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1586 if (FAILED(hr = set_string(&((char **)param->data)[i], ((const char **)data)[i])))
1587 return hr;
1589 break;
1592 default:
1593 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
1594 break;
1597 return D3D_OK;
1600 WARN("Invalid argument specified\n");
1602 return D3DERR_INVALIDCALL;
1605 static HRESULT d3dx9_base_effect_get_value(struct d3dx9_base_effect *base,
1606 D3DXHANDLE parameter, void *data, UINT bytes)
1608 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1610 if (!param)
1612 WARN("Invalid parameter %p specified\n", parameter);
1613 return D3DERR_INVALIDCALL;
1616 /* samplers don't touch data */
1617 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1619 TRACE("Sampler: returning E_FAIL\n");
1620 return E_FAIL;
1623 if (data && param->bytes <= bytes)
1625 TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1627 switch (param->type)
1629 case D3DXPT_VOID:
1630 case D3DXPT_BOOL:
1631 case D3DXPT_INT:
1632 case D3DXPT_FLOAT:
1633 case D3DXPT_STRING:
1634 break;
1636 case D3DXPT_VERTEXSHADER:
1637 case D3DXPT_PIXELSHADER:
1638 case D3DXPT_TEXTURE:
1639 case D3DXPT_TEXTURE1D:
1640 case D3DXPT_TEXTURE2D:
1641 case D3DXPT_TEXTURE3D:
1642 case D3DXPT_TEXTURECUBE:
1644 UINT i;
1646 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1648 IUnknown *unk = ((IUnknown **)param->data)[i];
1649 if (unk) IUnknown_AddRef(unk);
1651 break;
1654 default:
1655 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1656 break;
1659 TRACE("Copy %u bytes\n", param->bytes);
1660 memcpy(data, param->data, param->bytes);
1661 return D3D_OK;
1664 WARN("Parameter not found.\n");
1666 return D3DERR_INVALIDCALL;
1669 static HRESULT d3dx9_base_effect_set_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL b)
1671 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1673 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1675 set_number(param->data, param->type, &b, D3DXPT_BOOL);
1676 set_dirty(param);
1677 return D3D_OK;
1680 WARN("Parameter not found.\n");
1682 return D3DERR_INVALIDCALL;
1685 static HRESULT d3dx9_base_effect_get_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL *b)
1687 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1689 if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
1691 set_number(b, D3DXPT_BOOL, param->data, param->type);
1692 TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1693 return D3D_OK;
1696 WARN("Parameter not found.\n");
1698 return D3DERR_INVALIDCALL;
1701 static HRESULT d3dx9_base_effect_set_bool_array(struct d3dx9_base_effect *base,
1702 D3DXHANDLE parameter, const BOOL *b, UINT count)
1704 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1706 if (param)
1708 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1710 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1712 switch (param->class)
1714 case D3DXPC_SCALAR:
1715 case D3DXPC_VECTOR:
1716 case D3DXPC_MATRIX_ROWS:
1717 for (i = 0; i < size; ++i)
1719 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
1720 set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
1722 set_dirty(param);
1723 return D3D_OK;
1725 case D3DXPC_OBJECT:
1726 case D3DXPC_STRUCT:
1727 break;
1729 default:
1730 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1731 break;
1735 WARN("Parameter not found.\n");
1737 return D3DERR_INVALIDCALL;
1740 static HRESULT d3dx9_base_effect_get_bool_array(struct d3dx9_base_effect *base,
1741 D3DXHANDLE parameter, BOOL *b, UINT count)
1743 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1745 if (b && param && (param->class == D3DXPC_SCALAR
1746 || param->class == D3DXPC_VECTOR
1747 || param->class == D3DXPC_MATRIX_ROWS
1748 || param->class == D3DXPC_MATRIX_COLUMNS))
1750 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1752 for (i = 0; i < size; ++i)
1754 set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
1756 return D3D_OK;
1759 WARN("Parameter not found.\n");
1761 return D3DERR_INVALIDCALL;
1764 static HRESULT d3dx9_base_effect_set_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT n)
1766 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1768 if (param && !param->element_count)
1770 if (param->rows == 1 && param->columns == 1)
1772 DWORD value;
1774 set_number(&value, param->type, &n, D3DXPT_INT);
1775 if (value != *(DWORD *)param->data)
1776 set_dirty(param);
1777 *(DWORD *)param->data = value;
1778 return D3D_OK;
1782 * Split the value, if parameter is a vector with dimension 3 or 4.
1784 if (param->type == D3DXPT_FLOAT &&
1785 ((param->class == D3DXPC_VECTOR && param->columns != 2) ||
1786 (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1788 TRACE("Vector fixup\n");
1790 *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
1791 ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
1792 ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
1793 if (param->rows * param->columns > 3)
1795 ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
1797 set_dirty(param);
1798 return D3D_OK;
1802 WARN("Parameter not found.\n");
1804 return D3DERR_INVALIDCALL;
1807 static HRESULT d3dx9_base_effect_get_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT *n)
1809 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1811 if (n && param && !param->element_count)
1813 if (param->columns == 1 && param->rows == 1)
1815 set_number(n, D3DXPT_INT, param->data, param->type);
1816 TRACE("Returning %i\n", *n);
1817 return D3D_OK;
1820 if (param->type == D3DXPT_FLOAT &&
1821 ((param->class == D3DXPC_VECTOR && param->columns != 2)
1822 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1824 TRACE("Vector fixup\n");
1826 /* all components (3,4) are clamped (0,255) and put in the INT */
1827 *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
1828 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
1829 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
1830 if (param->columns * param->rows > 3)
1832 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
1835 TRACE("Returning %i\n", *n);
1836 return D3D_OK;
1840 WARN("Parameter not found.\n");
1842 return D3DERR_INVALIDCALL;
1845 static HRESULT d3dx9_base_effect_set_int_array(struct d3dx9_base_effect *base,
1846 D3DXHANDLE parameter, const INT *n, UINT count)
1848 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1850 if (param)
1852 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1854 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1856 switch (param->class)
1858 case D3DXPC_SCALAR:
1859 case D3DXPC_VECTOR:
1860 case D3DXPC_MATRIX_ROWS:
1861 for (i = 0; i < size; ++i)
1863 set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
1865 set_dirty(param);
1866 return D3D_OK;
1868 case D3DXPC_OBJECT:
1869 case D3DXPC_STRUCT:
1870 break;
1872 default:
1873 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1874 break;
1878 WARN("Parameter not found.\n");
1880 return D3DERR_INVALIDCALL;
1883 static HRESULT d3dx9_base_effect_get_int_array(struct d3dx9_base_effect *base,
1884 D3DXHANDLE parameter, INT *n, UINT count)
1886 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1888 if (n && param && (param->class == D3DXPC_SCALAR
1889 || param->class == D3DXPC_VECTOR
1890 || param->class == D3DXPC_MATRIX_ROWS
1891 || param->class == D3DXPC_MATRIX_COLUMNS))
1893 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1895 for (i = 0; i < size; ++i)
1897 set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
1899 return D3D_OK;
1902 WARN("Parameter not found.\n");
1904 return D3DERR_INVALIDCALL;
1907 static HRESULT d3dx9_base_effect_set_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float f)
1909 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1911 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1913 DWORD value;
1915 set_number(&value, param->type, &f, D3DXPT_FLOAT);
1916 if (value != *(DWORD *)param->data)
1917 set_dirty(param);
1918 *(DWORD *)param->data = value;
1919 return D3D_OK;
1922 WARN("Parameter not found.\n");
1924 return D3DERR_INVALIDCALL;
1927 static HRESULT d3dx9_base_effect_get_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float *f)
1929 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1931 if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
1933 set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
1934 TRACE("Returning %f\n", *f);
1935 return D3D_OK;
1938 WARN("Parameter not found.\n");
1940 return D3DERR_INVALIDCALL;
1943 static HRESULT d3dx9_base_effect_set_float_array(struct d3dx9_base_effect *base,
1944 D3DXHANDLE parameter, const float *f, UINT count)
1946 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1948 if (param)
1950 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1952 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1954 switch (param->class)
1956 case D3DXPC_SCALAR:
1957 case D3DXPC_VECTOR:
1958 case D3DXPC_MATRIX_ROWS:
1959 for (i = 0; i < size; ++i)
1961 set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
1963 set_dirty(param);
1964 return D3D_OK;
1966 case D3DXPC_OBJECT:
1967 case D3DXPC_STRUCT:
1968 break;
1970 default:
1971 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1972 break;
1976 WARN("Parameter not found.\n");
1978 return D3DERR_INVALIDCALL;
1981 static HRESULT d3dx9_base_effect_get_float_array(struct d3dx9_base_effect *base,
1982 D3DXHANDLE parameter, float *f, UINT count)
1984 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1986 if (f && param && (param->class == D3DXPC_SCALAR
1987 || param->class == D3DXPC_VECTOR
1988 || param->class == D3DXPC_MATRIX_ROWS
1989 || param->class == D3DXPC_MATRIX_COLUMNS))
1991 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1993 for (i = 0; i < size; ++i)
1995 set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
1997 return D3D_OK;
2000 WARN("Parameter not found.\n");
2002 return D3DERR_INVALIDCALL;
2005 static HRESULT d3dx9_base_effect_set_vector(struct d3dx9_base_effect *base,
2006 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2008 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2010 if (param && !param->element_count)
2012 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2014 switch (param->class)
2016 case D3DXPC_SCALAR:
2017 case D3DXPC_VECTOR:
2018 set_dirty(param);
2019 if (param->type == D3DXPT_INT && param->bytes == 4)
2021 DWORD tmp;
2023 TRACE("INT fixup\n");
2024 tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
2025 tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2026 tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2027 tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2029 *(INT *)param->data = tmp;
2030 return D3D_OK;
2032 if (param->type == D3DXPT_FLOAT)
2034 memcpy(param->data, vector, param->columns * sizeof(float));
2035 return D3D_OK;
2038 set_vector(param, vector);
2039 return D3D_OK;
2041 case D3DXPC_MATRIX_ROWS:
2042 case D3DXPC_OBJECT:
2043 case D3DXPC_STRUCT:
2044 break;
2046 default:
2047 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2048 break;
2052 WARN("Parameter not found.\n");
2054 return D3DERR_INVALIDCALL;
2057 static HRESULT d3dx9_base_effect_get_vector(struct d3dx9_base_effect *base,
2058 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2060 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2062 if (vector && param && !param->element_count)
2064 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2066 switch (param->class)
2068 case D3DXPC_SCALAR:
2069 case D3DXPC_VECTOR:
2070 if (param->type == D3DXPT_INT && param->bytes == 4)
2072 TRACE("INT fixup\n");
2073 vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2074 vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2075 vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2076 vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2077 return D3D_OK;
2079 get_vector(param, vector);
2080 return D3D_OK;
2082 case D3DXPC_MATRIX_ROWS:
2083 case D3DXPC_OBJECT:
2084 case D3DXPC_STRUCT:
2085 break;
2087 default:
2088 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2089 break;
2093 WARN("Parameter not found.\n");
2095 return D3DERR_INVALIDCALL;
2098 static HRESULT d3dx9_base_effect_set_vector_array(struct d3dx9_base_effect *base,
2099 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
2101 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2103 if (param && param->element_count && param->element_count >= count)
2105 UINT i;
2107 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2109 switch (param->class)
2111 case D3DXPC_VECTOR:
2112 set_dirty(param);
2113 if (param->type == D3DXPT_FLOAT)
2115 if (param->columns == 4)
2116 memcpy(param->data, vector, count * 4 * sizeof(float));
2117 else
2118 for (i = 0; i < count; ++i)
2119 memcpy((float *)param->data + param->columns * i, vector + i,
2120 param->columns * sizeof(float));
2121 return D3D_OK;
2124 for (i = 0; i < count; ++i)
2126 set_vector(&param->members[i], &vector[i]);
2128 return D3D_OK;
2130 case D3DXPC_SCALAR:
2131 case D3DXPC_MATRIX_ROWS:
2132 case D3DXPC_OBJECT:
2133 case D3DXPC_STRUCT:
2134 break;
2136 default:
2137 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2138 break;
2142 WARN("Parameter not found.\n");
2144 return D3DERR_INVALIDCALL;
2147 static HRESULT d3dx9_base_effect_get_vector_array(struct d3dx9_base_effect *base,
2148 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2150 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2152 if (!count) return D3D_OK;
2154 if (vector && param && count <= param->element_count)
2156 UINT i;
2158 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2160 switch (param->class)
2162 case D3DXPC_VECTOR:
2163 for (i = 0; i < count; ++i)
2165 get_vector(&param->members[i], &vector[i]);
2167 return D3D_OK;
2169 case D3DXPC_SCALAR:
2170 case D3DXPC_MATRIX_ROWS:
2171 case D3DXPC_OBJECT:
2172 case D3DXPC_STRUCT:
2173 break;
2175 default:
2176 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2177 break;
2181 WARN("Parameter not found.\n");
2183 return D3DERR_INVALIDCALL;
2186 static HRESULT d3dx9_base_effect_set_matrix(struct d3dx9_base_effect *base,
2187 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2189 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2191 if (param && !param->element_count)
2193 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2195 switch (param->class)
2197 case D3DXPC_MATRIX_ROWS:
2198 set_matrix(param, matrix);
2199 set_dirty(param);
2200 return D3D_OK;
2202 case D3DXPC_SCALAR:
2203 case D3DXPC_VECTOR:
2204 case D3DXPC_OBJECT:
2205 case D3DXPC_STRUCT:
2206 break;
2208 default:
2209 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2210 break;
2214 WARN("Parameter not found.\n");
2216 return D3DERR_INVALIDCALL;
2219 static HRESULT d3dx9_base_effect_get_matrix(struct d3dx9_base_effect *base,
2220 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2222 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2224 if (matrix && param && !param->element_count)
2226 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2228 switch (param->class)
2230 case D3DXPC_MATRIX_ROWS:
2231 get_matrix(param, matrix, FALSE);
2232 return D3D_OK;
2234 case D3DXPC_SCALAR:
2235 case D3DXPC_VECTOR:
2236 case D3DXPC_OBJECT:
2237 case D3DXPC_STRUCT:
2238 break;
2240 default:
2241 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2242 break;
2246 WARN("Parameter not found.\n");
2248 return D3DERR_INVALIDCALL;
2251 static HRESULT d3dx9_base_effect_set_matrix_array(struct d3dx9_base_effect *base,
2252 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2254 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2256 if (param && param->element_count >= count)
2258 UINT i;
2260 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2262 switch (param->class)
2264 case D3DXPC_MATRIX_ROWS:
2265 set_dirty(param);
2266 for (i = 0; i < count; ++i)
2268 set_matrix(&param->members[i], &matrix[i]);
2270 return D3D_OK;
2272 case D3DXPC_SCALAR:
2273 case D3DXPC_VECTOR:
2274 case D3DXPC_OBJECT:
2275 case D3DXPC_STRUCT:
2276 break;
2278 default:
2279 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2280 break;
2284 WARN("Parameter not found.\n");
2286 return D3DERR_INVALIDCALL;
2289 static HRESULT d3dx9_base_effect_get_matrix_array(struct d3dx9_base_effect *base,
2290 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2292 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2294 if (!count) return D3D_OK;
2296 if (matrix && param && count <= param->element_count)
2298 UINT i;
2300 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2302 switch (param->class)
2304 case D3DXPC_MATRIX_ROWS:
2305 for (i = 0; i < count; ++i)
2307 get_matrix(&param->members[i], &matrix[i], FALSE);
2309 return D3D_OK;
2311 case D3DXPC_SCALAR:
2312 case D3DXPC_VECTOR:
2313 case D3DXPC_OBJECT:
2314 case D3DXPC_STRUCT:
2315 break;
2317 default:
2318 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2319 break;
2323 WARN("Parameter not found.\n");
2325 return D3DERR_INVALIDCALL;
2328 static HRESULT d3dx9_base_effect_set_matrix_pointer_array(struct d3dx9_base_effect *base,
2329 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2331 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2333 if (param && count <= param->element_count)
2335 UINT i;
2337 switch (param->class)
2339 case D3DXPC_MATRIX_ROWS:
2340 set_dirty(param);
2341 for (i = 0; i < count; ++i)
2343 set_matrix(&param->members[i], matrix[i]);
2345 return D3D_OK;
2347 case D3DXPC_SCALAR:
2348 case D3DXPC_VECTOR:
2349 case D3DXPC_OBJECT:
2350 break;
2352 default:
2353 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2354 break;
2358 WARN("Parameter not found.\n");
2360 return D3DERR_INVALIDCALL;
2363 static HRESULT d3dx9_base_effect_get_matrix_pointer_array(struct d3dx9_base_effect *base,
2364 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2366 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2368 if (!count) return D3D_OK;
2370 if (param && matrix && count <= param->element_count)
2372 UINT i;
2374 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2376 switch (param->class)
2378 case D3DXPC_MATRIX_ROWS:
2379 for (i = 0; i < count; ++i)
2381 get_matrix(&param->members[i], matrix[i], FALSE);
2383 return D3D_OK;
2385 case D3DXPC_SCALAR:
2386 case D3DXPC_VECTOR:
2387 case D3DXPC_OBJECT:
2388 break;
2390 default:
2391 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2392 break;
2396 WARN("Parameter not found.\n");
2398 return D3DERR_INVALIDCALL;
2401 static HRESULT d3dx9_base_effect_set_matrix_transpose(struct d3dx9_base_effect *base,
2402 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2404 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2406 if (param && !param->element_count)
2408 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2410 switch (param->class)
2412 case D3DXPC_MATRIX_ROWS:
2413 set_dirty(param);
2414 set_matrix_transpose(param, matrix);
2415 return D3D_OK;
2417 case D3DXPC_SCALAR:
2418 case D3DXPC_VECTOR:
2419 case D3DXPC_OBJECT:
2420 case D3DXPC_STRUCT:
2421 break;
2423 default:
2424 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2425 break;
2429 WARN("Parameter not found.\n");
2431 return D3DERR_INVALIDCALL;
2434 static HRESULT d3dx9_base_effect_get_matrix_transpose(struct d3dx9_base_effect *base,
2435 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2437 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2439 if (matrix && param && !param->element_count)
2441 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2443 switch (param->class)
2445 case D3DXPC_SCALAR:
2446 case D3DXPC_VECTOR:
2447 get_matrix(param, matrix, FALSE);
2448 return D3D_OK;
2450 case D3DXPC_MATRIX_ROWS:
2451 get_matrix(param, matrix, TRUE);
2452 return D3D_OK;
2454 case D3DXPC_OBJECT:
2455 case D3DXPC_STRUCT:
2456 break;
2458 default:
2459 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2460 break;
2464 WARN("Parameter not found.\n");
2466 return D3DERR_INVALIDCALL;
2469 static HRESULT d3dx9_base_effect_set_matrix_transpose_array(struct d3dx9_base_effect *base,
2470 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2472 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2474 if (param && param->element_count >= count)
2476 UINT i;
2478 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2480 switch (param->class)
2482 case D3DXPC_MATRIX_ROWS:
2483 set_dirty(param);
2484 for (i = 0; i < count; ++i)
2486 set_matrix_transpose(&param->members[i], &matrix[i]);
2488 return D3D_OK;
2490 case D3DXPC_SCALAR:
2491 case D3DXPC_VECTOR:
2492 case D3DXPC_OBJECT:
2493 case D3DXPC_STRUCT:
2494 break;
2496 default:
2497 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2498 break;
2502 WARN("Parameter not found.\n");
2504 return D3DERR_INVALIDCALL;
2507 static HRESULT d3dx9_base_effect_get_matrix_transpose_array(struct d3dx9_base_effect *base,
2508 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2510 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2512 if (!count) return D3D_OK;
2514 if (matrix && param && count <= param->element_count)
2516 UINT i;
2518 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2520 switch (param->class)
2522 case D3DXPC_MATRIX_ROWS:
2523 for (i = 0; i < count; ++i)
2525 get_matrix(&param->members[i], &matrix[i], TRUE);
2527 return D3D_OK;
2529 case D3DXPC_SCALAR:
2530 case D3DXPC_VECTOR:
2531 case D3DXPC_OBJECT:
2532 case D3DXPC_STRUCT:
2533 break;
2535 default:
2536 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2537 break;
2541 WARN("Parameter not found.\n");
2543 return D3DERR_INVALIDCALL;
2546 static HRESULT d3dx9_base_effect_set_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2547 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2549 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2551 if (param && count <= param->element_count)
2553 UINT i;
2555 switch (param->class)
2557 case D3DXPC_MATRIX_ROWS:
2558 set_dirty(param);
2559 for (i = 0; i < count; ++i)
2561 set_matrix_transpose(&param->members[i], matrix[i]);
2563 return D3D_OK;
2565 case D3DXPC_SCALAR:
2566 case D3DXPC_VECTOR:
2567 case D3DXPC_OBJECT:
2568 break;
2570 default:
2571 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2572 break;
2576 WARN("Parameter not found.\n");
2578 return D3DERR_INVALIDCALL;
2581 static HRESULT d3dx9_base_effect_get_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2582 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2584 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2586 if (!count) return D3D_OK;
2588 if (matrix && param && count <= param->element_count)
2590 UINT i;
2592 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2594 switch (param->class)
2596 case D3DXPC_MATRIX_ROWS:
2597 for (i = 0; i < count; ++i)
2599 get_matrix(&param->members[i], matrix[i], TRUE);
2601 return D3D_OK;
2603 case D3DXPC_SCALAR:
2604 case D3DXPC_VECTOR:
2605 case D3DXPC_OBJECT:
2606 break;
2608 default:
2609 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2610 break;
2614 WARN("Parameter not found.\n");
2616 return D3DERR_INVALIDCALL;
2619 static HRESULT d3dx9_base_effect_set_string(struct d3dx9_base_effect *base,
2620 D3DXHANDLE parameter, const char *string)
2622 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2624 if (param && param->type == D3DXPT_STRING)
2626 set_dirty(param);
2627 return set_string(param->data, string);
2630 WARN("Parameter not found.\n");
2632 return D3DERR_INVALIDCALL;
2635 static HRESULT d3dx9_base_effect_get_string(struct d3dx9_base_effect *base,
2636 D3DXHANDLE parameter, const char **string)
2638 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2640 if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2642 *string = *(const char **)param->data;
2643 TRACE("Returning %s.\n", debugstr_a(*string));
2644 return D3D_OK;
2647 WARN("Parameter not found.\n");
2649 return D3DERR_INVALIDCALL;
2652 static HRESULT d3dx9_base_effect_set_texture(struct d3dx9_base_effect *base,
2653 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
2655 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2657 if (param && !param->element_count &&
2658 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2659 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2660 || param->type == D3DXPT_TEXTURECUBE))
2662 struct IDirect3DBaseTexture9 *oltexture = *(struct IDirect3DBaseTexture9 **)param->data;
2664 if (texture == oltexture)
2665 return D3D_OK;
2667 if (texture) IDirect3DBaseTexture9_AddRef(texture);
2668 if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2670 *(struct IDirect3DBaseTexture9 **)param->data = texture;
2671 set_dirty(param);
2673 return D3D_OK;
2676 WARN("Parameter not found.\n");
2678 return D3DERR_INVALIDCALL;
2681 static HRESULT d3dx9_base_effect_get_texture(struct d3dx9_base_effect *base,
2682 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
2684 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2686 if (texture && param && !param->element_count &&
2687 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2688 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2689 || param->type == D3DXPT_TEXTURECUBE))
2691 *texture = *(struct IDirect3DBaseTexture9 **)param->data;
2692 if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2693 TRACE("Returning %p\n", *texture);
2694 return D3D_OK;
2697 WARN("Parameter not found.\n");
2699 return D3DERR_INVALIDCALL;
2702 static HRESULT d3dx9_base_effect_get_pixel_shader(struct d3dx9_base_effect *base,
2703 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
2705 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2707 if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2709 if ((*shader = *(struct IDirect3DPixelShader9 **)param->data))
2710 IDirect3DPixelShader9_AddRef(*shader);
2711 TRACE("Returning %p.\n", *shader);
2712 return D3D_OK;
2715 WARN("Parameter not found.\n");
2717 return D3DERR_INVALIDCALL;
2720 static HRESULT d3dx9_base_effect_get_vertex_shader(struct d3dx9_base_effect *base,
2721 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
2723 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2725 if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2727 if ((*shader = *(struct IDirect3DVertexShader9 **)param->data))
2728 IDirect3DVertexShader9_AddRef(*shader);
2729 TRACE("Returning %p.\n", *shader);
2730 return D3D_OK;
2733 WARN("Parameter not found.\n");
2735 return D3DERR_INVALIDCALL;
2738 static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base,
2739 D3DXHANDLE parameter, UINT start, UINT end)
2741 FIXME("stub!\n");
2743 return E_NOTIMPL;
2746 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
2748 static const struct
2750 unsigned int offset;
2751 const char *name;
2753 light_tbl[] =
2755 {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
2756 {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
2757 {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
2758 {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
2759 {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
2760 {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
2761 {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
2762 {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
2763 {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
2764 {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
2765 {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
2766 {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
2767 {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
2769 switch (op)
2771 case LT_TYPE:
2772 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
2773 light->Type = *(D3DLIGHTTYPE *)value;
2774 break;
2775 case LT_DIFFUSE:
2776 case LT_SPECULAR:
2777 case LT_AMBIENT:
2779 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2781 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
2782 *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
2783 break;
2785 case LT_POSITION:
2786 case LT_DIRECTION:
2788 D3DVECTOR v = *(D3DVECTOR *)value;
2790 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
2791 *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
2792 break;
2794 case LT_RANGE:
2795 case LT_FALLOFF:
2796 case LT_ATTENUATION0:
2797 case LT_ATTENUATION1:
2798 case LT_ATTENUATION2:
2799 case LT_THETA:
2800 case LT_PHI:
2802 float v = *(float *)value;
2803 TRACE("%s %.8e.\n", light_tbl[op].name, v);
2804 *(float *)((BYTE *)light + light_tbl[op].offset) = v;
2805 break;
2807 default:
2808 WARN("Unknown light parameter %u.\n", op);
2809 break;
2813 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
2815 static const struct
2817 unsigned int offset;
2818 const char *name;
2820 material_tbl[] =
2822 {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
2823 {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
2824 {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
2825 {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
2826 {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
2829 switch (op)
2831 case MT_POWER:
2833 float v = *(float *)value;
2835 TRACE("%s %.8e.\n", material_tbl[op].name, v);
2836 material->Power = v;
2837 break;
2839 case MT_DIFFUSE:
2840 case MT_AMBIENT:
2841 case MT_SPECULAR:
2842 case MT_EMISSIVE:
2844 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2846 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
2847 *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
2848 break;
2850 default:
2851 WARN("Unknown material parameter %u.\n", op);
2852 break;
2856 static HRESULT d3dx_set_shader_const_state(struct ID3DXEffectImpl *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
2857 struct d3dx_parameter *param, void *value_ptr)
2859 static const struct
2861 D3DXPARAMETER_TYPE type;
2862 UINT elem_size;
2863 const char *name;
2865 const_tbl[] =
2867 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
2868 {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
2869 {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
2870 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
2871 {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
2872 {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
2874 unsigned int element_count;
2876 if (op < 0 || op > SCT_PSINT)
2878 FIXME("Unknown op %u.\n", op);
2879 return D3DERR_INVALIDCALL;
2881 element_count = param->bytes / const_tbl[op].elem_size;
2882 TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
2883 if (param->type != const_tbl[op].type)
2885 FIXME("Unexpected param type %u.\n", param->type);
2886 return D3DERR_INVALIDCALL;
2888 if (param->bytes % const_tbl[op].elem_size != 0)
2890 FIXME("Unexpected param size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
2891 return D3DERR_INVALIDCALL;
2894 switch (op)
2896 case SCT_VSFLOAT:
2897 return SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)value_ptr, element_count);
2898 case SCT_VSBOOL:
2899 return SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2900 case SCT_VSINT:
2901 return SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)value_ptr, element_count);
2902 case SCT_PSFLOAT:
2903 return SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)value_ptr, element_count);
2904 case SCT_PSBOOL:
2905 return SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2906 case SCT_PSINT:
2907 return SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)value_ptr, element_count);
2909 return D3D_OK;
2912 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2913 struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
2915 static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2916 struct d3dx_parameter *param, BOOL vs, BOOL update_all)
2918 HRESULT hr, ret;
2919 struct d3dx_parameter **params;
2920 D3DXCONSTANT_DESC *cdesc;
2921 unsigned int parameters_count;
2922 unsigned int i, j;
2924 if (!param->param_eval)
2926 FIXME("param_eval structure is null.\n");
2927 return D3DERR_INVALIDCALL;
2929 if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
2930 param->param_eval, update_all)))
2931 return hr;
2932 params = param->param_eval->shader_inputs.inputs_param;
2933 cdesc = param->param_eval->shader_inputs.inputs;
2934 parameters_count = param->param_eval->shader_inputs.input_count;
2935 ret = D3D_OK;
2936 for (i = 0; i < parameters_count; ++i)
2938 if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
2940 struct d3dx_sampler *sampler;
2941 unsigned int sampler_idx;
2943 for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
2945 sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
2946 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
2947 cdesc[i].RegisterIndex, sampler->state_count);
2948 for (j = 0; j < sampler->state_count; ++j)
2950 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
2951 cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
2952 update_all)))
2953 ret = hr;
2958 return ret;
2961 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2962 struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
2964 struct d3dx_parameter *param;
2965 void *param_value;
2966 BOOL param_dirty;
2967 HRESULT hr;
2969 TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
2971 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
2972 update_all, &param_dirty)))
2974 if (!update_all && hr == E_FAIL)
2976 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
2977 * out of bounds array access and does not touch the affected
2978 * states. */
2979 WARN("Returning D3D_OK on out of bounds array access.\n");
2980 return D3D_OK;
2982 return hr;
2985 if (!(update_all || param_dirty
2986 || state_table[state->operation].class == SC_VERTEXSHADER
2987 || state_table[state->operation].class == SC_PIXELSHADER
2988 || state_table[state->operation].class == SC_SETSAMPLER))
2989 return D3D_OK;
2991 switch (state_table[state->operation].class)
2993 case SC_RENDERSTATE:
2994 TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
2995 state_table[state->operation].op, *(DWORD *)param_value);
2996 return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
2997 case SC_FVF:
2998 TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
2999 return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
3000 case SC_TEXTURE:
3002 UINT unit;
3004 unit = parent_index == ~0u ? state->index : parent_index;
3005 TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
3006 *(IDirect3DBaseTexture9 **)param_value);
3007 return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
3009 case SC_TEXTURESTAGE:
3010 TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
3011 return SET_D3D_STATE(effect, SetTextureStageState, state->index,
3012 state_table[state->operation].op, *(DWORD *)param_value);
3013 case SC_SETSAMPLER:
3015 struct d3dx_sampler *sampler;
3016 HRESULT ret, hr;
3017 unsigned int i;
3019 sampler = (struct d3dx_sampler *)param_value;
3020 TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
3021 sampler->state_count);
3022 ret = D3D_OK;
3023 for (i = 0; i < sampler->state_count; i++)
3025 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
3026 ret = hr;
3028 return ret;
3030 case SC_SAMPLERSTATE:
3032 UINT sampler;
3034 sampler = parent_index == ~0u ? state->index : parent_index;
3035 TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
3036 return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
3037 *(DWORD *)param_value);
3039 case SC_VERTEXSHADER:
3040 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
3041 if ((update_all || param_dirty)
3042 && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
3043 *(IDirect3DVertexShader9 **)param_value)))
3044 ERR("Could not set vertex shader, hr %#x.\n", hr);
3045 else if (*(IDirect3DVertexShader9 **)param_value)
3046 hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
3047 return hr;
3048 case SC_PIXELSHADER:
3049 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
3050 if ((update_all || param_dirty)
3051 && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
3052 *(IDirect3DPixelShader9 **)param_value)))
3053 ERR("Could not set pixel shader, hr %#x.\n", hr);
3054 else if (*(IDirect3DPixelShader9 **)param_value)
3055 hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
3056 return hr;
3057 case SC_TRANSFORM:
3058 TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
3059 return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
3060 (D3DMATRIX *)param_value);
3061 case SC_LIGHTENABLE:
3062 TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
3063 return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
3064 case SC_LIGHT:
3066 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3067 state_table[state->operation].op);
3068 d3dx9_set_light_parameter(state_table[state->operation].op,
3069 &effect->current_light[state->index], param_value);
3070 effect->light_updated |= 1u << state->index;
3071 return D3D_OK;
3073 case SC_MATERIAL:
3075 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3076 state_table[state->operation].op);
3077 d3dx9_set_material_parameter(state_table[state->operation].op,
3078 &effect->current_material, param_value);
3079 effect->material_updated = TRUE;
3080 return D3D_OK;
3082 case SC_NPATCHMODE:
3083 TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
3084 return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
3085 case SC_SHADERCONST:
3086 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3087 state_table[state->operation].op);
3088 return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
3089 param, param_value);
3090 default:
3091 FIXME("%s not handled.\n", state_table[state->operation].name);
3092 break;
3094 return D3D_OK;
3097 static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass, BOOL update_all)
3099 unsigned int i;
3100 HRESULT ret;
3101 HRESULT hr;
3102 ULONG64 new_update_version = next_effect_update_version(&effect->base_effect);
3104 TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
3106 ret = D3D_OK;
3107 for (i = 0; i < pass->state_count; ++i)
3109 if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
3111 WARN("Error applying state, hr %#x.\n", hr);
3112 ret = hr;
3116 if (effect->light_updated)
3118 for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
3120 if ((effect->light_updated & (1u << i))
3121 && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
3123 WARN("Error setting light, hr %#x.\n", hr);
3124 ret = hr;
3127 effect->light_updated = 0;
3130 if (effect->material_updated
3131 && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
3133 WARN("Error setting material, hr %#x.\n", hr);
3134 ret = hr;
3136 effect->material_updated = FALSE;
3138 pass->update_version = new_update_version;
3139 return ret;
3142 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
3144 unsigned char *member_data = data;
3145 unsigned int i, count;
3147 count = param->element_count ? param->element_count : param->member_count;
3148 for (i = 0; i < count; ++i)
3150 param_set_data_pointer(&param->members[i], member_data, TRUE, free_data);
3151 if (data)
3152 member_data += param->members[i].bytes;
3154 if (free_data)
3155 free_parameter_data(param, child);
3156 param->data = data;
3159 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
3161 struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
3162 BOOL matches;
3163 unsigned int i, member_count;
3165 matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
3166 && param1->type == param2->type && param1->rows == param2->rows
3167 && param1->columns == param2->columns && param1->element_count == param2->element_count
3168 && param1->member_count == param2->member_count;
3170 member_count = param1->element_count ? param1->element_count : param1->member_count;
3172 if (!matches || !member_count)
3173 return matches;
3175 for (i = 0; i < member_count; ++i)
3177 if (!is_same_parameter(&param1->members[i], &param2->members[i]))
3178 return FALSE;
3180 return TRUE;
3183 static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param)
3185 unsigned int i, free_entry_index;
3186 unsigned int new_size, new_count;
3188 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
3189 return D3D_OK;
3191 free_entry_index = pool->size;
3192 for (i = 0; i < pool->size; ++i)
3194 if (!pool->shared_data[i].count)
3195 free_entry_index = i;
3196 else if (is_same_parameter(&param->param, &pool->shared_data[i].parameters[0]->param))
3197 break;
3199 if (i == pool->size)
3201 i = free_entry_index;
3202 if (i == pool->size)
3204 struct d3dx_shared_data *new_alloc;
3206 if (!pool->size)
3208 new_size = INITIAL_POOL_SIZE;
3209 new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3210 sizeof(*pool->shared_data) * new_size);
3211 if (!new_alloc)
3213 ERR("Out of memory.\n");
3214 return E_OUTOFMEMORY;
3217 else
3219 new_size = pool->size * 2;
3220 new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
3221 sizeof(*pool->shared_data) * new_size);
3222 if (!new_alloc)
3224 ERR("Out of memory.\n");
3225 return E_OUTOFMEMORY;
3227 if (new_alloc != pool->shared_data)
3229 unsigned int j, k;
3231 for (j = 0; j < pool->size; ++j)
3232 for (k = 0; k < new_alloc[j].count; ++k)
3233 new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
3236 pool->shared_data = new_alloc;
3237 pool->size = new_size;
3239 pool->shared_data[i].data = param->param.data;
3241 else
3243 param_set_data_pointer(&param->param, pool->shared_data[i].data, FALSE, TRUE);
3245 new_count = ++pool->shared_data[i].count;
3246 if (new_count >= pool->shared_data[i].size)
3248 if (!pool->shared_data[i].size)
3250 new_size = INITIAL_SHARED_DATA_SIZE;
3251 pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3252 sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
3254 else
3256 new_size = pool->shared_data[i].size * 2;
3257 pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3258 pool->shared_data[i].parameters,
3259 sizeof(*pool->shared_data[i].parameters) * new_size);
3261 pool->shared_data[i].size = new_size;
3264 param->shared_data = &pool->shared_data[i];
3265 pool->shared_data[i].parameters[new_count - 1] = param;
3267 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
3268 new_count);
3270 return D3D_OK;
3273 static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param)
3275 param->data = NULL;
3276 return FALSE;
3279 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param)
3281 unsigned int new_count;
3283 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
3284 return;
3285 new_count = --param->shared_data->count;
3287 TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
3289 if (new_count)
3291 unsigned int i;
3293 for (i = 0; i < new_count; ++i)
3295 if (param->shared_data->parameters[i] == param)
3297 memmove(&param->shared_data->parameters[i],
3298 &param->shared_data->parameters[i + 1],
3299 sizeof(param->shared_data->parameters[i]) * (new_count - i));
3300 break;
3303 walk_parameter_tree(&param->param, param_zero_data_func, NULL);
3305 else
3307 HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
3308 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
3309 param->shared_data->size = 0;
3310 param->shared_data = NULL;
3314 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
3316 return CONTAINING_RECORD(iface, struct d3dx_effect_pool, ID3DXEffectPool_iface);
3319 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
3321 return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
3324 /*** IUnknown methods ***/
3325 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
3327 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
3329 if (IsEqualGUID(riid, &IID_IUnknown) ||
3330 IsEqualGUID(riid, &IID_ID3DXEffect))
3332 iface->lpVtbl->AddRef(iface);
3333 *object = iface;
3334 return S_OK;
3337 ERR("Interface %s not found\n", debugstr_guid(riid));
3339 return E_NOINTERFACE;
3342 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
3344 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3346 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
3348 return InterlockedIncrement(&This->ref);
3351 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
3353 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3354 ULONG ref = InterlockedDecrement(&This->ref);
3356 TRACE("(%p)->(): Release from %u\n", This, ref + 1);
3358 if (!ref)
3360 free_effect(This);
3361 HeapFree(GetProcessHeap(), 0, This);
3364 return ref;
3367 /*** ID3DXBaseEffect methods ***/
3368 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
3370 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3372 TRACE("iface %p, desc %p.\n", iface, desc);
3374 return d3dx9_base_effect_get_desc(&effect->base_effect, desc);
3377 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface,
3378 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3380 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3382 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
3384 return d3dx9_base_effect_get_parameter_desc(&effect->base_effect, parameter, desc);
3387 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface,
3388 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3390 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3392 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
3394 return d3dx9_base_effect_get_technique_desc(&effect->base_effect, technique, desc);
3397 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3399 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3401 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
3403 return d3dx9_base_effect_get_pass_desc(&effect->base_effect, pass, desc);
3406 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3408 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3410 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
3412 return d3dx9_base_effect_get_function_desc(&effect->base_effect, shader, desc);
3415 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3417 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3419 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3421 return d3dx9_base_effect_get_parameter(&effect->base_effect, parameter, index);
3424 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface,
3425 D3DXHANDLE parameter, const char *name)
3427 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3429 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
3431 return d3dx9_base_effect_get_parameter_by_name(&effect->base_effect, parameter, name);
3434 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface,
3435 D3DXHANDLE parameter, const char *semantic)
3437 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3439 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
3441 return d3dx9_base_effect_get_parameter_by_semantic(&effect->base_effect, parameter, semantic);
3444 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3446 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3448 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3450 return d3dx9_base_effect_get_parameter_element(&effect->base_effect, parameter, index);
3453 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
3455 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3457 TRACE("iface %p, index %u.\n", iface, index);
3459 return d3dx9_base_effect_get_technique(&effect->base_effect, index);
3462 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, const char *name)
3464 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3466 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3468 return d3dx9_base_effect_get_technique_by_name(&effect->base_effect, name);
3471 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
3473 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3475 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
3477 return d3dx9_base_effect_get_pass(&effect->base_effect, technique, index);
3480 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface,
3481 D3DXHANDLE technique, const char *name)
3483 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3485 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
3487 return d3dx9_base_effect_get_pass_by_name(&effect->base_effect, technique, name);
3490 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
3492 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3494 TRACE("iface %p, index %u.\n", iface, index);
3496 return d3dx9_base_effect_get_function(&effect->base_effect, index);
3499 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, const char *name)
3501 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3503 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3505 return d3dx9_base_effect_get_function_by_name(&effect->base_effect, name);
3508 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
3510 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3512 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
3514 return d3dx9_base_effect_get_annotation(&effect->base_effect, object, index);
3517 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface,
3518 D3DXHANDLE object, const char *name)
3520 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3522 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
3524 return d3dx9_base_effect_get_annotation_by_name(&effect->base_effect, object, name);
3527 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface,
3528 D3DXHANDLE parameter, const void *data, UINT bytes)
3530 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3532 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3534 return d3dx9_base_effect_set_value(&effect->base_effect, parameter, data, bytes);
3537 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface,
3538 D3DXHANDLE parameter, void *data, UINT bytes)
3540 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3542 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3544 return d3dx9_base_effect_get_value(&effect->base_effect, parameter, data, bytes);
3547 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
3549 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3551 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
3553 return d3dx9_base_effect_set_bool(&effect->base_effect, parameter, b);
3556 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
3558 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3560 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
3562 return d3dx9_base_effect_get_bool(&effect->base_effect, parameter, b);
3565 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface,
3566 D3DXHANDLE parameter, const BOOL *b, UINT count)
3568 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3570 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3572 return d3dx9_base_effect_set_bool_array(&effect->base_effect, parameter, b, count);
3575 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface,
3576 D3DXHANDLE parameter, BOOL *b, UINT count)
3578 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3580 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3582 return d3dx9_base_effect_get_bool_array(&effect->base_effect, parameter, b, count);
3585 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
3587 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3589 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
3591 return d3dx9_base_effect_set_int(&effect->base_effect, parameter, n);
3594 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
3596 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3598 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
3600 return d3dx9_base_effect_get_int(&effect->base_effect, parameter, n);
3603 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface,
3604 D3DXHANDLE parameter, const INT *n, UINT count)
3606 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3608 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3610 return d3dx9_base_effect_set_int_array(&effect->base_effect, parameter, n, count);
3613 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface,
3614 D3DXHANDLE parameter, INT *n, UINT count)
3616 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3618 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3620 return d3dx9_base_effect_get_int_array(&effect->base_effect, parameter, n, count);
3623 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
3625 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3627 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
3629 return d3dx9_base_effect_set_float(&effect->base_effect, parameter, f);
3632 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
3634 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3636 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
3638 return d3dx9_base_effect_get_float(&effect->base_effect, parameter, f);
3641 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface,
3642 D3DXHANDLE parameter, const float *f, UINT count)
3644 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3646 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3648 return d3dx9_base_effect_set_float_array(&effect->base_effect, parameter, f, count);
3651 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface,
3652 D3DXHANDLE parameter, float *f, UINT count)
3654 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3656 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3658 return d3dx9_base_effect_get_float_array(&effect->base_effect, parameter, f, count);
3661 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface,
3662 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
3664 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3666 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3668 return d3dx9_base_effect_set_vector(&effect->base_effect, parameter, vector);
3671 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface,
3672 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3674 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3676 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3678 return d3dx9_base_effect_get_vector(&effect->base_effect, parameter, vector);
3681 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface,
3682 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
3684 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3686 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3688 return d3dx9_base_effect_set_vector_array(&effect->base_effect, parameter, vector, count);
3691 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface,
3692 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3694 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3696 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3698 return d3dx9_base_effect_get_vector_array(&effect->base_effect, parameter, vector, count);
3701 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface,
3702 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3704 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3706 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3708 return d3dx9_base_effect_set_matrix(&effect->base_effect, parameter, matrix);
3711 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface,
3712 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3714 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3716 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3718 return d3dx9_base_effect_get_matrix(&effect->base_effect, parameter, matrix);
3721 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface,
3722 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3724 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3726 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3728 return d3dx9_base_effect_set_matrix_array(&effect->base_effect, parameter, matrix, count);
3731 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface,
3732 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3734 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3736 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3738 return d3dx9_base_effect_get_matrix_array(&effect->base_effect, parameter, matrix, count);
3741 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface,
3742 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3744 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3746 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3748 return d3dx9_base_effect_set_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3751 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface,
3752 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3754 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3756 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3758 return d3dx9_base_effect_get_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3761 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface,
3762 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3764 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3766 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3768 return d3dx9_base_effect_set_matrix_transpose(&effect->base_effect, parameter, matrix);
3771 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface,
3772 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3774 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3776 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3778 return d3dx9_base_effect_get_matrix_transpose(&effect->base_effect, parameter, matrix);
3781 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface,
3782 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3784 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3786 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3788 return d3dx9_base_effect_set_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3791 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface,
3792 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3794 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3796 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3798 return d3dx9_base_effect_get_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3801 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface,
3802 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3804 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3806 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3808 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3811 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface,
3812 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3814 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3816 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3818 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3821 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char *string)
3823 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3825 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
3827 return d3dx9_base_effect_set_string(&effect->base_effect, parameter, string);
3830 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char **string)
3832 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3834 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
3836 return d3dx9_base_effect_get_string(&effect->base_effect, parameter, string);
3839 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(struct ID3DXEffect *iface,
3840 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
3842 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3844 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3846 return d3dx9_base_effect_set_texture(&effect->base_effect, parameter, texture);
3849 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(struct ID3DXEffect *iface,
3850 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
3852 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3854 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3856 return d3dx9_base_effect_get_texture(&effect->base_effect, parameter, texture);
3859 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface,
3860 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
3862 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3864 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3866 return d3dx9_base_effect_get_pixel_shader(&effect->base_effect, parameter, shader);
3869 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(struct ID3DXEffect *iface,
3870 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
3872 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3874 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3876 return d3dx9_base_effect_get_vertex_shader(&effect->base_effect, parameter, shader);
3879 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3881 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3883 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
3885 return d3dx9_base_effect_set_array_range(&effect->base_effect, parameter, start, end);
3888 /*** ID3DXEffect methods ***/
3889 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, ID3DXEffectPool **pool)
3891 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3893 TRACE("iface %p, pool %p\n", This, pool);
3895 if (!pool)
3897 WARN("Invalid argument supplied.\n");
3898 return D3DERR_INVALIDCALL;
3901 if (This->pool)
3903 This->pool->lpVtbl->AddRef(This->pool);
3906 *pool = This->pool;
3908 TRACE("Returning pool %p\n", *pool);
3910 return S_OK;
3913 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3915 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3916 struct d3dx9_base_effect *base = &This->base_effect;
3917 struct d3dx_technique *tech = get_valid_technique(base, technique);
3919 TRACE("iface %p, technique %p\n", This, technique);
3921 if (tech)
3923 This->active_technique = tech;
3924 TRACE("Technique %p\n", tech);
3925 return D3D_OK;
3928 WARN("Technique not found.\n");
3930 return D3DERR_INVALIDCALL;
3933 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
3935 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3937 TRACE("iface %p\n", This);
3939 return get_technique_handle(This->active_technique);
3942 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
3944 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3945 struct d3dx9_base_effect *base = &effect->base_effect;
3946 struct d3dx_technique *tech = get_valid_technique(base, technique);
3947 HRESULT ret = D3D_OK;
3948 unsigned int i, j;
3950 FIXME("iface %p, technique %p semi-stub.\n", iface, technique);
3952 if (!tech)
3954 ret = D3DERR_INVALIDCALL;
3955 goto done;
3957 for (i = 0; i < tech->pass_count; ++i)
3959 struct d3dx_pass *pass = &tech->passes[i];
3961 for (j = 0; j < pass->state_count; ++j)
3963 struct d3dx_state *state = &pass->states[j];
3965 if (state_table[state->operation].class == SC_VERTEXSHADER
3966 || state_table[state->operation].class == SC_PIXELSHADER)
3968 struct d3dx_parameter *param;
3969 void *param_value;
3970 BOOL param_dirty;
3971 HRESULT hr;
3973 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[j], &param_value, &param,
3974 FALSE, &param_dirty)))
3975 return hr;
3977 if (param->object_id && base->objects[param->object_id].creation_failed)
3979 ret = E_FAIL;
3980 goto done;
3985 done:
3986 TRACE("Returning %#x.\n", ret);
3987 return ret;
3990 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
3992 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3994 FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
3996 return E_NOTIMPL;
3999 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
4000 void *data);
4002 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func,
4003 void *data)
4005 struct d3dx_parameter **params;
4006 unsigned int i, param_count;
4008 if (!param_eval)
4009 return FALSE;
4011 params = param_eval->shader_inputs.inputs_param;
4012 param_count = param_eval->shader_inputs.input_count;
4013 for (i = 0; i < param_count; ++i)
4015 if (walk_parameter_dep(params[i], param_func, data))
4016 return TRUE;
4019 params = param_eval->pres.inputs.inputs_param;
4020 param_count = param_eval->pres.inputs.input_count;
4021 for (i = 0; i < param_count; ++i)
4023 if (walk_parameter_dep(params[i], param_func, data))
4024 return TRUE;
4026 return FALSE;
4029 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func,
4030 void *data)
4032 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type))
4034 if (walk_parameter_dep(&state->parameter, param_func, data))
4035 return TRUE;
4037 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER)
4039 if (walk_parameter_dep(state->referenced_param, param_func, data))
4040 return TRUE;
4042 return walk_param_eval_dep(state->parameter.param_eval, param_func, data);
4045 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
4046 void *data)
4048 unsigned int i;
4049 unsigned int member_count;
4051 param = &param->top_level_param->param;
4052 if (param_func(data, param))
4053 return TRUE;
4055 if (walk_param_eval_dep(param->param_eval, param_func, data))
4056 return TRUE;
4058 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
4060 struct d3dx_sampler *sampler;
4061 unsigned int sampler_idx;
4062 unsigned int samplers_count = max(param->element_count, 1);
4064 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx)
4066 sampler = param->element_count ? param->members[sampler_idx].data : param->data;
4067 for (i = 0; i < sampler->state_count; ++i)
4069 if (walk_state_dep(&sampler->states[i], param_func, data))
4070 return TRUE;
4073 return FALSE;
4076 member_count = param->element_count ? param->element_count : param->member_count;
4077 for (i = 0; i < member_count; ++i)
4079 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data))
4080 return TRUE;
4083 return FALSE;
4086 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech)
4088 unsigned int i, j;
4089 struct d3dx_pass *pass;
4091 if (!tech || !param)
4092 return FALSE;
4094 for (i = 0; i < tech->pass_count; ++i)
4096 pass = &tech->passes[i];
4097 for (j = 0; j < pass->state_count; ++j)
4099 if (walk_state_dep(&pass->states[j], is_same_parameter, param))
4100 return TRUE;
4103 return FALSE;
4106 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
4108 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4109 struct d3dx_parameter *param = get_valid_parameter(&effect->base_effect, parameter);
4110 struct d3dx_technique *tech = get_valid_technique(&effect->base_effect, technique);
4111 BOOL ret;
4113 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique);
4114 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech);
4116 ret = is_parameter_used(param, tech);
4117 TRACE("Returning %#x.\n", ret);
4118 return ret;
4121 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
4123 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4124 struct d3dx_technique *technique = effect->active_technique;
4126 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags);
4128 if (passes && technique)
4130 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE))
4131 WARN("Invalid flags (%#x) specified.\n", flags);
4133 if (flags & D3DXFX_DONOTSAVESTATE)
4135 TRACE("State capturing disabled.\n");
4137 else
4139 HRESULT hr;
4140 unsigned int i;
4142 if (!technique->saved_state)
4144 ID3DXEffectStateManager *manager;
4146 manager = effect->manager;
4147 effect->manager = NULL;
4148 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
4149 ERR("BeginStateBlock failed, hr %#x.\n", hr);
4150 for (i = 0; i < technique->pass_count; i++)
4151 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE);
4152 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
4153 ERR("EndStateBlock failed, hr %#x.\n", hr);
4154 effect->manager = manager;
4156 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
4157 ERR("StateBlock Capture failed, hr %#x.\n", hr);
4160 *passes = technique->pass_count;
4161 effect->started = TRUE;
4162 effect->begin_flags = flags;
4164 return D3D_OK;
4167 WARN("Invalid argument supplied.\n");
4169 return D3DERR_INVALIDCALL;
4172 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
4174 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4175 struct d3dx_technique *technique = effect->active_technique;
4177 TRACE("iface %p, pass %u\n", effect, pass);
4179 if (technique && pass < technique->pass_count && !effect->active_pass)
4181 HRESULT hr;
4183 memset(effect->current_light, 0, sizeof(effect->current_light));
4184 memset(&effect->current_material, 0, sizeof(effect->current_material));
4186 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE)))
4187 effect->active_pass = &technique->passes[pass];
4188 return hr;
4191 WARN("Invalid argument supplied.\n");
4193 return D3DERR_INVALIDCALL;
4196 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect *iface)
4198 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4200 TRACE("iface %p.\n", iface);
4202 if (!effect->active_pass)
4204 WARN("Called without an active pass.\n");
4205 return D3D_OK;
4207 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE);
4210 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
4212 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4214 TRACE("iface %p\n", This);
4216 if (This->active_pass)
4218 This->active_pass = NULL;
4219 return D3D_OK;
4222 WARN("Invalid call.\n");
4224 return D3DERR_INVALIDCALL;
4227 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect *iface)
4229 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4230 struct d3dx_technique *technique = effect->active_technique;
4232 TRACE("iface %p.\n", iface);
4234 if (!effect->started)
4235 return D3D_OK;
4237 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE)
4239 TRACE("State restoring disabled.\n");
4241 else
4243 HRESULT hr;
4245 if (technique && technique->saved_state)
4247 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
4248 ERR("State block apply failed, hr %#x.\n", hr);
4250 else
4251 ERR("No saved state.\n");
4254 effect->started = FALSE;
4256 return D3D_OK;
4259 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device)
4261 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4263 TRACE("iface %p, device %p\n", This, device);
4265 if (!device)
4267 WARN("Invalid argument supplied.\n");
4268 return D3DERR_INVALIDCALL;
4271 IDirect3DDevice9_AddRef(This->device);
4273 *device = This->device;
4275 TRACE("Returning device %p\n", *device);
4277 return S_OK;
4280 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
4282 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4284 FIXME("(%p)->(): stub\n", This);
4286 return E_NOTIMPL;
4289 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
4291 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4293 FIXME("(%p)->(): stub\n", This);
4295 return E_NOTIMPL;
4298 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager)
4300 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4302 TRACE("iface %p, manager %p\n", This, manager);
4304 if (manager) IUnknown_AddRef(manager);
4305 if (This->manager) IUnknown_Release(This->manager);
4307 This->manager = manager;
4309 return D3D_OK;
4312 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager)
4314 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4316 TRACE("iface %p, manager %p\n", This, manager);
4318 if (!manager)
4320 WARN("Invalid argument supplied.\n");
4321 return D3DERR_INVALIDCALL;
4324 if (This->manager) IUnknown_AddRef(This->manager);
4325 *manager = This->manager;
4327 return D3D_OK;
4330 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
4332 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4334 FIXME("(%p)->(): stub\n", This);
4336 return E_NOTIMPL;
4339 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
4341 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4343 FIXME("(%p)->(): stub\n", This);
4345 return NULL;
4348 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4350 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4352 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4354 return E_NOTIMPL;
4357 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4359 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4361 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4363 return E_NOTIMPL;
4366 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
4367 struct IDirect3DDevice9 *device, struct ID3DXEffect **effect)
4369 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4371 FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
4373 if (!effect)
4374 return D3DERR_INVALIDCALL;
4376 if (This->base_effect.flags & D3DXFX_NOT_CLONEABLE)
4377 return E_FAIL;
4379 if (!device)
4380 return D3DERR_INVALIDCALL;
4382 return E_NOTIMPL;
4385 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface,
4386 D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes)
4388 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4389 iface, parameter, data, byte_offset, bytes);
4391 return E_NOTIMPL;
4394 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
4396 /*** IUnknown methods ***/
4397 ID3DXEffectImpl_QueryInterface,
4398 ID3DXEffectImpl_AddRef,
4399 ID3DXEffectImpl_Release,
4400 /*** ID3DXBaseEffect methods ***/
4401 ID3DXEffectImpl_GetDesc,
4402 ID3DXEffectImpl_GetParameterDesc,
4403 ID3DXEffectImpl_GetTechniqueDesc,
4404 ID3DXEffectImpl_GetPassDesc,
4405 ID3DXEffectImpl_GetFunctionDesc,
4406 ID3DXEffectImpl_GetParameter,
4407 ID3DXEffectImpl_GetParameterByName,
4408 ID3DXEffectImpl_GetParameterBySemantic,
4409 ID3DXEffectImpl_GetParameterElement,
4410 ID3DXEffectImpl_GetTechnique,
4411 ID3DXEffectImpl_GetTechniqueByName,
4412 ID3DXEffectImpl_GetPass,
4413 ID3DXEffectImpl_GetPassByName,
4414 ID3DXEffectImpl_GetFunction,
4415 ID3DXEffectImpl_GetFunctionByName,
4416 ID3DXEffectImpl_GetAnnotation,
4417 ID3DXEffectImpl_GetAnnotationByName,
4418 ID3DXEffectImpl_SetValue,
4419 ID3DXEffectImpl_GetValue,
4420 ID3DXEffectImpl_SetBool,
4421 ID3DXEffectImpl_GetBool,
4422 ID3DXEffectImpl_SetBoolArray,
4423 ID3DXEffectImpl_GetBoolArray,
4424 ID3DXEffectImpl_SetInt,
4425 ID3DXEffectImpl_GetInt,
4426 ID3DXEffectImpl_SetIntArray,
4427 ID3DXEffectImpl_GetIntArray,
4428 ID3DXEffectImpl_SetFloat,
4429 ID3DXEffectImpl_GetFloat,
4430 ID3DXEffectImpl_SetFloatArray,
4431 ID3DXEffectImpl_GetFloatArray,
4432 ID3DXEffectImpl_SetVector,
4433 ID3DXEffectImpl_GetVector,
4434 ID3DXEffectImpl_SetVectorArray,
4435 ID3DXEffectImpl_GetVectorArray,
4436 ID3DXEffectImpl_SetMatrix,
4437 ID3DXEffectImpl_GetMatrix,
4438 ID3DXEffectImpl_SetMatrixArray,
4439 ID3DXEffectImpl_GetMatrixArray,
4440 ID3DXEffectImpl_SetMatrixPointerArray,
4441 ID3DXEffectImpl_GetMatrixPointerArray,
4442 ID3DXEffectImpl_SetMatrixTranspose,
4443 ID3DXEffectImpl_GetMatrixTranspose,
4444 ID3DXEffectImpl_SetMatrixTransposeArray,
4445 ID3DXEffectImpl_GetMatrixTransposeArray,
4446 ID3DXEffectImpl_SetMatrixTransposePointerArray,
4447 ID3DXEffectImpl_GetMatrixTransposePointerArray,
4448 ID3DXEffectImpl_SetString,
4449 ID3DXEffectImpl_GetString,
4450 ID3DXEffectImpl_SetTexture,
4451 ID3DXEffectImpl_GetTexture,
4452 ID3DXEffectImpl_GetPixelShader,
4453 ID3DXEffectImpl_GetVertexShader,
4454 ID3DXEffectImpl_SetArrayRange,
4455 /*** ID3DXEffect methods ***/
4456 ID3DXEffectImpl_GetPool,
4457 ID3DXEffectImpl_SetTechnique,
4458 ID3DXEffectImpl_GetCurrentTechnique,
4459 ID3DXEffectImpl_ValidateTechnique,
4460 ID3DXEffectImpl_FindNextValidTechnique,
4461 ID3DXEffectImpl_IsParameterUsed,
4462 ID3DXEffectImpl_Begin,
4463 ID3DXEffectImpl_BeginPass,
4464 ID3DXEffectImpl_CommitChanges,
4465 ID3DXEffectImpl_EndPass,
4466 ID3DXEffectImpl_End,
4467 ID3DXEffectImpl_GetDevice,
4468 ID3DXEffectImpl_OnLostDevice,
4469 ID3DXEffectImpl_OnResetDevice,
4470 ID3DXEffectImpl_SetStateManager,
4471 ID3DXEffectImpl_GetStateManager,
4472 ID3DXEffectImpl_BeginParameterBlock,
4473 ID3DXEffectImpl_EndParameterBlock,
4474 ID3DXEffectImpl_ApplyParameterBlock,
4475 ID3DXEffectImpl_DeleteParameterBlock,
4476 ID3DXEffectImpl_CloneEffect,
4477 ID3DXEffectImpl_SetRawValue
4480 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
4482 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
4485 /*** IUnknown methods ***/
4486 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
4488 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
4490 if (IsEqualGUID(riid, &IID_IUnknown) ||
4491 IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
4493 iface->lpVtbl->AddRef(iface);
4494 *object = iface;
4495 return S_OK;
4498 ERR("Interface %s not found\n", debugstr_guid(riid));
4500 return E_NOINTERFACE;
4503 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
4505 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4507 TRACE("iface %p: AddRef from %u\n", iface, This->ref);
4509 return InterlockedIncrement(&This->ref);
4512 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
4514 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4515 ULONG ref = InterlockedDecrement(&This->ref);
4517 TRACE("iface %p: Release from %u\n", iface, ref + 1);
4519 if (!ref)
4521 free_effect_compiler(This);
4522 HeapFree(GetProcessHeap(), 0, This);
4525 return ref;
4528 /*** ID3DXBaseEffect methods ***/
4529 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
4531 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4533 TRACE("iface %p, desc %p.\n", iface, desc);
4535 return d3dx9_base_effect_get_desc(&compiler->base_effect, desc);
4538 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface,
4539 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
4541 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4543 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
4545 return d3dx9_base_effect_get_parameter_desc(&compiler->base_effect, parameter, desc);
4548 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface,
4549 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
4551 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4553 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
4555 return d3dx9_base_effect_get_technique_desc(&compiler->base_effect, technique, desc);
4558 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface,
4559 D3DXHANDLE pass, D3DXPASS_DESC *desc)
4561 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4563 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
4565 return d3dx9_base_effect_get_pass_desc(&compiler->base_effect, pass, desc);
4568 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface,
4569 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
4571 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4573 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
4575 return d3dx9_base_effect_get_function_desc(&compiler->base_effect, shader, desc);
4578 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface,
4579 D3DXHANDLE parameter, UINT index)
4581 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4583 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
4585 return d3dx9_base_effect_get_parameter(&compiler->base_effect, parameter, index);
4588 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface,
4589 D3DXHANDLE parameter, const char *name)
4591 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4593 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
4595 return d3dx9_base_effect_get_parameter_by_name(&compiler->base_effect, parameter, name);
4598 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface,
4599 D3DXHANDLE parameter, const char *semantic)
4601 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4603 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
4605 return d3dx9_base_effect_get_parameter_by_semantic(&compiler->base_effect, parameter, semantic);
4608 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface,
4609 D3DXHANDLE parameter, UINT index)
4611 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4613 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
4615 return d3dx9_base_effect_get_parameter_element(&compiler->base_effect, parameter, index);
4618 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
4620 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4622 TRACE("iface %p, index %u.\n", iface, index);
4624 return d3dx9_base_effect_get_technique(&compiler->base_effect, index);
4627 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name)
4629 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4631 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
4633 return d3dx9_base_effect_get_technique_by_name(&compiler->base_effect, name);
4636 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
4638 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4640 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
4642 return d3dx9_base_effect_get_pass(&compiler->base_effect, technique, index);
4645 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface,
4646 D3DXHANDLE technique, const char *name)
4648 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4650 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
4652 return d3dx9_base_effect_get_pass_by_name(&compiler->base_effect, technique, name);
4655 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
4657 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4659 TRACE("iface %p, index %u.\n", iface, index);
4661 return d3dx9_base_effect_get_function(&compiler->base_effect, index);
4664 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name)
4666 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4668 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
4670 return d3dx9_base_effect_get_function_by_name(&compiler->base_effect, name);
4673 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface,
4674 D3DXHANDLE object, UINT index)
4676 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4678 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
4680 return d3dx9_base_effect_get_annotation(&compiler->base_effect, object, index);
4683 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface,
4684 D3DXHANDLE object, const char *name)
4686 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4688 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
4690 return d3dx9_base_effect_get_annotation_by_name(&compiler->base_effect, object, name);
4693 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface,
4694 D3DXHANDLE parameter, const void *data, UINT bytes)
4696 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4698 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
4700 return d3dx9_base_effect_set_value(&compiler->base_effect, parameter, data, bytes);
4703 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface,
4704 D3DXHANDLE parameter, void *data, UINT bytes)
4706 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4708 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
4710 return d3dx9_base_effect_get_value(&compiler->base_effect, parameter, data, bytes);
4713 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4715 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4717 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
4719 return d3dx9_base_effect_set_bool(&compiler->base_effect, parameter, b);
4722 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4724 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4726 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
4728 return d3dx9_base_effect_get_bool(&compiler->base_effect, parameter, b);
4731 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface,
4732 D3DXHANDLE parameter, const BOOL *b, UINT count)
4734 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4736 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
4738 return d3dx9_base_effect_set_bool_array(&compiler->base_effect, parameter, b, count);
4741 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface,
4742 D3DXHANDLE parameter, BOOL *b, UINT count)
4744 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4746 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
4748 return d3dx9_base_effect_get_bool_array(&compiler->base_effect, parameter, b, count);
4751 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4753 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4755 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
4757 return d3dx9_base_effect_set_int(&compiler->base_effect, parameter, n);
4760 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4762 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4764 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
4766 return d3dx9_base_effect_get_int(&compiler->base_effect, parameter, n);
4769 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface,
4770 D3DXHANDLE parameter, const INT *n, UINT count)
4772 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4774 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
4776 return d3dx9_base_effect_set_int_array(&compiler->base_effect, parameter, n, count);
4779 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface,
4780 D3DXHANDLE parameter, INT *n, UINT count)
4782 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4784 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
4786 return d3dx9_base_effect_get_int_array(&compiler->base_effect, parameter, n, count);
4789 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f)
4791 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4793 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
4795 return d3dx9_base_effect_set_float(&compiler->base_effect, parameter, f);
4798 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f)
4800 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4802 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
4804 return d3dx9_base_effect_get_float(&compiler->base_effect, parameter, f);
4807 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface,
4808 D3DXHANDLE parameter, const float *f, UINT count)
4810 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4812 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
4814 return d3dx9_base_effect_set_float_array(&compiler->base_effect, parameter, f, count);
4817 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface,
4818 D3DXHANDLE parameter, float *f, UINT count)
4820 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4822 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
4824 return d3dx9_base_effect_get_float_array(&compiler->base_effect, parameter, f, count);
4827 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface,
4828 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
4830 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4832 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
4834 return d3dx9_base_effect_set_vector(&compiler->base_effect, parameter, vector);
4837 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface,
4838 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4840 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4842 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
4844 return d3dx9_base_effect_get_vector(&compiler->base_effect, parameter, vector);
4847 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface,
4848 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
4850 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4852 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
4854 return d3dx9_base_effect_set_vector_array(&compiler->base_effect, parameter, vector, count);
4857 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface,
4858 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4860 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4862 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
4864 return d3dx9_base_effect_get_vector_array(&compiler->base_effect, parameter, vector, count);
4867 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface,
4868 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4870 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4872 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4874 return d3dx9_base_effect_set_matrix(&compiler->base_effect, parameter, matrix);
4877 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface,
4878 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4880 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4882 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4884 return d3dx9_base_effect_get_matrix(&compiler->base_effect, parameter, matrix);
4887 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface,
4888 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4890 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4892 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4894 return d3dx9_base_effect_set_matrix_array(&compiler->base_effect, parameter, matrix, count);
4897 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface,
4898 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4900 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4902 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4904 return d3dx9_base_effect_get_matrix_array(&compiler->base_effect, parameter, matrix, count);
4907 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface,
4908 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4910 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4912 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4914 return d3dx9_base_effect_set_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count);
4917 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface,
4918 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4920 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4922 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4924 return d3dx9_base_effect_get_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count);
4927 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface,
4928 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4930 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4932 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4934 return d3dx9_base_effect_set_matrix_transpose(&compiler->base_effect, parameter, matrix);
4937 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface,
4938 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4940 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4942 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4944 return d3dx9_base_effect_get_matrix_transpose(&compiler->base_effect, parameter, matrix);
4947 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4948 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4950 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4952 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4954 return d3dx9_base_effect_set_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count);
4957 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4958 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4960 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4962 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4964 return d3dx9_base_effect_get_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count);
4967 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4968 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4970 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4972 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4974 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count);
4977 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4978 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4980 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4982 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4984 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count);
4987 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface,
4988 D3DXHANDLE parameter, const char *string)
4990 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4992 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
4994 return d3dx9_base_effect_set_string(&compiler->base_effect, parameter, string);
4997 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface,
4998 D3DXHANDLE parameter, const char **string)
5000 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5002 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
5004 return d3dx9_base_effect_get_string(&compiler->base_effect, parameter, string);
5007 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
5008 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
5010 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5012 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
5014 return d3dx9_base_effect_set_texture(&compiler->base_effect, parameter, texture);
5017 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
5018 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
5020 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5022 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
5024 return d3dx9_base_effect_get_texture(&compiler->base_effect, parameter, texture);
5027 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
5028 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
5030 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5032 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
5034 return d3dx9_base_effect_get_pixel_shader(&compiler->base_effect, parameter, shader);
5037 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
5038 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
5040 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5042 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
5044 return d3dx9_base_effect_get_vertex_shader(&compiler->base_effect, parameter, shader);
5047 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface,
5048 D3DXHANDLE parameter, UINT start, UINT end)
5050 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5052 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
5054 return d3dx9_base_effect_set_array_range(&compiler->base_effect, parameter, start, end);
5057 /*** ID3DXEffectCompiler methods ***/
5058 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
5060 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5062 FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
5064 return E_NOTIMPL;
5067 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
5069 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5071 FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
5073 return E_NOTIMPL;
5076 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
5077 ID3DXBuffer **effect, ID3DXBuffer **error_msgs)
5079 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5081 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
5083 return E_NOTIMPL;
5086 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
5087 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs,
5088 ID3DXConstantTable **constant_table)
5090 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5092 FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
5093 This, function, target, flags, shader, error_msgs, constant_table);
5095 return E_NOTIMPL;
5098 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
5100 /*** IUnknown methods ***/
5101 ID3DXEffectCompilerImpl_QueryInterface,
5102 ID3DXEffectCompilerImpl_AddRef,
5103 ID3DXEffectCompilerImpl_Release,
5104 /*** ID3DXBaseEffect methods ***/
5105 ID3DXEffectCompilerImpl_GetDesc,
5106 ID3DXEffectCompilerImpl_GetParameterDesc,
5107 ID3DXEffectCompilerImpl_GetTechniqueDesc,
5108 ID3DXEffectCompilerImpl_GetPassDesc,
5109 ID3DXEffectCompilerImpl_GetFunctionDesc,
5110 ID3DXEffectCompilerImpl_GetParameter,
5111 ID3DXEffectCompilerImpl_GetParameterByName,
5112 ID3DXEffectCompilerImpl_GetParameterBySemantic,
5113 ID3DXEffectCompilerImpl_GetParameterElement,
5114 ID3DXEffectCompilerImpl_GetTechnique,
5115 ID3DXEffectCompilerImpl_GetTechniqueByName,
5116 ID3DXEffectCompilerImpl_GetPass,
5117 ID3DXEffectCompilerImpl_GetPassByName,
5118 ID3DXEffectCompilerImpl_GetFunction,
5119 ID3DXEffectCompilerImpl_GetFunctionByName,
5120 ID3DXEffectCompilerImpl_GetAnnotation,
5121 ID3DXEffectCompilerImpl_GetAnnotationByName,
5122 ID3DXEffectCompilerImpl_SetValue,
5123 ID3DXEffectCompilerImpl_GetValue,
5124 ID3DXEffectCompilerImpl_SetBool,
5125 ID3DXEffectCompilerImpl_GetBool,
5126 ID3DXEffectCompilerImpl_SetBoolArray,
5127 ID3DXEffectCompilerImpl_GetBoolArray,
5128 ID3DXEffectCompilerImpl_SetInt,
5129 ID3DXEffectCompilerImpl_GetInt,
5130 ID3DXEffectCompilerImpl_SetIntArray,
5131 ID3DXEffectCompilerImpl_GetIntArray,
5132 ID3DXEffectCompilerImpl_SetFloat,
5133 ID3DXEffectCompilerImpl_GetFloat,
5134 ID3DXEffectCompilerImpl_SetFloatArray,
5135 ID3DXEffectCompilerImpl_GetFloatArray,
5136 ID3DXEffectCompilerImpl_SetVector,
5137 ID3DXEffectCompilerImpl_GetVector,
5138 ID3DXEffectCompilerImpl_SetVectorArray,
5139 ID3DXEffectCompilerImpl_GetVectorArray,
5140 ID3DXEffectCompilerImpl_SetMatrix,
5141 ID3DXEffectCompilerImpl_GetMatrix,
5142 ID3DXEffectCompilerImpl_SetMatrixArray,
5143 ID3DXEffectCompilerImpl_GetMatrixArray,
5144 ID3DXEffectCompilerImpl_SetMatrixPointerArray,
5145 ID3DXEffectCompilerImpl_GetMatrixPointerArray,
5146 ID3DXEffectCompilerImpl_SetMatrixTranspose,
5147 ID3DXEffectCompilerImpl_GetMatrixTranspose,
5148 ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
5149 ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
5150 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
5151 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
5152 ID3DXEffectCompilerImpl_SetString,
5153 ID3DXEffectCompilerImpl_GetString,
5154 ID3DXEffectCompilerImpl_SetTexture,
5155 ID3DXEffectCompilerImpl_GetTexture,
5156 ID3DXEffectCompilerImpl_GetPixelShader,
5157 ID3DXEffectCompilerImpl_GetVertexShader,
5158 ID3DXEffectCompilerImpl_SetArrayRange,
5159 /*** ID3DXEffectCompiler methods ***/
5160 ID3DXEffectCompilerImpl_SetLiteral,
5161 ID3DXEffectCompilerImpl_GetLiteral,
5162 ID3DXEffectCompilerImpl_CompileEffect,
5163 ID3DXEffectCompilerImpl_CompileShader,
5166 static HRESULT d3dx9_parse_sampler(struct d3dx9_base_effect *base, struct d3dx_sampler *sampler,
5167 const char *data, const char **ptr, struct d3dx_object *objects)
5169 HRESULT hr;
5170 UINT i;
5172 read_dword(ptr, &sampler->state_count);
5173 TRACE("Count: %u\n", sampler->state_count);
5175 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count);
5176 if (!sampler->states)
5178 ERR("Out of memory\n");
5179 return E_OUTOFMEMORY;
5182 for (i = 0; i < sampler->state_count; ++i)
5184 hr = d3dx9_parse_state(base, &sampler->states[i], data, ptr, objects);
5185 if (hr != D3D_OK)
5187 WARN("Failed to parse state %u\n", i);
5188 goto err_out;
5192 return D3D_OK;
5194 err_out:
5196 for (i = 0; i < sampler->state_count; ++i)
5198 free_state(&sampler->states[i]);
5200 HeapFree(GetProcessHeap(), 0, sampler->states);
5201 sampler->states = NULL;
5203 return hr;
5206 static HRESULT d3dx9_parse_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5207 void *value, const char *data, const char **ptr, struct d3dx_object *objects)
5209 unsigned int i;
5210 HRESULT hr;
5211 UINT old_size = 0;
5213 if (param->element_count)
5215 param->data = value;
5217 for (i = 0; i < param->element_count; ++i)
5219 struct d3dx_parameter *member = &param->members[i];
5221 hr = d3dx9_parse_value(base, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
5222 if (hr != D3D_OK)
5224 WARN("Failed to parse value %u\n", i);
5225 return hr;
5228 old_size += member->bytes;
5231 return D3D_OK;
5234 switch(param->class)
5236 case D3DXPC_SCALAR:
5237 case D3DXPC_VECTOR:
5238 case D3DXPC_MATRIX_ROWS:
5239 case D3DXPC_MATRIX_COLUMNS:
5240 param->data = value;
5241 break;
5243 case D3DXPC_STRUCT:
5244 param->data = value;
5246 for (i = 0; i < param->member_count; ++i)
5248 struct d3dx_parameter *member = &param->members[i];
5250 hr = d3dx9_parse_value(base, member, (char *)value + old_size, data, ptr, objects);
5251 if (hr != D3D_OK)
5253 WARN("Failed to parse value %u\n", i);
5254 return hr;
5257 old_size += member->bytes;
5259 break;
5261 case D3DXPC_OBJECT:
5262 switch (param->type)
5264 case D3DXPT_STRING:
5265 case D3DXPT_TEXTURE:
5266 case D3DXPT_TEXTURE1D:
5267 case D3DXPT_TEXTURE2D:
5268 case D3DXPT_TEXTURE3D:
5269 case D3DXPT_TEXTURECUBE:
5270 case D3DXPT_PIXELSHADER:
5271 case D3DXPT_VERTEXSHADER:
5272 read_dword(ptr, &param->object_id);
5273 TRACE("Id: %u\n", param->object_id);
5274 objects[param->object_id].param = param;
5275 param->data = value;
5276 break;
5278 case D3DXPT_SAMPLER:
5279 case D3DXPT_SAMPLER1D:
5280 case D3DXPT_SAMPLER2D:
5281 case D3DXPT_SAMPLER3D:
5282 case D3DXPT_SAMPLERCUBE:
5284 struct d3dx_sampler *sampler;
5286 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
5287 if (!sampler)
5288 return E_OUTOFMEMORY;
5290 hr = d3dx9_parse_sampler(base, sampler, data, ptr, objects);
5291 if (hr != D3D_OK)
5293 HeapFree(GetProcessHeap(), 0, sampler);
5294 WARN("Failed to parse sampler\n");
5295 return hr;
5298 param->data = sampler;
5299 break;
5302 default:
5303 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5304 break;
5306 break;
5308 default:
5309 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5310 break;
5313 return D3D_OK;
5316 static HRESULT d3dx9_parse_init_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5317 const char *data, const char *ptr, struct d3dx_object *objects)
5319 UINT size = param->bytes;
5320 HRESULT hr;
5321 void *value = NULL;
5323 TRACE("param size: %u\n", size);
5325 if (size)
5327 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5328 if (!value)
5330 ERR("Failed to allocate data memory.\n");
5331 return E_OUTOFMEMORY;
5334 switch(param->class)
5336 case D3DXPC_OBJECT:
5337 break;
5339 case D3DXPC_SCALAR:
5340 case D3DXPC_VECTOR:
5341 case D3DXPC_MATRIX_ROWS:
5342 case D3DXPC_MATRIX_COLUMNS:
5343 case D3DXPC_STRUCT:
5344 TRACE("Data: %s.\n", debugstr_an(ptr, size));
5345 memcpy(value, ptr, size);
5346 break;
5348 default:
5349 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5350 break;
5354 hr = d3dx9_parse_value(base, param, value, data, &ptr, objects);
5355 if (hr != D3D_OK)
5357 WARN("Failed to parse value\n");
5358 HeapFree(GetProcessHeap(), 0, value);
5359 return hr;
5362 return D3D_OK;
5365 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
5367 DWORD size;
5369 read_dword(&ptr, &size);
5370 TRACE("Name size: %#x\n", size);
5372 if (!size)
5374 return D3D_OK;
5377 *name = HeapAlloc(GetProcessHeap(), 0, size);
5378 if (!*name)
5380 ERR("Failed to allocate name memory.\n");
5381 return E_OUTOFMEMORY;
5384 TRACE("Name: %s.\n", debugstr_an(ptr, size));
5385 memcpy(*name, ptr, size);
5387 return D3D_OK;
5390 static HRESULT d3dx9_copy_data(struct d3dx9_base_effect *base, unsigned int object_id, const char **ptr)
5392 struct d3dx_object *object = &base->objects[object_id];
5394 if (object->size || object->data)
5396 if (object_id)
5397 FIXME("Overwriting object id %u!\n", object_id);
5398 else
5399 TRACE("Overwriting object id 0.\n");
5401 HeapFree(GetProcessHeap(), 0, object->data);
5402 object->data = NULL;
5405 read_dword(ptr, &object->size);
5406 TRACE("Data size: %#x.\n", object->size);
5408 if (!object->size)
5409 return D3D_OK;
5411 object->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5412 if (!object->data)
5414 ERR("Failed to allocate object memory.\n");
5415 return E_OUTOFMEMORY;
5418 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size));
5419 memcpy(object->data, *ptr, object->size);
5421 *ptr += ((object->size + 3) & ~3);
5423 return D3D_OK;
5426 static void param_set_magic_number(struct d3dx_parameter *param)
5428 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string));
5431 static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5432 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
5434 DWORD offset;
5435 HRESULT hr;
5436 UINT i;
5438 param->flags = flags;
5440 if (!parent)
5442 read_dword(ptr, (DWORD *)&param->type);
5443 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
5445 read_dword(ptr, (DWORD *)&param->class);
5446 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
5448 read_dword(ptr, &offset);
5449 TRACE("Type name offset: %#x\n", offset);
5450 hr = d3dx9_parse_name(&param->name, data + offset);
5451 if (hr != D3D_OK)
5453 WARN("Failed to parse name\n");
5454 goto err_out;
5457 read_dword(ptr, &offset);
5458 TRACE("Type semantic offset: %#x\n", offset);
5459 hr = d3dx9_parse_name(&param->semantic, data + offset);
5460 if (hr != D3D_OK)
5462 WARN("Failed to parse semantic\n");
5463 goto err_out;
5466 read_dword(ptr, &param->element_count);
5467 TRACE("Elements: %u\n", param->element_count);
5469 switch (param->class)
5471 case D3DXPC_VECTOR:
5472 read_dword(ptr, &param->columns);
5473 TRACE("Columns: %u\n", param->columns);
5475 read_dword(ptr, &param->rows);
5476 TRACE("Rows: %u\n", param->rows);
5478 /* sizeof(DWORD) * rows * columns */
5479 param->bytes = 4 * param->rows * param->columns;
5480 break;
5482 case D3DXPC_SCALAR:
5483 case D3DXPC_MATRIX_ROWS:
5484 case D3DXPC_MATRIX_COLUMNS:
5485 read_dword(ptr, &param->rows);
5486 TRACE("Rows: %u\n", param->rows);
5488 read_dword(ptr, &param->columns);
5489 TRACE("Columns: %u\n", param->columns);
5491 /* sizeof(DWORD) * rows * columns */
5492 param->bytes = 4 * param->rows * param->columns;
5493 break;
5495 case D3DXPC_STRUCT:
5496 read_dword(ptr, &param->member_count);
5497 TRACE("Members: %u\n", param->member_count);
5498 break;
5500 case D3DXPC_OBJECT:
5501 switch (param->type)
5503 case D3DXPT_STRING:
5504 case D3DXPT_PIXELSHADER:
5505 case D3DXPT_VERTEXSHADER:
5506 case D3DXPT_TEXTURE:
5507 case D3DXPT_TEXTURE1D:
5508 case D3DXPT_TEXTURE2D:
5509 case D3DXPT_TEXTURE3D:
5510 case D3DXPT_TEXTURECUBE:
5511 param->bytes = sizeof(void *);
5512 break;
5514 case D3DXPT_SAMPLER:
5515 case D3DXPT_SAMPLER1D:
5516 case D3DXPT_SAMPLER2D:
5517 case D3DXPT_SAMPLER3D:
5518 case D3DXPT_SAMPLERCUBE:
5519 param->bytes = 0;
5520 break;
5522 default:
5523 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5524 break;
5526 break;
5528 default:
5529 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5530 break;
5533 else
5535 /* elements */
5536 param->type = parent->type;
5537 param->class = parent->class;
5538 param->name = parent->name;
5539 param->semantic = parent->semantic;
5540 param->element_count = 0;
5541 param->member_count = parent->member_count;
5542 param->bytes = parent->bytes;
5543 param->rows = parent->rows;
5544 param->columns = parent->columns;
5547 if (param->element_count)
5549 unsigned int param_bytes = 0;
5550 const char *save_ptr = *ptr;
5552 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count);
5553 if (!param->members)
5555 ERR("Out of memory\n");
5556 hr = E_OUTOFMEMORY;
5557 goto err_out;
5560 for (i = 0; i < param->element_count; ++i)
5562 *ptr = save_ptr;
5564 param_set_magic_number(&param->members[i]);
5565 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, param, flags);
5566 if (hr != D3D_OK)
5568 WARN("Failed to parse member %u\n", i);
5569 goto err_out;
5572 param_bytes += param->members[i].bytes;
5575 param->bytes = param_bytes;
5577 else if (param->member_count)
5579 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count);
5580 if (!param->members)
5582 ERR("Out of memory\n");
5583 hr = E_OUTOFMEMORY;
5584 goto err_out;
5587 for (i = 0; i < param->member_count; ++i)
5589 param_set_magic_number(&param->members[i]);
5590 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, NULL, flags);
5591 if (hr != D3D_OK)
5593 WARN("Failed to parse member %u\n", i);
5594 goto err_out;
5597 param->bytes += param->members[i].bytes;
5600 return D3D_OK;
5602 err_out:
5604 if (param->members)
5606 unsigned int count = param->element_count ? param->element_count : param->member_count;
5608 for (i = 0; i < count; ++i)
5609 free_parameter(&param->members[i], param->element_count != 0, TRUE);
5610 HeapFree(GetProcessHeap(), 0, param->members);
5611 param->members = NULL;
5614 if (!parent)
5616 HeapFree(GetProcessHeap(), 0, param->name);
5617 HeapFree(GetProcessHeap(), 0, param->semantic);
5619 param->name = NULL;
5620 param->semantic = NULL;
5622 return hr;
5625 static HRESULT d3dx9_parse_effect_annotation(struct d3dx9_base_effect *base, struct d3dx_parameter *anno,
5626 const char *data, const char **ptr, struct d3dx_object *objects)
5628 DWORD offset;
5629 const char *ptr2;
5630 HRESULT hr;
5632 anno->flags = D3DX_PARAMETER_ANNOTATION;
5634 read_dword(ptr, &offset);
5635 TRACE("Typedef offset: %#x\n", offset);
5636 ptr2 = data + offset;
5637 hr = d3dx9_parse_effect_typedef(base, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5638 if (hr != D3D_OK)
5640 WARN("Failed to parse type definition\n");
5641 return hr;
5644 read_dword(ptr, &offset);
5645 TRACE("Value offset: %#x\n", offset);
5646 hr = d3dx9_parse_init_value(base, anno, data, data + offset, objects);
5647 if (hr != D3D_OK)
5649 WARN("Failed to parse value\n");
5650 return hr;
5653 return D3D_OK;
5656 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
5657 const char *data, const char **ptr, struct d3dx_object *objects)
5659 DWORD offset;
5660 const char *ptr2;
5661 HRESULT hr;
5663 state->type = ST_CONSTANT;
5665 read_dword(ptr, &state->operation);
5666 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5668 read_dword(ptr, &state->index);
5669 TRACE("Index: %#x\n", state->index);
5671 read_dword(ptr, &offset);
5672 TRACE("Typedef offset: %#x\n", offset);
5673 ptr2 = data + offset;
5674 hr = d3dx9_parse_effect_typedef(base, &state->parameter, data, &ptr2, NULL, 0);
5675 if (hr != D3D_OK)
5677 WARN("Failed to parse type definition\n");
5678 goto err_out;
5681 read_dword(ptr, &offset);
5682 TRACE("Value offset: %#x\n", offset);
5683 hr = d3dx9_parse_init_value(base, &state->parameter, data, data + offset, objects);
5684 if (hr != D3D_OK)
5686 WARN("Failed to parse value\n");
5687 goto err_out;
5690 return D3D_OK;
5692 err_out:
5694 free_parameter(&state->parameter, FALSE, FALSE);
5696 return hr;
5699 static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_top_level_parameter *param,
5700 const char *data, const char **ptr, struct d3dx_object *objects)
5702 DWORD offset;
5703 HRESULT hr;
5704 unsigned int i;
5705 const char *ptr2;
5707 read_dword(ptr, &offset);
5708 TRACE("Typedef offset: %#x.\n", offset);
5709 ptr2 = data + offset;
5711 read_dword(ptr, &offset);
5712 TRACE("Value offset: %#x.\n", offset);
5714 read_dword(ptr, &param->param.flags);
5715 TRACE("Flags: %#x.\n", param->param.flags);
5717 read_dword(ptr, &param->annotation_count);
5718 TRACE("Annotation count: %u.\n", param->annotation_count);
5720 hr = d3dx9_parse_effect_typedef(base, &param->param, data, &ptr2, NULL, param->param.flags);
5721 if (hr != D3D_OK)
5723 WARN("Failed to parse type definition.\n");
5724 return hr;
5727 hr = d3dx9_parse_init_value(base, &param->param, data, data + offset, objects);
5728 if (hr != D3D_OK)
5730 WARN("Failed to parse value.\n");
5731 return hr;
5734 if (param->annotation_count)
5736 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5737 sizeof(*param->annotations) * param->annotation_count);
5738 if (!param->annotations)
5740 ERR("Out of memory.\n");
5741 hr = E_OUTOFMEMORY;
5742 goto err_out;
5745 for (i = 0; i < param->annotation_count; ++i)
5747 param_set_magic_number(&param->annotations[i]);
5748 hr = d3dx9_parse_effect_annotation(base, &param->annotations[i], data, ptr, objects);
5749 if (hr != D3D_OK)
5751 WARN("Failed to parse annotation.\n");
5752 goto err_out;
5757 return D3D_OK;
5759 err_out:
5761 if (param->annotations)
5763 for (i = 0; i < param->annotation_count; ++i)
5764 free_parameter(&param->annotations[i], FALSE, FALSE);
5765 HeapFree(GetProcessHeap(), 0, param->annotations);
5766 param->annotations = NULL;
5769 return hr;
5772 static HRESULT d3dx9_parse_effect_pass(struct d3dx9_base_effect *base, struct d3dx_pass *pass,
5773 const char *data, const char **ptr, struct d3dx_object *objects)
5775 DWORD offset;
5776 HRESULT hr;
5777 unsigned int i;
5778 struct d3dx_state *states = NULL;
5779 char *name = NULL;
5781 read_dword(ptr, &offset);
5782 TRACE("Pass name offset: %#x\n", offset);
5783 hr = d3dx9_parse_name(&name, data + offset);
5784 if (hr != D3D_OK)
5786 WARN("Failed to parse name\n");
5787 goto err_out;
5790 read_dword(ptr, &pass->annotation_count);
5791 TRACE("Annotation count: %u\n", pass->annotation_count);
5793 read_dword(ptr, &pass->state_count);
5794 TRACE("State count: %u\n", pass->state_count);
5796 if (pass->annotation_count)
5798 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5799 sizeof(*pass->annotations) * pass->annotation_count);
5800 if (!pass->annotations)
5802 ERR("Out of memory\n");
5803 hr = E_OUTOFMEMORY;
5804 goto err_out;
5807 for (i = 0; i < pass->annotation_count; ++i)
5809 param_set_magic_number(&pass->annotations[i]);
5810 hr = d3dx9_parse_effect_annotation(base, &pass->annotations[i], data, ptr, objects);
5811 if (hr != D3D_OK)
5813 WARN("Failed to parse annotation %u\n", i);
5814 goto err_out;
5819 if (pass->state_count)
5821 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5822 if (!states)
5824 ERR("Out of memory\n");
5825 hr = E_OUTOFMEMORY;
5826 goto err_out;
5829 for (i = 0; i < pass->state_count; ++i)
5831 hr = d3dx9_parse_state(base, &states[i], data, ptr, objects);
5832 if (hr != D3D_OK)
5834 WARN("Failed to parse annotation %u\n", i);
5835 goto err_out;
5840 pass->name = name;
5841 pass->states = states;
5843 return D3D_OK;
5845 err_out:
5847 if (pass->annotations)
5849 for (i = 0; i < pass->annotation_count; ++i)
5850 free_parameter(&pass->annotations[i], FALSE, FALSE);
5851 HeapFree(GetProcessHeap(), 0, pass->annotations);
5852 pass->annotations = NULL;
5855 if (states)
5857 for (i = 0; i < pass->state_count; ++i)
5859 free_state(&states[i]);
5861 HeapFree(GetProcessHeap(), 0, states);
5864 HeapFree(GetProcessHeap(), 0, name);
5866 return hr;
5869 static HRESULT d3dx9_parse_effect_technique(struct d3dx9_base_effect *base, struct d3dx_technique *technique,
5870 const char *data, const char **ptr, struct d3dx_object *objects)
5872 DWORD offset;
5873 HRESULT hr;
5874 unsigned int i;
5875 char *name = NULL;
5877 read_dword(ptr, &offset);
5878 TRACE("Technique name offset: %#x\n", offset);
5879 hr = d3dx9_parse_name(&name, data + offset);
5880 if (hr != D3D_OK)
5882 WARN("Failed to parse name\n");
5883 goto err_out;
5886 read_dword(ptr, &technique->annotation_count);
5887 TRACE("Annotation count: %u\n", technique->annotation_count);
5889 read_dword(ptr, &technique->pass_count);
5890 TRACE("Pass count: %u\n", technique->pass_count);
5892 if (technique->annotation_count)
5894 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5895 sizeof(*technique->annotations) * technique->annotation_count);
5896 if (!technique->annotations)
5898 ERR("Out of memory\n");
5899 hr = E_OUTOFMEMORY;
5900 goto err_out;
5903 for (i = 0; i < technique->annotation_count; ++i)
5905 param_set_magic_number(&technique->annotations[i]);
5906 hr = d3dx9_parse_effect_annotation(base, &technique->annotations[i], data, ptr, objects);
5907 if (hr != D3D_OK)
5909 WARN("Failed to parse annotation %u\n", i);
5910 goto err_out;
5915 if (technique->pass_count)
5917 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5918 sizeof(*technique->passes) * technique->pass_count);
5919 if (!technique->passes)
5921 ERR("Out of memory\n");
5922 hr = E_OUTOFMEMORY;
5923 goto err_out;
5926 for (i = 0; i < technique->pass_count; ++i)
5928 hr = d3dx9_parse_effect_pass(base, &technique->passes[i], data, ptr, objects);
5929 if (hr != D3D_OK)
5931 WARN("Failed to parse pass %u\n", i);
5932 goto err_out;
5937 technique->name = name;
5939 return D3D_OK;
5941 err_out:
5943 if (technique->passes)
5945 for (i = 0; i < technique->pass_count; ++i)
5946 free_pass(&technique->passes[i]);
5947 HeapFree(GetProcessHeap(), 0, technique->passes);
5948 technique->passes = NULL;
5951 if (technique->annotations)
5953 for (i = 0; i < technique->annotation_count; ++i)
5954 free_parameter(&technique->annotations[i], FALSE, FALSE);
5955 HeapFree(GetProcessHeap(), 0, technique->annotations);
5956 technique->annotations = NULL;
5959 HeapFree(GetProcessHeap(), 0, name);
5961 return hr;
5964 static HRESULT d3dx9_create_object(struct d3dx9_base_effect *base, struct d3dx_object *object)
5966 struct d3dx_parameter *param = object->param;
5967 struct IDirect3DDevice9 *device = base->effect->device;
5968 HRESULT hr;
5970 if (*(char **)param->data)
5971 ERR("Parameter data already allocated.\n");
5973 switch (param->type)
5975 case D3DXPT_STRING:
5976 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5977 if (!*(char **)param->data)
5979 ERR("Out of memory.\n");
5980 return E_OUTOFMEMORY;
5982 memcpy(*(char **)param->data, object->data, object->size);
5983 break;
5984 case D3DXPT_VERTEXSHADER:
5985 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data,
5986 (IDirect3DVertexShader9 **)param->data)))
5988 WARN("Failed to create vertex shader.\n");
5989 object->creation_failed = TRUE;
5991 break;
5992 case D3DXPT_PIXELSHADER:
5993 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data,
5994 (IDirect3DPixelShader9 **)param->data)))
5996 WARN("Failed to create pixel shader.\n");
5997 object->creation_failed = TRUE;
5999 break;
6000 default:
6001 break;
6003 return D3D_OK;
6006 static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct d3dx_state *state,
6007 const char **skip_constants, unsigned int skip_constants_count)
6009 DWORD string_size;
6010 struct d3dx_parameter *param = &state->parameter;
6011 struct d3dx_object *object = &base->objects[param->object_id];
6012 char *ptr = object->data;
6013 HRESULT ret;
6015 TRACE("Parsing array entry selection state for parameter %p.\n", param);
6017 string_size = *(DWORD *)ptr;
6018 state->referenced_param = get_parameter_by_name(base, NULL, ptr + 4);
6019 if (state->referenced_param)
6021 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
6023 else
6025 FIXME("Referenced parameter %s not found.\n", ptr + 4);
6026 return D3DXERR_INVALIDDATA;
6028 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
6030 if (string_size % sizeof(DWORD))
6031 FIXME("Unaligned string_size %u.\n", string_size);
6032 if (FAILED(ret = d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1,
6033 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, &param->param_eval,
6034 get_version_counter_ptr(base), NULL, 0)))
6035 return ret;
6036 ret = D3D_OK;
6037 param = state->referenced_param;
6038 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
6040 unsigned int i;
6042 for (i = 0; i < param->element_count; i++)
6044 if (param->members[i].type != param->type)
6046 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
6047 return D3DXERR_INVALIDDATA;
6049 if (!param->members[i].param_eval)
6051 TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
6052 object = &base->objects[param->members[i].object_id];
6053 if (FAILED(ret = d3dx_create_param_eval(base, object->data, object->size, param->type,
6054 &param->members[i].param_eval, get_version_counter_ptr(base),
6055 skip_constants, skip_constants_count)))
6056 break;
6060 return ret;
6063 static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr,
6064 const char **skip_constants, unsigned int skip_constants_count)
6066 DWORD technique_index;
6067 DWORD index, state_index, usage, element_index;
6068 struct d3dx_state *state;
6069 struct d3dx_parameter *param;
6070 struct d3dx_object *object;
6071 HRESULT hr = E_FAIL;
6073 read_dword(ptr, &technique_index);
6074 TRACE("technique_index: %u\n", technique_index);
6076 read_dword(ptr, &index);
6077 TRACE("index: %u\n", index);
6079 read_dword(ptr, &element_index);
6080 TRACE("element_index: %u\n", element_index);
6082 read_dword(ptr, &state_index);
6083 TRACE("state_index: %u\n", state_index);
6085 read_dword(ptr, &usage);
6086 TRACE("usage: %u\n", usage);
6088 if (technique_index == 0xffffffff)
6090 struct d3dx_parameter *parameter;
6091 struct d3dx_sampler *sampler;
6093 if (index >= base->parameter_count)
6095 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
6096 return E_FAIL;
6099 parameter = &base->parameters[index].param;
6100 if (element_index != 0xffffffff)
6102 if (element_index >= parameter->element_count && parameter->element_count != 0)
6104 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
6105 return E_FAIL;
6108 if (parameter->element_count)
6109 parameter = &parameter->members[element_index];
6112 sampler = parameter->data;
6113 if (state_index >= sampler->state_count)
6115 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
6116 return E_FAIL;
6119 state = &sampler->states[state_index];
6121 else
6123 struct d3dx_technique *technique;
6124 struct d3dx_pass *pass;
6126 if (technique_index >= base->technique_count)
6128 FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
6129 return E_FAIL;
6132 technique = &base->techniques[technique_index];
6133 if (index >= technique->pass_count)
6135 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
6136 return E_FAIL;
6139 pass = &technique->passes[index];
6140 if (state_index >= pass->state_count)
6142 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
6143 return E_FAIL;
6146 state = &pass->states[state_index];
6149 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name);
6150 param = &state->parameter;
6151 TRACE("Using object id %u.\n", param->object_id);
6152 object = &base->objects[param->object_id];
6154 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class),
6155 debug_d3dxparameter_type(param->type));
6156 switch (usage)
6158 case 0:
6159 switch (param->type)
6161 case D3DXPT_VERTEXSHADER:
6162 case D3DXPT_PIXELSHADER:
6163 state->type = ST_CONSTANT;
6164 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6165 return hr;
6167 if (object->data)
6169 if (FAILED(hr = d3dx9_create_object(base, object)))
6170 return hr;
6171 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6172 &param->param_eval, get_version_counter_ptr(base),
6173 skip_constants, skip_constants_count)))
6174 return hr;
6176 break;
6178 case D3DXPT_BOOL:
6179 case D3DXPT_INT:
6180 case D3DXPT_FLOAT:
6181 case D3DXPT_STRING:
6182 state->type = ST_FXLC;
6183 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6184 return hr;
6185 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6186 &param->param_eval, get_version_counter_ptr(base), NULL, 0)))
6187 return hr;
6188 break;
6190 default:
6191 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
6192 break;
6194 break;
6196 case 1:
6197 state->type = ST_PARAMETER;
6198 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6199 return hr;
6201 TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
6202 state->referenced_param = get_parameter_by_name(base, NULL, object->data);
6203 if (state->referenced_param)
6205 struct d3dx_parameter *refpar = state->referenced_param;
6207 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
6208 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
6210 struct d3dx_object *refobj = &base->objects[refpar->object_id];
6212 if (!refpar->param_eval)
6214 if (FAILED(hr = d3dx_create_param_eval(base, refobj->data, refobj->size,
6215 refpar->type, &refpar->param_eval, get_version_counter_ptr(base),
6216 skip_constants, skip_constants_count)))
6217 return hr;
6221 else
6223 FIXME("Referenced parameter %s not found.\n", (char *)object->data);
6224 return D3DXERR_INVALIDDATA;
6226 break;
6228 case 2:
6229 state->type = ST_ARRAY_SELECTOR;
6230 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6231 return hr;
6232 hr = d3dx9_parse_array_selector(base, state, skip_constants, skip_constants_count);
6233 break;
6235 default:
6236 FIXME("Unknown usage %x\n", usage);
6237 break;
6240 return hr;
6243 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param)
6245 param->top_level_param = top_level_param;
6246 return FALSE;
6249 static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *data, UINT data_size,
6250 DWORD start, const char **skip_constants, unsigned int skip_constants_count)
6252 const char *ptr = data + start;
6253 UINT stringcount, resourcecount;
6254 HRESULT hr;
6255 UINT i;
6257 read_dword(&ptr, &base->parameter_count);
6258 TRACE("Parameter count: %u.\n", base->parameter_count);
6260 read_dword(&ptr, &base->technique_count);
6261 TRACE("Technique count: %u.\n", base->technique_count);
6263 skip_dword_unknown(&ptr, 1);
6265 read_dword(&ptr, &base->object_count);
6266 TRACE("Object count: %u.\n", base->object_count);
6268 base->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base->objects) * base->object_count);
6269 if (!base->objects)
6271 ERR("Out of memory.\n");
6272 hr = E_OUTOFMEMORY;
6273 goto err_out;
6276 if (base->parameter_count)
6278 base->parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6279 sizeof(*base->parameters) * base->parameter_count);
6280 if (!base->parameters)
6282 ERR("Out of memory.\n");
6283 hr = E_OUTOFMEMORY;
6284 goto err_out;
6287 for (i = 0; i < base->parameter_count; ++i)
6289 param_set_magic_number(&base->parameters[i].param);
6290 hr = d3dx9_parse_effect_parameter(base, &base->parameters[i], data, &ptr, base->objects);
6291 if (hr != D3D_OK)
6293 WARN("Failed to parse parameter %u.\n", i);
6294 goto err_out;
6296 walk_parameter_tree(&base->parameters[i].param, param_set_top_level_param,
6297 &base->parameters[i]);
6301 if (base->technique_count)
6303 base->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6304 sizeof(*base->techniques) * base->technique_count);
6305 if (!base->techniques)
6307 ERR("Out of memory.\n");
6308 hr = E_OUTOFMEMORY;
6309 goto err_out;
6312 for (i = 0; i < base->technique_count; ++i)
6314 TRACE("Parsing technique %u.\n", i);
6315 hr = d3dx9_parse_effect_technique(base, &base->techniques[i], data, &ptr, base->objects);
6316 if (hr != D3D_OK)
6318 WARN("Failed to parse technique %u.\n", i);
6319 goto err_out;
6324 read_dword(&ptr, &stringcount);
6325 TRACE("String count: %u.\n", stringcount);
6327 read_dword(&ptr, &resourcecount);
6328 TRACE("Resource count: %u.\n", resourcecount);
6330 for (i = 0; i < stringcount; ++i)
6332 DWORD id;
6334 read_dword(&ptr, &id);
6335 TRACE("id: %u.\n", id);
6337 if (FAILED(hr = d3dx9_copy_data(base, id, &ptr)))
6338 goto err_out;
6340 if (base->objects[id].data)
6342 if (FAILED(hr = d3dx9_create_object(base, &base->objects[id])))
6343 goto err_out;
6347 for (i = 0; i < resourcecount; ++i)
6349 TRACE("parse resource %u.\n", i);
6351 hr = d3dx9_parse_resource(base, data, &ptr, skip_constants, skip_constants_count);
6352 if (hr != D3D_OK)
6354 WARN("Failed to parse resource %u.\n", i);
6355 goto err_out;
6359 for (i = 0; i < base->parameter_count; ++i)
6361 if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i])))
6362 goto err_out;
6363 base->parameters[i].version_counter = base->pool
6364 ? &base->pool->version_counter
6365 : &base->version_counter;
6366 set_dirty(&base->parameters[i].param);
6368 return D3D_OK;
6370 err_out:
6372 if (base->techniques)
6374 for (i = 0; i < base->technique_count; ++i)
6375 free_technique(&base->techniques[i]);
6376 HeapFree(GetProcessHeap(), 0, base->techniques);
6377 base->techniques = NULL;
6380 if (base->parameters)
6382 for (i = 0; i < base->parameter_count; ++i)
6384 free_top_level_parameter(&base->parameters[i]);
6386 HeapFree(GetProcessHeap(), 0, base->parameters);
6387 base->parameters = NULL;
6390 if (base->objects)
6392 for (i = 0; i < base->object_count; ++i)
6394 free_object(&base->objects[i]);
6396 HeapFree(GetProcessHeap(), 0, base->objects);
6397 base->objects = NULL;
6400 return hr;
6403 #define INITIAL_CONST_NAMES_SIZE 4
6405 static char *next_valid_constant_name(char **string)
6407 char *ret = *string;
6408 char *next;
6410 while (*ret && !isalpha(*ret) && *ret != '_')
6411 ++ret;
6412 if (!*ret)
6413 return NULL;
6415 next = ret + 1;
6416 while (isalpha(*next) || isdigit(*next) || *next == '_')
6417 ++next;
6418 if (*next)
6419 *next++ = 0;
6420 *string = next;
6421 return ret;
6424 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count)
6426 const char **names, **new_alloc;
6427 const char *name;
6428 char *s;
6429 unsigned int size = INITIAL_CONST_NAMES_SIZE;
6431 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size);
6432 if (!names)
6433 return NULL;
6435 *names_count = 0;
6436 s = skip_constants_string;
6437 while ((name = next_valid_constant_name(&s)))
6439 if (*names_count == size)
6441 size *= 2;
6442 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size);
6443 if (!new_alloc)
6445 HeapFree(GetProcessHeap(), 0, names);
6446 return NULL;
6448 names = new_alloc;
6450 names[(*names_count)++] = name;
6452 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names));
6453 if (!new_alloc)
6454 return names;
6455 return new_alloc;
6458 static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
6459 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6460 UINT eflags, ID3DBlob **errors, struct ID3DXEffectImpl *effect, struct d3dx_effect_pool *pool,
6461 const char *skip_constants_string)
6463 DWORD tag, offset;
6464 const char *ptr = data;
6465 HRESULT hr;
6466 ID3DBlob *bytecode = NULL, *temp_errors = NULL;
6467 char *skip_constants_buffer = NULL;
6468 const char **skip_constants = NULL;
6469 unsigned int skip_constants_count = 0;
6470 #if D3DX_SDK_VERSION <= 36
6471 UINT compile_flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
6472 #else
6473 UINT compile_flags = 0;
6474 #endif
6475 unsigned int i, j;
6477 TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n",
6478 base, data, data_size, effect, pool, debugstr_a(skip_constants_string));
6480 base->effect = effect;
6481 base->pool = pool;
6482 base->flags = eflags;
6484 read_dword(&ptr, &tag);
6485 TRACE("Tag: %x\n", tag);
6487 if (tag != d3dx9_effect_version(9, 1))
6489 TRACE("HLSL ASCII effect, trying to compile it.\n");
6490 hr = D3DCompile(data, data_size, NULL, defines, include,
6491 "main", "fx_2_0", compile_flags, eflags, &bytecode, &temp_errors);
6492 if (FAILED(hr))
6494 WARN("Failed to compile ASCII effect.\n");
6495 if (bytecode)
6496 ID3D10Blob_Release(bytecode);
6497 if (temp_errors)
6499 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors);
6500 const char *string_ptr;
6502 while (*error_string)
6504 string_ptr = error_string;
6505 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r'
6506 && string_ptr - error_string < 80)
6507 ++string_ptr;
6508 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string));
6509 error_string = string_ptr;
6510 while (*error_string == '\n' || *error_string == '\r')
6511 ++error_string;
6514 if (errors)
6515 *errors = temp_errors;
6516 else if (temp_errors)
6517 ID3D10Blob_Release(temp_errors);
6518 return hr;
6520 if (!bytecode)
6522 FIXME("No output from effect compilation.\n");
6523 return D3DERR_INVALIDCALL;
6525 if (errors)
6526 *errors = temp_errors;
6527 else if (temp_errors)
6528 ID3D10Blob_Release(temp_errors);
6530 ptr = ID3D10Blob_GetBufferPointer(bytecode);
6531 read_dword(&ptr, &tag);
6532 TRACE("Tag: %x\n", tag);
6535 if (skip_constants_string)
6537 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0,
6538 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1));
6539 if (!skip_constants_buffer)
6541 if (bytecode)
6542 ID3D10Blob_Release(bytecode);
6543 return E_OUTOFMEMORY;
6545 strcpy(skip_constants_buffer, skip_constants_string);
6547 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count)))
6549 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6550 if (bytecode)
6551 ID3D10Blob_Release(bytecode);
6552 return E_OUTOFMEMORY;
6555 read_dword(&ptr, &offset);
6556 TRACE("Offset: %x\n", offset);
6558 hr = d3dx9_parse_effect(base, ptr, data_size, offset, skip_constants, skip_constants_count);
6559 if (bytecode)
6560 ID3D10Blob_Release(bytecode);
6561 if (hr != D3D_OK)
6563 FIXME("Failed to parse effect.\n");
6564 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6565 HeapFree(GetProcessHeap(), 0, skip_constants);
6566 return hr;
6569 for (i = 0; i < skip_constants_count; ++i)
6571 struct d3dx_parameter *param;
6572 param = get_parameter_by_name(base, NULL, skip_constants[i]);
6573 if (param)
6575 for (j = 0; j < base->technique_count; ++j)
6577 if (is_parameter_used(param, &base->techniques[j]))
6579 WARN("skip_constants parameter %s is used in technique %u.\n",
6580 debugstr_a(skip_constants[i]), j);
6581 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6582 HeapFree(GetProcessHeap(), 0, skip_constants);
6583 d3dx9_base_effect_cleanup(base);
6584 return D3DERR_INVALIDCALL;
6588 else
6590 TRACE("skip_constants parameter %s not found.\n",
6591 debugstr_a(skip_constants[i]));
6595 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6596 HeapFree(GetProcessHeap(), 0, skip_constants);
6598 return D3D_OK;
6601 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, struct IDirect3DDevice9 *device,
6602 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6603 UINT eflags, ID3DBlob **error_messages, struct ID3DXEffectPool *pool, const char *skip_constants)
6605 HRESULT hr;
6606 struct d3dx_effect_pool *pool_impl = NULL;
6608 TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
6610 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
6611 effect->ref = 1;
6613 if (pool)
6615 pool->lpVtbl->AddRef(pool);
6616 pool_impl = impl_from_ID3DXEffectPool(pool);
6618 effect->pool = pool;
6620 IDirect3DDevice9_AddRef(device);
6621 effect->device = device;
6623 if (FAILED(hr = d3dx9_base_effect_init(&effect->base_effect, data, data_size, defines, include,
6624 eflags, error_messages, effect, pool_impl, skip_constants)))
6626 FIXME("Failed to parse effect, hr %#x.\n", hr);
6627 free_effect(effect);
6628 return hr;
6631 /* initialize defaults - check because of unsupported ascii effects */
6632 if (effect->base_effect.techniques)
6634 effect->active_technique = &effect->base_effect.techniques[0];
6635 effect->active_pass = NULL;
6638 return D3D_OK;
6641 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6642 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags,
6643 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6645 struct ID3DXEffectImpl *object;
6646 HRESULT hr;
6648 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p,"
6649 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n",
6650 device, srcdata, srcdatalen, defines, include,
6651 skip_constants, flags, pool, effect, compilation_errors);
6653 if (compilation_errors)
6654 *compilation_errors = NULL;
6656 if (!device || !srcdata)
6657 return D3DERR_INVALIDCALL;
6659 if (!srcdatalen)
6660 return E_FAIL;
6662 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6663 if (!effect)
6664 return D3D_OK;
6666 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6667 if (!object)
6668 return E_OUTOFMEMORY;
6670 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6671 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants);
6672 if (FAILED(hr))
6674 WARN("Failed to create effect object.\n");
6675 HeapFree(GetProcessHeap(), 0, object);
6676 return hr;
6679 *effect = &object->ID3DXEffect_iface;
6681 TRACE("Created ID3DXEffect %p\n", object);
6683 return D3D_OK;
6686 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6687 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6688 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6690 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
6691 include, flags, pool, effect, compilation_errors);
6693 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
6696 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler,
6697 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6698 UINT eflags, ID3DBlob **error_messages)
6700 HRESULT hr;
6702 TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
6704 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
6705 compiler->ref = 1;
6707 if (FAILED(hr = d3dx9_base_effect_init(&compiler->base_effect, data, data_size, defines,
6708 include, eflags, error_messages, NULL, NULL, NULL)))
6710 FIXME("Failed to parse effect, hr %#x.\n", hr);
6711 free_effect_compiler(compiler);
6712 return hr;
6715 return D3D_OK;
6718 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines,
6719 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors)
6721 struct ID3DXEffectCompilerImpl *object;
6722 HRESULT hr;
6724 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
6725 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
6727 if (!srcdata || !compiler)
6729 WARN("Invalid arguments supplied\n");
6730 return D3DERR_INVALIDCALL;
6733 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6734 if (!object)
6735 return E_OUTOFMEMORY;
6737 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6738 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors);
6739 if (FAILED(hr))
6741 WARN("Failed to initialize effect compiler\n");
6742 HeapFree(GetProcessHeap(), 0, object);
6743 return hr;
6746 *compiler = &object->ID3DXEffectCompiler_iface;
6748 TRACE("Created ID3DXEffectCompiler %p\n", object);
6750 return D3D_OK;
6753 /*** IUnknown methods ***/
6754 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
6756 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
6758 if (IsEqualGUID(riid, &IID_IUnknown) ||
6759 IsEqualGUID(riid, &IID_ID3DXEffectPool))
6761 iface->lpVtbl->AddRef(iface);
6762 *object = iface;
6763 return S_OK;
6766 WARN("Interface %s not found\n", debugstr_guid(riid));
6768 return E_NOINTERFACE;
6771 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface)
6773 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6774 ULONG refcount = InterlockedIncrement(&pool->refcount);
6776 TRACE("%p increasing refcount to %u.\n", pool, refcount);
6778 return refcount;
6781 static void free_effect_pool(struct d3dx_effect_pool *pool)
6783 unsigned int i;
6785 for (i = 0; i < pool->size; ++i)
6787 if (pool->shared_data[i].count)
6789 unsigned int j;
6791 WARN("Releasing pool with referenced parameters.\n");
6793 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE);
6794 pool->shared_data[i].parameters[0]->shared_data = NULL;
6796 for (j = 1; j < pool->shared_data[i].count; ++j)
6798 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL);
6799 pool->shared_data[i].parameters[j]->shared_data = NULL;
6801 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);
6804 HeapFree(GetProcessHeap(), 0, pool->shared_data);
6805 HeapFree(GetProcessHeap(), 0, pool);
6808 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface)
6810 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6811 ULONG refcount = InterlockedDecrement(&pool->refcount);
6813 TRACE("%p decreasing refcount to %u.\n", pool, refcount);
6815 if (!refcount)
6816 free_effect_pool(pool);
6818 return refcount;
6821 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
6823 /*** IUnknown methods ***/
6824 d3dx_effect_pool_QueryInterface,
6825 d3dx_effect_pool_AddRef,
6826 d3dx_effect_pool_Release
6829 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool)
6831 struct d3dx_effect_pool *object;
6833 TRACE("pool %p.\n", pool);
6835 if (!pool)
6836 return D3DERR_INVALIDCALL;
6838 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6839 if (!object)
6840 return E_OUTOFMEMORY;
6842 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6843 object->refcount = 1;
6845 *pool = &object->ID3DXEffectPool_iface;
6847 return S_OK;
6850 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6851 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6852 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6854 void *buffer;
6855 HRESULT ret;
6856 DWORD size;
6858 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6859 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6860 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants),
6861 flags, pool, effect, compilationerrors);
6863 if (!device || !srcfile)
6864 return D3DERR_INVALIDCALL;
6866 ret = map_view_of_file(srcfile, &buffer, &size);
6868 if (FAILED(ret))
6869 return D3DXERR_INVALIDDATA;
6871 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6872 UnmapViewOfFile(buffer);
6874 return ret;
6877 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
6878 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6879 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6881 WCHAR *srcfileW;
6882 HRESULT ret;
6883 DWORD len;
6885 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6886 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6887 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants),
6888 flags, pool, effect, compilationerrors);
6890 if (!srcfile)
6891 return D3DERR_INVALIDCALL;
6893 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6894 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6895 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6897 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6898 HeapFree(GetProcessHeap(), 0, srcfileW);
6900 return ret;
6903 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6904 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6905 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6907 TRACE("(void): relay\n");
6908 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6911 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile,
6912 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6913 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6915 TRACE("(void): relay\n");
6916 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6919 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6920 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6921 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6923 HRSRC resinfo;
6924 void *buffer;
6925 DWORD size;
6927 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6928 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6929 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants),
6930 flags, pool, effect, compilationerrors);
6932 if (!device)
6933 return D3DERR_INVALIDCALL;
6935 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
6936 return D3DXERR_INVALIDDATA;
6938 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6939 return D3DXERR_INVALIDDATA;
6941 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6942 skipconstants, flags, pool, effect, compilationerrors);
6945 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6946 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6947 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6949 HRSRC resinfo;
6950 void *buffer;
6951 DWORD size;
6953 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6954 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6955 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants),
6956 flags, pool, effect, compilationerrors);
6958 if (!device)
6959 return D3DERR_INVALIDCALL;
6961 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6962 return D3DXERR_INVALIDDATA;
6964 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6965 return D3DXERR_INVALIDDATA;
6967 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6968 skipconstants, flags, pool, effect, compilationerrors);
6971 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6972 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6973 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6975 TRACE("(void): relay\n");
6976 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6979 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6980 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6981 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6983 TRACE("(void): relay\n");
6984 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6987 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines,
6988 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6990 void *buffer;
6991 HRESULT ret;
6992 DWORD size;
6994 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6995 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors);
6997 if (!srcfile)
6998 return D3DERR_INVALIDCALL;
7000 ret = map_view_of_file(srcfile, &buffer, &size);
7002 if (FAILED(ret))
7003 return D3DXERR_INVALIDDATA;
7005 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7006 UnmapViewOfFile(buffer);
7008 return ret;
7011 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines,
7012 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7014 WCHAR *srcfileW;
7015 HRESULT ret;
7016 DWORD len;
7018 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7019 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors);
7021 if (!srcfile)
7022 return D3DERR_INVALIDCALL;
7024 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
7025 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
7026 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
7028 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
7029 HeapFree(GetProcessHeap(), 0, srcfileW);
7031 return ret;
7034 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource,
7035 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
7036 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7038 HRSRC resinfo;
7039 void *buffer;
7040 DWORD size;
7042 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7043 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors);
7045 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
7046 return D3DXERR_INVALIDDATA;
7048 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7049 return D3DXERR_INVALIDDATA;
7051 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7054 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource,
7055 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
7056 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7058 HRSRC resinfo;
7059 void *buffer;
7060 DWORD size;
7062 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7063 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors);
7065 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
7066 return D3DXERR_INVALIDDATA;
7068 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7069 return D3DXERR_INVALIDDATA;
7071 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7074 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly)
7076 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly);
7078 return D3DXERR_INVALIDDATA;