reg: Fail if the source and destination keys are the same when copying.
[wine.git] / dlls / d3dx9_36 / effect.c
blob710e999f27fde8e7cccdc6ccdae827f1a0beb27e
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
21 #include <stdio.h>
22 #include <assert.h>
24 #include "d3dx9_private.h"
25 #include "d3dcompiler.h"
26 #include "winternl.h"
27 #include "wine/list.h"
29 /* Constants for special INT/FLOAT conversation */
30 #define INT_FLOAT_MULTI 255.0f
31 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
33 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
34 static const char parameter_block_magic_string[4] = {'@', '!', '#', '\xFE'};
36 #define PARAMETER_FLAG_SHARED 1
38 #define INITIAL_POOL_SIZE 16
39 #define INITIAL_PARAM_BLOCK_SIZE 1024
41 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
43 enum STATE_CLASS
45 SC_LIGHTENABLE,
46 SC_FVF,
47 SC_LIGHT,
48 SC_MATERIAL,
49 SC_NPATCHMODE,
50 SC_PIXELSHADER,
51 SC_RENDERSTATE,
52 SC_SETSAMPLER,
53 SC_SAMPLERSTATE,
54 SC_TEXTURE,
55 SC_TEXTURESTAGE,
56 SC_TRANSFORM,
57 SC_VERTEXSHADER,
58 SC_SHADERCONST,
59 SC_UNKNOWN,
62 enum MATERIAL_TYPE
64 MT_DIFFUSE,
65 MT_AMBIENT,
66 MT_SPECULAR,
67 MT_EMISSIVE,
68 MT_POWER,
71 enum LIGHT_TYPE
73 LT_TYPE,
74 LT_DIFFUSE,
75 LT_SPECULAR,
76 LT_AMBIENT,
77 LT_POSITION,
78 LT_DIRECTION,
79 LT_RANGE,
80 LT_FALLOFF,
81 LT_ATTENUATION0,
82 LT_ATTENUATION1,
83 LT_ATTENUATION2,
84 LT_THETA,
85 LT_PHI,
88 enum SHADER_CONSTANT_TYPE
90 SCT_VSFLOAT,
91 SCT_VSBOOL,
92 SCT_VSINT,
93 SCT_PSFLOAT,
94 SCT_PSBOOL,
95 SCT_PSINT,
98 enum STATE_TYPE
100 ST_CONSTANT,
101 ST_PARAMETER,
102 ST_FXLC,
103 ST_ARRAY_SELECTOR,
106 struct d3dx_object
108 UINT size;
109 void *data;
110 struct d3dx_parameter *param;
111 BOOL creation_failed;
114 struct d3dx_state
116 UINT operation;
117 UINT index;
118 enum STATE_TYPE type;
119 struct d3dx_parameter parameter;
120 struct d3dx_parameter *referenced_param;
123 struct d3dx_sampler
125 UINT state_count;
126 struct d3dx_state *states;
129 struct d3dx_pass
131 char *name;
132 UINT state_count;
133 UINT annotation_count;
135 struct d3dx_state *states;
136 struct d3dx_parameter *annotations;
138 ULONG64 update_version;
141 struct d3dx_technique
143 char *name;
144 UINT pass_count;
145 UINT annotation_count;
147 struct d3dx_parameter *annotations;
148 struct d3dx_pass *passes;
150 struct IDirect3DStateBlock9 *saved_state;
153 struct d3dx_parameter_block
155 char magic_string[ARRAY_SIZE(parameter_block_magic_string)];
156 struct d3dx_effect *effect;
157 struct list entry;
158 size_t size;
159 size_t offset;
160 BYTE *buffer;
163 struct d3dx_recorded_parameter
165 struct d3dx_parameter *param;
166 unsigned int bytes;
169 struct d3dx_effect
171 ID3DXEffect ID3DXEffect_iface;
172 LONG ref;
174 unsigned int parameter_count;
175 unsigned int technique_count;
176 unsigned int object_count;
177 struct d3dx_top_level_parameter *parameters;
178 struct d3dx_technique *techniques;
179 struct d3dx_object *objects;
180 DWORD flags;
182 struct wine_rb_tree param_tree;
183 char *full_name_tmp;
184 unsigned int full_name_tmp_size;
186 struct ID3DXEffectStateManager *manager;
187 struct IDirect3DDevice9 *device;
188 struct d3dx_effect_pool *pool;
189 struct d3dx_technique *active_technique;
190 struct d3dx_pass *active_pass;
191 BOOL started;
192 DWORD begin_flags;
193 ULONG64 version_counter;
195 D3DLIGHT9 current_light[8];
196 unsigned int light_updated;
197 D3DMATERIAL9 current_material;
198 BOOL material_updated;
200 struct list parameter_block_list;
201 struct d3dx_parameter_block *current_parameter_block;
204 #define INITIAL_SHARED_DATA_SIZE 4
206 struct d3dx_effect_pool
208 ID3DXEffectPool ID3DXEffectPool_iface;
209 LONG refcount;
211 struct d3dx_shared_data *shared_data;
212 unsigned int size;
214 ULONG64 version_counter;
217 struct ID3DXEffectCompilerImpl
219 ID3DXEffectCompiler ID3DXEffectCompiler_iface;
220 LONG ref;
223 static HRESULT d3dx_parse_state(struct d3dx_effect *effect, struct d3dx_state *state,
224 const char *data, const char **ptr, struct d3dx_object *objects);
225 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
227 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param);
229 static const struct
231 enum STATE_CLASS class;
232 UINT op;
233 const char *name;
235 state_table[] =
237 /* Render states */
238 {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
239 {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
240 {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
241 {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
242 {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
243 {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
244 {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
245 {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
246 {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
247 {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
248 {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
249 {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
250 {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
251 {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
252 {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
253 {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
254 {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
255 {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
256 {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
257 {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
258 {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
259 {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
260 {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
261 {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
262 {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
263 {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
264 {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
265 {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
266 {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
267 {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
268 {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
269 {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
270 {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
271 {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
272 {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
273 {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
274 {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
275 {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
276 {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
277 {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
278 {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
279 {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
280 {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
281 {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
282 {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
283 {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
284 {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
285 {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
286 {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
287 {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
288 {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
289 {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
290 {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
291 {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
292 {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
293 {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
294 {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
295 {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
296 {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
297 {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
298 {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
299 {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
300 {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
301 {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
302 {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
303 {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
304 {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
305 {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
306 {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
307 {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
308 {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
309 {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
310 {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
311 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
312 {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
313 {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
314 {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
315 {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
316 {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
317 {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
318 {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
319 {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
320 {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
321 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
322 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
323 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
324 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
325 {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
326 {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
327 {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
328 {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
329 {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
330 {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
331 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
332 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
333 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
334 {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
335 {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
336 {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
337 {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
338 {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
339 {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
340 {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
341 /* Texture stages */
342 {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
343 {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
344 {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
345 {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
346 {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
347 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
348 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
349 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
350 {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
351 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
352 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
353 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
354 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
355 {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
356 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
357 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
358 {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
359 {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
360 /* NPatchMode */
361 {SC_NPATCHMODE, 0, "NPatchMode"},
362 /* FVF */
363 {SC_FVF, 0, "FVF"},
364 /* Transform */
365 {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
366 {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
367 {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
368 {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
369 /* Material */
370 {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
371 {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
372 {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
373 {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
374 {SC_MATERIAL, MT_POWER, "MaterialPower"},
375 /* Light */
376 {SC_LIGHT, LT_TYPE, "LightType"},
377 {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
378 {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
379 {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
380 {SC_LIGHT, LT_POSITION, "LightPosition"},
381 {SC_LIGHT, LT_DIRECTION, "LightDirection"},
382 {SC_LIGHT, LT_RANGE, "LightRange"},
383 {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
384 {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
385 {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
386 {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
387 {SC_LIGHT, LT_THETA, "LightTheta"},
388 {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
389 /* Lightenable */
390 {SC_LIGHTENABLE, 0, "LightEnable"},
391 /* Vertexshader */
392 {SC_VERTEXSHADER, 0, "Vertexshader"},
393 /* Pixelshader */
394 {SC_PIXELSHADER, 0, "Pixelshader"},
395 /* Shader constants */
396 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
397 {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
398 {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
399 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
400 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
401 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
402 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
403 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
404 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
405 {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
406 {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
407 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
408 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
409 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
410 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
411 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
412 /* Texture */
413 {SC_TEXTURE, 0, "Texture"},
414 /* Sampler states */
415 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
416 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
417 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
418 {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
419 {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
420 {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
421 {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
422 {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
423 {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
424 {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
425 {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
426 {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
427 {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
428 /* Set sampler */
429 {SC_SETSAMPLER, 0, "Sampler"},
432 static inline void read_dword(const char **ptr, DWORD *d)
434 memcpy(d, *ptr, sizeof(*d));
435 *ptr += sizeof(*d);
438 static void skip_dword_unknown(const char **ptr, unsigned int count)
440 unsigned int i;
441 DWORD d;
443 WARN("Skipping %u unknown DWORDs:\n", count);
444 for (i = 0; i < count; ++i)
446 read_dword(ptr, &d);
447 WARN("\t0x%08x\n", d);
451 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
453 return (D3DXHANDLE)parameter;
456 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
458 return (D3DXHANDLE)technique;
461 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
463 return (D3DXHANDLE)pass;
466 static struct d3dx_technique *get_technique_by_name(struct d3dx_effect *effect, const char *name)
468 unsigned int i;
470 if (!name) return NULL;
472 for (i = 0; i < effect->technique_count; ++i)
474 if (!strcmp(effect->techniques[i].name, name))
475 return &effect->techniques[i];
478 return NULL;
481 static struct d3dx_technique *get_valid_technique(struct d3dx_effect *effect, D3DXHANDLE technique)
483 unsigned int i;
485 for (i = 0; i < effect->technique_count; ++i)
487 if (get_technique_handle(&effect->techniques[i]) == technique)
488 return &effect->techniques[i];
491 return get_technique_by_name(effect, technique);
494 static struct d3dx_pass *get_valid_pass(struct d3dx_effect *effect, D3DXHANDLE pass)
496 unsigned int i, k;
498 for (i = 0; i < effect->technique_count; ++i)
500 struct d3dx_technique *technique = &effect->techniques[i];
502 for (k = 0; k < technique->pass_count; ++k)
504 if (get_pass_handle(&technique->passes[k]) == pass)
505 return &technique->passes[k];
509 return NULL;
512 static struct d3dx_parameter *get_valid_parameter(struct d3dx_effect *effect, D3DXHANDLE parameter)
514 struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter;
516 if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string,
517 sizeof(parameter_magic_string)))
518 return handle_param;
520 return effect->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(effect, NULL, parameter);
523 static struct d3dx_parameter_block *get_valid_parameter_block(D3DXHANDLE handle)
525 struct d3dx_parameter_block *block = (struct d3dx_parameter_block *)handle;
527 return block && !strncmp(block->magic_string, parameter_block_magic_string,
528 sizeof(parameter_block_magic_string)) ? block : NULL;
531 static void free_state(struct d3dx_state *state)
533 free_parameter(&state->parameter, FALSE, FALSE);
536 static void free_object(struct d3dx_object *object)
538 HeapFree(GetProcessHeap(), 0, object->data);
541 static void free_sampler(struct d3dx_sampler *sampler)
543 UINT i;
545 for (i = 0; i < sampler->state_count; ++i)
547 free_state(&sampler->states[i]);
549 heap_free(sampler->states);
552 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param);
554 static void free_parameter_object_data(struct d3dx_parameter *param, const void *data, unsigned int bytes)
556 unsigned int i, count;
558 if (param->class != D3DXPC_OBJECT)
559 return;
561 count = min(param->element_count ? param->element_count : 1, bytes / sizeof(void *));
563 for (i = 0; i < count; ++i)
565 switch (param->type)
567 case D3DXPT_STRING:
568 heap_free(((char **)data)[i]);
569 break;
571 case D3DXPT_TEXTURE:
572 case D3DXPT_TEXTURE1D:
573 case D3DXPT_TEXTURE2D:
574 case D3DXPT_TEXTURE3D:
575 case D3DXPT_TEXTURECUBE:
576 case D3DXPT_PIXELSHADER:
577 case D3DXPT_VERTEXSHADER:
578 if (*(IUnknown **)data)
579 IUnknown_Release(((IUnknown **)data)[i]);
580 break;
582 case D3DXPT_SAMPLER:
583 case D3DXPT_SAMPLER1D:
584 case D3DXPT_SAMPLER2D:
585 case D3DXPT_SAMPLER3D:
586 case D3DXPT_SAMPLERCUBE:
587 assert(count == 1);
588 free_sampler((struct d3dx_sampler *)data);
589 return;
591 default:
592 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
593 break;
598 static void free_parameter_data(struct d3dx_parameter *param, BOOL child)
600 if (!param->data)
601 return;
603 if (!param->element_count)
604 free_parameter_object_data(param, param->data, param->bytes);
606 if (!child || is_param_type_sampler(param->type))
607 heap_free(param->data);
610 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child)
612 unsigned int i;
614 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name,
615 debug_d3dxparameter_type(param->type), element, child);
617 if (param->param_eval)
618 d3dx_free_param_eval(param->param_eval);
620 if (param->members)
622 unsigned int count = param->element_count ? param->element_count : param->member_count;
624 for (i = 0; i < count; ++i)
625 free_parameter(&param->members[i], param->element_count != 0, TRUE);
626 HeapFree(GetProcessHeap(), 0, param->members);
629 heap_free(param->full_name);
630 free_parameter_data(param, child);
632 /* only the parent has to release name and semantic */
633 if (!element)
635 HeapFree(GetProcessHeap(), 0, param->name);
636 HeapFree(GetProcessHeap(), 0, param->semantic);
640 static void free_top_level_parameter(struct d3dx_top_level_parameter *param)
642 if (param->annotations)
644 unsigned int i;
646 for (i = 0; i < param->annotation_count; ++i)
647 free_parameter(&param->annotations[i], FALSE, FALSE);
648 HeapFree(GetProcessHeap(), 0, param->annotations);
650 d3dx_pool_release_shared_parameter(param);
651 free_parameter(&param->param, FALSE, FALSE);
654 static void free_pass(struct d3dx_pass *pass)
656 unsigned int i;
658 TRACE("Free pass %p\n", pass);
660 if (!pass)
661 return;
663 if (pass->annotations)
665 for (i = 0; i < pass->annotation_count; ++i)
666 free_parameter(&pass->annotations[i], FALSE, FALSE);
667 HeapFree(GetProcessHeap(), 0, pass->annotations);
668 pass->annotations = NULL;
671 if (pass->states)
673 for (i = 0; i < pass->state_count; ++i)
674 free_state(&pass->states[i]);
675 HeapFree(GetProcessHeap(), 0, pass->states);
676 pass->states = NULL;
679 HeapFree(GetProcessHeap(), 0, pass->name);
680 pass->name = NULL;
683 static void free_technique(struct d3dx_technique *technique)
685 unsigned int i;
687 TRACE("Free technique %p\n", technique);
689 if (!technique)
690 return;
692 if (technique->saved_state)
694 IDirect3DStateBlock9_Release(technique->saved_state);
695 technique->saved_state = NULL;
698 if (technique->annotations)
700 for (i = 0; i < technique->annotation_count; ++i)
701 free_parameter(&technique->annotations[i], FALSE, FALSE);
702 HeapFree(GetProcessHeap(), 0, technique->annotations);
703 technique->annotations = NULL;
706 if (technique->passes)
708 for (i = 0; i < technique->pass_count; ++i)
709 free_pass(&technique->passes[i]);
710 HeapFree(GetProcessHeap(), 0, technique->passes);
711 technique->passes = NULL;
714 HeapFree(GetProcessHeap(), 0, technique->name);
715 technique->name = NULL;
718 static unsigned int get_recorded_parameter_size(const struct d3dx_recorded_parameter *record)
720 return sizeof(*record) + record->bytes;
723 static void free_parameter_block(struct d3dx_parameter_block *block)
725 struct d3dx_recorded_parameter *record;
727 if (!block)
728 return;
730 record = (struct d3dx_recorded_parameter *)block->buffer;
731 while ((BYTE *)record < block->buffer + block->offset)
733 free_parameter_object_data(record->param, record + 1, record->bytes);
734 record = (struct d3dx_recorded_parameter *)((BYTE *)record + get_recorded_parameter_size(record));
736 assert((BYTE *)record == block->buffer + block->offset);
738 heap_free(block->buffer);
739 heap_free(block);
742 static void d3dx_effect_cleanup(struct d3dx_effect *effect)
744 struct d3dx_parameter_block *block, *cursor;
745 ID3DXEffectPool *pool;
746 unsigned int i;
748 TRACE("effect %p.\n", effect);
750 free_parameter_block(effect->current_parameter_block);
751 LIST_FOR_EACH_ENTRY_SAFE(block, cursor, &effect->parameter_block_list, struct d3dx_parameter_block, entry)
753 list_remove(&block->entry);
754 free_parameter_block(block);
757 heap_free(effect->full_name_tmp);
759 if (effect->parameters)
761 for (i = 0; i < effect->parameter_count; ++i)
762 free_top_level_parameter(&effect->parameters[i]);
763 heap_free(effect->parameters);
766 if (effect->techniques)
768 for (i = 0; i < effect->technique_count; ++i)
769 free_technique(&effect->techniques[i]);
770 heap_free(effect->techniques);
773 if (effect->objects)
775 for (i = 0; i < effect->object_count; ++i)
776 free_object(&effect->objects[i]);
777 heap_free(effect->objects);
780 if (effect->pool)
782 pool = &effect->pool->ID3DXEffectPool_iface;
783 pool->lpVtbl->Release(pool);
786 if (effect->manager)
787 IUnknown_Release(effect->manager);
789 IDirect3DDevice9_Release(effect->device);
790 heap_free(effect);
793 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
795 UINT i;
797 for (i = 0; i < 4; ++i)
799 if (i < param->columns)
800 set_number((FLOAT *)vector + i, D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
801 else
802 ((FLOAT *)vector)[i] = 0.0f;
806 static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector, void *dst_data)
808 UINT i;
810 for (i = 0; i < param->columns; ++i)
811 set_number((FLOAT *)dst_data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
814 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
816 UINT i, k;
818 for (i = 0; i < 4; ++i)
820 for (k = 0; k < 4; ++k)
822 FLOAT *tmp = transpose ? (FLOAT *)&matrix->u.m[k][i] : (FLOAT *)&matrix->u.m[i][k];
824 if ((i < param->rows) && (k < param->columns))
825 set_number(tmp, D3DXPT_FLOAT, (DWORD *)param->data + i * param->columns + k, param->type);
826 else
827 *tmp = 0.0f;
832 static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix, void *dst_data)
834 UINT i, k;
836 if (param->type == D3DXPT_FLOAT)
838 if (param->columns == 4)
840 memcpy(dst_data, matrix->u.m, param->rows * 4 * sizeof(float));
842 else
844 for (i = 0; i < param->rows; ++i)
845 memcpy((float *)dst_data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float));
847 return;
850 for (i = 0; i < param->rows; ++i)
852 for (k = 0; k < param->columns; ++k)
853 set_number((FLOAT *)dst_data + i * param->columns + k, param->type,
854 &matrix->u.m[i][k], D3DXPT_FLOAT);
858 static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix, void *dst_data)
860 UINT i, k;
862 for (i = 0; i < param->rows; ++i)
864 for (k = 0; k < param->columns; ++k)
866 set_number((FLOAT *)dst_data + i * param->columns + k, param->type,
867 &matrix->u.m[k][i], D3DXPT_FLOAT);
872 static HRESULT set_string(char **param_data, const char *string)
874 heap_free(*param_data);
875 *param_data = heap_alloc(strlen(string) + 1);
876 if (!*param_data)
878 ERR("Out of memory.\n");
879 return E_OUTOFMEMORY;
881 strcpy(*param_data, string);
882 return D3D_OK;
885 static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigned int bytes,
886 void *dst_data)
888 unsigned int i, count;
890 bytes = min(bytes, param->bytes);
891 count = min(param->element_count ? param->element_count : 1, bytes / sizeof(void *));
893 switch (param->type)
895 case D3DXPT_TEXTURE:
896 case D3DXPT_TEXTURE1D:
897 case D3DXPT_TEXTURE2D:
898 case D3DXPT_TEXTURE3D:
899 case D3DXPT_TEXTURECUBE:
900 for (i = 0; i < count; ++i)
902 IUnknown *old_texture = ((IUnknown **)dst_data)[i];
903 IUnknown *new_texture = ((IUnknown **)data)[i];
905 if (new_texture == old_texture)
906 continue;
908 if (new_texture)
909 IUnknown_AddRef(new_texture);
910 if (old_texture)
911 IUnknown_Release(old_texture);
913 /* fallthrough */
914 case D3DXPT_VOID:
915 case D3DXPT_BOOL:
916 case D3DXPT_INT:
917 case D3DXPT_FLOAT:
918 TRACE("Copy %u bytes.\n", bytes);
919 memcpy(dst_data, data, bytes);
920 break;
922 case D3DXPT_STRING:
924 HRESULT hr;
926 for (i = 0; i < count; ++i)
927 if (FAILED(hr = set_string(&((char **)dst_data)[i], ((const char **)data)[i])))
928 return hr;
929 break;
932 default:
933 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
934 break;
937 return D3D_OK;
940 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_effect *effect,
941 struct d3dx_parameter *parameter, const char *name)
943 UINT element;
944 struct d3dx_parameter *temp_parameter;
945 const char *part;
947 TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
949 if (!name || !*name) return NULL;
951 element = atoi(name);
952 part = strchr(name, ']') + 1;
954 /* check for empty [] && element range */
955 if ((part - name) > 1 && parameter->element_count > element)
957 temp_parameter = &parameter->members[element];
959 switch (*part++)
961 case '.':
962 return get_parameter_by_name(effect, temp_parameter, part);
964 case '\0':
965 TRACE("Returning parameter %p\n", temp_parameter);
966 return temp_parameter;
968 default:
969 FIXME("Unhandled case \"%c\"\n", *--part);
970 break;
974 TRACE("Parameter not found\n");
975 return NULL;
978 static struct d3dx_parameter *get_annotation_by_name(struct d3dx_effect *effect, unsigned int count,
979 struct d3dx_parameter *annotations, const char *name)
981 UINT i, length;
982 struct d3dx_parameter *temp_parameter;
983 const char *part;
985 TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name));
987 if (!name || !*name) return NULL;
989 length = strcspn( name, "[.@" );
990 part = name + length;
992 for (i = 0; i < count; ++i)
994 temp_parameter = &annotations[i];
996 if (!strcmp(temp_parameter->name, name))
998 TRACE("Returning annotation %p\n", temp_parameter);
999 return temp_parameter;
1001 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1003 switch (*part++)
1005 case '.':
1006 return get_parameter_by_name(effect, temp_parameter, part);
1008 case '[':
1009 return get_parameter_element_by_name(effect, temp_parameter, part);
1011 default:
1012 FIXME("Unhandled case \"%c\"\n", *--part);
1013 break;
1018 TRACE("Annotation not found\n");
1019 return NULL;
1022 struct d3dx_parameter *get_parameter_by_name(struct d3dx_effect* effect,
1023 struct d3dx_parameter *parameter, const char *name)
1025 struct d3dx_parameter *temp_parameter;
1026 unsigned int name_len, param_name_len;
1027 unsigned int i, count, length;
1028 struct wine_rb_entry *entry;
1029 unsigned int full_name_size;
1030 const char *part;
1031 char *full_name;
1033 TRACE("effect %p, parameter %p, name %s.\n", effect, parameter, debugstr_a(name));
1035 if (!name || !*name) return NULL;
1037 if (!parameter)
1039 if ((entry = wine_rb_get(&effect->param_tree, name)))
1040 return WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
1041 return NULL;
1044 if (parameter->full_name)
1046 name_len = strlen(name);
1047 param_name_len = strlen(parameter->full_name);
1048 full_name_size = name_len + param_name_len + 2;
1049 if (effect->full_name_tmp_size < full_name_size)
1051 if (!(full_name = heap_realloc(effect->full_name_tmp, full_name_size)))
1053 ERR("Out of memory.\n");
1054 return NULL;
1056 effect->full_name_tmp = full_name;
1057 effect->full_name_tmp_size = full_name_size;
1059 else
1061 full_name = effect->full_name_tmp;
1063 memcpy(full_name, parameter->full_name, param_name_len);
1064 full_name[param_name_len] = '.';
1065 memcpy(full_name + param_name_len + 1, name, name_len);
1066 full_name[param_name_len + 1 + name_len] = 0;
1068 if ((entry = wine_rb_get(&effect->param_tree, full_name)))
1069 return WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
1070 return NULL;
1073 /* Pass / technique annotations are not stored in the parameters tree,
1074 * do a linear search. */
1075 count = parameter->member_count;
1077 length = strcspn( name, "[." );
1078 part = name + length;
1080 for (i = 0; i < count; i++)
1082 temp_parameter = &parameter->members[i];
1084 if (!strcmp(temp_parameter->name, name))
1086 TRACE("Returning parameter %p\n", temp_parameter);
1087 return temp_parameter;
1089 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1091 switch (*part++)
1093 case '.':
1094 return get_parameter_by_name(effect, temp_parameter, part);
1096 case '[':
1097 return get_parameter_element_by_name(effect, temp_parameter, part);
1099 default:
1100 FIXME("Unhandled case \"%c\"\n", *--part);
1101 break;
1106 TRACE("Parameter not found\n");
1107 return NULL;
1110 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
1112 return (0xfeff0000 | ((major) << 8) | (minor));
1115 static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
1116 void **param_value, struct d3dx_parameter **out_param,
1117 BOOL update_all, BOOL *param_dirty)
1119 struct d3dx_parameter *param = &state->parameter;
1121 *param_value = NULL;
1122 *out_param = NULL;
1123 *param_dirty = FALSE;
1125 switch (state->type)
1127 case ST_PARAMETER:
1128 param = state->referenced_param;
1129 *param_dirty = is_param_dirty(param, pass->update_version);
1130 /* fallthrough */
1131 case ST_CONSTANT:
1132 *out_param = param;
1133 *param_value = param->data;
1134 return D3D_OK;
1135 case ST_ARRAY_SELECTOR:
1137 unsigned int array_idx;
1138 static const struct d3dx_parameter array_idx_param =
1139 {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)};
1140 HRESULT hr;
1141 struct d3dx_parameter *ref_param, *selected_param;
1143 if (!param->param_eval)
1145 FIXME("Preshader structure is null.\n");
1146 return D3DERR_INVALIDCALL;
1148 /* We override with the update_version of the pass because we want
1149 * to force index recomputation and check for out of bounds. */
1150 if (is_param_eval_input_dirty(param->param_eval, pass->update_version))
1152 if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
1153 return hr;
1155 else
1157 array_idx = state->index;
1159 ref_param = state->referenced_param;
1160 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
1161 ref_param->element_count);
1162 /* According to the tests, native d3dx handles the case of array index evaluated to -1
1163 * in a specific way, always selecting first array element and not returning error. */
1164 if (array_idx == ~0u)
1166 WARN("Array index is -1, setting to 0.\n");
1167 array_idx = 0;
1170 if (array_idx >= ref_param->element_count)
1172 WARN("Computed array index %u is larger than array size %u.\n",
1173 array_idx, ref_param->element_count);
1174 return E_FAIL;
1176 selected_param = &ref_param->members[array_idx];
1177 *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
1178 state->index = array_idx;
1180 *param_value = selected_param->data;
1181 *out_param = selected_param;
1182 return D3D_OK;
1184 case ST_FXLC:
1185 if (param->param_eval)
1187 *out_param = param;
1188 *param_value = param->data;
1189 /* We check with the update_version of the pass because the
1190 * same preshader might be used by both the vertex and the
1191 * pixel shader (that can happen e.g. for sampler states). */
1192 if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version))
1194 *param_dirty = TRUE;
1195 return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
1197 else
1198 return D3D_OK;
1200 else
1202 FIXME("No preshader for FXLC parameter.\n");
1203 return D3DERR_INVALIDCALL;
1206 return E_NOTIMPL;
1209 static unsigned int get_annotation_from_object(struct d3dx_effect *effect, D3DXHANDLE object,
1210 struct d3dx_parameter **annotations)
1212 struct d3dx_parameter *param = get_valid_parameter(effect, object);
1213 struct d3dx_pass *pass = get_valid_pass(effect, object);
1214 struct d3dx_technique *technique = get_valid_technique(effect, object);
1216 if (pass)
1218 *annotations = pass->annotations;
1219 return pass->annotation_count;
1221 else if (technique)
1223 *annotations = technique->annotations;
1224 return technique->annotation_count;
1226 else if (param)
1228 if (is_top_level_parameter(param))
1230 struct d3dx_top_level_parameter *top_param
1231 = top_level_parameter_from_parameter(param);
1233 *annotations = top_param->annotations;
1234 return top_param->annotation_count;
1236 else
1238 *annotations = NULL;
1239 return 0;
1242 else
1244 FIXME("Functions are not handled, yet!\n");
1245 return 0;
1249 static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
1250 void *data)
1252 unsigned int i;
1253 unsigned int member_count;
1255 if (param_func(data, param))
1256 return TRUE;
1258 member_count = param->element_count ? param->element_count : param->member_count;
1259 for (i = 0; i < member_count; ++i)
1261 if (walk_parameter_tree(&param->members[i], param_func, data))
1262 return TRUE;
1264 return FALSE;
1267 static ULONG64 *get_version_counter_ptr(struct d3dx_effect *effect)
1269 return effect->pool ? &effect->pool->version_counter : &effect->version_counter;
1272 static ULONG64 next_effect_update_version(struct d3dx_effect *effect)
1274 return next_update_version(get_version_counter_ptr(effect));
1277 static void *record_parameter(struct d3dx_effect *effect, struct d3dx_parameter *param, unsigned int bytes)
1279 struct d3dx_parameter_block *block = effect->current_parameter_block;
1280 struct d3dx_recorded_parameter new_record, *record;
1281 unsigned int new_size, alloc_size;
1283 new_record.param = param;
1284 new_record.bytes = bytes;
1285 new_size = block->offset + get_recorded_parameter_size(&new_record);
1287 if (new_size > block->size)
1289 BYTE *new_alloc;
1291 alloc_size = max(block->size * 2, max(new_size, INITIAL_PARAM_BLOCK_SIZE));
1292 if (block->size)
1293 new_alloc = heap_realloc(block->buffer, alloc_size);
1294 else
1295 new_alloc = heap_alloc(alloc_size);
1297 if (!new_alloc)
1299 ERR("Out of memory.\n");
1300 return param->data;
1302 /* Data update functions may want to free some references upon setting value. */
1303 memset(new_alloc + block->size, 0, alloc_size - block->size);
1305 block->size = alloc_size;
1306 block->buffer = new_alloc;
1308 record = (struct d3dx_recorded_parameter *)(block->buffer + block->offset);
1309 *record = new_record;
1310 block->offset = new_size;
1311 return record + 1;
1314 static void set_dirty(struct d3dx_parameter *param)
1316 struct d3dx_shared_data *shared_data;
1317 struct d3dx_top_level_parameter *top_param = param->top_level_param;
1318 ULONG64 new_update_version = next_update_version(top_param->version_counter);
1320 if ((shared_data = top_param->shared_data))
1321 shared_data->update_version = new_update_version;
1322 else
1323 top_param->update_version = new_update_version;
1326 static void *param_get_data_and_dirtify(struct d3dx_effect *effect, struct d3dx_parameter *param,
1327 unsigned int bytes, BOOL value_changed)
1329 assert(bytes <= param->bytes);
1331 if (value_changed && !effect->current_parameter_block)
1332 set_dirty(param);
1334 return effect->current_parameter_block ? record_parameter(effect, param, bytes) : param->data;
1337 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
1339 static const struct
1341 unsigned int offset;
1342 const char *name;
1344 light_tbl[] =
1346 {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
1347 {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
1348 {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
1349 {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
1350 {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
1351 {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
1352 {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
1353 {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
1354 {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
1355 {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
1356 {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
1357 {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
1358 {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
1360 switch (op)
1362 case LT_TYPE:
1363 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
1364 light->Type = *(D3DLIGHTTYPE *)value;
1365 break;
1366 case LT_DIFFUSE:
1367 case LT_SPECULAR:
1368 case LT_AMBIENT:
1370 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
1372 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
1373 *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
1374 break;
1376 case LT_POSITION:
1377 case LT_DIRECTION:
1379 D3DVECTOR v = *(D3DVECTOR *)value;
1381 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
1382 *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
1383 break;
1385 case LT_RANGE:
1386 case LT_FALLOFF:
1387 case LT_ATTENUATION0:
1388 case LT_ATTENUATION1:
1389 case LT_ATTENUATION2:
1390 case LT_THETA:
1391 case LT_PHI:
1393 float v = *(float *)value;
1394 TRACE("%s %.8e.\n", light_tbl[op].name, v);
1395 *(float *)((BYTE *)light + light_tbl[op].offset) = v;
1396 break;
1398 default:
1399 WARN("Unknown light parameter %u.\n", op);
1400 break;
1404 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
1406 static const struct
1408 unsigned int offset;
1409 const char *name;
1411 material_tbl[] =
1413 {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
1414 {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
1415 {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
1416 {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
1417 {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
1420 switch (op)
1422 case MT_POWER:
1424 float v = *(float *)value;
1426 TRACE("%s %.8e.\n", material_tbl[op].name, v);
1427 material->Power = v;
1428 break;
1430 case MT_DIFFUSE:
1431 case MT_AMBIENT:
1432 case MT_SPECULAR:
1433 case MT_EMISSIVE:
1435 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
1437 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
1438 *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
1439 break;
1441 default:
1442 WARN("Unknown material parameter %u.\n", op);
1443 break;
1447 static HRESULT d3dx_set_shader_const_state(struct d3dx_effect *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
1448 struct d3dx_parameter *param, void *value_ptr)
1450 static const struct
1452 D3DXPARAMETER_TYPE type;
1453 UINT elem_size;
1454 const char *name;
1456 const_tbl[] =
1458 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
1459 {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
1460 {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
1461 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
1462 {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
1463 {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
1466 BOOL is_heap_buffer = FALSE;
1467 unsigned int element_count;
1468 void *buffer = value_ptr;
1469 D3DXVECTOR4 value;
1470 HRESULT ret;
1472 assert(op < ARRAY_SIZE(const_tbl));
1473 element_count = param->bytes / const_tbl[op].elem_size;
1474 TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
1475 if (param->type != const_tbl[op].type)
1477 FIXME("Unexpected param type %u.\n", param->type);
1478 return D3DERR_INVALIDCALL;
1481 if (param->bytes % const_tbl[op].elem_size || element_count > 1)
1483 unsigned int param_data_size;
1485 TRACE("Parameter size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
1487 if (param->bytes % const_tbl[op].elem_size)
1488 ++element_count;
1489 if (element_count > 1)
1491 WARN("Setting %u elements.\n", element_count);
1492 buffer = HeapAlloc(GetProcessHeap(), 0, const_tbl[op].elem_size * element_count);
1493 if (!buffer)
1495 ERR("Out of memory.\n");
1496 return E_OUTOFMEMORY;
1498 is_heap_buffer = TRUE;
1500 else
1502 assert(const_tbl[op].elem_size <= sizeof(value));
1503 buffer = &value;
1505 param_data_size = min(param->bytes, const_tbl[op].elem_size);
1506 memcpy(buffer, value_ptr, param_data_size);
1507 memset((unsigned char *)buffer + param_data_size, 0,
1508 const_tbl[op].elem_size * element_count - param_data_size);
1511 switch (op)
1513 case SCT_VSFLOAT:
1514 ret = SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)buffer, element_count);
1515 break;
1516 case SCT_VSBOOL:
1517 ret = SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)buffer, element_count);
1518 break;
1519 case SCT_VSINT:
1520 ret = SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)buffer, element_count);
1521 break;
1522 case SCT_PSFLOAT:
1523 ret = SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)buffer, element_count);
1524 break;
1525 case SCT_PSBOOL:
1526 ret = SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)buffer, element_count);
1527 break;
1528 case SCT_PSINT:
1529 ret = SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)buffer, element_count);
1530 break;
1531 default:
1532 ret = D3DERR_INVALIDCALL;
1533 break;
1536 if (is_heap_buffer)
1537 HeapFree(GetProcessHeap(), 0, buffer);
1539 return ret;
1542 static HRESULT d3dx9_apply_state(struct d3dx_effect *effect, struct d3dx_pass *pass,
1543 struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
1545 static HRESULT d3dx_set_shader_constants(struct d3dx_effect *effect, struct d3dx_pass *pass,
1546 struct d3dx_parameter *param, BOOL vs, BOOL update_all)
1548 HRESULT hr, ret;
1549 struct d3dx_parameter **params;
1550 D3DXCONSTANT_DESC *cdesc;
1551 unsigned int parameters_count;
1552 unsigned int i, j;
1554 if (!param->param_eval)
1556 FIXME("param_eval structure is null.\n");
1557 return D3DERR_INVALIDCALL;
1559 if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
1560 param->param_eval, update_all)))
1561 return hr;
1562 params = param->param_eval->shader_inputs.inputs_param;
1563 cdesc = param->param_eval->shader_inputs.inputs;
1564 parameters_count = param->param_eval->shader_inputs.input_count;
1565 ret = D3D_OK;
1566 for (i = 0; i < parameters_count; ++i)
1568 if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
1570 struct d3dx_sampler *sampler;
1571 unsigned int sampler_idx;
1573 for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
1575 sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
1576 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
1577 cdesc[i].RegisterIndex, sampler->state_count);
1578 for (j = 0; j < sampler->state_count; ++j)
1580 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
1581 cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
1582 update_all)))
1583 ret = hr;
1588 return ret;
1591 static HRESULT d3dx9_apply_state(struct d3dx_effect *effect, struct d3dx_pass *pass,
1592 struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
1594 struct d3dx_parameter *param;
1595 void *param_value;
1596 BOOL param_dirty;
1597 HRESULT hr;
1599 TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
1601 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
1602 update_all, &param_dirty)))
1604 if (!update_all && hr == E_FAIL)
1606 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
1607 * out of bounds array access and does not touch the affected
1608 * states. */
1609 WARN("Returning D3D_OK on out of bounds array access.\n");
1610 return D3D_OK;
1612 return hr;
1615 if (!(update_all || param_dirty
1616 || state_table[state->operation].class == SC_VERTEXSHADER
1617 || state_table[state->operation].class == SC_PIXELSHADER
1618 || state_table[state->operation].class == SC_SETSAMPLER))
1619 return D3D_OK;
1621 switch (state_table[state->operation].class)
1623 case SC_RENDERSTATE:
1624 TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
1625 state_table[state->operation].op, *(DWORD *)param_value);
1626 return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
1627 case SC_FVF:
1628 TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
1629 return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
1630 case SC_TEXTURE:
1632 UINT unit;
1634 unit = parent_index == ~0u ? state->index : parent_index;
1635 TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
1636 *(IDirect3DBaseTexture9 **)param_value);
1637 return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
1639 case SC_TEXTURESTAGE:
1640 TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
1641 return SET_D3D_STATE(effect, SetTextureStageState, state->index,
1642 state_table[state->operation].op, *(DWORD *)param_value);
1643 case SC_SETSAMPLER:
1645 struct d3dx_sampler *sampler;
1646 HRESULT ret, hr;
1647 unsigned int i;
1649 sampler = (struct d3dx_sampler *)param_value;
1650 TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
1651 sampler->state_count);
1652 ret = D3D_OK;
1653 for (i = 0; i < sampler->state_count; i++)
1655 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
1656 ret = hr;
1658 return ret;
1660 case SC_SAMPLERSTATE:
1662 UINT sampler;
1664 sampler = parent_index == ~0u ? state->index : parent_index;
1665 TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
1666 return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
1667 *(DWORD *)param_value);
1669 case SC_VERTEXSHADER:
1670 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
1671 if ((update_all || param_dirty)
1672 && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
1673 *(IDirect3DVertexShader9 **)param_value)))
1674 ERR("Could not set vertex shader, hr %#x.\n", hr);
1675 else if (*(IDirect3DVertexShader9 **)param_value)
1676 hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
1677 return hr;
1678 case SC_PIXELSHADER:
1679 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
1680 if ((update_all || param_dirty)
1681 && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
1682 *(IDirect3DPixelShader9 **)param_value)))
1683 ERR("Could not set pixel shader, hr %#x.\n", hr);
1684 else if (*(IDirect3DPixelShader9 **)param_value)
1685 hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
1686 return hr;
1687 case SC_TRANSFORM:
1688 TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
1689 return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
1690 (D3DMATRIX *)param_value);
1691 case SC_LIGHTENABLE:
1692 TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
1693 return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
1694 case SC_LIGHT:
1696 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
1697 state_table[state->operation].op);
1698 d3dx9_set_light_parameter(state_table[state->operation].op,
1699 &effect->current_light[state->index], param_value);
1700 effect->light_updated |= 1u << state->index;
1701 return D3D_OK;
1703 case SC_MATERIAL:
1705 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
1706 state_table[state->operation].op);
1707 d3dx9_set_material_parameter(state_table[state->operation].op,
1708 &effect->current_material, param_value);
1709 effect->material_updated = TRUE;
1710 return D3D_OK;
1712 case SC_NPATCHMODE:
1713 TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
1714 return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
1715 case SC_SHADERCONST:
1716 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
1717 state_table[state->operation].op);
1718 return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
1719 param, param_value);
1720 default:
1721 FIXME("%s not handled.\n", state_table[state->operation].name);
1722 break;
1724 return D3D_OK;
1727 static HRESULT d3dx9_apply_pass_states(struct d3dx_effect *effect, struct d3dx_pass *pass, BOOL update_all)
1729 unsigned int i;
1730 HRESULT ret;
1731 HRESULT hr;
1732 ULONG64 new_update_version = next_effect_update_version(effect);
1734 TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
1736 ret = D3D_OK;
1737 for (i = 0; i < pass->state_count; ++i)
1739 if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
1741 WARN("Error applying state, hr %#x.\n", hr);
1742 ret = hr;
1746 if (effect->light_updated)
1748 for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
1750 if ((effect->light_updated & (1u << i))
1751 && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
1753 WARN("Error setting light, hr %#x.\n", hr);
1754 ret = hr;
1757 effect->light_updated = 0;
1760 if (effect->material_updated
1761 && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
1763 WARN("Error setting material, hr %#x.\n", hr);
1764 ret = hr;
1766 effect->material_updated = FALSE;
1768 pass->update_version = new_update_version;
1769 return ret;
1772 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
1774 unsigned char *member_data = data;
1775 unsigned int i, count;
1777 count = param->element_count ? param->element_count : param->member_count;
1778 for (i = 0; i < count; ++i)
1780 param_set_data_pointer(&param->members[i], member_data, TRUE, free_data);
1781 if (data)
1782 member_data += param->members[i].bytes;
1784 if (free_data)
1785 free_parameter_data(param, child);
1786 param->data = data;
1789 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
1791 struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
1792 BOOL matches;
1793 unsigned int i, member_count;
1795 matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
1796 && param1->type == param2->type && param1->rows == param2->rows
1797 && param1->columns == param2->columns && param1->element_count == param2->element_count
1798 && param1->member_count == param2->member_count;
1800 member_count = param1->element_count ? param1->element_count : param1->member_count;
1802 if (!matches || !member_count)
1803 return matches;
1805 for (i = 0; i < member_count; ++i)
1807 if (!is_same_parameter(&param1->members[i], &param2->members[i]))
1808 return FALSE;
1810 return TRUE;
1813 static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param)
1815 unsigned int i, free_entry_index;
1816 unsigned int new_size, new_count;
1818 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
1819 return D3D_OK;
1821 free_entry_index = pool->size;
1822 for (i = 0; i < pool->size; ++i)
1824 if (!pool->shared_data[i].count)
1825 free_entry_index = i;
1826 else if (is_same_parameter(&param->param, &pool->shared_data[i].parameters[0]->param))
1827 break;
1829 if (i == pool->size)
1831 i = free_entry_index;
1832 if (i == pool->size)
1834 struct d3dx_shared_data *new_alloc;
1836 if (!pool->size)
1838 new_size = INITIAL_POOL_SIZE;
1839 new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1840 sizeof(*pool->shared_data) * new_size);
1841 if (!new_alloc)
1843 ERR("Out of memory.\n");
1844 return E_OUTOFMEMORY;
1847 else
1849 new_size = pool->size * 2;
1850 new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
1851 sizeof(*pool->shared_data) * new_size);
1852 if (!new_alloc)
1854 ERR("Out of memory.\n");
1855 return E_OUTOFMEMORY;
1857 if (new_alloc != pool->shared_data)
1859 unsigned int j, k;
1861 for (j = 0; j < pool->size; ++j)
1862 for (k = 0; k < new_alloc[j].count; ++k)
1863 new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
1866 pool->shared_data = new_alloc;
1867 pool->size = new_size;
1869 pool->shared_data[i].data = param->param.data;
1871 else
1873 param_set_data_pointer(&param->param, pool->shared_data[i].data, FALSE, TRUE);
1875 new_count = ++pool->shared_data[i].count;
1876 if (new_count >= pool->shared_data[i].size)
1878 if (!pool->shared_data[i].size)
1880 new_size = INITIAL_SHARED_DATA_SIZE;
1881 pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1882 sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
1884 else
1886 new_size = pool->shared_data[i].size * 2;
1887 pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1888 pool->shared_data[i].parameters,
1889 sizeof(*pool->shared_data[i].parameters) * new_size);
1891 pool->shared_data[i].size = new_size;
1894 param->shared_data = &pool->shared_data[i];
1895 pool->shared_data[i].parameters[new_count - 1] = param;
1897 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
1898 new_count);
1900 return D3D_OK;
1903 static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param)
1905 param->data = NULL;
1906 return FALSE;
1909 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param)
1911 unsigned int new_count;
1913 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
1914 return;
1915 new_count = --param->shared_data->count;
1917 TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
1919 if (new_count)
1921 unsigned int i;
1923 for (i = 0; i < new_count; ++i)
1925 if (param->shared_data->parameters[i] == param)
1927 memmove(&param->shared_data->parameters[i],
1928 &param->shared_data->parameters[i + 1],
1929 sizeof(param->shared_data->parameters[i]) * (new_count - i));
1930 break;
1933 walk_parameter_tree(&param->param, param_zero_data_func, NULL);
1935 else
1937 HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
1938 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
1939 param->shared_data->size = 0;
1940 param->shared_data = NULL;
1944 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
1946 return CONTAINING_RECORD(iface, struct d3dx_effect_pool, ID3DXEffectPool_iface);
1949 static inline struct d3dx_effect_pool *unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool *iface);
1951 static inline struct d3dx_effect *impl_from_ID3DXEffect(ID3DXEffect *iface)
1953 return CONTAINING_RECORD(iface, struct d3dx_effect, ID3DXEffect_iface);
1956 /*** IUnknown methods ***/
1957 static HRESULT WINAPI d3dx_effect_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
1959 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
1961 if (IsEqualGUID(riid, &IID_IUnknown) ||
1962 IsEqualGUID(riid, &IID_ID3DXEffect))
1964 iface->lpVtbl->AddRef(iface);
1965 *object = iface;
1966 return S_OK;
1969 ERR("Interface %s not found\n", debugstr_guid(riid));
1971 return E_NOINTERFACE;
1974 static ULONG WINAPI d3dx_effect_AddRef(ID3DXEffect *iface)
1976 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
1978 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
1980 return InterlockedIncrement(&This->ref);
1983 static ULONG WINAPI d3dx_effect_Release(ID3DXEffect *iface)
1985 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
1986 ULONG refcount = InterlockedDecrement(&effect->ref);
1988 TRACE("%p decreasing refcount to %u.\n", effect, refcount);
1990 if (!refcount)
1991 d3dx_effect_cleanup(effect);
1993 return refcount;
1996 /*** ID3DXBaseEffect methods ***/
1997 static HRESULT WINAPI d3dx_effect_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
1999 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2001 FIXME("iface %p, desc %p partial stub.\n", iface, desc);
2003 if (!desc)
2005 WARN("Invalid argument specified.\n");
2006 return D3DERR_INVALIDCALL;
2009 /* TODO: add creator and function count. */
2010 desc->Creator = NULL;
2011 desc->Functions = 0;
2012 desc->Parameters = effect->parameter_count;
2013 desc->Techniques = effect->technique_count;
2015 return D3D_OK;
2018 static HRESULT WINAPI d3dx_effect_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter,
2019 D3DXPARAMETER_DESC *desc)
2021 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2022 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2024 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
2026 if (!desc || !param)
2028 WARN("Invalid argument specified.\n");
2029 return D3DERR_INVALIDCALL;
2032 desc->Name = param->name;
2033 desc->Semantic = param->semantic;
2034 desc->Class = param->class;
2035 desc->Type = param->type;
2036 desc->Rows = param->rows;
2037 desc->Columns = param->columns;
2038 desc->Elements = param->element_count;
2039 desc->Annotations = is_top_level_parameter(param)
2040 ? top_level_parameter_from_parameter(param)->annotation_count : 0;
2041 desc->StructMembers = param->member_count;
2042 desc->Flags = param->flags;
2043 desc->Bytes = param->bytes;
2045 return D3D_OK;
2048 static HRESULT WINAPI d3dx_effect_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique,
2049 D3DXTECHNIQUE_DESC *desc)
2051 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2052 struct d3dx_technique *tech = technique ? get_valid_technique(effect, technique) : &effect->techniques[0];
2054 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
2056 if (!desc || !tech)
2058 WARN("Invalid argument specified.\n");
2059 return D3DERR_INVALIDCALL;
2062 desc->Name = tech->name;
2063 desc->Passes = tech->pass_count;
2064 desc->Annotations = tech->annotation_count;
2066 return D3D_OK;
2069 static HRESULT WINAPI d3dx_effect_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
2071 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2072 struct d3dx_pass *pass = get_valid_pass(effect, pass_handle);
2073 unsigned int i;
2075 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
2077 if (!desc || !pass)
2079 WARN("Invalid argument specified.\n");
2080 return D3DERR_INVALIDCALL;
2083 desc->Name = pass->name;
2084 desc->Annotations = pass->annotation_count;
2086 desc->pVertexShaderFunction = NULL;
2087 desc->pPixelShaderFunction = NULL;
2089 if (effect->flags & D3DXFX_NOT_CLONEABLE)
2090 return D3D_OK;
2092 for (i = 0; i < pass->state_count; ++i)
2094 struct d3dx_state *state = &pass->states[i];
2096 if (state_table[state->operation].class == SC_VERTEXSHADER
2097 || state_table[state->operation].class == SC_PIXELSHADER)
2099 struct d3dx_parameter *param;
2100 void *param_value;
2101 BOOL param_dirty;
2102 HRESULT hr;
2103 void *data;
2105 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
2106 FALSE, &param_dirty)))
2107 return hr;
2109 data = param->object_id ? effect->objects[param->object_id].data : NULL;
2110 if (state_table[state->operation].class == SC_VERTEXSHADER)
2111 desc->pVertexShaderFunction = data;
2112 else
2113 desc->pPixelShaderFunction = data;
2117 return D3D_OK;
2120 static HRESULT WINAPI d3dx_effect_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader,
2121 D3DXFUNCTION_DESC *desc)
2123 FIXME("iface %p, shader %p, desc %p stub.\n", iface, shader, desc);
2125 return E_NOTIMPL;
2128 static D3DXHANDLE WINAPI d3dx_effect_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2130 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2131 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2133 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
2135 if (!parameter)
2137 if (index < effect->parameter_count)
2139 TRACE("Returning parameter %p.\n", &effect->parameters[index]);
2140 return get_parameter_handle(&effect->parameters[index].param);
2143 else
2145 if (param && !param->element_count && index < param->member_count)
2147 TRACE("Returning parameter %p.\n", &param->members[index]);
2148 return get_parameter_handle(&param->members[index]);
2152 WARN("Parameter not found.\n");
2154 return NULL;
2157 static D3DXHANDLE WINAPI d3dx_effect_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter,
2158 const char *name)
2160 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2161 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2162 D3DXHANDLE handle;
2164 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
2166 if (!name)
2168 handle = get_parameter_handle(param);
2169 TRACE("Returning parameter %p.\n", handle);
2170 return handle;
2173 handle = get_parameter_handle(get_parameter_by_name(effect, param, name));
2174 TRACE("Returning parameter %p.\n", handle);
2176 return handle;
2179 static D3DXHANDLE WINAPI d3dx_effect_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter,
2180 const char *semantic)
2182 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2183 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2184 struct d3dx_parameter *temp_param;
2185 unsigned int i;
2187 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
2189 if (!parameter)
2191 for (i = 0; i < effect->parameter_count; ++i)
2193 temp_param = &effect->parameters[i].param;
2195 if (!temp_param->semantic)
2197 if (!semantic)
2199 TRACE("Returning parameter %p\n", temp_param);
2200 return get_parameter_handle(temp_param);
2202 continue;
2205 if (!stricmp(temp_param->semantic, semantic))
2207 TRACE("Returning parameter %p\n", temp_param);
2208 return get_parameter_handle(temp_param);
2212 else if (param)
2214 for (i = 0; i < param->member_count; ++i)
2216 temp_param = &param->members[i];
2218 if (!temp_param->semantic)
2220 if (!semantic)
2222 TRACE("Returning parameter %p\n", temp_param);
2223 return get_parameter_handle(temp_param);
2225 continue;
2228 if (!stricmp(temp_param->semantic, semantic))
2230 TRACE("Returning parameter %p\n", temp_param);
2231 return get_parameter_handle(temp_param);
2236 WARN("Parameter not found.\n");
2238 return NULL;
2241 static D3DXHANDLE WINAPI d3dx_effect_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2243 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2244 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2246 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
2248 if (!param)
2250 if (index < effect->parameter_count)
2252 TRACE("Returning parameter %p.\n", &effect->parameters[index]);
2253 return get_parameter_handle(&effect->parameters[index].param);
2256 else
2258 if (index < param->element_count)
2260 TRACE("Returning parameter %p.\n", &param->members[index]);
2261 return get_parameter_handle(&param->members[index]);
2265 WARN("Parameter not found.\n");
2267 return NULL;
2270 static D3DXHANDLE WINAPI d3dx_effect_GetTechnique(ID3DXEffect *iface, UINT index)
2272 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2274 TRACE("iface %p, index %u.\n", iface, index);
2276 if (index >= effect->technique_count)
2278 WARN("Invalid argument specified.\n");
2279 return NULL;
2282 TRACE("Returning technique %p.\n", &effect->techniques[index]);
2284 return get_technique_handle(&effect->techniques[index]);
2287 static D3DXHANDLE WINAPI d3dx_effect_GetTechniqueByName(ID3DXEffect *iface, const char *name)
2289 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2290 struct d3dx_technique *tech = get_technique_by_name(effect, name);
2292 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
2294 if (tech)
2296 D3DXHANDLE t = get_technique_handle(tech);
2297 TRACE("Returning technique %p\n", t);
2298 return t;
2301 WARN("Technique not found.\n");
2303 return NULL;
2306 static D3DXHANDLE WINAPI d3dx_effect_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
2308 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2309 struct d3dx_technique *tech = get_valid_technique(effect, technique);
2311 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
2313 if (tech && index < tech->pass_count)
2315 TRACE("Returning pass %p\n", &tech->passes[index]);
2316 return get_pass_handle(&tech->passes[index]);
2319 WARN("Pass not found.\n");
2321 return NULL;
2324 static D3DXHANDLE WINAPI d3dx_effect_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, const char *name)
2326 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2327 struct d3dx_technique *tech = get_valid_technique(effect, technique);
2329 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
2331 if (tech && name)
2333 unsigned int i;
2335 for (i = 0; i < tech->pass_count; ++i)
2337 struct d3dx_pass *pass = &tech->passes[i];
2339 if (!strcmp(pass->name, name))
2341 TRACE("Returning pass %p\n", pass);
2342 return get_pass_handle(pass);
2347 WARN("Pass not found.\n");
2349 return NULL;
2352 static D3DXHANDLE WINAPI d3dx_effect_GetFunction(ID3DXEffect *iface, UINT index)
2354 FIXME("iface %p, index %u stub.\n", iface, index);
2356 return NULL;
2359 static D3DXHANDLE WINAPI d3dx_effect_GetFunctionByName(ID3DXEffect *iface, const char *name)
2361 FIXME("iface %p, name %s stub.\n", iface, debugstr_a(name));
2363 return NULL;
2366 static D3DXHANDLE WINAPI d3dx_effect_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
2368 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2369 struct d3dx_parameter *annotations = NULL;
2370 unsigned int annotation_count;
2372 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
2374 annotation_count = get_annotation_from_object(effect, object, &annotations);
2376 if (index < annotation_count)
2378 TRACE("Returning parameter %p\n", &annotations[index]);
2379 return get_parameter_handle(&annotations[index]);
2382 WARN("Annotation not found.\n");
2384 return NULL;
2387 static D3DXHANDLE WINAPI d3dx_effect_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object,
2388 const char *name)
2390 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2391 struct d3dx_parameter *annotation = NULL;
2392 struct d3dx_parameter *annotations = NULL;
2393 unsigned int annotation_count;
2395 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
2397 if (!name)
2399 WARN("Invalid argument specified\n");
2400 return NULL;
2403 annotation_count = get_annotation_from_object(effect, object, &annotations);
2405 annotation = get_annotation_by_name(effect, annotation_count, annotations, name);
2406 if (annotation)
2408 TRACE("Returning parameter %p\n", annotation);
2409 return get_parameter_handle(annotation);
2412 WARN("Annotation not found.\n");
2414 return NULL;
2417 static HRESULT WINAPI d3dx_effect_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter,
2418 const void *data, UINT bytes)
2420 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2421 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2423 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
2425 if (!param)
2427 WARN("Invalid parameter %p specified.\n", parameter);
2428 return D3DERR_INVALIDCALL;
2430 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
2432 WARN("Parameter is a sampler, returning E_FAIL.\n");
2433 return E_FAIL;
2436 if (data && param->bytes <= bytes)
2437 return set_value(param, data, bytes, param_get_data_and_dirtify(effect, param, param->bytes, TRUE));
2439 WARN("Invalid argument specified.\n");
2441 return D3DERR_INVALIDCALL;
2444 static HRESULT WINAPI d3dx_effect_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, void *data, UINT bytes)
2446 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2447 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2449 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
2451 if (!param)
2453 WARN("Invalid parameter %p specified.\n", parameter);
2454 return D3DERR_INVALIDCALL;
2456 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
2458 WARN("Parameter is a sampler, returning E_FAIL.\n");
2459 return E_FAIL;
2462 if (data && param->bytes <= bytes)
2464 TRACE("Type %s.\n", debug_d3dxparameter_type(param->type));
2466 switch (param->type)
2468 case D3DXPT_VOID:
2469 case D3DXPT_BOOL:
2470 case D3DXPT_INT:
2471 case D3DXPT_FLOAT:
2472 case D3DXPT_STRING:
2473 break;
2475 case D3DXPT_VERTEXSHADER:
2476 case D3DXPT_PIXELSHADER:
2477 case D3DXPT_TEXTURE:
2478 case D3DXPT_TEXTURE1D:
2479 case D3DXPT_TEXTURE2D:
2480 case D3DXPT_TEXTURE3D:
2481 case D3DXPT_TEXTURECUBE:
2483 unsigned int i;
2485 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
2487 IUnknown *unk = ((IUnknown **)param->data)[i];
2488 if (unk)
2489 IUnknown_AddRef(unk);
2491 break;
2494 default:
2495 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
2496 break;
2499 TRACE("Copy %u bytes.\n", param->bytes);
2500 memcpy(data, param->data, param->bytes);
2501 return D3D_OK;
2504 WARN("Parameter not found.\n");
2506 return D3DERR_INVALIDCALL;
2509 static HRESULT WINAPI d3dx_effect_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
2511 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2512 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2514 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
2516 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
2518 set_number(param_get_data_and_dirtify(effect, param, sizeof(int), TRUE),
2519 param->type, &b, D3DXPT_BOOL);
2520 return D3D_OK;
2523 WARN("Parameter not found.\n");
2525 return D3DERR_INVALIDCALL;
2528 static HRESULT WINAPI d3dx_effect_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
2530 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2531 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2533 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
2535 if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
2537 set_number(b, D3DXPT_BOOL, param->data, param->type);
2538 TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
2539 return D3D_OK;
2542 WARN("Parameter not found.\n");
2544 return D3DERR_INVALIDCALL;
2547 static HRESULT WINAPI d3dx_effect_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, const BOOL *b, UINT count)
2549 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2550 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2551 DWORD *data;
2553 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
2555 if (param)
2557 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2559 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2561 switch (param->class)
2563 case D3DXPC_SCALAR:
2564 case D3DXPC_VECTOR:
2565 case D3DXPC_MATRIX_ROWS:
2566 data = param_get_data_and_dirtify(effect, param, size * sizeof(int), TRUE);
2567 for (i = 0; i < size; ++i)
2569 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
2570 set_number(data + i, param->type, &b[i], D3DXPT_INT);
2572 return D3D_OK;
2574 case D3DXPC_OBJECT:
2575 case D3DXPC_STRUCT:
2576 break;
2578 default:
2579 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2580 break;
2584 WARN("Parameter not found.\n");
2586 return D3DERR_INVALIDCALL;
2589 static HRESULT WINAPI d3dx_effect_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
2591 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2592 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2594 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
2596 if (b && param && (param->class == D3DXPC_SCALAR
2597 || param->class == D3DXPC_VECTOR
2598 || param->class == D3DXPC_MATRIX_ROWS
2599 || param->class == D3DXPC_MATRIX_COLUMNS))
2601 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2603 for (i = 0; i < size; ++i)
2605 set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
2607 return D3D_OK;
2610 WARN("Parameter not found.\n");
2612 return D3DERR_INVALIDCALL;
2615 static HRESULT WINAPI d3dx_effect_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
2617 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2618 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2620 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
2622 if (param && !param->element_count)
2624 if (param->rows == 1 && param->columns == 1)
2626 DWORD value;
2628 set_number(&value, param->type, &n, D3DXPT_INT);
2629 *(DWORD *)param_get_data_and_dirtify(effect, param, sizeof(int),
2630 value != *(DWORD *)param->data) = value;
2631 return D3D_OK;
2634 /* Split the value if parameter is a vector with dimension 3 or 4. */
2635 if (param->type == D3DXPT_FLOAT
2636 && ((param->class == D3DXPC_VECTOR && param->columns != 2)
2637 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
2639 float *data;
2641 TRACE("Vector fixup.\n");
2643 data = param_get_data_and_dirtify(effect, param,
2644 min(4, param->rows * param->columns) * sizeof(float), TRUE);
2646 data[0] = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2647 data[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2648 data[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
2649 if (param->rows * param->columns > 3)
2650 data[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2652 return D3D_OK;
2656 WARN("Parameter not found.\n");
2658 return D3DERR_INVALIDCALL;
2661 static HRESULT WINAPI d3dx_effect_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
2663 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2664 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2666 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
2668 if (n && param && !param->element_count)
2670 if (param->columns == 1 && param->rows == 1)
2672 set_number(n, D3DXPT_INT, param->data, param->type);
2673 TRACE("Returning %d.\n", *n);
2674 return D3D_OK;
2677 if (param->type == D3DXPT_FLOAT &&
2678 ((param->class == D3DXPC_VECTOR && param->columns != 2)
2679 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
2681 TRACE("Vector fixup.\n");
2683 *n = min(max(0.0f, *((float *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI;
2684 *n += ((int)(min(max(0.0f, *((float *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
2685 *n += ((int)(min(max(0.0f, *((float *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
2686 if (param->columns * param->rows > 3)
2687 *n += ((int)(min(max(0.0f, *((float *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
2689 TRACE("Returning %d.\n", *n);
2690 return D3D_OK;
2694 WARN("Parameter not found.\n");
2696 return D3DERR_INVALIDCALL;
2699 static HRESULT WINAPI d3dx_effect_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, const INT *n, UINT count)
2701 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2702 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2703 DWORD *data;
2705 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
2707 if (param)
2709 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2711 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2713 switch (param->class)
2715 case D3DXPC_SCALAR:
2716 case D3DXPC_VECTOR:
2717 case D3DXPC_MATRIX_ROWS:
2718 data = param_get_data_and_dirtify(effect, param, size * sizeof(int), TRUE);
2719 for (i = 0; i < size; ++i)
2720 set_number(data + i, param->type, &n[i], D3DXPT_INT);
2721 return D3D_OK;
2723 case D3DXPC_OBJECT:
2724 case D3DXPC_STRUCT:
2725 break;
2727 default:
2728 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2729 break;
2733 WARN("Parameter not found.\n");
2735 return D3DERR_INVALIDCALL;
2738 static HRESULT WINAPI d3dx_effect_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
2740 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2741 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2743 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
2745 if (n && param && (param->class == D3DXPC_SCALAR
2746 || param->class == D3DXPC_VECTOR
2747 || param->class == D3DXPC_MATRIX_ROWS
2748 || param->class == D3DXPC_MATRIX_COLUMNS))
2750 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2752 for (i = 0; i < size; ++i)
2753 set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
2754 return D3D_OK;
2757 WARN("Parameter not found.\n");
2759 return D3DERR_INVALIDCALL;
2762 static HRESULT WINAPI d3dx_effect_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
2764 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2765 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2767 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
2769 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
2771 DWORD value;
2773 set_number(&value, param->type, &f, D3DXPT_FLOAT);
2774 *(DWORD *)param_get_data_and_dirtify(effect, param, sizeof(float),
2775 value != *(DWORD *)param->data) = value;
2776 return D3D_OK;
2779 WARN("Parameter not found.\n");
2781 return D3DERR_INVALIDCALL;
2784 static HRESULT WINAPI d3dx_effect_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
2786 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2787 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2789 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
2791 if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
2793 set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
2794 TRACE("Returning %f.\n", *f);
2795 return D3D_OK;
2798 WARN("Parameter not found.\n");
2800 return D3DERR_INVALIDCALL;
2803 static HRESULT WINAPI d3dx_effect_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter,
2804 const float *f, UINT count)
2806 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2807 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2808 DWORD *data;
2810 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
2812 if (param)
2814 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2816 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2818 switch (param->class)
2820 case D3DXPC_SCALAR:
2821 case D3DXPC_VECTOR:
2822 case D3DXPC_MATRIX_ROWS:
2823 data = param_get_data_and_dirtify(effect, param, size * sizeof(float), TRUE);
2824 for (i = 0; i < size; ++i)
2825 set_number(data + i, param->type, &f[i], D3DXPT_FLOAT);
2826 return D3D_OK;
2828 case D3DXPC_OBJECT:
2829 case D3DXPC_STRUCT:
2830 break;
2832 default:
2833 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2834 break;
2838 WARN("Parameter not found.\n");
2840 return D3DERR_INVALIDCALL;
2843 static HRESULT WINAPI d3dx_effect_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, float *f, UINT count)
2845 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2846 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2848 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
2850 if (f && param && (param->class == D3DXPC_SCALAR
2851 || param->class == D3DXPC_VECTOR
2852 || param->class == D3DXPC_MATRIX_ROWS
2853 || param->class == D3DXPC_MATRIX_COLUMNS))
2855 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2857 for (i = 0; i < size; ++i)
2858 set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
2859 return D3D_OK;
2862 WARN("Parameter not found.\n");
2864 return D3DERR_INVALIDCALL;
2867 static HRESULT WINAPI d3dx_effect_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2869 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2870 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2872 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
2874 if (param && !param->element_count)
2876 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2878 switch (param->class)
2880 case D3DXPC_SCALAR:
2881 case D3DXPC_VECTOR:
2882 if (param->type == D3DXPT_INT && param->bytes == 4)
2884 DWORD tmp;
2886 TRACE("INT fixup.\n");
2887 tmp = max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI;
2888 tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2889 tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2890 tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2892 *(int *)param_get_data_and_dirtify(effect, param, sizeof(int), TRUE) = tmp;
2893 return D3D_OK;
2895 if (param->type == D3DXPT_FLOAT)
2897 memcpy(param_get_data_and_dirtify(effect, param, param->columns * sizeof(float), TRUE),
2898 vector, param->columns * sizeof(float));
2899 return D3D_OK;
2902 set_vector(param, vector, param_get_data_and_dirtify(effect, param, param->columns * sizeof(float), TRUE));
2903 return D3D_OK;
2905 case D3DXPC_MATRIX_ROWS:
2906 case D3DXPC_OBJECT:
2907 case D3DXPC_STRUCT:
2908 break;
2910 default:
2911 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2912 break;
2916 WARN("Parameter not found.\n");
2918 return D3DERR_INVALIDCALL;
2921 static HRESULT WINAPI d3dx_effect_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2923 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2924 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2926 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
2928 if (vector && param && !param->element_count)
2930 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2932 switch (param->class)
2934 case D3DXPC_SCALAR:
2935 case D3DXPC_VECTOR:
2936 if (param->type == D3DXPT_INT && param->bytes == 4)
2938 TRACE("INT fixup.\n");
2939 vector->x = (((*(int *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2940 vector->y = (((*(int *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2941 vector->z = ((*(int *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2942 vector->w = (((*(int *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2943 return D3D_OK;
2945 get_vector(param, vector);
2946 return D3D_OK;
2948 case D3DXPC_MATRIX_ROWS:
2949 case D3DXPC_OBJECT:
2950 case D3DXPC_STRUCT:
2951 break;
2953 default:
2954 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2955 break;
2959 WARN("Parameter not found.\n");
2961 return D3DERR_INVALIDCALL;
2964 static HRESULT WINAPI d3dx_effect_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter,
2965 const D3DXVECTOR4 *vector, UINT count)
2967 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2968 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2970 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
2972 if (param && param->element_count && param->element_count >= count)
2974 unsigned int i;
2975 BYTE *data;
2977 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2979 switch (param->class)
2981 case D3DXPC_VECTOR:
2982 data = param_get_data_and_dirtify(effect, param, count * param->columns * sizeof(float), TRUE);
2984 if (param->type == D3DXPT_FLOAT)
2986 if (param->columns == 4)
2988 memcpy(data, vector, count * 4 * sizeof(float));
2990 else
2992 for (i = 0; i < count; ++i)
2993 memcpy((float *)data + param->columns * i, vector + i,
2994 param->columns * sizeof(float));
2996 return D3D_OK;
2999 for (i = 0; i < count; ++i)
3000 set_vector(&param->members[i], &vector[i], data + i * param->columns * sizeof(float));
3002 return D3D_OK;
3004 case D3DXPC_SCALAR:
3005 case D3DXPC_MATRIX_ROWS:
3006 case D3DXPC_OBJECT:
3007 case D3DXPC_STRUCT:
3008 break;
3010 default:
3011 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3012 break;
3016 WARN("Parameter not found.\n");
3018 return D3DERR_INVALIDCALL;
3021 static HRESULT WINAPI d3dx_effect_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3022 D3DXVECTOR4 *vector, UINT count)
3024 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3025 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3027 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3029 if (!count)
3030 return D3D_OK;
3032 if (vector && param && count <= param->element_count)
3034 unsigned int i;
3036 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3038 switch (param->class)
3040 case D3DXPC_VECTOR:
3041 for (i = 0; i < count; ++i)
3042 get_vector(&param->members[i], &vector[i]);
3043 return D3D_OK;
3045 case D3DXPC_SCALAR:
3046 case D3DXPC_MATRIX_ROWS:
3047 case D3DXPC_OBJECT:
3048 case D3DXPC_STRUCT:
3049 break;
3051 default:
3052 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3053 break;
3057 WARN("Parameter not found.\n");
3059 return D3DERR_INVALIDCALL;
3062 static HRESULT WINAPI d3dx_effect_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3064 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3065 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3067 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3069 if (param && !param->element_count)
3071 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3073 switch (param->class)
3075 case D3DXPC_MATRIX_ROWS:
3076 set_matrix(param, matrix, param_get_data_and_dirtify(effect, param,
3077 param->rows * param->columns * sizeof(float), TRUE));
3078 return D3D_OK;
3080 case D3DXPC_SCALAR:
3081 case D3DXPC_VECTOR:
3082 case D3DXPC_OBJECT:
3083 case D3DXPC_STRUCT:
3084 break;
3086 default:
3087 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3088 break;
3092 WARN("Parameter not found.\n");
3094 return D3DERR_INVALIDCALL;
3097 static HRESULT WINAPI d3dx_effect_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3099 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3100 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3102 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3104 if (matrix && param && !param->element_count)
3106 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3108 switch (param->class)
3110 case D3DXPC_MATRIX_ROWS:
3111 get_matrix(param, matrix, FALSE);
3112 return D3D_OK;
3114 case D3DXPC_SCALAR:
3115 case D3DXPC_VECTOR:
3116 case D3DXPC_OBJECT:
3117 case D3DXPC_STRUCT:
3118 break;
3120 default:
3121 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3122 break;
3126 WARN("Parameter not found.\n");
3128 return D3DERR_INVALIDCALL;
3131 static HRESULT WINAPI d3dx_effect_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3132 const D3DXMATRIX *matrix, UINT count)
3134 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3135 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3137 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3139 if (param && param->element_count >= count)
3141 unsigned int i;
3142 BYTE *data;
3144 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3146 switch (param->class)
3148 case D3DXPC_MATRIX_ROWS:
3149 data = param_get_data_and_dirtify(effect, param, count * param->rows
3150 * param->columns * sizeof(float), TRUE);
3152 for (i = 0; i < count; ++i)
3153 set_matrix(&param->members[i], &matrix[i],
3154 data + i * param->rows * param->columns * sizeof(float));
3156 return D3D_OK;
3158 case D3DXPC_SCALAR:
3159 case D3DXPC_VECTOR:
3160 case D3DXPC_OBJECT:
3161 case D3DXPC_STRUCT:
3162 break;
3164 default:
3165 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3166 break;
3170 WARN("Parameter not found.\n");
3172 return D3DERR_INVALIDCALL;
3175 static HRESULT WINAPI d3dx_effect_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3176 D3DXMATRIX *matrix, UINT count)
3178 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3179 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3181 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3183 if (!count)
3184 return D3D_OK;
3186 if (matrix && param && count <= param->element_count)
3188 unsigned int i;
3190 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3192 switch (param->class)
3194 case D3DXPC_MATRIX_ROWS:
3195 for (i = 0; i < count; ++i)
3196 get_matrix(&param->members[i], &matrix[i], FALSE);
3197 return D3D_OK;
3199 case D3DXPC_SCALAR:
3200 case D3DXPC_VECTOR:
3201 case D3DXPC_OBJECT:
3202 case D3DXPC_STRUCT:
3203 break;
3205 default:
3206 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3207 break;
3211 WARN("Parameter not found.\n");
3213 return D3DERR_INVALIDCALL;
3216 static HRESULT WINAPI d3dx_effect_SetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3217 const D3DXMATRIX **matrix, UINT count)
3219 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3220 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3222 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3224 if (param && count <= param->element_count)
3226 unsigned int i;
3227 BYTE *data;
3229 switch (param->class)
3231 case D3DXPC_MATRIX_ROWS:
3232 data = param_get_data_and_dirtify(effect, param, count * param->rows
3233 * param->columns * sizeof(float), TRUE);
3235 for (i = 0; i < count; ++i)
3236 set_matrix(&param->members[i], matrix[i], data + i * param->rows
3237 * param->columns * sizeof(float));
3239 return D3D_OK;
3241 case D3DXPC_SCALAR:
3242 case D3DXPC_VECTOR:
3243 case D3DXPC_OBJECT:
3244 break;
3246 default:
3247 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3248 break;
3252 WARN("Parameter not found.\n");
3254 return D3DERR_INVALIDCALL;
3257 static HRESULT WINAPI d3dx_effect_GetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3258 D3DXMATRIX **matrix, UINT count)
3260 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3261 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3263 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3265 if (!count)
3266 return D3D_OK;
3268 if (param && matrix && count <= param->element_count)
3270 unsigned int i;
3272 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3274 switch (param->class)
3276 case D3DXPC_MATRIX_ROWS:
3277 for (i = 0; i < count; ++i)
3278 get_matrix(&param->members[i], matrix[i], FALSE);
3279 return D3D_OK;
3281 case D3DXPC_SCALAR:
3282 case D3DXPC_VECTOR:
3283 case D3DXPC_OBJECT:
3284 break;
3286 default:
3287 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3288 break;
3292 WARN("Parameter not found.\n");
3294 return D3DERR_INVALIDCALL;
3297 static HRESULT WINAPI d3dx_effect_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter,
3298 const D3DXMATRIX *matrix)
3300 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3301 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3303 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3305 if (param && !param->element_count)
3307 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3309 switch (param->class)
3311 case D3DXPC_MATRIX_ROWS:
3312 set_matrix_transpose(param, matrix, param_get_data_and_dirtify(effect, param,
3313 param->rows * param->columns * sizeof(float), TRUE));
3314 return D3D_OK;
3316 case D3DXPC_SCALAR:
3317 case D3DXPC_VECTOR:
3318 case D3DXPC_OBJECT:
3319 case D3DXPC_STRUCT:
3320 break;
3322 default:
3323 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3324 break;
3328 WARN("Parameter not found.\n");
3330 return D3DERR_INVALIDCALL;
3333 static HRESULT WINAPI d3dx_effect_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter,
3334 D3DXMATRIX *matrix)
3336 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3337 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3339 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3341 if (matrix && param && !param->element_count)
3343 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3345 switch (param->class)
3347 case D3DXPC_SCALAR:
3348 case D3DXPC_VECTOR:
3349 get_matrix(param, matrix, FALSE);
3350 return D3D_OK;
3352 case D3DXPC_MATRIX_ROWS:
3353 get_matrix(param, matrix, TRUE);
3354 return D3D_OK;
3356 case D3DXPC_OBJECT:
3357 case D3DXPC_STRUCT:
3358 break;
3360 default:
3361 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3362 break;
3366 WARN("Parameter not found.\n");
3368 return D3DERR_INVALIDCALL;
3371 static HRESULT WINAPI d3dx_effect_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3372 const D3DXMATRIX *matrix, UINT count)
3374 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3375 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3377 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3379 if (param && param->element_count >= count)
3381 unsigned int i;
3382 BYTE *data;
3384 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3386 switch (param->class)
3388 case D3DXPC_MATRIX_ROWS:
3389 data = param_get_data_and_dirtify(effect, param, count * param->rows
3390 * param->columns * sizeof(float), TRUE);
3392 for (i = 0; i < count; ++i)
3393 set_matrix_transpose(&param->members[i], &matrix[i], data
3394 + i * param->rows * param->columns * sizeof(float));
3396 return D3D_OK;
3398 case D3DXPC_SCALAR:
3399 case D3DXPC_VECTOR:
3400 case D3DXPC_OBJECT:
3401 case D3DXPC_STRUCT:
3402 break;
3404 default:
3405 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3406 break;
3410 WARN("Parameter not found.\n");
3412 return D3DERR_INVALIDCALL;
3415 static HRESULT WINAPI d3dx_effect_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3416 D3DXMATRIX *matrix, UINT count)
3418 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3419 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3421 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3423 if (!count)
3424 return D3D_OK;
3426 if (matrix && param && count <= param->element_count)
3428 unsigned int i;
3430 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3432 switch (param->class)
3434 case D3DXPC_MATRIX_ROWS:
3435 for (i = 0; i < count; ++i)
3436 get_matrix(&param->members[i], &matrix[i], TRUE);
3437 return D3D_OK;
3439 case D3DXPC_SCALAR:
3440 case D3DXPC_VECTOR:
3441 case D3DXPC_OBJECT:
3442 case D3DXPC_STRUCT:
3443 break;
3445 default:
3446 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3447 break;
3451 WARN("Parameter not found.\n");
3453 return D3DERR_INVALIDCALL;
3456 static HRESULT WINAPI d3dx_effect_SetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3457 const D3DXMATRIX **matrix, UINT count)
3459 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3460 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3462 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3464 if (param && count <= param->element_count)
3466 unsigned int i;
3467 BYTE *data;
3469 switch (param->class)
3471 case D3DXPC_MATRIX_ROWS:
3472 data = param_get_data_and_dirtify(effect, param, count * param->rows
3473 * param->columns * sizeof(float), TRUE);
3475 for (i = 0; i < count; ++i)
3476 set_matrix_transpose(&param->members[i], matrix[i], data
3477 + i * param->rows * param->columns * sizeof(float));
3479 return D3D_OK;
3481 case D3DXPC_SCALAR:
3482 case D3DXPC_VECTOR:
3483 case D3DXPC_OBJECT:
3484 break;
3486 default:
3487 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3488 break;
3492 WARN("Parameter not found.\n");
3494 return D3DERR_INVALIDCALL;
3497 static HRESULT WINAPI d3dx_effect_GetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3498 D3DXMATRIX **matrix, UINT count)
3500 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3501 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3503 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3505 if (!count)
3506 return D3D_OK;
3508 if (matrix && param && count <= param->element_count)
3510 unsigned int i;
3512 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3514 switch (param->class)
3516 case D3DXPC_MATRIX_ROWS:
3517 for (i = 0; i < count; ++i)
3518 get_matrix(&param->members[i], matrix[i], TRUE);
3519 return D3D_OK;
3521 case D3DXPC_SCALAR:
3522 case D3DXPC_VECTOR:
3523 case D3DXPC_OBJECT:
3524 break;
3526 default:
3527 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3528 break;
3532 WARN("Parameter not found.\n");
3534 return D3DERR_INVALIDCALL;
3537 static HRESULT WINAPI d3dx_effect_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char *string)
3539 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3540 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3542 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
3544 if (param && param->type == D3DXPT_STRING)
3545 return set_string(param_get_data_and_dirtify(effect, param, sizeof(void *), TRUE), string);
3547 WARN("Parameter not found.\n");
3549 return D3DERR_INVALIDCALL;
3552 static HRESULT WINAPI d3dx_effect_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char **string)
3554 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3555 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3557 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
3559 if (string && param && !param->element_count && param->type == D3DXPT_STRING)
3561 *string = *(const char **)param->data;
3562 TRACE("Returning %s.\n", debugstr_a(*string));
3563 return D3D_OK;
3566 WARN("Parameter not found.\n");
3568 return D3DERR_INVALIDCALL;
3571 static HRESULT WINAPI d3dx_effect_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter,
3572 IDirect3DBaseTexture9 *texture)
3574 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3575 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3577 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3579 if (param && !param->element_count
3580 && (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
3581 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
3582 || param->type == D3DXPT_TEXTURECUBE))
3584 IDirect3DBaseTexture9 **data = param_get_data_and_dirtify(effect, param,
3585 sizeof(void *), texture != *(IDirect3DBaseTexture9 **)param->data);
3586 IDirect3DBaseTexture9 *old_texture = *data;
3588 *data = texture;
3590 if (texture == old_texture)
3591 return D3D_OK;
3593 if (texture)
3594 IDirect3DBaseTexture9_AddRef(texture);
3595 if (old_texture)
3596 IDirect3DBaseTexture9_Release(old_texture);
3598 return D3D_OK;
3601 WARN("Parameter not found.\n");
3603 return D3DERR_INVALIDCALL;
3606 static HRESULT WINAPI d3dx_effect_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter,
3607 IDirect3DBaseTexture9 **texture)
3609 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3610 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3612 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3614 if (texture && param && !param->element_count
3615 && (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
3616 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
3617 || param->type == D3DXPT_TEXTURECUBE))
3619 *texture = *(IDirect3DBaseTexture9 **)param->data;
3620 if (*texture)
3621 IDirect3DBaseTexture9_AddRef(*texture);
3622 TRACE("Returning %p.\n", *texture);
3623 return D3D_OK;
3626 WARN("Parameter not found.\n");
3628 return D3DERR_INVALIDCALL;
3631 static HRESULT WINAPI d3dx_effect_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter,
3632 IDirect3DPixelShader9 **shader)
3634 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3635 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3637 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3639 if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
3641 if ((*shader = *(IDirect3DPixelShader9 **)param->data))
3642 IDirect3DPixelShader9_AddRef(*shader);
3643 TRACE("Returning %p.\n", *shader);
3644 return D3D_OK;
3647 WARN("Parameter not found.\n");
3649 return D3DERR_INVALIDCALL;
3652 static HRESULT WINAPI d3dx_effect_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter,
3653 IDirect3DVertexShader9 **shader)
3655 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3656 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3658 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3660 if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
3662 if ((*shader = *(IDirect3DVertexShader9 **)param->data))
3663 IDirect3DVertexShader9_AddRef(*shader);
3664 TRACE("Returning %p.\n", *shader);
3665 return D3D_OK;
3668 WARN("Parameter not found.\n");
3670 return D3DERR_INVALIDCALL;
3673 static HRESULT WINAPI d3dx_effect_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3675 FIXME("iface %p, parameter %p, start %u, end %u stub.\n", iface, parameter, start, end);
3677 return E_NOTIMPL;
3680 /*** ID3DXEffect methods ***/
3681 static HRESULT WINAPI d3dx_effect_GetPool(ID3DXEffect *iface, ID3DXEffectPool **pool)
3683 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3685 TRACE("iface %p, pool %p.\n", effect, pool);
3687 if (!pool)
3689 WARN("Invalid argument supplied.\n");
3690 return D3DERR_INVALIDCALL;
3693 *pool = NULL;
3694 if (effect->pool)
3696 *pool = &effect->pool->ID3DXEffectPool_iface;
3697 (*pool)->lpVtbl->AddRef(*pool);
3700 TRACE("Returning pool %p.\n", *pool);
3702 return S_OK;
3705 static HRESULT WINAPI d3dx_effect_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3707 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3708 struct d3dx_technique *tech = get_valid_technique(effect, technique);
3710 TRACE("iface %p, technique %p\n", iface, technique);
3712 if (tech)
3714 effect->active_technique = tech;
3715 TRACE("Technique %p\n", tech);
3716 return D3D_OK;
3719 WARN("Technique not found.\n");
3721 return D3DERR_INVALIDCALL;
3724 static D3DXHANDLE WINAPI d3dx_effect_GetCurrentTechnique(ID3DXEffect *iface)
3726 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
3728 TRACE("iface %p\n", This);
3730 return get_technique_handle(This->active_technique);
3733 static HRESULT WINAPI d3dx_effect_ValidateTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3735 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3736 struct d3dx_technique *tech = get_valid_technique(effect, technique);
3737 HRESULT ret = D3D_OK;
3738 unsigned int i, j;
3740 FIXME("iface %p, technique %p semi-stub.\n", iface, technique);
3742 if (!tech)
3744 ret = D3DERR_INVALIDCALL;
3745 goto done;
3747 for (i = 0; i < tech->pass_count; ++i)
3749 struct d3dx_pass *pass = &tech->passes[i];
3751 for (j = 0; j < pass->state_count; ++j)
3753 struct d3dx_state *state = &pass->states[j];
3755 if (state_table[state->operation].class == SC_VERTEXSHADER
3756 || state_table[state->operation].class == SC_PIXELSHADER)
3758 struct d3dx_parameter *param;
3759 void *param_value;
3760 BOOL param_dirty;
3761 HRESULT hr;
3763 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[j], &param_value, &param,
3764 FALSE, &param_dirty)))
3765 return hr;
3767 if (param->object_id && effect->objects[param->object_id].creation_failed)
3769 ret = E_FAIL;
3770 goto done;
3775 done:
3776 TRACE("Returning %#x.\n", ret);
3777 return ret;
3780 static HRESULT WINAPI d3dx_effect_FindNextValidTechnique(ID3DXEffect *iface, D3DXHANDLE technique,
3781 D3DXHANDLE *next_technique)
3783 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3784 struct d3dx_technique *prev_tech, *tech;
3785 unsigned int i;
3787 TRACE("iface %p, technique %p, next_technique %p.\n", iface, technique, next_technique);
3789 if (technique)
3791 if (!(prev_tech = get_valid_technique(effect, technique)))
3792 return D3DERR_INVALIDCALL;
3794 for (i = 0; i < effect->technique_count; ++i)
3796 tech = &effect->techniques[i];
3797 if (tech == prev_tech)
3799 ++i;
3800 break;
3804 else
3806 i = 0;
3809 for (; i < effect->technique_count; ++i)
3811 tech = &effect->techniques[i];
3812 if (SUCCEEDED(d3dx_effect_ValidateTechnique(iface, get_technique_handle(tech))))
3814 *next_technique = get_technique_handle(tech);
3815 return D3D_OK;
3819 *next_technique = get_technique_handle(&effect->techniques[0]);
3820 return S_FALSE;
3823 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
3824 void *data);
3826 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func,
3827 void *data)
3829 struct d3dx_parameter **params;
3830 unsigned int i, param_count;
3832 if (!param_eval)
3833 return FALSE;
3835 params = param_eval->shader_inputs.inputs_param;
3836 param_count = param_eval->shader_inputs.input_count;
3837 for (i = 0; i < param_count; ++i)
3839 if (walk_parameter_dep(params[i], param_func, data))
3840 return TRUE;
3843 params = param_eval->pres.inputs.inputs_param;
3844 param_count = param_eval->pres.inputs.input_count;
3845 for (i = 0; i < param_count; ++i)
3847 if (walk_parameter_dep(params[i], param_func, data))
3848 return TRUE;
3850 return FALSE;
3853 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func,
3854 void *data)
3856 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type))
3858 if (walk_parameter_dep(&state->parameter, param_func, data))
3859 return TRUE;
3861 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER)
3863 if (walk_parameter_dep(state->referenced_param, param_func, data))
3864 return TRUE;
3866 return walk_param_eval_dep(state->parameter.param_eval, param_func, data);
3869 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
3870 void *data)
3872 unsigned int i;
3873 unsigned int member_count;
3875 param = &param->top_level_param->param;
3876 if (param_func(data, param))
3877 return TRUE;
3879 if (walk_param_eval_dep(param->param_eval, param_func, data))
3880 return TRUE;
3882 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
3884 struct d3dx_sampler *sampler;
3885 unsigned int sampler_idx;
3886 unsigned int samplers_count = max(param->element_count, 1);
3888 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx)
3890 sampler = param->element_count ? param->members[sampler_idx].data : param->data;
3891 for (i = 0; i < sampler->state_count; ++i)
3893 if (walk_state_dep(&sampler->states[i], param_func, data))
3894 return TRUE;
3897 return FALSE;
3900 member_count = param->element_count ? param->element_count : param->member_count;
3901 for (i = 0; i < member_count; ++i)
3903 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data))
3904 return TRUE;
3907 return FALSE;
3910 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech)
3912 unsigned int i, j;
3913 struct d3dx_pass *pass;
3915 if (!tech || !param)
3916 return FALSE;
3918 for (i = 0; i < tech->pass_count; ++i)
3920 pass = &tech->passes[i];
3921 for (j = 0; j < pass->state_count; ++j)
3923 if (walk_state_dep(&pass->states[j], is_same_parameter, param))
3924 return TRUE;
3927 return FALSE;
3930 static BOOL WINAPI d3dx_effect_IsParameterUsed(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXHANDLE technique)
3932 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3933 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3934 struct d3dx_technique *tech = get_valid_technique(effect, technique);
3935 BOOL ret;
3937 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique);
3938 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech);
3940 ret = is_parameter_used(param, tech);
3941 TRACE("Returning %#x.\n", ret);
3942 return ret;
3945 static HRESULT WINAPI d3dx_effect_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
3947 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3948 struct d3dx_technique *technique = effect->active_technique;
3950 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags);
3952 if (technique)
3954 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE))
3955 WARN("Invalid flags (%#x) specified.\n", flags);
3957 if (flags & D3DXFX_DONOTSAVESTATE)
3959 TRACE("State capturing disabled.\n");
3961 else
3963 HRESULT hr;
3964 unsigned int i;
3966 if (!technique->saved_state)
3968 ID3DXEffectStateManager *manager;
3970 manager = effect->manager;
3971 effect->manager = NULL;
3972 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
3973 ERR("BeginStateBlock failed, hr %#x.\n", hr);
3974 for (i = 0; i < technique->pass_count; i++)
3975 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE);
3976 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
3977 ERR("EndStateBlock failed, hr %#x.\n", hr);
3978 effect->manager = manager;
3980 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
3981 ERR("StateBlock Capture failed, hr %#x.\n", hr);
3984 if (passes)
3985 *passes = technique->pass_count;
3986 effect->started = TRUE;
3987 effect->begin_flags = flags;
3989 return D3D_OK;
3992 WARN("Invalid argument supplied.\n");
3994 return D3DERR_INVALIDCALL;
3997 static HRESULT WINAPI d3dx_effect_BeginPass(ID3DXEffect *iface, UINT pass)
3999 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4000 struct d3dx_technique *technique = effect->active_technique;
4002 TRACE("iface %p, pass %u\n", effect, pass);
4004 if (technique && pass < technique->pass_count && !effect->active_pass)
4006 HRESULT hr;
4008 memset(effect->current_light, 0, sizeof(effect->current_light));
4009 memset(&effect->current_material, 0, sizeof(effect->current_material));
4011 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE)))
4012 effect->active_pass = &technique->passes[pass];
4013 return hr;
4016 WARN("Invalid argument supplied.\n");
4018 return D3DERR_INVALIDCALL;
4021 static HRESULT WINAPI d3dx_effect_CommitChanges(ID3DXEffect *iface)
4023 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4025 TRACE("iface %p.\n", iface);
4027 if (!effect->active_pass)
4029 WARN("Called without an active pass.\n");
4030 return D3D_OK;
4032 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE);
4035 static HRESULT WINAPI d3dx_effect_EndPass(ID3DXEffect *iface)
4037 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4039 TRACE("iface %p\n", This);
4041 if (This->active_pass)
4043 This->active_pass = NULL;
4044 return D3D_OK;
4047 WARN("Invalid call.\n");
4049 return D3DERR_INVALIDCALL;
4052 static HRESULT WINAPI d3dx_effect_End(ID3DXEffect *iface)
4054 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4055 struct d3dx_technique *technique = effect->active_technique;
4057 TRACE("iface %p.\n", iface);
4059 if (!effect->started)
4060 return D3D_OK;
4062 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE)
4064 TRACE("State restoring disabled.\n");
4066 else
4068 HRESULT hr;
4070 if (technique && technique->saved_state)
4072 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
4073 ERR("State block apply failed, hr %#x.\n", hr);
4075 else
4076 ERR("No saved state.\n");
4079 effect->started = FALSE;
4081 return D3D_OK;
4084 static HRESULT WINAPI d3dx_effect_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device)
4086 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4088 TRACE("iface %p, device %p\n", This, device);
4090 if (!device)
4092 WARN("Invalid argument supplied.\n");
4093 return D3DERR_INVALIDCALL;
4096 IDirect3DDevice9_AddRef(This->device);
4098 *device = This->device;
4100 TRACE("Returning device %p\n", *device);
4102 return S_OK;
4105 static BOOL param_on_lost_device(void *data, struct d3dx_parameter *param)
4107 struct IDirect3DVolumeTexture9 *volume_texture;
4108 struct IDirect3DCubeTexture9 *cube_texture;
4109 struct IDirect3DTexture9 *texture;
4110 D3DSURFACE_DESC surface_desc;
4111 D3DVOLUME_DESC volume_desc;
4113 if (param->class == D3DXPC_OBJECT && !param->element_count)
4115 switch (param->type)
4117 case D3DXPT_TEXTURE:
4118 case D3DXPT_TEXTURE1D:
4119 case D3DXPT_TEXTURE2D:
4120 texture = *(IDirect3DTexture9 **)param->data;
4121 if (!texture)
4122 return FALSE;
4123 IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
4124 if (surface_desc.Pool != D3DPOOL_DEFAULT)
4125 return FALSE;
4126 break;
4127 case D3DXPT_TEXTURE3D:
4128 volume_texture = *(IDirect3DVolumeTexture9 **)param->data;
4129 if (!volume_texture)
4130 return FALSE;
4131 IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
4132 if (volume_desc.Pool != D3DPOOL_DEFAULT)
4133 return FALSE;
4134 break;
4135 case D3DXPT_TEXTURECUBE:
4136 cube_texture = *(IDirect3DCubeTexture9 **)param->data;
4137 if (!cube_texture)
4138 return FALSE;
4139 IDirect3DTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
4140 if (surface_desc.Pool != D3DPOOL_DEFAULT)
4141 return FALSE;
4142 break;
4143 default:
4144 return FALSE;
4146 IUnknown_Release(*(IUnknown **)param->data);
4147 *(IUnknown **)param->data = NULL;
4149 return FALSE;
4152 static HRESULT WINAPI d3dx_effect_OnLostDevice(ID3DXEffect *iface)
4154 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4155 unsigned int i;
4157 TRACE("iface %p.\n", iface);
4159 for (i = 0; i < effect->parameter_count; ++i)
4160 walk_parameter_tree(&effect->parameters[i].param, param_on_lost_device, NULL);
4162 return D3D_OK;
4165 static HRESULT WINAPI d3dx_effect_OnResetDevice(ID3DXEffect *iface)
4167 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4169 FIXME("(%p)->(): stub\n", This);
4171 return E_NOTIMPL;
4174 static HRESULT WINAPI d3dx_effect_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager)
4176 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4178 TRACE("iface %p, manager %p\n", This, manager);
4180 if (manager) IUnknown_AddRef(manager);
4181 if (This->manager) IUnknown_Release(This->manager);
4183 This->manager = manager;
4185 return D3D_OK;
4188 static HRESULT WINAPI d3dx_effect_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager)
4190 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4192 TRACE("iface %p, manager %p\n", This, manager);
4194 if (!manager)
4196 WARN("Invalid argument supplied.\n");
4197 return D3DERR_INVALIDCALL;
4200 if (This->manager) IUnknown_AddRef(This->manager);
4201 *manager = This->manager;
4203 return D3D_OK;
4206 static HRESULT WINAPI d3dx_effect_BeginParameterBlock(ID3DXEffect *iface)
4208 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4210 TRACE("iface %p.\n", iface);
4212 if (effect->current_parameter_block)
4214 WARN("Parameter block is already started.\n");
4215 return D3DERR_INVALIDCALL;
4218 effect->current_parameter_block = heap_alloc_zero(sizeof(*effect->current_parameter_block));
4219 memcpy(effect->current_parameter_block->magic_string, parameter_block_magic_string,
4220 sizeof(parameter_block_magic_string));
4221 effect->current_parameter_block->effect = effect;
4223 return D3D_OK;
4226 static D3DXHANDLE WINAPI d3dx_effect_EndParameterBlock(ID3DXEffect *iface)
4228 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4229 struct d3dx_parameter_block *ret;
4231 TRACE("iface %p.\n", iface);
4233 if (!effect->current_parameter_block)
4235 WARN("No active parameter block.\n");
4236 return NULL;
4238 ret = effect->current_parameter_block;
4240 ret->buffer = heap_realloc(ret->buffer, ret->offset);
4241 ret->size = ret->offset;
4243 effect->current_parameter_block = NULL;
4244 list_add_tail(&effect->parameter_block_list, &ret->entry);
4245 return (D3DXHANDLE)ret;
4248 static HRESULT WINAPI d3dx_effect_ApplyParameterBlock(ID3DXEffect *iface, D3DXHANDLE parameter_block)
4250 struct d3dx_parameter_block *block = get_valid_parameter_block(parameter_block);
4251 struct d3dx_recorded_parameter *record;
4253 TRACE("iface %p, parameter_block %p.\n", iface, parameter_block);
4255 if (!block || !block->offset)
4256 return D3DERR_INVALIDCALL;
4258 record = (struct d3dx_recorded_parameter *)block->buffer;
4259 while ((BYTE *)record < block->buffer + block->offset)
4261 set_value(record->param, record + 1, record->bytes,
4262 param_get_data_and_dirtify(block->effect, record->param, record->bytes, TRUE));
4263 record = (struct d3dx_recorded_parameter *)((BYTE *)record + get_recorded_parameter_size(record));
4265 assert((BYTE *)record == block->buffer + block->offset);
4266 return D3D_OK;
4269 #if D3DX_SDK_VERSION >= 26
4270 static HRESULT WINAPI d3dx_effect_DeleteParameterBlock(ID3DXEffect *iface, D3DXHANDLE parameter_block)
4272 struct d3dx_parameter_block *block = get_valid_parameter_block(parameter_block);
4273 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4274 struct d3dx_parameter_block *b;
4276 TRACE("iface %p, parameter_block %p.\n", iface, parameter_block);
4278 if (!block)
4279 return D3DERR_INVALIDCALL;
4281 LIST_FOR_EACH_ENTRY(b, &effect->parameter_block_list, struct d3dx_parameter_block, entry)
4283 if (b == block)
4285 list_remove(&b->entry);
4286 free_parameter_block(b);
4287 return D3D_OK;
4291 WARN("Block is not found in issued block list, not freeing memory.\n");
4292 return D3DERR_INVALIDCALL;
4294 #endif
4296 static HRESULT WINAPI d3dx_effect_CloneEffect(ID3DXEffect *iface, IDirect3DDevice9 *device,
4297 ID3DXEffect **new_effect)
4299 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4301 FIXME("iface %p, device %p, new_effect %p stub.\n", effect, device, new_effect);
4303 if (!new_effect)
4304 return D3DERR_INVALIDCALL;
4306 if (effect->flags & D3DXFX_NOT_CLONEABLE)
4307 return E_FAIL;
4309 if (!device)
4310 return D3DERR_INVALIDCALL;
4312 return E_NOTIMPL;
4315 #if D3DX_SDK_VERSION >= 27
4316 static HRESULT WINAPI d3dx_effect_SetRawValue(ID3DXEffect *iface, D3DXHANDLE parameter, const void *data,
4317 UINT byte_offset, UINT bytes)
4319 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4320 iface, parameter, data, byte_offset, bytes);
4322 return E_NOTIMPL;
4324 #endif
4326 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
4328 /*** IUnknown methods ***/
4329 d3dx_effect_QueryInterface,
4330 d3dx_effect_AddRef,
4331 d3dx_effect_Release,
4332 /*** ID3DXBaseEffect methods ***/
4333 d3dx_effect_GetDesc,
4334 d3dx_effect_GetParameterDesc,
4335 d3dx_effect_GetTechniqueDesc,
4336 d3dx_effect_GetPassDesc,
4337 d3dx_effect_GetFunctionDesc,
4338 d3dx_effect_GetParameter,
4339 d3dx_effect_GetParameterByName,
4340 d3dx_effect_GetParameterBySemantic,
4341 d3dx_effect_GetParameterElement,
4342 d3dx_effect_GetTechnique,
4343 d3dx_effect_GetTechniqueByName,
4344 d3dx_effect_GetPass,
4345 d3dx_effect_GetPassByName,
4346 d3dx_effect_GetFunction,
4347 d3dx_effect_GetFunctionByName,
4348 d3dx_effect_GetAnnotation,
4349 d3dx_effect_GetAnnotationByName,
4350 d3dx_effect_SetValue,
4351 d3dx_effect_GetValue,
4352 d3dx_effect_SetBool,
4353 d3dx_effect_GetBool,
4354 d3dx_effect_SetBoolArray,
4355 d3dx_effect_GetBoolArray,
4356 d3dx_effect_SetInt,
4357 d3dx_effect_GetInt,
4358 d3dx_effect_SetIntArray,
4359 d3dx_effect_GetIntArray,
4360 d3dx_effect_SetFloat,
4361 d3dx_effect_GetFloat,
4362 d3dx_effect_SetFloatArray,
4363 d3dx_effect_GetFloatArray,
4364 d3dx_effect_SetVector,
4365 d3dx_effect_GetVector,
4366 d3dx_effect_SetVectorArray,
4367 d3dx_effect_GetVectorArray,
4368 d3dx_effect_SetMatrix,
4369 d3dx_effect_GetMatrix,
4370 d3dx_effect_SetMatrixArray,
4371 d3dx_effect_GetMatrixArray,
4372 d3dx_effect_SetMatrixPointerArray,
4373 d3dx_effect_GetMatrixPointerArray,
4374 d3dx_effect_SetMatrixTranspose,
4375 d3dx_effect_GetMatrixTranspose,
4376 d3dx_effect_SetMatrixTransposeArray,
4377 d3dx_effect_GetMatrixTransposeArray,
4378 d3dx_effect_SetMatrixTransposePointerArray,
4379 d3dx_effect_GetMatrixTransposePointerArray,
4380 d3dx_effect_SetString,
4381 d3dx_effect_GetString,
4382 d3dx_effect_SetTexture,
4383 d3dx_effect_GetTexture,
4384 d3dx_effect_GetPixelShader,
4385 d3dx_effect_GetVertexShader,
4386 d3dx_effect_SetArrayRange,
4387 /*** ID3DXEffect methods ***/
4388 d3dx_effect_GetPool,
4389 d3dx_effect_SetTechnique,
4390 d3dx_effect_GetCurrentTechnique,
4391 d3dx_effect_ValidateTechnique,
4392 d3dx_effect_FindNextValidTechnique,
4393 d3dx_effect_IsParameterUsed,
4394 d3dx_effect_Begin,
4395 d3dx_effect_BeginPass,
4396 d3dx_effect_CommitChanges,
4397 d3dx_effect_EndPass,
4398 d3dx_effect_End,
4399 d3dx_effect_GetDevice,
4400 d3dx_effect_OnLostDevice,
4401 d3dx_effect_OnResetDevice,
4402 d3dx_effect_SetStateManager,
4403 d3dx_effect_GetStateManager,
4404 d3dx_effect_BeginParameterBlock,
4405 d3dx_effect_EndParameterBlock,
4406 d3dx_effect_ApplyParameterBlock,
4407 #if D3DX_SDK_VERSION >= 26
4408 d3dx_effect_DeleteParameterBlock,
4409 #endif
4410 d3dx_effect_CloneEffect,
4411 #if D3DX_SDK_VERSION >= 27
4412 d3dx_effect_SetRawValue
4413 #endif
4416 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
4418 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
4421 /*** IUnknown methods ***/
4422 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
4424 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
4426 if (IsEqualGUID(riid, &IID_IUnknown)
4427 || IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
4429 iface->lpVtbl->AddRef(iface);
4430 *object = iface;
4431 return S_OK;
4434 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
4436 *object = NULL;
4437 return E_NOINTERFACE;
4440 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
4442 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4443 ULONG refcount = InterlockedIncrement(&compiler->ref);
4445 TRACE("%p increasing refcount to %u.\n", iface, refcount);
4447 return refcount;
4450 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
4452 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4453 ULONG refcount = InterlockedDecrement(&compiler->ref);
4455 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
4457 if (!refcount)
4459 heap_free(compiler);
4462 return refcount;
4465 /*** ID3DXBaseEffect methods ***/
4466 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
4468 FIXME("iface %p, desc %p stub!\n", iface, desc);
4470 return E_NOTIMPL;
4473 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface,
4474 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
4476 FIXME("iface %p, parameter %p, desc %p stub!\n", iface, parameter, desc);
4478 return E_NOTIMPL;
4481 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface,
4482 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
4484 FIXME("iface %p, technique %p, desc %p stub!\n", iface, technique, desc);
4486 return E_NOTIMPL;
4489 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface,
4490 D3DXHANDLE pass, D3DXPASS_DESC *desc)
4492 FIXME("iface %p, pass %p, desc %p stub!\n", iface, pass, desc);
4494 return E_NOTIMPL;
4497 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface,
4498 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
4500 FIXME("iface %p, shader %p, desc %p stub!\n", iface, shader, desc);
4502 return E_NOTIMPL;
4505 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface,
4506 D3DXHANDLE parameter, UINT index)
4508 FIXME("iface %p, parameter %p, index %u stub!\n", iface, parameter, index);
4510 return NULL;
4513 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface,
4514 D3DXHANDLE parameter, const char *name)
4516 FIXME("iface %p, parameter %p, name %s stub!\n", iface, parameter, debugstr_a(name));
4518 return NULL;
4521 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface,
4522 D3DXHANDLE parameter, const char *semantic)
4524 FIXME("iface %p, parameter %p, semantic %s stub!\n", iface, parameter, debugstr_a(semantic));
4526 return NULL;
4529 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface,
4530 D3DXHANDLE parameter, UINT index)
4532 FIXME("iface %p, parameter %p, index %u stub!\n", iface, parameter, index);
4534 return NULL;
4537 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
4539 FIXME("iface %p, index %u stub!\n", iface, index);
4541 return NULL;
4544 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name)
4546 FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name));
4548 return NULL;
4551 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
4553 FIXME("iface %p, technique %p, index %u stub!\n", iface, technique, index);
4555 return NULL;
4558 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface,
4559 D3DXHANDLE technique, const char *name)
4561 FIXME("iface %p, technique %p, name %s stub!\n", iface, technique, debugstr_a(name));
4563 return NULL;
4566 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
4568 FIXME("iface %p, index %u stub!\n", iface, index);
4570 return NULL;
4573 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name)
4575 FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name));
4577 return NULL;
4580 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface,
4581 D3DXHANDLE object, UINT index)
4583 FIXME("iface %p, object %p, index %u stub!\n", iface, object, index);
4585 return NULL;
4588 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface,
4589 D3DXHANDLE object, const char *name)
4591 FIXME("iface %p, object %p, name %s stub!\n", iface, object, debugstr_a(name));
4593 return NULL;
4596 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface,
4597 D3DXHANDLE parameter, const void *data, UINT bytes)
4599 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface, parameter, data, bytes);
4601 return E_NOTIMPL;
4604 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface,
4605 D3DXHANDLE parameter, void *data, UINT bytes)
4607 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface, parameter, data, bytes);
4609 return E_NOTIMPL;
4612 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4614 FIXME("iface %p, parameter %p, b %#x stub!\n", iface, parameter, b);
4616 return E_NOTIMPL;
4619 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4621 FIXME("iface %p, parameter %p, b %p stub!\n", iface, parameter, b);
4623 return E_NOTIMPL;
4626 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface,
4627 D3DXHANDLE parameter, const BOOL *b, UINT count)
4629 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface, parameter, b, count);
4631 return E_NOTIMPL;
4634 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface,
4635 D3DXHANDLE parameter, BOOL *b, UINT count)
4637 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface, parameter, b, count);
4639 return E_NOTIMPL;
4642 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4644 FIXME("iface %p, parameter %p, n %d stub!\n", iface, parameter, n);
4646 return E_NOTIMPL;
4649 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4651 FIXME("iface %p, parameter %p, n %p stub!\n", iface, parameter, n);
4653 return E_NOTIMPL;
4656 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface,
4657 D3DXHANDLE parameter, const INT *n, UINT count)
4659 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface, parameter, n, count);
4661 return E_NOTIMPL;
4664 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface,
4665 D3DXHANDLE parameter, INT *n, UINT count)
4667 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface, parameter, n, count);
4669 return E_NOTIMPL;
4672 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f)
4674 FIXME("iface %p, parameter %p, f %.8e stub!\n", iface, parameter, f);
4676 return E_NOTIMPL;
4679 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f)
4681 FIXME("iface %p, parameter %p, f %p stub!\n", iface, parameter, f);
4683 return E_NOTIMPL;
4686 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface,
4687 D3DXHANDLE parameter, const float *f, UINT count)
4689 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface, parameter, f, count);
4691 return E_NOTIMPL;
4694 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface,
4695 D3DXHANDLE parameter, float *f, UINT count)
4697 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface, parameter, f, count);
4699 return E_NOTIMPL;
4702 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface,
4703 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
4705 FIXME("iface %p, parameter %p, vector %p stub!\n", iface, parameter, vector);
4707 return E_NOTIMPL;
4710 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface,
4711 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4713 FIXME("iface %p, parameter %p, vector %p stub!\n", iface, parameter, vector);
4715 return E_NOTIMPL;
4718 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface,
4719 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
4721 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface, parameter, vector, count);
4723 return E_NOTIMPL;
4726 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface,
4727 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4729 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface, parameter, vector, count);
4731 return E_NOTIMPL;
4734 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface,
4735 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4737 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4739 return E_NOTIMPL;
4742 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface,
4743 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4745 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4747 return E_NOTIMPL;
4750 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface,
4751 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4753 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4755 return E_NOTIMPL;
4758 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface,
4759 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4761 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4763 return E_NOTIMPL;
4766 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface,
4767 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4769 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4771 return E_NOTIMPL;
4774 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface,
4775 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4777 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4779 return E_NOTIMPL;
4782 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface,
4783 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4785 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4787 return E_NOTIMPL;
4790 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface,
4791 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4793 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4795 return E_NOTIMPL;
4798 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4799 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4801 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4803 return E_NOTIMPL;
4806 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4807 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4809 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4811 return E_NOTIMPL;
4814 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4815 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4817 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4819 return E_NOTIMPL;
4822 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4823 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4825 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4827 return E_NOTIMPL;
4830 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface,
4831 D3DXHANDLE parameter, const char *string)
4833 FIXME("iface %p, parameter %p, string %s stub!\n", iface, parameter, debugstr_a(string));
4835 return E_NOTIMPL;
4838 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface,
4839 D3DXHANDLE parameter, const char **string)
4841 FIXME("iface %p, parameter %p, string %p stub!\n", iface, parameter, string);
4843 return E_NOTIMPL;
4846 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
4847 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
4849 FIXME("iface %p, parameter %p, texture %p stub!\n", iface, parameter, texture);
4851 return E_NOTIMPL;
4854 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
4855 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
4857 FIXME("iface %p, parameter %p, texture %p stub!\n", iface, parameter, texture);
4859 return E_NOTIMPL;
4862 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
4863 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
4865 FIXME("iface %p, parameter %p, shader %p stub!\n", iface, parameter, shader);
4867 return E_NOTIMPL;
4870 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
4871 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
4873 FIXME("iface %p, parameter %p, shader %p stub!\n", iface, parameter, shader);
4875 return E_NOTIMPL;
4878 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface,
4879 D3DXHANDLE parameter, UINT start, UINT end)
4881 FIXME("iface %p, parameter %p, start %u, end %u stub!\n", iface, parameter, start, end);
4883 return E_NOTIMPL;
4886 /*** ID3DXEffectCompiler methods ***/
4887 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
4889 FIXME("iface %p, parameter %p, literal %#x stub!\n", iface, parameter, literal);
4891 return E_NOTIMPL;
4894 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
4896 FIXME("iface %p, parameter %p, literal %p stub!\n", iface, parameter, literal);
4898 return E_NOTIMPL;
4901 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
4902 ID3DXBuffer **effect, ID3DXBuffer **error_msgs)
4904 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub!\n", iface, flags, effect, error_msgs);
4906 return E_NOTIMPL;
4909 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
4910 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs,
4911 ID3DXConstantTable **constant_table)
4913 FIXME("iface %p, function %p, target %s, flags %#x, shader %p, error_msgs %p, constant_table %p stub!\n",
4914 iface, function, debugstr_a(target), flags, shader, error_msgs, constant_table);
4916 return E_NOTIMPL;
4919 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
4921 /*** IUnknown methods ***/
4922 ID3DXEffectCompilerImpl_QueryInterface,
4923 ID3DXEffectCompilerImpl_AddRef,
4924 ID3DXEffectCompilerImpl_Release,
4925 /*** ID3DXBaseEffect methods ***/
4926 ID3DXEffectCompilerImpl_GetDesc,
4927 ID3DXEffectCompilerImpl_GetParameterDesc,
4928 ID3DXEffectCompilerImpl_GetTechniqueDesc,
4929 ID3DXEffectCompilerImpl_GetPassDesc,
4930 ID3DXEffectCompilerImpl_GetFunctionDesc,
4931 ID3DXEffectCompilerImpl_GetParameter,
4932 ID3DXEffectCompilerImpl_GetParameterByName,
4933 ID3DXEffectCompilerImpl_GetParameterBySemantic,
4934 ID3DXEffectCompilerImpl_GetParameterElement,
4935 ID3DXEffectCompilerImpl_GetTechnique,
4936 ID3DXEffectCompilerImpl_GetTechniqueByName,
4937 ID3DXEffectCompilerImpl_GetPass,
4938 ID3DXEffectCompilerImpl_GetPassByName,
4939 ID3DXEffectCompilerImpl_GetFunction,
4940 ID3DXEffectCompilerImpl_GetFunctionByName,
4941 ID3DXEffectCompilerImpl_GetAnnotation,
4942 ID3DXEffectCompilerImpl_GetAnnotationByName,
4943 ID3DXEffectCompilerImpl_SetValue,
4944 ID3DXEffectCompilerImpl_GetValue,
4945 ID3DXEffectCompilerImpl_SetBool,
4946 ID3DXEffectCompilerImpl_GetBool,
4947 ID3DXEffectCompilerImpl_SetBoolArray,
4948 ID3DXEffectCompilerImpl_GetBoolArray,
4949 ID3DXEffectCompilerImpl_SetInt,
4950 ID3DXEffectCompilerImpl_GetInt,
4951 ID3DXEffectCompilerImpl_SetIntArray,
4952 ID3DXEffectCompilerImpl_GetIntArray,
4953 ID3DXEffectCompilerImpl_SetFloat,
4954 ID3DXEffectCompilerImpl_GetFloat,
4955 ID3DXEffectCompilerImpl_SetFloatArray,
4956 ID3DXEffectCompilerImpl_GetFloatArray,
4957 ID3DXEffectCompilerImpl_SetVector,
4958 ID3DXEffectCompilerImpl_GetVector,
4959 ID3DXEffectCompilerImpl_SetVectorArray,
4960 ID3DXEffectCompilerImpl_GetVectorArray,
4961 ID3DXEffectCompilerImpl_SetMatrix,
4962 ID3DXEffectCompilerImpl_GetMatrix,
4963 ID3DXEffectCompilerImpl_SetMatrixArray,
4964 ID3DXEffectCompilerImpl_GetMatrixArray,
4965 ID3DXEffectCompilerImpl_SetMatrixPointerArray,
4966 ID3DXEffectCompilerImpl_GetMatrixPointerArray,
4967 ID3DXEffectCompilerImpl_SetMatrixTranspose,
4968 ID3DXEffectCompilerImpl_GetMatrixTranspose,
4969 ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
4970 ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
4971 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
4972 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
4973 ID3DXEffectCompilerImpl_SetString,
4974 ID3DXEffectCompilerImpl_GetString,
4975 ID3DXEffectCompilerImpl_SetTexture,
4976 ID3DXEffectCompilerImpl_GetTexture,
4977 ID3DXEffectCompilerImpl_GetPixelShader,
4978 ID3DXEffectCompilerImpl_GetVertexShader,
4979 ID3DXEffectCompilerImpl_SetArrayRange,
4980 /*** ID3DXEffectCompiler methods ***/
4981 ID3DXEffectCompilerImpl_SetLiteral,
4982 ID3DXEffectCompilerImpl_GetLiteral,
4983 ID3DXEffectCompilerImpl_CompileEffect,
4984 ID3DXEffectCompilerImpl_CompileShader,
4987 static HRESULT d3dx_parse_sampler(struct d3dx_effect *effect, struct d3dx_sampler *sampler,
4988 const char *data, const char **ptr, struct d3dx_object *objects)
4990 HRESULT hr;
4991 UINT i;
4993 read_dword(ptr, &sampler->state_count);
4994 TRACE("Count: %u\n", sampler->state_count);
4996 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count);
4997 if (!sampler->states)
4999 ERR("Out of memory\n");
5000 return E_OUTOFMEMORY;
5003 for (i = 0; i < sampler->state_count; ++i)
5005 hr = d3dx_parse_state(effect, &sampler->states[i], data, ptr, objects);
5006 if (hr != D3D_OK)
5008 WARN("Failed to parse state %u\n", i);
5009 goto err_out;
5013 return D3D_OK;
5015 err_out:
5017 for (i = 0; i < sampler->state_count; ++i)
5019 free_state(&sampler->states[i]);
5021 HeapFree(GetProcessHeap(), 0, sampler->states);
5022 sampler->states = NULL;
5024 return hr;
5027 static HRESULT d3dx_parse_value(struct d3dx_effect *effect, struct d3dx_parameter *param,
5028 void *value, const char *data, const char **ptr, struct d3dx_object *objects)
5030 unsigned int i;
5031 HRESULT hr;
5032 UINT old_size = 0;
5034 if (param->element_count)
5036 param->data = value;
5038 for (i = 0; i < param->element_count; ++i)
5040 struct d3dx_parameter *member = &param->members[i];
5042 hr = d3dx_parse_value(effect, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
5043 if (hr != D3D_OK)
5045 WARN("Failed to parse value %u\n", i);
5046 return hr;
5049 old_size += member->bytes;
5052 return D3D_OK;
5055 switch(param->class)
5057 case D3DXPC_SCALAR:
5058 case D3DXPC_VECTOR:
5059 case D3DXPC_MATRIX_ROWS:
5060 case D3DXPC_MATRIX_COLUMNS:
5061 param->data = value;
5062 break;
5064 case D3DXPC_STRUCT:
5065 param->data = value;
5067 for (i = 0; i < param->member_count; ++i)
5069 struct d3dx_parameter *member = &param->members[i];
5071 hr = d3dx_parse_value(effect, member, (char *)value + old_size, data, ptr, objects);
5072 if (hr != D3D_OK)
5074 WARN("Failed to parse value %u\n", i);
5075 return hr;
5078 old_size += member->bytes;
5080 break;
5082 case D3DXPC_OBJECT:
5083 switch (param->type)
5085 case D3DXPT_STRING:
5086 case D3DXPT_TEXTURE:
5087 case D3DXPT_TEXTURE1D:
5088 case D3DXPT_TEXTURE2D:
5089 case D3DXPT_TEXTURE3D:
5090 case D3DXPT_TEXTURECUBE:
5091 case D3DXPT_PIXELSHADER:
5092 case D3DXPT_VERTEXSHADER:
5093 read_dword(ptr, &param->object_id);
5094 TRACE("Id: %u\n", param->object_id);
5095 objects[param->object_id].param = param;
5096 param->data = value;
5097 break;
5099 case D3DXPT_SAMPLER:
5100 case D3DXPT_SAMPLER1D:
5101 case D3DXPT_SAMPLER2D:
5102 case D3DXPT_SAMPLER3D:
5103 case D3DXPT_SAMPLERCUBE:
5105 struct d3dx_sampler *sampler;
5107 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
5108 if (!sampler)
5109 return E_OUTOFMEMORY;
5111 hr = d3dx_parse_sampler(effect, sampler, data, ptr, objects);
5112 if (hr != D3D_OK)
5114 HeapFree(GetProcessHeap(), 0, sampler);
5115 WARN("Failed to parse sampler\n");
5116 return hr;
5119 param->data = sampler;
5120 break;
5123 default:
5124 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5125 break;
5127 break;
5129 default:
5130 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5131 break;
5134 return D3D_OK;
5137 static HRESULT d3dx_parse_init_value(struct d3dx_effect *effect, struct d3dx_parameter *param,
5138 const char *data, const char *ptr, struct d3dx_object *objects)
5140 UINT size = param->bytes;
5141 HRESULT hr;
5142 void *value = NULL;
5144 TRACE("param size: %u\n", size);
5146 if (size)
5148 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5149 if (!value)
5151 ERR("Failed to allocate data memory.\n");
5152 return E_OUTOFMEMORY;
5155 switch(param->class)
5157 case D3DXPC_OBJECT:
5158 break;
5160 case D3DXPC_SCALAR:
5161 case D3DXPC_VECTOR:
5162 case D3DXPC_MATRIX_ROWS:
5163 case D3DXPC_MATRIX_COLUMNS:
5164 case D3DXPC_STRUCT:
5165 TRACE("Data: %s.\n", debugstr_an(ptr, size));
5166 memcpy(value, ptr, size);
5167 break;
5169 default:
5170 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5171 break;
5175 hr = d3dx_parse_value(effect, param, value, data, &ptr, objects);
5176 if (hr != D3D_OK)
5178 WARN("Failed to parse value\n");
5179 HeapFree(GetProcessHeap(), 0, value);
5180 return hr;
5183 return D3D_OK;
5186 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
5188 DWORD size;
5190 read_dword(&ptr, &size);
5191 TRACE("Name size: %#x\n", size);
5193 if (!size)
5195 return D3D_OK;
5198 *name = HeapAlloc(GetProcessHeap(), 0, size);
5199 if (!*name)
5201 ERR("Failed to allocate name memory.\n");
5202 return E_OUTOFMEMORY;
5205 TRACE("Name: %s.\n", debugstr_an(ptr, size));
5206 memcpy(*name, ptr, size);
5208 return D3D_OK;
5211 static HRESULT d3dx9_copy_data(struct d3dx_effect *effect, unsigned int object_id, const char **ptr)
5213 struct d3dx_object *object = &effect->objects[object_id];
5215 if (object->size || object->data)
5217 if (object_id)
5218 FIXME("Overwriting object id %u!\n", object_id);
5219 else
5220 TRACE("Overwriting object id 0.\n");
5222 HeapFree(GetProcessHeap(), 0, object->data);
5223 object->data = NULL;
5226 read_dword(ptr, &object->size);
5227 TRACE("Data size: %#x.\n", object->size);
5229 if (!object->size)
5230 return D3D_OK;
5232 object->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5233 if (!object->data)
5235 ERR("Failed to allocate object memory.\n");
5236 return E_OUTOFMEMORY;
5239 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size));
5240 memcpy(object->data, *ptr, object->size);
5242 *ptr += ((object->size + 3) & ~3);
5244 return D3D_OK;
5247 static void param_set_magic_number(struct d3dx_parameter *param)
5249 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string));
5252 static int param_rb_compare(const void *key, const struct wine_rb_entry *entry)
5254 const char *name = key;
5255 struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
5257 return strcmp(name, param->full_name);
5260 static void add_param_to_tree(struct d3dx_effect *effect, struct d3dx_parameter *param,
5261 struct d3dx_parameter *parent, char separator, unsigned int element)
5263 const char *parent_name = parent ? parent->full_name : NULL;
5264 unsigned int i;
5266 TRACE("Adding parameter %p (%s - parent %p, element %u) to the rbtree.\n",
5267 param, debugstr_a(param->name), parent, element);
5269 if (parent_name)
5271 unsigned int parent_name_len = strlen(parent_name);
5272 unsigned int name_len = strlen(param->name);
5273 unsigned int part_str_len;
5274 unsigned int len;
5275 char part_str[16];
5277 if (separator == '[')
5279 sprintf(part_str, "[%u]", element);
5280 part_str_len = strlen(part_str);
5281 name_len = 0;
5283 else
5285 part_str[0] = separator;
5286 part_str[1] = 0;
5287 part_str_len = 1;
5289 len = parent_name_len + part_str_len + name_len + 1;
5291 if (!(param->full_name = heap_alloc(len)))
5293 ERR("Out of memory.\n");
5294 return;
5297 memcpy(param->full_name, parent_name, parent_name_len);
5298 memcpy(param->full_name + parent_name_len, part_str, part_str_len);
5299 memcpy(param->full_name + parent_name_len + part_str_len, param->name, name_len);
5300 param->full_name[len - 1] = 0;
5302 else
5304 unsigned int len = strlen(param->name) + 1;
5306 if (!(param->full_name = heap_alloc(len)))
5308 ERR("Out of memory.\n");
5309 return;
5312 memcpy(param->full_name, param->name, len);
5314 TRACE("Full name is %s.\n", param->full_name);
5315 wine_rb_put(&effect->param_tree, param->full_name, &param->rb_entry);
5317 if (is_top_level_parameter(param))
5318 for (i = 0; i < param->top_level_param->annotation_count; ++i)
5319 add_param_to_tree(effect, &param->top_level_param->annotations[i], param, '@', 0);
5321 if (param->element_count)
5322 for (i = 0; i < param->element_count; ++i)
5323 add_param_to_tree(effect, &param->members[i], param, '[', i);
5324 else
5325 for (i = 0; i < param->member_count; ++i)
5326 add_param_to_tree(effect, &param->members[i], param, '.', 0);
5329 static HRESULT d3dx_parse_effect_typedef(struct d3dx_effect *effect, struct d3dx_parameter *param,
5330 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
5332 DWORD offset;
5333 HRESULT hr;
5334 UINT i;
5336 param->flags = flags;
5338 if (!parent)
5340 read_dword(ptr, (DWORD *)&param->type);
5341 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
5343 read_dword(ptr, (DWORD *)&param->class);
5344 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
5346 read_dword(ptr, &offset);
5347 TRACE("Type name offset: %#x\n", offset);
5348 hr = d3dx9_parse_name(&param->name, data + offset);
5349 if (hr != D3D_OK)
5351 WARN("Failed to parse name\n");
5352 goto err_out;
5355 read_dword(ptr, &offset);
5356 TRACE("Type semantic offset: %#x\n", offset);
5357 hr = d3dx9_parse_name(&param->semantic, data + offset);
5358 if (hr != D3D_OK)
5360 WARN("Failed to parse semantic\n");
5361 goto err_out;
5364 read_dword(ptr, &param->element_count);
5365 TRACE("Elements: %u\n", param->element_count);
5367 switch (param->class)
5369 case D3DXPC_VECTOR:
5370 read_dword(ptr, &param->columns);
5371 TRACE("Columns: %u\n", param->columns);
5373 read_dword(ptr, &param->rows);
5374 TRACE("Rows: %u\n", param->rows);
5376 /* sizeof(DWORD) * rows * columns */
5377 param->bytes = 4 * param->rows * param->columns;
5378 break;
5380 case D3DXPC_SCALAR:
5381 case D3DXPC_MATRIX_ROWS:
5382 case D3DXPC_MATRIX_COLUMNS:
5383 read_dword(ptr, &param->rows);
5384 TRACE("Rows: %u\n", param->rows);
5386 read_dword(ptr, &param->columns);
5387 TRACE("Columns: %u\n", param->columns);
5389 /* sizeof(DWORD) * rows * columns */
5390 param->bytes = 4 * param->rows * param->columns;
5391 break;
5393 case D3DXPC_STRUCT:
5394 read_dword(ptr, &param->member_count);
5395 TRACE("Members: %u\n", param->member_count);
5396 break;
5398 case D3DXPC_OBJECT:
5399 switch (param->type)
5401 case D3DXPT_STRING:
5402 case D3DXPT_PIXELSHADER:
5403 case D3DXPT_VERTEXSHADER:
5404 case D3DXPT_TEXTURE:
5405 case D3DXPT_TEXTURE1D:
5406 case D3DXPT_TEXTURE2D:
5407 case D3DXPT_TEXTURE3D:
5408 case D3DXPT_TEXTURECUBE:
5409 param->bytes = sizeof(void *);
5410 break;
5412 case D3DXPT_SAMPLER:
5413 case D3DXPT_SAMPLER1D:
5414 case D3DXPT_SAMPLER2D:
5415 case D3DXPT_SAMPLER3D:
5416 case D3DXPT_SAMPLERCUBE:
5417 param->bytes = 0;
5418 break;
5420 default:
5421 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5422 break;
5424 break;
5426 default:
5427 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5428 break;
5431 else
5433 /* elements */
5434 param->type = parent->type;
5435 param->class = parent->class;
5436 param->name = parent->name;
5437 param->semantic = parent->semantic;
5438 param->element_count = 0;
5439 param->member_count = parent->member_count;
5440 param->bytes = parent->bytes;
5441 param->rows = parent->rows;
5442 param->columns = parent->columns;
5445 if (param->element_count)
5447 unsigned int param_bytes = 0;
5448 const char *save_ptr = *ptr;
5450 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count);
5451 if (!param->members)
5453 ERR("Out of memory\n");
5454 hr = E_OUTOFMEMORY;
5455 goto err_out;
5458 for (i = 0; i < param->element_count; ++i)
5460 *ptr = save_ptr;
5462 param_set_magic_number(&param->members[i]);
5463 hr = d3dx_parse_effect_typedef(effect, &param->members[i], data, ptr, param, flags);
5464 if (hr != D3D_OK)
5466 WARN("Failed to parse member %u\n", i);
5467 goto err_out;
5470 param_bytes += param->members[i].bytes;
5473 param->bytes = param_bytes;
5475 else if (param->member_count)
5477 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count);
5478 if (!param->members)
5480 ERR("Out of memory\n");
5481 hr = E_OUTOFMEMORY;
5482 goto err_out;
5485 for (i = 0; i < param->member_count; ++i)
5487 param_set_magic_number(&param->members[i]);
5488 hr = d3dx_parse_effect_typedef(effect, &param->members[i], data, ptr, NULL, flags);
5489 if (hr != D3D_OK)
5491 WARN("Failed to parse member %u\n", i);
5492 goto err_out;
5495 param->bytes += param->members[i].bytes;
5498 return D3D_OK;
5500 err_out:
5502 if (param->members)
5504 unsigned int count = param->element_count ? param->element_count : param->member_count;
5506 for (i = 0; i < count; ++i)
5507 free_parameter(&param->members[i], param->element_count != 0, TRUE);
5508 HeapFree(GetProcessHeap(), 0, param->members);
5509 param->members = NULL;
5512 if (!parent)
5514 HeapFree(GetProcessHeap(), 0, param->name);
5515 HeapFree(GetProcessHeap(), 0, param->semantic);
5517 param->name = NULL;
5518 param->semantic = NULL;
5520 return hr;
5523 static HRESULT d3dx_parse_effect_annotation(struct d3dx_effect *effect, struct d3dx_parameter *anno,
5524 const char *data, const char **ptr, struct d3dx_object *objects)
5526 DWORD offset;
5527 const char *ptr2;
5528 HRESULT hr;
5530 anno->flags = D3DX_PARAMETER_ANNOTATION;
5532 read_dword(ptr, &offset);
5533 TRACE("Typedef offset: %#x\n", offset);
5534 ptr2 = data + offset;
5535 hr = d3dx_parse_effect_typedef(effect, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5536 if (hr != D3D_OK)
5538 WARN("Failed to parse type definition\n");
5539 return hr;
5542 read_dword(ptr, &offset);
5543 TRACE("Value offset: %#x\n", offset);
5544 hr = d3dx_parse_init_value(effect, anno, data, data + offset, objects);
5545 if (hr != D3D_OK)
5547 WARN("Failed to parse value\n");
5548 return hr;
5551 return D3D_OK;
5554 static HRESULT d3dx_parse_state(struct d3dx_effect *effect, struct d3dx_state *state,
5555 const char *data, const char **ptr, struct d3dx_object *objects)
5557 struct d3dx_parameter *param = &state->parameter;
5558 enum STATE_CLASS state_class;
5559 const char *ptr2;
5560 void *new_data;
5561 DWORD offset;
5562 HRESULT hr;
5564 state->type = ST_CONSTANT;
5566 read_dword(ptr, &state->operation);
5567 if (state->operation >= ARRAY_SIZE(state_table))
5569 WARN("Unknown state operation %u.\n", state->operation);
5570 return D3DERR_INVALIDCALL;
5573 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5575 read_dword(ptr, &state->index);
5576 TRACE("Index: %#x\n", state->index);
5578 read_dword(ptr, &offset);
5579 TRACE("Typedef offset: %#x\n", offset);
5580 ptr2 = data + offset;
5581 hr = d3dx_parse_effect_typedef(effect, param, data, &ptr2, NULL, 0);
5582 if (hr != D3D_OK)
5584 WARN("Failed to parse type definition\n");
5585 goto err_out;
5588 read_dword(ptr, &offset);
5589 TRACE("Value offset: %#x\n", offset);
5590 hr = d3dx_parse_init_value(effect, param, data, data + offset, objects);
5591 if (hr != D3D_OK)
5593 WARN("Failed to parse value\n");
5594 goto err_out;
5597 if (((state_class = state_table[state->operation].class) == SC_VERTEXSHADER
5598 || state_class == SC_PIXELSHADER || state_class == SC_TEXTURE)
5599 && param->bytes < sizeof(void *))
5601 if (param->type != D3DXPT_INT || *(unsigned int *)param->data)
5603 FIXME("Unexpected parameter for object, param->type %#x, param->class %#x, *param->data %#x.\n",
5604 param->type, param->class, *(unsigned int *)param->data);
5605 hr = D3DXERR_INVALIDDATA;
5606 goto err_out;
5609 new_data = heap_realloc(param->data, sizeof(void *));
5610 if (!new_data)
5612 ERR("Out of memory.\n");
5613 hr = E_OUTOFMEMORY;
5614 goto err_out;
5616 memset(new_data, 0, sizeof(void *));
5617 param->data = new_data;
5618 param->bytes = sizeof(void *);
5621 return D3D_OK;
5623 err_out:
5625 free_parameter(param, FALSE, FALSE);
5627 return hr;
5630 static HRESULT d3dx_parse_effect_parameter(struct d3dx_effect *effect, struct d3dx_top_level_parameter *param,
5631 const char *data, const char **ptr, struct d3dx_object *objects)
5633 DWORD offset;
5634 HRESULT hr;
5635 unsigned int i;
5636 const char *ptr2;
5638 read_dword(ptr, &offset);
5639 TRACE("Typedef offset: %#x.\n", offset);
5640 ptr2 = data + offset;
5642 read_dword(ptr, &offset);
5643 TRACE("Value offset: %#x.\n", offset);
5645 read_dword(ptr, &param->param.flags);
5646 TRACE("Flags: %#x.\n", param->param.flags);
5648 read_dword(ptr, &param->annotation_count);
5649 TRACE("Annotation count: %u.\n", param->annotation_count);
5651 hr = d3dx_parse_effect_typedef(effect, &param->param, data, &ptr2, NULL, param->param.flags);
5652 if (hr != D3D_OK)
5654 WARN("Failed to parse type definition.\n");
5655 return hr;
5658 hr = d3dx_parse_init_value(effect, &param->param, data, data + offset, objects);
5659 if (hr != D3D_OK)
5661 WARN("Failed to parse value.\n");
5662 return hr;
5665 if (param->annotation_count)
5667 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5668 sizeof(*param->annotations) * param->annotation_count);
5669 if (!param->annotations)
5671 ERR("Out of memory.\n");
5672 hr = E_OUTOFMEMORY;
5673 goto err_out;
5676 for (i = 0; i < param->annotation_count; ++i)
5678 param_set_magic_number(&param->annotations[i]);
5679 hr = d3dx_parse_effect_annotation(effect, &param->annotations[i], data, ptr, objects);
5680 if (hr != D3D_OK)
5682 WARN("Failed to parse annotation.\n");
5683 goto err_out;
5688 return D3D_OK;
5690 err_out:
5692 if (param->annotations)
5694 for (i = 0; i < param->annotation_count; ++i)
5695 free_parameter(&param->annotations[i], FALSE, FALSE);
5696 HeapFree(GetProcessHeap(), 0, param->annotations);
5697 param->annotations = NULL;
5700 return hr;
5703 static HRESULT d3dx_parse_effect_pass(struct d3dx_effect *effect, struct d3dx_pass *pass,
5704 const char *data, const char **ptr, struct d3dx_object *objects)
5706 DWORD offset;
5707 HRESULT hr;
5708 unsigned int i;
5709 struct d3dx_state *states = NULL;
5710 char *name = NULL;
5712 read_dword(ptr, &offset);
5713 TRACE("Pass name offset: %#x\n", offset);
5714 hr = d3dx9_parse_name(&name, data + offset);
5715 if (hr != D3D_OK)
5717 WARN("Failed to parse name\n");
5718 goto err_out;
5721 read_dword(ptr, &pass->annotation_count);
5722 TRACE("Annotation count: %u\n", pass->annotation_count);
5724 read_dword(ptr, &pass->state_count);
5725 TRACE("State count: %u\n", pass->state_count);
5727 if (pass->annotation_count)
5729 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5730 sizeof(*pass->annotations) * pass->annotation_count);
5731 if (!pass->annotations)
5733 ERR("Out of memory\n");
5734 hr = E_OUTOFMEMORY;
5735 goto err_out;
5738 for (i = 0; i < pass->annotation_count; ++i)
5740 param_set_magic_number(&pass->annotations[i]);
5741 hr = d3dx_parse_effect_annotation(effect, &pass->annotations[i], data, ptr, objects);
5742 if (hr != D3D_OK)
5744 WARN("Failed to parse annotation %u\n", i);
5745 goto err_out;
5750 if (pass->state_count)
5752 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5753 if (!states)
5755 ERR("Out of memory\n");
5756 hr = E_OUTOFMEMORY;
5757 goto err_out;
5760 for (i = 0; i < pass->state_count; ++i)
5762 hr = d3dx_parse_state(effect, &states[i], data, ptr, objects);
5763 if (hr != D3D_OK)
5765 WARN("Failed to parse annotation %u\n", i);
5766 goto err_out;
5771 pass->name = name;
5772 pass->states = states;
5774 return D3D_OK;
5776 err_out:
5778 if (pass->annotations)
5780 for (i = 0; i < pass->annotation_count; ++i)
5781 free_parameter(&pass->annotations[i], FALSE, FALSE);
5782 HeapFree(GetProcessHeap(), 0, pass->annotations);
5783 pass->annotations = NULL;
5786 if (states)
5788 for (i = 0; i < pass->state_count; ++i)
5790 free_state(&states[i]);
5792 HeapFree(GetProcessHeap(), 0, states);
5795 HeapFree(GetProcessHeap(), 0, name);
5797 return hr;
5800 static HRESULT d3dx_parse_effect_technique(struct d3dx_effect *effect, struct d3dx_technique *technique,
5801 const char *data, const char **ptr, struct d3dx_object *objects)
5803 DWORD offset;
5804 HRESULT hr;
5805 unsigned int i;
5806 char *name = NULL;
5808 read_dword(ptr, &offset);
5809 TRACE("Technique name offset: %#x\n", offset);
5810 hr = d3dx9_parse_name(&name, data + offset);
5811 if (hr != D3D_OK)
5813 WARN("Failed to parse name\n");
5814 goto err_out;
5817 read_dword(ptr, &technique->annotation_count);
5818 TRACE("Annotation count: %u\n", technique->annotation_count);
5820 read_dword(ptr, &technique->pass_count);
5821 TRACE("Pass count: %u\n", technique->pass_count);
5823 if (technique->annotation_count)
5825 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5826 sizeof(*technique->annotations) * technique->annotation_count);
5827 if (!technique->annotations)
5829 ERR("Out of memory\n");
5830 hr = E_OUTOFMEMORY;
5831 goto err_out;
5834 for (i = 0; i < technique->annotation_count; ++i)
5836 param_set_magic_number(&technique->annotations[i]);
5837 hr = d3dx_parse_effect_annotation(effect, &technique->annotations[i], data, ptr, objects);
5838 if (hr != D3D_OK)
5840 WARN("Failed to parse annotation %u\n", i);
5841 goto err_out;
5846 if (technique->pass_count)
5848 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5849 sizeof(*technique->passes) * technique->pass_count);
5850 if (!technique->passes)
5852 ERR("Out of memory\n");
5853 hr = E_OUTOFMEMORY;
5854 goto err_out;
5857 for (i = 0; i < technique->pass_count; ++i)
5859 hr = d3dx_parse_effect_pass(effect, &technique->passes[i], data, ptr, objects);
5860 if (hr != D3D_OK)
5862 WARN("Failed to parse pass %u\n", i);
5863 goto err_out;
5868 technique->name = name;
5870 return D3D_OK;
5872 err_out:
5874 if (technique->passes)
5876 for (i = 0; i < technique->pass_count; ++i)
5877 free_pass(&technique->passes[i]);
5878 HeapFree(GetProcessHeap(), 0, technique->passes);
5879 technique->passes = NULL;
5882 if (technique->annotations)
5884 for (i = 0; i < technique->annotation_count; ++i)
5885 free_parameter(&technique->annotations[i], FALSE, FALSE);
5886 HeapFree(GetProcessHeap(), 0, technique->annotations);
5887 technique->annotations = NULL;
5890 HeapFree(GetProcessHeap(), 0, name);
5892 return hr;
5895 static HRESULT d3dx9_create_object(struct d3dx_effect *effect, struct d3dx_object *object)
5897 struct d3dx_parameter *param = object->param;
5898 IDirect3DDevice9 *device = effect->device;
5899 HRESULT hr;
5901 if (*(char **)param->data)
5902 ERR("Parameter data already allocated.\n");
5904 switch (param->type)
5906 case D3DXPT_STRING:
5907 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5908 if (!*(char **)param->data)
5910 ERR("Out of memory.\n");
5911 return E_OUTOFMEMORY;
5913 memcpy(*(char **)param->data, object->data, object->size);
5914 break;
5915 case D3DXPT_VERTEXSHADER:
5916 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data,
5917 (IDirect3DVertexShader9 **)param->data)))
5919 WARN("Failed to create vertex shader.\n");
5920 object->creation_failed = TRUE;
5922 break;
5923 case D3DXPT_PIXELSHADER:
5924 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data,
5925 (IDirect3DPixelShader9 **)param->data)))
5927 WARN("Failed to create pixel shader.\n");
5928 object->creation_failed = TRUE;
5930 break;
5931 default:
5932 break;
5934 return D3D_OK;
5937 static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx_state *state,
5938 const char **skip_constants, unsigned int skip_constants_count)
5940 DWORD string_size;
5941 struct d3dx_parameter *param = &state->parameter;
5942 struct d3dx_object *object = &effect->objects[param->object_id];
5943 char *ptr = object->data;
5944 HRESULT ret;
5946 TRACE("Parsing array entry selection state for parameter %p.\n", param);
5948 string_size = *(DWORD *)ptr;
5949 state->referenced_param = get_parameter_by_name(effect, NULL, ptr + 4);
5950 if (state->referenced_param)
5952 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
5954 else
5956 FIXME("Referenced parameter %s not found.\n", ptr + 4);
5957 return D3DXERR_INVALIDDATA;
5959 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
5961 if (string_size % sizeof(DWORD))
5962 FIXME("Unaligned string_size %u.\n", string_size);
5963 if (FAILED(ret = d3dx_create_param_eval(effect, (DWORD *)(ptr + string_size) + 1,
5964 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, &param->param_eval,
5965 get_version_counter_ptr(effect), NULL, 0)))
5966 return ret;
5967 ret = D3D_OK;
5968 param = state->referenced_param;
5969 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
5971 unsigned int i;
5973 for (i = 0; i < param->element_count; i++)
5975 if (param->members[i].type != param->type)
5977 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
5978 return D3DXERR_INVALIDDATA;
5980 if (!param->members[i].param_eval)
5982 TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
5983 object = &effect->objects[param->members[i].object_id];
5984 if (FAILED(ret = d3dx_create_param_eval(effect, object->data, object->size, param->type,
5985 &param->members[i].param_eval, get_version_counter_ptr(effect),
5986 skip_constants, skip_constants_count)))
5987 break;
5991 return ret;
5994 static HRESULT d3dx_parse_resource(struct d3dx_effect *effect, const char *data, const char **ptr,
5995 const char **skip_constants, unsigned int skip_constants_count)
5997 DWORD technique_index;
5998 DWORD index, state_index, usage, element_index;
5999 struct d3dx_state *state;
6000 struct d3dx_parameter *param;
6001 struct d3dx_object *object;
6002 HRESULT hr = E_FAIL;
6004 read_dword(ptr, &technique_index);
6005 TRACE("technique_index: %u\n", technique_index);
6007 read_dword(ptr, &index);
6008 TRACE("index: %u\n", index);
6010 read_dword(ptr, &element_index);
6011 TRACE("element_index: %u\n", element_index);
6013 read_dword(ptr, &state_index);
6014 TRACE("state_index: %u\n", state_index);
6016 read_dword(ptr, &usage);
6017 TRACE("usage: %u\n", usage);
6019 if (technique_index == 0xffffffff)
6021 struct d3dx_parameter *parameter;
6022 struct d3dx_sampler *sampler;
6024 if (index >= effect->parameter_count)
6026 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, effect->parameter_count);
6027 return E_FAIL;
6030 parameter = &effect->parameters[index].param;
6031 if (element_index != 0xffffffff)
6033 if (element_index >= parameter->element_count && parameter->element_count != 0)
6035 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
6036 return E_FAIL;
6039 if (parameter->element_count)
6040 parameter = &parameter->members[element_index];
6043 sampler = parameter->data;
6044 if (state_index >= sampler->state_count)
6046 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
6047 return E_FAIL;
6050 state = &sampler->states[state_index];
6052 else
6054 struct d3dx_technique *technique;
6055 struct d3dx_pass *pass;
6057 if (technique_index >= effect->technique_count)
6059 FIXME("Index out of bounds: technique_index %u >= technique_count %u.\n", technique_index,
6060 effect->technique_count);
6061 return E_FAIL;
6064 technique = &effect->techniques[technique_index];
6065 if (index >= technique->pass_count)
6067 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
6068 return E_FAIL;
6071 pass = &technique->passes[index];
6072 if (state_index >= pass->state_count)
6074 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
6075 return E_FAIL;
6078 state = &pass->states[state_index];
6081 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name);
6082 param = &state->parameter;
6083 TRACE("Using object id %u.\n", param->object_id);
6084 object = &effect->objects[param->object_id];
6086 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class),
6087 debug_d3dxparameter_type(param->type));
6088 switch (usage)
6090 case 0:
6091 switch (param->type)
6093 case D3DXPT_VERTEXSHADER:
6094 case D3DXPT_PIXELSHADER:
6095 state->type = ST_CONSTANT;
6096 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6097 return hr;
6099 if (object->data)
6101 if (FAILED(hr = d3dx9_create_object(effect, object)))
6102 return hr;
6103 if (FAILED(hr = d3dx_create_param_eval(effect, object->data, object->size, param->type,
6104 &param->param_eval, get_version_counter_ptr(effect),
6105 skip_constants, skip_constants_count)))
6106 return hr;
6108 break;
6110 case D3DXPT_BOOL:
6111 case D3DXPT_INT:
6112 case D3DXPT_FLOAT:
6113 case D3DXPT_STRING:
6114 state->type = ST_FXLC;
6115 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6116 return hr;
6117 if (FAILED(hr = d3dx_create_param_eval(effect, object->data, object->size, param->type,
6118 &param->param_eval, get_version_counter_ptr(effect), NULL, 0)))
6119 return hr;
6120 break;
6122 default:
6123 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
6124 break;
6126 break;
6128 case 1:
6129 state->type = ST_PARAMETER;
6130 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6131 return hr;
6133 TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
6134 state->referenced_param = get_parameter_by_name(effect, NULL, object->data);
6135 if (state->referenced_param)
6137 struct d3dx_parameter *refpar = state->referenced_param;
6139 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
6140 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
6142 struct d3dx_object *refobj = &effect->objects[refpar->object_id];
6144 if (!refpar->param_eval)
6146 if (FAILED(hr = d3dx_create_param_eval(effect, refobj->data, refobj->size,
6147 refpar->type, &refpar->param_eval, get_version_counter_ptr(effect),
6148 skip_constants, skip_constants_count)))
6149 return hr;
6153 else
6155 FIXME("Referenced parameter %s not found.\n", (char *)object->data);
6156 return D3DXERR_INVALIDDATA;
6158 break;
6160 case 2:
6161 state->type = ST_ARRAY_SELECTOR;
6162 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6163 return hr;
6164 hr = d3dx_parse_array_selector(effect, state, skip_constants, skip_constants_count);
6165 break;
6167 default:
6168 FIXME("Unknown usage %x\n", usage);
6169 break;
6172 return hr;
6175 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param)
6177 param->top_level_param = top_level_param;
6178 return FALSE;
6181 static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, UINT data_size,
6182 DWORD start, const char **skip_constants, unsigned int skip_constants_count)
6184 const char *ptr = data + start;
6185 UINT stringcount, resourcecount;
6186 HRESULT hr;
6187 UINT i;
6189 read_dword(&ptr, &effect->parameter_count);
6190 TRACE("Parameter count: %u.\n", effect->parameter_count);
6192 read_dword(&ptr, &effect->technique_count);
6193 TRACE("Technique count: %u.\n", effect->technique_count);
6195 skip_dword_unknown(&ptr, 1);
6197 read_dword(&ptr, &effect->object_count);
6198 TRACE("Object count: %u.\n", effect->object_count);
6200 effect->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6201 sizeof(*effect->objects) * effect->object_count);
6202 if (!effect->objects)
6204 ERR("Out of memory.\n");
6205 hr = E_OUTOFMEMORY;
6206 goto err_out;
6209 wine_rb_init(&effect->param_tree, param_rb_compare);
6210 if (effect->parameter_count)
6212 effect->parameters = heap_alloc_zero(sizeof(*effect->parameters) * effect->parameter_count);
6213 if (!effect->parameters)
6215 ERR("Out of memory.\n");
6216 hr = E_OUTOFMEMORY;
6217 goto err_out;
6220 for (i = 0; i < effect->parameter_count; ++i)
6222 param_set_magic_number(&effect->parameters[i].param);
6223 hr = d3dx_parse_effect_parameter(effect, &effect->parameters[i], data, &ptr, effect->objects);
6224 if (hr != D3D_OK)
6226 WARN("Failed to parse parameter %u.\n", i);
6227 goto err_out;
6229 walk_parameter_tree(&effect->parameters[i].param, param_set_top_level_param, &effect->parameters[i]);
6230 add_param_to_tree(effect, &effect->parameters[i].param, NULL, 0, 0);
6234 if (effect->technique_count)
6236 effect->techniques = heap_alloc_zero(sizeof(*effect->techniques) * effect->technique_count);
6237 if (!effect->techniques)
6239 ERR("Out of memory.\n");
6240 hr = E_OUTOFMEMORY;
6241 goto err_out;
6244 for (i = 0; i < effect->technique_count; ++i)
6246 TRACE("Parsing technique %u.\n", i);
6247 hr = d3dx_parse_effect_technique(effect, &effect->techniques[i], data, &ptr, effect->objects);
6248 if (hr != D3D_OK)
6250 WARN("Failed to parse technique %u.\n", i);
6251 goto err_out;
6256 read_dword(&ptr, &stringcount);
6257 TRACE("String count: %u.\n", stringcount);
6259 read_dword(&ptr, &resourcecount);
6260 TRACE("Resource count: %u.\n", resourcecount);
6262 for (i = 0; i < stringcount; ++i)
6264 DWORD id;
6266 read_dword(&ptr, &id);
6267 TRACE("id: %u.\n", id);
6269 if (FAILED(hr = d3dx9_copy_data(effect, id, &ptr)))
6270 goto err_out;
6272 if (effect->objects[id].data)
6274 if (FAILED(hr = d3dx9_create_object(effect, &effect->objects[id])))
6275 goto err_out;
6279 for (i = 0; i < resourcecount; ++i)
6281 TRACE("parse resource %u.\n", i);
6283 hr = d3dx_parse_resource(effect, data, &ptr, skip_constants, skip_constants_count);
6284 if (hr != D3D_OK)
6286 WARN("Failed to parse resource %u.\n", i);
6287 goto err_out;
6291 for (i = 0; i < effect->parameter_count; ++i)
6293 if (FAILED(hr = d3dx_pool_sync_shared_parameter(effect->pool, &effect->parameters[i])))
6294 goto err_out;
6295 effect->parameters[i].version_counter = get_version_counter_ptr(effect);
6296 set_dirty(&effect->parameters[i].param);
6298 return D3D_OK;
6300 err_out:
6302 if (effect->techniques)
6304 for (i = 0; i < effect->technique_count; ++i)
6305 free_technique(&effect->techniques[i]);
6306 heap_free(effect->techniques);
6307 effect->techniques = NULL;
6310 if (effect->parameters)
6312 for (i = 0; i < effect->parameter_count; ++i)
6314 free_top_level_parameter(&effect->parameters[i]);
6316 heap_free(effect->parameters);
6317 effect->parameters = NULL;
6320 if (effect->objects)
6322 for (i = 0; i < effect->object_count; ++i)
6324 free_object(&effect->objects[i]);
6326 HeapFree(GetProcessHeap(), 0, effect->objects);
6327 effect->objects = NULL;
6330 return hr;
6333 #define INITIAL_CONST_NAMES_SIZE 4
6335 static char *next_valid_constant_name(char **string)
6337 char *ret = *string;
6338 char *next;
6340 while (*ret && !isalpha(*ret) && *ret != '_')
6341 ++ret;
6342 if (!*ret)
6343 return NULL;
6345 next = ret + 1;
6346 while (isalpha(*next) || isdigit(*next) || *next == '_')
6347 ++next;
6348 if (*next)
6349 *next++ = 0;
6350 *string = next;
6351 return ret;
6354 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count)
6356 const char **names, **new_alloc;
6357 const char *name;
6358 char *s;
6359 unsigned int size = INITIAL_CONST_NAMES_SIZE;
6361 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size);
6362 if (!names)
6363 return NULL;
6365 *names_count = 0;
6366 s = skip_constants_string;
6367 while ((name = next_valid_constant_name(&s)))
6369 if (*names_count == size)
6371 size *= 2;
6372 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size);
6373 if (!new_alloc)
6375 HeapFree(GetProcessHeap(), 0, names);
6376 return NULL;
6378 names = new_alloc;
6380 names[(*names_count)++] = name;
6382 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names));
6383 if (!new_alloc)
6384 return names;
6385 return new_alloc;
6388 static HRESULT d3dx9_effect_init(struct d3dx_effect *effect, struct IDirect3DDevice9 *device,
6389 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6390 UINT eflags, ID3DBlob **errors, struct ID3DXEffectPool *pool, const char *skip_constants_string)
6392 #if D3DX_SDK_VERSION <= 36
6393 UINT compile_flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
6394 #else
6395 UINT compile_flags = 0;
6396 #endif
6397 ID3DBlob *bytecode = NULL, *temp_errors = NULL;
6398 unsigned int skip_constants_count = 0;
6399 char *skip_constants_buffer = NULL;
6400 const char **skip_constants = NULL;
6401 const char *ptr = data;
6402 DWORD tag, offset;
6403 unsigned int i, j;
6404 HRESULT hr;
6406 TRACE("effect %p, device %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, errors %p, "
6407 "pool %p, skip_constants %s.\n",
6408 effect, device, data, data_size, defines, include, eflags, errors, pool,
6409 debugstr_a(skip_constants_string));
6411 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
6412 effect->ref = 1;
6414 if (pool)
6416 effect->pool = unsafe_impl_from_ID3DXEffectPool(pool);
6417 pool->lpVtbl->AddRef(pool);
6420 IDirect3DDevice9_AddRef(device);
6421 effect->device = device;
6423 effect->flags = eflags;
6425 list_init(&effect->parameter_block_list);
6427 read_dword(&ptr, &tag);
6428 TRACE("Tag: %x\n", tag);
6430 if (tag != d3dx9_effect_version(9, 1))
6432 TRACE("HLSL ASCII effect, trying to compile it.\n");
6433 hr = D3DCompile(data, data_size, NULL, defines, include,
6434 NULL, "fx_2_0", compile_flags, eflags, &bytecode, &temp_errors);
6435 if (FAILED(hr))
6437 WARN("Failed to compile ASCII effect.\n");
6438 if (bytecode)
6439 ID3D10Blob_Release(bytecode);
6440 if (temp_errors)
6442 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors);
6443 const char *string_ptr;
6445 while (*error_string)
6447 string_ptr = error_string;
6448 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r'
6449 && string_ptr - error_string < 80)
6450 ++string_ptr;
6451 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string));
6452 error_string = string_ptr;
6453 while (*error_string == '\n' || *error_string == '\r')
6454 ++error_string;
6457 if (errors)
6458 *errors = temp_errors;
6459 else if (temp_errors)
6460 ID3D10Blob_Release(temp_errors);
6461 return hr;
6463 if (!bytecode)
6465 FIXME("No output from effect compilation.\n");
6466 return D3DERR_INVALIDCALL;
6468 if (errors)
6469 *errors = temp_errors;
6470 else if (temp_errors)
6471 ID3D10Blob_Release(temp_errors);
6473 ptr = ID3D10Blob_GetBufferPointer(bytecode);
6474 read_dword(&ptr, &tag);
6475 TRACE("Tag: %x\n", tag);
6478 if (skip_constants_string)
6480 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0,
6481 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1));
6482 if (!skip_constants_buffer)
6484 if (bytecode)
6485 ID3D10Blob_Release(bytecode);
6486 return E_OUTOFMEMORY;
6488 strcpy(skip_constants_buffer, skip_constants_string);
6490 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count)))
6492 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6493 if (bytecode)
6494 ID3D10Blob_Release(bytecode);
6495 return E_OUTOFMEMORY;
6498 read_dword(&ptr, &offset);
6499 TRACE("Offset: %x\n", offset);
6501 hr = d3dx_parse_effect(effect, ptr, data_size, offset, skip_constants, skip_constants_count);
6502 if (bytecode)
6503 ID3D10Blob_Release(bytecode);
6504 if (hr != D3D_OK)
6506 FIXME("Failed to parse effect.\n");
6507 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6508 HeapFree(GetProcessHeap(), 0, skip_constants);
6509 return hr;
6512 for (i = 0; i < skip_constants_count; ++i)
6514 struct d3dx_parameter *param;
6515 param = get_parameter_by_name(effect, NULL, skip_constants[i]);
6516 if (param)
6518 for (j = 0; j < effect->technique_count; ++j)
6520 if (is_parameter_used(param, &effect->techniques[j]))
6522 WARN("skip_constants parameter %s is used in technique %u.\n",
6523 debugstr_a(skip_constants[i]), j);
6524 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6525 HeapFree(GetProcessHeap(), 0, skip_constants);
6526 return D3DERR_INVALIDCALL;
6530 else
6532 TRACE("skip_constants parameter %s not found.\n",
6533 debugstr_a(skip_constants[i]));
6537 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6538 HeapFree(GetProcessHeap(), 0, skip_constants);
6540 /* initialize defaults - check because of unsupported ascii effects */
6541 if (effect->techniques)
6543 effect->active_technique = &effect->techniques[0];
6544 effect->active_pass = NULL;
6547 return D3D_OK;
6550 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6551 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags,
6552 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6554 struct d3dx_effect *object;
6555 HRESULT hr;
6557 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p,"
6558 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n",
6559 device, srcdata, srcdatalen, defines, include,
6560 skip_constants, flags, pool, effect, compilation_errors);
6562 if (compilation_errors)
6563 *compilation_errors = NULL;
6565 if (!device || !srcdata)
6566 return D3DERR_INVALIDCALL;
6568 if (!srcdatalen)
6569 return E_FAIL;
6571 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6572 if (!effect)
6573 return D3D_OK;
6575 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6576 if (!object)
6577 return E_OUTOFMEMORY;
6579 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6580 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants);
6581 if (FAILED(hr))
6583 WARN("Failed to create effect object, hr %#x.\n", hr);
6584 d3dx_effect_cleanup(object);
6585 return hr;
6588 *effect = &object->ID3DXEffect_iface;
6590 TRACE("Created ID3DXEffect %p\n", object);
6592 return D3D_OK;
6595 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6596 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6597 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6599 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
6600 include, flags, pool, effect, compilation_errors);
6602 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
6605 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler,
6606 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6607 UINT eflags, ID3DBlob **error_messages)
6609 TRACE("compiler %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, error_messages %p.\n",
6610 compiler, data, data_size, defines, include, eflags, error_messages);
6612 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
6613 compiler->ref = 1;
6615 FIXME("ID3DXEffectCompiler implementation is only a stub.\n");
6617 return D3D_OK;
6620 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines,
6621 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors)
6623 struct ID3DXEffectCompilerImpl *object;
6624 HRESULT hr;
6626 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
6627 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
6629 if (!srcdata || !compiler)
6631 WARN("Invalid arguments supplied\n");
6632 return D3DERR_INVALIDCALL;
6635 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6636 if (!object)
6637 return E_OUTOFMEMORY;
6639 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6640 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors);
6641 if (FAILED(hr))
6643 WARN("Failed to initialize effect compiler\n");
6644 HeapFree(GetProcessHeap(), 0, object);
6645 return hr;
6648 *compiler = &object->ID3DXEffectCompiler_iface;
6650 TRACE("Created ID3DXEffectCompiler %p\n", object);
6652 return D3D_OK;
6655 /*** IUnknown methods ***/
6656 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
6658 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
6660 if (IsEqualGUID(riid, &IID_IUnknown) ||
6661 IsEqualGUID(riid, &IID_ID3DXEffectPool))
6663 iface->lpVtbl->AddRef(iface);
6664 *object = iface;
6665 return S_OK;
6668 WARN("Interface %s not found\n", debugstr_guid(riid));
6670 return E_NOINTERFACE;
6673 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface)
6675 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6676 ULONG refcount = InterlockedIncrement(&pool->refcount);
6678 TRACE("%p increasing refcount to %u.\n", pool, refcount);
6680 return refcount;
6683 static void free_effect_pool(struct d3dx_effect_pool *pool)
6685 unsigned int i;
6687 for (i = 0; i < pool->size; ++i)
6689 if (pool->shared_data[i].count)
6691 unsigned int j;
6693 WARN("Releasing pool with referenced parameters.\n");
6695 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE);
6696 pool->shared_data[i].parameters[0]->shared_data = NULL;
6698 for (j = 1; j < pool->shared_data[i].count; ++j)
6700 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL);
6701 pool->shared_data[i].parameters[j]->shared_data = NULL;
6703 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);
6706 HeapFree(GetProcessHeap(), 0, pool->shared_data);
6707 HeapFree(GetProcessHeap(), 0, pool);
6710 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface)
6712 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6713 ULONG refcount = InterlockedDecrement(&pool->refcount);
6715 TRACE("%p decreasing refcount to %u.\n", pool, refcount);
6717 if (!refcount)
6718 free_effect_pool(pool);
6720 return refcount;
6723 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
6725 /*** IUnknown methods ***/
6726 d3dx_effect_pool_QueryInterface,
6727 d3dx_effect_pool_AddRef,
6728 d3dx_effect_pool_Release
6731 static inline struct d3dx_effect_pool *unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
6733 if (!iface)
6734 return NULL;
6736 assert(iface->lpVtbl == &ID3DXEffectPool_Vtbl);
6737 return impl_from_ID3DXEffectPool(iface);
6740 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool)
6742 struct d3dx_effect_pool *object;
6744 TRACE("pool %p.\n", pool);
6746 if (!pool)
6747 return D3DERR_INVALIDCALL;
6749 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6750 if (!object)
6751 return E_OUTOFMEMORY;
6753 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6754 object->refcount = 1;
6756 *pool = &object->ID3DXEffectPool_iface;
6758 return S_OK;
6761 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6762 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6763 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6765 struct d3dx_include_from_file include_from_file;
6766 const void *buffer;
6767 unsigned int size;
6768 char *filename_a;
6769 HRESULT ret;
6771 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6772 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6773 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants),
6774 flags, pool, effect, compilationerrors);
6776 if (!device || !srcfile)
6777 return D3DERR_INVALIDCALL;
6779 if (!include)
6781 include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
6782 include = &include_from_file.ID3DXInclude_iface;
6785 size = WideCharToMultiByte(CP_ACP, 0, srcfile, -1, NULL, 0, NULL, NULL);
6786 filename_a = heap_alloc(size);
6787 if (!filename_a)
6788 return E_OUTOFMEMORY;
6789 WideCharToMultiByte(CP_ACP, 0, srcfile, -1, filename_a, size, NULL, NULL);
6791 EnterCriticalSection(&from_file_mutex);
6792 ret = ID3DXInclude_Open(include, D3DXINC_LOCAL, filename_a, NULL, &buffer, &size);
6793 if (FAILED(ret))
6795 LeaveCriticalSection(&from_file_mutex);
6796 heap_free(filename_a);
6797 return D3DXERR_INVALIDDATA;
6800 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool,
6801 effect, compilationerrors);
6803 ID3DXInclude_Close(include, buffer);
6804 LeaveCriticalSection(&from_file_mutex);
6805 heap_free(filename_a);
6806 return ret;
6809 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
6810 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6811 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6813 WCHAR *srcfileW;
6814 HRESULT ret;
6815 DWORD len;
6817 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6818 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6819 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants),
6820 flags, pool, effect, compilationerrors);
6822 if (!srcfile)
6823 return D3DERR_INVALIDCALL;
6825 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6826 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6827 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6829 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6830 HeapFree(GetProcessHeap(), 0, srcfileW);
6832 return ret;
6835 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6836 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6837 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6839 TRACE("(void): relay\n");
6840 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6843 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile,
6844 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6845 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6847 TRACE("(void): relay\n");
6848 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6851 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6852 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6853 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6855 HRSRC resinfo;
6856 void *buffer;
6857 DWORD size;
6859 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6860 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6861 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants),
6862 flags, pool, effect, compilationerrors);
6864 if (!device)
6865 return D3DERR_INVALIDCALL;
6867 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
6868 return D3DXERR_INVALIDDATA;
6870 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6871 return D3DXERR_INVALIDDATA;
6873 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6874 skipconstants, flags, pool, effect, compilationerrors);
6877 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6878 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6879 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6881 HRSRC resinfo;
6882 void *buffer;
6883 DWORD size;
6885 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6886 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6887 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants),
6888 flags, pool, effect, compilationerrors);
6890 if (!device)
6891 return D3DERR_INVALIDCALL;
6893 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6894 return D3DXERR_INVALIDDATA;
6896 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6897 return D3DXERR_INVALIDDATA;
6899 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6900 skipconstants, flags, pool, effect, compilationerrors);
6903 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6904 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6905 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6907 TRACE("(void): relay\n");
6908 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6911 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6912 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6913 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6915 TRACE("(void): relay\n");
6916 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6919 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines,
6920 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6922 void *buffer;
6923 HRESULT ret;
6924 DWORD size;
6926 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6927 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors);
6929 if (!srcfile)
6930 return D3DERR_INVALIDCALL;
6932 ret = map_view_of_file(srcfile, &buffer, &size);
6934 if (FAILED(ret))
6935 return D3DXERR_INVALIDDATA;
6937 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6938 UnmapViewOfFile(buffer);
6940 return ret;
6943 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines,
6944 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6946 WCHAR *srcfileW;
6947 HRESULT ret;
6948 DWORD len;
6950 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6951 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors);
6953 if (!srcfile)
6954 return D3DERR_INVALIDCALL;
6956 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6957 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6958 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6960 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
6961 HeapFree(GetProcessHeap(), 0, srcfileW);
6963 return ret;
6966 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource,
6967 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
6968 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6970 HRSRC resinfo;
6971 void *buffer;
6972 DWORD size;
6974 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6975 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors);
6977 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6978 return D3DXERR_INVALIDDATA;
6980 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6981 return D3DXERR_INVALIDDATA;
6983 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6986 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource,
6987 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
6988 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6990 HRSRC resinfo;
6991 void *buffer;
6992 DWORD size;
6994 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6995 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors);
6997 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
6998 return D3DXERR_INVALIDDATA;
7000 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7001 return D3DXERR_INVALIDDATA;
7003 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7006 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly)
7008 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly);
7010 return D3DXERR_INVALIDDATA;