secur32: Set output buffer size to zero during handshake when no data needs to be...
[wine.git] / dlls / d3dx9_36 / effect.c
blob33197de9bd14c3c53f9e581a1d82ae0b3c16bc6e
1 /*
2 * Copyright 2010 Christian Costa
3 * Copyright 2011 Rico Schüller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
21 #include "wine/port.h"
23 #include <stdio.h>
25 #include "d3dx9_private.h"
26 #include "d3dcompiler.h"
28 /* Constants for special INT/FLOAT conversation */
29 #define INT_FLOAT_MULTI 255.0f
30 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
32 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
34 #define PARAMETER_FLAG_SHARED 1
36 #define INITIAL_POOL_SIZE 16
38 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
40 enum STATE_CLASS
42 SC_LIGHTENABLE,
43 SC_FVF,
44 SC_LIGHT,
45 SC_MATERIAL,
46 SC_NPATCHMODE,
47 SC_PIXELSHADER,
48 SC_RENDERSTATE,
49 SC_SETSAMPLER,
50 SC_SAMPLERSTATE,
51 SC_TEXTURE,
52 SC_TEXTURESTAGE,
53 SC_TRANSFORM,
54 SC_VERTEXSHADER,
55 SC_SHADERCONST,
56 SC_UNKNOWN,
59 enum MATERIAL_TYPE
61 MT_DIFFUSE,
62 MT_AMBIENT,
63 MT_SPECULAR,
64 MT_EMISSIVE,
65 MT_POWER,
68 enum LIGHT_TYPE
70 LT_TYPE,
71 LT_DIFFUSE,
72 LT_SPECULAR,
73 LT_AMBIENT,
74 LT_POSITION,
75 LT_DIRECTION,
76 LT_RANGE,
77 LT_FALLOFF,
78 LT_ATTENUATION0,
79 LT_ATTENUATION1,
80 LT_ATTENUATION2,
81 LT_THETA,
82 LT_PHI,
85 enum SHADER_CONSTANT_TYPE
87 SCT_VSFLOAT,
88 SCT_VSBOOL,
89 SCT_VSINT,
90 SCT_PSFLOAT,
91 SCT_PSBOOL,
92 SCT_PSINT,
95 enum STATE_TYPE
97 ST_CONSTANT,
98 ST_PARAMETER,
99 ST_FXLC,
100 ST_ARRAY_SELECTOR,
103 struct d3dx_object
105 UINT size;
106 void *data;
107 struct d3dx_parameter *param;
108 BOOL creation_failed;
111 struct d3dx_state
113 UINT operation;
114 UINT index;
115 enum STATE_TYPE type;
116 struct d3dx_parameter parameter;
117 struct d3dx_parameter *referenced_param;
120 struct d3dx_sampler
122 UINT state_count;
123 struct d3dx_state *states;
126 struct d3dx_pass
128 char *name;
129 UINT state_count;
130 UINT annotation_count;
132 struct d3dx_state *states;
133 struct d3dx_parameter *annotations;
135 ULONG64 update_version;
138 struct d3dx_technique
140 char *name;
141 UINT pass_count;
142 UINT annotation_count;
144 struct d3dx_parameter *annotations;
145 struct d3dx_pass *passes;
147 struct IDirect3DStateBlock9 *saved_state;
150 struct d3dx9_base_effect
152 struct ID3DXEffectImpl *effect;
154 UINT parameter_count;
155 UINT technique_count;
156 UINT object_count;
158 struct d3dx_top_level_parameter *parameters;
159 struct d3dx_technique *techniques;
160 struct d3dx_object *objects;
162 struct d3dx_effect_pool *pool;
163 DWORD flags;
165 ULONG64 version_counter;
167 struct wine_rb_tree param_tree;
168 char *full_name_tmp;
169 unsigned int full_name_tmp_size;
172 struct ID3DXEffectImpl
174 ID3DXEffect ID3DXEffect_iface;
175 LONG ref;
177 struct d3dx9_base_effect base_effect;
179 struct ID3DXEffectStateManager *manager;
180 struct IDirect3DDevice9 *device;
181 struct ID3DXEffectPool *pool;
182 struct d3dx_technique *active_technique;
183 struct d3dx_pass *active_pass;
184 BOOL started;
185 DWORD begin_flags;
187 D3DLIGHT9 current_light[8];
188 unsigned int light_updated;
189 D3DMATERIAL9 current_material;
190 BOOL material_updated;
193 #define INITIAL_SHARED_DATA_SIZE 4
195 struct d3dx_effect_pool
197 ID3DXEffectPool ID3DXEffectPool_iface;
198 LONG refcount;
200 struct d3dx_shared_data *shared_data;
201 unsigned int size;
203 ULONG64 version_counter;
206 struct ID3DXEffectCompilerImpl
208 ID3DXEffectCompiler ID3DXEffectCompiler_iface;
209 LONG ref;
212 static struct d3dx_parameter *get_annotation_by_name(struct d3dx9_base_effect *base,
213 unsigned int count, struct d3dx_parameter *parameters, const char *name);
214 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
215 const char *data, const char **ptr, struct d3dx_object *objects);
216 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
218 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param);
220 static const struct
222 enum STATE_CLASS class;
223 UINT op;
224 const char *name;
226 state_table[] =
228 /* Render states */
229 {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
230 {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
231 {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
232 {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
233 {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
234 {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
235 {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
236 {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
237 {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
238 {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
239 {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
240 {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
241 {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
242 {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
243 {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
244 {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
245 {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
246 {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
247 {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
248 {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
249 {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
250 {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
251 {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
252 {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
253 {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
254 {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
255 {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
256 {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
257 {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
258 {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
259 {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
260 {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
261 {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
262 {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
263 {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
264 {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
265 {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
266 {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
267 {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
268 {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
269 {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
270 {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
271 {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
272 {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
273 {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
274 {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
275 {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
276 {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
277 {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
278 {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
279 {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
280 {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
281 {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
282 {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
283 {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
284 {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
285 {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
286 {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
287 {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
288 {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
289 {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
290 {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
291 {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
292 {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
293 {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
294 {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
295 {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
296 {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
297 {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
298 {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
299 {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
300 {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
301 {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
302 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
303 {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
304 {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
305 {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
306 {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
307 {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
308 {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
309 {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
310 {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
311 {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
312 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
313 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
314 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
315 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
316 {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
317 {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
318 {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
319 {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
320 {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
321 {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
322 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
323 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
324 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
325 {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
326 {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
327 {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
328 {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
329 {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
330 {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
331 {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
332 /* Texture stages */
333 {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
334 {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
335 {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
336 {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
337 {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
338 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
339 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
340 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
341 {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
342 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
343 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
344 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
345 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
346 {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
347 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
348 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
349 {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
350 {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
351 /* NPatchMode */
352 {SC_NPATCHMODE, 0, "NPatchMode"},
353 /* FVF */
354 {SC_FVF, 0, "FVF"},
355 /* Transform */
356 {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
357 {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
358 {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
359 {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
360 /* Material */
361 {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
362 {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
363 {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
364 {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
365 {SC_MATERIAL, MT_POWER, "MaterialPower"},
366 /* Light */
367 {SC_LIGHT, LT_TYPE, "LightType"},
368 {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
369 {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
370 {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
371 {SC_LIGHT, LT_POSITION, "LightPosition"},
372 {SC_LIGHT, LT_DIRECTION, "LightDirection"},
373 {SC_LIGHT, LT_RANGE, "LightRange"},
374 {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
375 {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
376 {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
377 {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
378 {SC_LIGHT, LT_THETA, "LightTheta"},
379 {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
380 /* Lightenable */
381 {SC_LIGHTENABLE, 0, "LightEnable"},
382 /* Vertexshader */
383 {SC_VERTEXSHADER, 0, "Vertexshader"},
384 /* Pixelshader */
385 {SC_PIXELSHADER, 0, "Pixelshader"},
386 /* Shader constants */
387 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
388 {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
389 {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
390 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
391 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
392 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
393 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
394 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
395 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
396 {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
397 {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
398 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
399 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
400 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
401 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
402 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
403 /* Texture */
404 {SC_TEXTURE, 0, "Texture"},
405 /* Sampler states */
406 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
407 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
408 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
409 {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
410 {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
411 {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
412 {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
413 {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
414 {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
415 {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
416 {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
417 {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
418 {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
419 /* Set sampler */
420 {SC_SETSAMPLER, 0, "Sampler"},
423 static inline void read_dword(const char **ptr, DWORD *d)
425 memcpy(d, *ptr, sizeof(*d));
426 *ptr += sizeof(*d);
429 static void skip_dword_unknown(const char **ptr, unsigned int count)
431 unsigned int i;
432 DWORD d;
434 WARN("Skipping %u unknown DWORDs:\n", count);
435 for (i = 0; i < count; ++i)
437 read_dword(ptr, &d);
438 WARN("\t0x%08x\n", d);
442 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
444 return (D3DXHANDLE)parameter;
447 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
449 return (D3DXHANDLE)technique;
452 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
454 return (D3DXHANDLE)pass;
457 static struct d3dx_technique *get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
459 UINT i;
461 if (!name) return NULL;
463 for (i = 0; i < base->technique_count; ++i)
465 if (!strcmp(base->techniques[i].name, name))
466 return &base->techniques[i];
469 return NULL;
472 static struct d3dx_technique *get_valid_technique(struct d3dx9_base_effect *base, D3DXHANDLE technique)
474 unsigned int i;
476 for (i = 0; i < base->technique_count; ++i)
478 if (get_technique_handle(&base->techniques[i]) == technique)
479 return &base->techniques[i];
482 return get_technique_by_name(base, technique);
485 static struct d3dx_pass *get_valid_pass(struct d3dx9_base_effect *base, D3DXHANDLE pass)
487 unsigned int i, k;
489 for (i = 0; i < base->technique_count; ++i)
491 struct d3dx_technique *technique = &base->techniques[i];
493 for (k = 0; k < technique->pass_count; ++k)
495 if (get_pass_handle(&technique->passes[k]) == pass)
496 return &technique->passes[k];
500 return NULL;
503 static struct d3dx_parameter *get_valid_parameter(struct d3dx9_base_effect *base, D3DXHANDLE parameter)
505 struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter;
507 if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string,
508 sizeof(parameter_magic_string)))
509 return handle_param;
511 return base->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(base, NULL, parameter);
514 static void free_state(struct d3dx_state *state)
516 free_parameter(&state->parameter, FALSE, FALSE);
519 static void free_object(struct d3dx_object *object)
521 HeapFree(GetProcessHeap(), 0, object->data);
524 static void free_sampler(struct d3dx_sampler *sampler)
526 UINT i;
528 for (i = 0; i < sampler->state_count; ++i)
530 free_state(&sampler->states[i]);
532 HeapFree(GetProcessHeap(), 0, sampler->states);
535 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param);
537 static void free_parameter_data(struct d3dx_parameter *param, BOOL child)
539 if (!param->data)
540 return;
541 if (param->class == D3DXPC_OBJECT && !param->element_count)
543 switch (param->type)
545 case D3DXPT_STRING:
546 HeapFree(GetProcessHeap(), 0, *(char **)param->data);
547 break;
549 case D3DXPT_TEXTURE:
550 case D3DXPT_TEXTURE1D:
551 case D3DXPT_TEXTURE2D:
552 case D3DXPT_TEXTURE3D:
553 case D3DXPT_TEXTURECUBE:
554 case D3DXPT_PIXELSHADER:
555 case D3DXPT_VERTEXSHADER:
556 if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
557 break;
559 case D3DXPT_SAMPLER:
560 case D3DXPT_SAMPLER1D:
561 case D3DXPT_SAMPLER2D:
562 case D3DXPT_SAMPLER3D:
563 case D3DXPT_SAMPLERCUBE:
564 free_sampler((struct d3dx_sampler *)param->data);
565 break;
567 default:
568 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
569 break;
572 if (!child)
573 HeapFree(GetProcessHeap(), 0, param->data);
576 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child)
578 unsigned int i;
580 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name,
581 debug_d3dxparameter_type(param->type), element, child);
583 if (param->param_eval)
584 d3dx_free_param_eval(param->param_eval);
586 if (param->members)
588 unsigned int count = param->element_count ? param->element_count : param->member_count;
590 for (i = 0; i < count; ++i)
591 free_parameter(&param->members[i], param->element_count != 0, TRUE);
592 HeapFree(GetProcessHeap(), 0, param->members);
595 free_parameter_data(param, child);
597 /* only the parent has to release name and semantic */
598 if (!element)
600 HeapFree(GetProcessHeap(), 0, param->name);
601 HeapFree(GetProcessHeap(), 0, param->semantic);
605 static void free_top_level_parameter(struct d3dx_top_level_parameter *param)
607 if (param->annotations)
609 unsigned int i;
611 for (i = 0; i < param->annotation_count; ++i)
612 free_parameter(&param->annotations[i], FALSE, FALSE);
613 HeapFree(GetProcessHeap(), 0, param->annotations);
615 d3dx_pool_release_shared_parameter(param);
616 free_parameter(&param->param, FALSE, FALSE);
619 static void free_pass(struct d3dx_pass *pass)
621 unsigned int i;
623 TRACE("Free pass %p\n", pass);
625 if (!pass)
626 return;
628 if (pass->annotations)
630 for (i = 0; i < pass->annotation_count; ++i)
631 free_parameter(&pass->annotations[i], FALSE, FALSE);
632 HeapFree(GetProcessHeap(), 0, pass->annotations);
633 pass->annotations = NULL;
636 if (pass->states)
638 for (i = 0; i < pass->state_count; ++i)
639 free_state(&pass->states[i]);
640 HeapFree(GetProcessHeap(), 0, pass->states);
641 pass->states = NULL;
644 HeapFree(GetProcessHeap(), 0, pass->name);
645 pass->name = NULL;
648 static void free_technique(struct d3dx_technique *technique)
650 unsigned int i;
652 TRACE("Free technique %p\n", technique);
654 if (!technique)
655 return;
657 if (technique->saved_state)
659 IDirect3DStateBlock9_Release(technique->saved_state);
660 technique->saved_state = NULL;
663 if (technique->annotations)
665 for (i = 0; i < technique->annotation_count; ++i)
666 free_parameter(&technique->annotations[i], FALSE, FALSE);
667 HeapFree(GetProcessHeap(), 0, technique->annotations);
668 technique->annotations = NULL;
671 if (technique->passes)
673 for (i = 0; i < technique->pass_count; ++i)
674 free_pass(&technique->passes[i]);
675 HeapFree(GetProcessHeap(), 0, technique->passes);
676 technique->passes = NULL;
679 HeapFree(GetProcessHeap(), 0, technique->name);
680 technique->name = NULL;
683 static void d3dx9_base_effect_cleanup(struct d3dx9_base_effect *base)
685 unsigned int i;
687 TRACE("base %p.\n", base);
689 heap_free(base->full_name_tmp);
691 if (base->parameters)
693 for (i = 0; i < base->parameter_count; ++i)
694 free_top_level_parameter(&base->parameters[i]);
695 HeapFree(GetProcessHeap(), 0, base->parameters);
696 base->parameters = NULL;
699 if (base->techniques)
701 for (i = 0; i < base->technique_count; ++i)
702 free_technique(&base->techniques[i]);
703 HeapFree(GetProcessHeap(), 0, base->techniques);
704 base->techniques = NULL;
707 if (base->objects)
709 for (i = 0; i < base->object_count; ++i)
711 free_object(&base->objects[i]);
713 HeapFree(GetProcessHeap(), 0, base->objects);
714 base->objects = NULL;
718 static void free_effect(struct ID3DXEffectImpl *effect)
720 TRACE("Free effect %p\n", effect);
722 d3dx9_base_effect_cleanup(&effect->base_effect);
724 if (effect->pool)
726 effect->pool->lpVtbl->Release(effect->pool);
729 if (effect->manager)
731 IUnknown_Release(effect->manager);
734 IDirect3DDevice9_Release(effect->device);
737 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
739 UINT i;
741 for (i = 0; i < 4; ++i)
743 if (i < param->columns)
744 set_number((FLOAT *)vector + i, D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
745 else
746 ((FLOAT *)vector)[i] = 0.0f;
750 static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector)
752 UINT i;
754 for (i = 0; i < param->columns; ++i)
756 set_number((FLOAT *)param->data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
760 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
762 UINT i, k;
764 for (i = 0; i < 4; ++i)
766 for (k = 0; k < 4; ++k)
768 FLOAT *tmp = transpose ? (FLOAT *)&matrix->u.m[k][i] : (FLOAT *)&matrix->u.m[i][k];
770 if ((i < param->rows) && (k < param->columns))
771 set_number(tmp, D3DXPT_FLOAT, (DWORD *)param->data + i * param->columns + k, param->type);
772 else
773 *tmp = 0.0f;
778 static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix)
780 UINT i, k;
782 if (param->type == D3DXPT_FLOAT)
784 if (param->columns == 4)
785 memcpy(param->data, matrix->u.m, param->rows * 4 * sizeof(float));
786 else
787 for (i = 0; i < param->rows; ++i)
788 memcpy((float *)param->data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float));
789 return;
792 for (i = 0; i < param->rows; ++i)
794 for (k = 0; k < param->columns; ++k)
796 set_number((FLOAT *)param->data + i * param->columns + k, param->type,
797 &matrix->u.m[i][k], D3DXPT_FLOAT);
802 static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix)
804 UINT i, k;
806 for (i = 0; i < param->rows; ++i)
808 for (k = 0; k < param->columns; ++k)
810 set_number((FLOAT *)param->data + i * param->columns + k, param->type,
811 &matrix->u.m[k][i], D3DXPT_FLOAT);
816 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx9_base_effect *base,
817 struct d3dx_parameter *parameter, const char *name)
819 UINT element;
820 struct d3dx_parameter *temp_parameter;
821 const char *part;
823 TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
825 if (!name || !*name) return NULL;
827 element = atoi(name);
828 part = strchr(name, ']') + 1;
830 /* check for empty [] && element range */
831 if ((part - name) > 1 && parameter->element_count > element)
833 temp_parameter = &parameter->members[element];
835 switch (*part++)
837 case '.':
838 return get_parameter_by_name(base, temp_parameter, part);
840 case '\0':
841 TRACE("Returning parameter %p\n", temp_parameter);
842 return temp_parameter;
844 default:
845 FIXME("Unhandled case \"%c\"\n", *--part);
846 break;
850 TRACE("Parameter not found\n");
851 return NULL;
854 static struct d3dx_parameter *get_annotation_by_name(struct d3dx9_base_effect *base,
855 unsigned int count, struct d3dx_parameter *annotations, const char *name)
857 UINT i, length;
858 struct d3dx_parameter *temp_parameter;
859 const char *part;
861 TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name));
863 if (!name || !*name) return NULL;
865 length = strcspn( name, "[.@" );
866 part = name + length;
868 for (i = 0; i < count; ++i)
870 temp_parameter = &annotations[i];
872 if (!strcmp(temp_parameter->name, name))
874 TRACE("Returning annotation %p\n", temp_parameter);
875 return temp_parameter;
877 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
879 switch (*part++)
881 case '.':
882 return get_parameter_by_name(base, temp_parameter, part);
884 case '[':
885 return get_parameter_element_by_name(base, temp_parameter, part);
887 default:
888 FIXME("Unhandled case \"%c\"\n", *--part);
889 break;
894 TRACE("Annotation not found\n");
895 return NULL;
898 struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
899 struct d3dx_parameter *parameter, const char *name)
901 struct d3dx_parameter *temp_parameter;
902 unsigned int name_len, param_name_len;
903 unsigned int i, count, length;
904 struct wine_rb_entry *entry;
905 unsigned int full_name_size;
906 const char *part;
907 char *full_name;
909 TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
911 if (!name || !*name) return NULL;
913 if (!parameter)
915 if ((entry = wine_rb_get(&base->param_tree, name)))
916 return WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
917 return NULL;
920 /* Pass / technique annotations are not in the parameters tree. */
921 if (parameter->full_name)
923 name_len = strlen(name);
924 param_name_len = strlen(parameter->full_name);
925 full_name_size = name_len + param_name_len + 2;
926 if (base->full_name_tmp_size < full_name_size)
928 if (!(full_name = heap_realloc(base->full_name_tmp, full_name_size)))
930 ERR("Out of memory.\n");
931 return NULL;
933 base->full_name_tmp = full_name;
934 base->full_name_tmp_size = full_name_size;
936 else
938 full_name = base->full_name_tmp;
940 memcpy(full_name, parameter->full_name, param_name_len);
941 full_name[param_name_len] = '.';
942 memcpy(full_name + param_name_len + 1, name, name_len);
943 full_name[param_name_len + 1 + name_len] = 0;
945 if ((entry = wine_rb_get(&base->param_tree, full_name)))
946 return WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
947 return NULL;
950 count = parameter ? parameter->member_count : base->parameter_count;
952 length = strcspn( name, "[.@" );
953 part = name + length;
955 for (i = 0; i < count; i++)
957 temp_parameter = !parameter ? &base->parameters[i].param
958 : &parameter->members[i];
960 if (!strcmp(temp_parameter->name, name))
962 TRACE("Returning parameter %p\n", temp_parameter);
963 return temp_parameter;
965 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
967 switch (*part++)
969 case '.':
970 return get_parameter_by_name(base, temp_parameter, part);
972 case '@':
974 struct d3dx_top_level_parameter *top_param
975 = top_level_parameter_from_parameter(temp_parameter);
977 return parameter ? NULL : get_annotation_by_name(base, top_param->annotation_count,
978 top_param->annotations, part);
980 case '[':
981 return get_parameter_element_by_name(base, temp_parameter, part);
983 default:
984 FIXME("Unhandled case \"%c\"\n", *--part);
985 break;
990 TRACE("Parameter not found\n");
991 return NULL;
994 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
996 return (0xfeff0000 | ((major) << 8) | (minor));
999 static HRESULT d3dx9_base_effect_get_desc(struct d3dx9_base_effect *base, D3DXEFFECT_DESC *desc)
1001 if (!desc)
1003 WARN("Invalid argument specified.\n");
1004 return D3DERR_INVALIDCALL;
1007 FIXME("partial stub!\n");
1009 /* TODO: add creator and function count. */
1010 desc->Creator = NULL;
1011 desc->Functions = 0;
1012 desc->Parameters = base->parameter_count;
1013 desc->Techniques = base->technique_count;
1015 return D3D_OK;
1018 static HRESULT d3dx9_base_effect_get_parameter_desc(struct d3dx9_base_effect *base,
1019 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
1021 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1023 if (!desc || !param)
1025 WARN("Invalid argument specified.\n");
1026 return D3DERR_INVALIDCALL;
1029 desc->Name = param->name;
1030 desc->Semantic = param->semantic;
1031 desc->Class = param->class;
1032 desc->Type = param->type;
1033 desc->Rows = param->rows;
1034 desc->Columns = param->columns;
1035 desc->Elements = param->element_count;
1036 desc->Annotations = is_top_level_parameter(param)
1037 ? top_level_parameter_from_parameter(param)->annotation_count : 0;
1038 desc->StructMembers = param->member_count;
1039 desc->Flags = param->flags;
1040 desc->Bytes = param->bytes;
1042 return D3D_OK;
1045 static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *base,
1046 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1048 struct d3dx_technique *tech = technique ? get_valid_technique(base, technique) : &base->techniques[0];
1050 if (!desc || !tech)
1052 WARN("Invalid argument specified.\n");
1053 return D3DERR_INVALIDCALL;
1056 desc->Name = tech->name;
1057 desc->Passes = tech->pass_count;
1058 desc->Annotations = tech->annotation_count;
1060 return D3D_OK;
1063 static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
1064 void **param_value, struct d3dx_parameter **out_param,
1065 BOOL update_all, BOOL *param_dirty)
1067 struct d3dx_parameter *param = &state->parameter;
1069 *param_value = NULL;
1070 *out_param = NULL;
1071 *param_dirty = FALSE;
1073 switch (state->type)
1075 case ST_PARAMETER:
1076 param = state->referenced_param;
1077 *param_dirty = is_param_dirty(param, pass->update_version);
1078 /* fallthrough */
1079 case ST_CONSTANT:
1080 *out_param = param;
1081 *param_value = param->data;
1082 return D3D_OK;
1083 case ST_ARRAY_SELECTOR:
1085 unsigned int array_idx;
1086 static const struct d3dx_parameter array_idx_param =
1087 {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)};
1088 HRESULT hr;
1089 struct d3dx_parameter *ref_param, *selected_param;
1091 if (!param->param_eval)
1093 FIXME("Preshader structure is null.\n");
1094 return D3DERR_INVALIDCALL;
1096 /* We override with the update_version of the pass because we want
1097 * to force index recomputation and check for out of bounds. */
1098 if (is_param_eval_input_dirty(param->param_eval, pass->update_version))
1100 if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
1101 return hr;
1103 else
1105 array_idx = state->index;
1107 ref_param = state->referenced_param;
1108 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
1109 ref_param->element_count);
1110 /* According to the tests, native d3dx handles the case of array index evaluated to -1
1111 * in a specific way, always selecting first array element and not returning error. */
1112 if (array_idx == ~0u)
1114 WARN("Array index is -1, setting to 0.\n");
1115 array_idx = 0;
1118 if (array_idx >= ref_param->element_count)
1120 WARN("Computed array index %u is larger than array size %u.\n",
1121 array_idx, ref_param->element_count);
1122 return E_FAIL;
1124 selected_param = &ref_param->members[array_idx];
1125 *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
1126 state->index = array_idx;
1128 *param_value = selected_param->data;
1129 *out_param = selected_param;
1130 return D3D_OK;
1132 case ST_FXLC:
1133 if (param->param_eval)
1135 *out_param = param;
1136 *param_value = param->data;
1137 /* We check with the update_version of the pass because the
1138 * same preshader might be used by both the vertex and the
1139 * pixel shader (that can happen e.g. for sampler states). */
1140 if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version))
1142 *param_dirty = TRUE;
1143 return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
1145 else
1146 return D3D_OK;
1148 else
1150 FIXME("No preshader for FXLC parameter.\n");
1151 return D3DERR_INVALIDCALL;
1154 return E_NOTIMPL;
1157 static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
1158 D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
1160 struct d3dx_pass *pass = get_valid_pass(base, pass_handle);
1161 unsigned int i;
1163 if (!desc || !pass)
1165 WARN("Invalid argument specified.\n");
1166 return D3DERR_INVALIDCALL;
1169 desc->Name = pass->name;
1170 desc->Annotations = pass->annotation_count;
1172 desc->pVertexShaderFunction = NULL;
1173 desc->pPixelShaderFunction = NULL;
1175 if (base->flags & D3DXFX_NOT_CLONEABLE)
1176 return D3D_OK;
1178 for (i = 0; i < pass->state_count; ++i)
1180 struct d3dx_state *state = &pass->states[i];
1182 if (state_table[state->operation].class == SC_VERTEXSHADER
1183 || state_table[state->operation].class == SC_PIXELSHADER)
1185 struct d3dx_parameter *param;
1186 void *param_value;
1187 BOOL param_dirty;
1188 HRESULT hr;
1189 void *data;
1191 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
1192 FALSE, &param_dirty)))
1193 return hr;
1195 data = param->object_id ? base->objects[param->object_id].data : NULL;
1196 if (state_table[state->operation].class == SC_VERTEXSHADER)
1197 desc->pVertexShaderFunction = data;
1198 else
1199 desc->pPixelShaderFunction = data;
1203 return D3D_OK;
1206 static HRESULT d3dx9_base_effect_get_function_desc(struct d3dx9_base_effect *base,
1207 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
1209 FIXME("stub!\n");
1211 return E_NOTIMPL;
1214 static D3DXHANDLE d3dx9_base_effect_get_parameter(struct d3dx9_base_effect *base,
1215 D3DXHANDLE parameter, UINT index)
1217 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1219 if (!parameter)
1221 if (index < base->parameter_count)
1223 TRACE("Returning parameter %p.\n", &base->parameters[index]);
1224 return get_parameter_handle(&base->parameters[index].param);
1227 else
1229 if (param && !param->element_count && index < param->member_count)
1231 TRACE("Returning parameter %p.\n", &param->members[index]);
1232 return get_parameter_handle(&param->members[index]);
1236 WARN("Parameter not found.\n");
1238 return NULL;
1241 static D3DXHANDLE d3dx9_base_effect_get_parameter_by_name(struct d3dx9_base_effect *base,
1242 D3DXHANDLE parameter, const char *name)
1244 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1245 D3DXHANDLE handle;
1247 if (!name)
1249 handle = get_parameter_handle(param);
1250 TRACE("Returning parameter %p.\n", handle);
1251 return handle;
1254 handle = get_parameter_handle(get_parameter_by_name(base, param, name));
1255 TRACE("Returning parameter %p.\n", handle);
1257 return handle;
1260 static D3DXHANDLE d3dx9_base_effect_get_parameter_by_semantic(struct d3dx9_base_effect *base,
1261 D3DXHANDLE parameter, const char *semantic)
1263 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1264 struct d3dx_parameter *temp_param;
1265 UINT i;
1267 if (!parameter)
1269 for (i = 0; i < base->parameter_count; ++i)
1271 temp_param = &base->parameters[i].param;
1273 if (!temp_param->semantic)
1275 if (!semantic)
1277 TRACE("Returning parameter %p\n", temp_param);
1278 return get_parameter_handle(temp_param);
1280 continue;
1283 if (!strcasecmp(temp_param->semantic, semantic))
1285 TRACE("Returning parameter %p\n", temp_param);
1286 return get_parameter_handle(temp_param);
1290 else if (param)
1292 for (i = 0; i < param->member_count; ++i)
1294 temp_param = &param->members[i];
1296 if (!temp_param->semantic)
1298 if (!semantic)
1300 TRACE("Returning parameter %p\n", temp_param);
1301 return get_parameter_handle(temp_param);
1303 continue;
1306 if (!strcasecmp(temp_param->semantic, semantic))
1308 TRACE("Returning parameter %p\n", temp_param);
1309 return get_parameter_handle(temp_param);
1314 WARN("Parameter not found.\n");
1316 return NULL;
1319 static D3DXHANDLE d3dx9_base_effect_get_parameter_element(struct d3dx9_base_effect *base,
1320 D3DXHANDLE parameter, UINT index)
1322 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1324 if (!param)
1326 if (index < base->parameter_count)
1328 TRACE("Returning parameter %p.\n", &base->parameters[index]);
1329 return get_parameter_handle(&base->parameters[index].param);
1332 else
1334 if (index < param->element_count)
1336 TRACE("Returning parameter %p.\n", &param->members[index]);
1337 return get_parameter_handle(&param->members[index]);
1341 WARN("Parameter not found.\n");
1343 return NULL;
1346 static D3DXHANDLE d3dx9_base_effect_get_technique(struct d3dx9_base_effect *base, UINT index)
1348 if (index >= base->technique_count)
1350 WARN("Invalid argument specified.\n");
1351 return NULL;
1354 TRACE("Returning technique %p.\n", &base->techniques[index]);
1356 return get_technique_handle(&base->techniques[index]);
1359 static D3DXHANDLE d3dx9_base_effect_get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
1361 struct d3dx_technique *tech = get_technique_by_name(base, name);
1363 if (tech)
1365 D3DXHANDLE t = get_technique_handle(tech);
1366 TRACE("Returning technique %p\n", t);
1367 return t;
1370 WARN("Technique not found.\n");
1372 return NULL;
1375 static D3DXHANDLE d3dx9_base_effect_get_pass(struct d3dx9_base_effect *base,
1376 D3DXHANDLE technique, UINT index)
1378 struct d3dx_technique *tech = get_valid_technique(base, technique);
1380 if (tech && index < tech->pass_count)
1382 TRACE("Returning pass %p\n", &tech->passes[index]);
1383 return get_pass_handle(&tech->passes[index]);
1386 WARN("Pass not found.\n");
1388 return NULL;
1391 static D3DXHANDLE d3dx9_base_effect_get_pass_by_name(struct d3dx9_base_effect *base,
1392 D3DXHANDLE technique, const char *name)
1394 struct d3dx_technique *tech = get_valid_technique(base, technique);
1396 if (tech && name)
1398 unsigned int i;
1400 for (i = 0; i < tech->pass_count; ++i)
1402 struct d3dx_pass *pass = &tech->passes[i];
1404 if (!strcmp(pass->name, name))
1406 TRACE("Returning pass %p\n", pass);
1407 return get_pass_handle(pass);
1412 WARN("Pass not found.\n");
1414 return NULL;
1417 static D3DXHANDLE d3dx9_base_effect_get_function(struct d3dx9_base_effect *base, UINT index)
1419 FIXME("stub!\n");
1421 return NULL;
1424 static D3DXHANDLE d3dx9_base_effect_get_function_by_name(struct d3dx9_base_effect *base, const char *name)
1426 FIXME("stub!\n");
1428 return NULL;
1431 static UINT get_annotation_from_object(struct d3dx9_base_effect *base,
1432 D3DXHANDLE object, struct d3dx_parameter **annotations)
1434 struct d3dx_parameter *param = get_valid_parameter(base, object);
1435 struct d3dx_pass *pass = get_valid_pass(base, object);
1436 struct d3dx_technique *technique = get_valid_technique(base, object);
1438 if (pass)
1440 *annotations = pass->annotations;
1441 return pass->annotation_count;
1443 else if (technique)
1445 *annotations = technique->annotations;
1446 return technique->annotation_count;
1448 else if (param)
1450 if (is_top_level_parameter(param))
1452 struct d3dx_top_level_parameter *top_param
1453 = top_level_parameter_from_parameter(param);
1455 *annotations = top_param->annotations;
1456 return top_param->annotation_count;
1458 else
1460 *annotations = NULL;
1461 return 0;
1464 else
1466 FIXME("Functions are not handled, yet!\n");
1467 return 0;
1471 static D3DXHANDLE d3dx9_base_effect_get_annotation(struct d3dx9_base_effect *base,
1472 D3DXHANDLE object, UINT index)
1474 struct d3dx_parameter *annotations = NULL;
1475 UINT annotation_count = 0;
1477 annotation_count = get_annotation_from_object(base, object, &annotations);
1479 if (index < annotation_count)
1481 TRACE("Returning parameter %p\n", &annotations[index]);
1482 return get_parameter_handle(&annotations[index]);
1485 WARN("Annotation not found.\n");
1487 return NULL;
1490 static D3DXHANDLE d3dx9_base_effect_get_annotation_by_name(struct d3dx9_base_effect *base,
1491 D3DXHANDLE object, const char *name)
1493 struct d3dx_parameter *annotation = NULL;
1494 struct d3dx_parameter *annotations = NULL;
1495 UINT annotation_count = 0;
1497 if (!name)
1499 WARN("Invalid argument specified\n");
1500 return NULL;
1503 annotation_count = get_annotation_from_object(base, object, &annotations);
1505 annotation = get_annotation_by_name(base, annotation_count, annotations, name);
1506 if (annotation)
1508 TRACE("Returning parameter %p\n", annotation);
1509 return get_parameter_handle(annotation);
1512 WARN("Annotation not found.\n");
1514 return NULL;
1517 static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
1518 void *data)
1520 unsigned int i;
1521 unsigned int member_count;
1523 if (param_func(data, param))
1524 return TRUE;
1526 member_count = param->element_count ? param->element_count : param->member_count;
1527 for (i = 0; i < member_count; ++i)
1529 if (walk_parameter_tree(&param->members[i], param_func, data))
1530 return TRUE;
1532 return FALSE;
1535 static ULONG64 *get_version_counter_ptr(struct d3dx9_base_effect *base)
1537 return base->pool ? &base->pool->version_counter : &base->version_counter;
1540 static ULONG64 next_effect_update_version(struct d3dx9_base_effect *base)
1542 return next_update_version(get_version_counter_ptr(base));
1545 static void set_dirty(struct d3dx_parameter *param)
1547 struct d3dx_shared_data *shared_data;
1548 struct d3dx_top_level_parameter *top_param = param->top_level_param;
1549 ULONG64 new_update_version = next_update_version(top_param->version_counter);
1551 if ((shared_data = top_param->shared_data))
1552 shared_data->update_version = new_update_version;
1553 else
1554 top_param->update_version = new_update_version;
1557 static HRESULT set_string(char **param_data, const char *string)
1559 HeapFree(GetProcessHeap(), 0, *param_data);
1560 *param_data = HeapAlloc(GetProcessHeap(), 0, strlen(string) + 1);
1561 if (!*param_data)
1563 ERR("Out of memory.\n");
1564 return E_OUTOFMEMORY;
1566 strcpy(*param_data, string);
1567 return D3D_OK;
1570 static HRESULT d3dx9_base_effect_set_value(struct d3dx9_base_effect *base,
1571 D3DXHANDLE parameter, const void *data, UINT bytes)
1573 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1574 unsigned int i;
1576 if (!param)
1578 WARN("Invalid parameter %p specified\n", parameter);
1579 return D3DERR_INVALIDCALL;
1582 /* samplers don't touch data */
1583 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1585 TRACE("Sampler: returning E_FAIL\n");
1586 return E_FAIL;
1589 if (data && param->bytes <= bytes)
1591 switch (param->type)
1593 case D3DXPT_TEXTURE:
1594 case D3DXPT_TEXTURE1D:
1595 case D3DXPT_TEXTURE2D:
1596 case D3DXPT_TEXTURE3D:
1597 case D3DXPT_TEXTURECUBE:
1598 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1600 IUnknown *old_texture = ((IUnknown **)param->data)[i];
1601 IUnknown *new_texture = ((IUnknown **)data)[i];
1603 if (new_texture == old_texture)
1604 continue;
1606 if (new_texture)
1607 IUnknown_AddRef(new_texture);
1608 if (old_texture)
1609 IUnknown_Release(old_texture);
1611 /* fallthrough */
1612 case D3DXPT_VOID:
1613 case D3DXPT_BOOL:
1614 case D3DXPT_INT:
1615 case D3DXPT_FLOAT:
1616 TRACE("Copy %u bytes.\n", param->bytes);
1617 memcpy(param->data, data, param->bytes);
1618 set_dirty(param);
1619 break;
1621 case D3DXPT_STRING:
1623 HRESULT hr;
1625 set_dirty(param);
1626 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1628 if (FAILED(hr = set_string(&((char **)param->data)[i], ((const char **)data)[i])))
1629 return hr;
1631 break;
1634 default:
1635 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
1636 break;
1639 return D3D_OK;
1642 WARN("Invalid argument specified\n");
1644 return D3DERR_INVALIDCALL;
1647 static HRESULT d3dx9_base_effect_get_value(struct d3dx9_base_effect *base,
1648 D3DXHANDLE parameter, void *data, UINT bytes)
1650 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1652 if (!param)
1654 WARN("Invalid parameter %p specified\n", parameter);
1655 return D3DERR_INVALIDCALL;
1658 /* samplers don't touch data */
1659 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1661 TRACE("Sampler: returning E_FAIL\n");
1662 return E_FAIL;
1665 if (data && param->bytes <= bytes)
1667 TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1669 switch (param->type)
1671 case D3DXPT_VOID:
1672 case D3DXPT_BOOL:
1673 case D3DXPT_INT:
1674 case D3DXPT_FLOAT:
1675 case D3DXPT_STRING:
1676 break;
1678 case D3DXPT_VERTEXSHADER:
1679 case D3DXPT_PIXELSHADER:
1680 case D3DXPT_TEXTURE:
1681 case D3DXPT_TEXTURE1D:
1682 case D3DXPT_TEXTURE2D:
1683 case D3DXPT_TEXTURE3D:
1684 case D3DXPT_TEXTURECUBE:
1686 UINT i;
1688 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1690 IUnknown *unk = ((IUnknown **)param->data)[i];
1691 if (unk) IUnknown_AddRef(unk);
1693 break;
1696 default:
1697 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1698 break;
1701 TRACE("Copy %u bytes\n", param->bytes);
1702 memcpy(data, param->data, param->bytes);
1703 return D3D_OK;
1706 WARN("Parameter not found.\n");
1708 return D3DERR_INVALIDCALL;
1711 static HRESULT d3dx9_base_effect_set_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL b)
1713 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1715 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1717 set_number(param->data, param->type, &b, D3DXPT_BOOL);
1718 set_dirty(param);
1719 return D3D_OK;
1722 WARN("Parameter not found.\n");
1724 return D3DERR_INVALIDCALL;
1727 static HRESULT d3dx9_base_effect_get_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL *b)
1729 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1731 if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
1733 set_number(b, D3DXPT_BOOL, param->data, param->type);
1734 TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1735 return D3D_OK;
1738 WARN("Parameter not found.\n");
1740 return D3DERR_INVALIDCALL;
1743 static HRESULT d3dx9_base_effect_set_bool_array(struct d3dx9_base_effect *base,
1744 D3DXHANDLE parameter, const BOOL *b, UINT count)
1746 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1748 if (param)
1750 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1752 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1754 switch (param->class)
1756 case D3DXPC_SCALAR:
1757 case D3DXPC_VECTOR:
1758 case D3DXPC_MATRIX_ROWS:
1759 for (i = 0; i < size; ++i)
1761 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
1762 set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
1764 set_dirty(param);
1765 return D3D_OK;
1767 case D3DXPC_OBJECT:
1768 case D3DXPC_STRUCT:
1769 break;
1771 default:
1772 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1773 break;
1777 WARN("Parameter not found.\n");
1779 return D3DERR_INVALIDCALL;
1782 static HRESULT d3dx9_base_effect_get_bool_array(struct d3dx9_base_effect *base,
1783 D3DXHANDLE parameter, BOOL *b, UINT count)
1785 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1787 if (b && param && (param->class == D3DXPC_SCALAR
1788 || param->class == D3DXPC_VECTOR
1789 || param->class == D3DXPC_MATRIX_ROWS
1790 || param->class == D3DXPC_MATRIX_COLUMNS))
1792 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1794 for (i = 0; i < size; ++i)
1796 set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
1798 return D3D_OK;
1801 WARN("Parameter not found.\n");
1803 return D3DERR_INVALIDCALL;
1806 static HRESULT d3dx9_base_effect_set_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT n)
1808 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1810 if (param && !param->element_count)
1812 if (param->rows == 1 && param->columns == 1)
1814 DWORD value;
1816 set_number(&value, param->type, &n, D3DXPT_INT);
1817 if (value != *(DWORD *)param->data)
1818 set_dirty(param);
1819 *(DWORD *)param->data = value;
1820 return D3D_OK;
1824 * Split the value, if parameter is a vector with dimension 3 or 4.
1826 if (param->type == D3DXPT_FLOAT &&
1827 ((param->class == D3DXPC_VECTOR && param->columns != 2) ||
1828 (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1830 TRACE("Vector fixup\n");
1832 *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
1833 ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
1834 ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
1835 if (param->rows * param->columns > 3)
1837 ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
1839 set_dirty(param);
1840 return D3D_OK;
1844 WARN("Parameter not found.\n");
1846 return D3DERR_INVALIDCALL;
1849 static HRESULT d3dx9_base_effect_get_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT *n)
1851 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1853 if (n && param && !param->element_count)
1855 if (param->columns == 1 && param->rows == 1)
1857 set_number(n, D3DXPT_INT, param->data, param->type);
1858 TRACE("Returning %i\n", *n);
1859 return D3D_OK;
1862 if (param->type == D3DXPT_FLOAT &&
1863 ((param->class == D3DXPC_VECTOR && param->columns != 2)
1864 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1866 TRACE("Vector fixup\n");
1868 /* all components (3,4) are clamped (0,255) and put in the INT */
1869 *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
1870 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
1871 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
1872 if (param->columns * param->rows > 3)
1874 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
1877 TRACE("Returning %i\n", *n);
1878 return D3D_OK;
1882 WARN("Parameter not found.\n");
1884 return D3DERR_INVALIDCALL;
1887 static HRESULT d3dx9_base_effect_set_int_array(struct d3dx9_base_effect *base,
1888 D3DXHANDLE parameter, const INT *n, UINT count)
1890 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1892 if (param)
1894 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1896 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1898 switch (param->class)
1900 case D3DXPC_SCALAR:
1901 case D3DXPC_VECTOR:
1902 case D3DXPC_MATRIX_ROWS:
1903 for (i = 0; i < size; ++i)
1905 set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
1907 set_dirty(param);
1908 return D3D_OK;
1910 case D3DXPC_OBJECT:
1911 case D3DXPC_STRUCT:
1912 break;
1914 default:
1915 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1916 break;
1920 WARN("Parameter not found.\n");
1922 return D3DERR_INVALIDCALL;
1925 static HRESULT d3dx9_base_effect_get_int_array(struct d3dx9_base_effect *base,
1926 D3DXHANDLE parameter, INT *n, UINT count)
1928 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1930 if (n && param && (param->class == D3DXPC_SCALAR
1931 || param->class == D3DXPC_VECTOR
1932 || param->class == D3DXPC_MATRIX_ROWS
1933 || param->class == D3DXPC_MATRIX_COLUMNS))
1935 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1937 for (i = 0; i < size; ++i)
1939 set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
1941 return D3D_OK;
1944 WARN("Parameter not found.\n");
1946 return D3DERR_INVALIDCALL;
1949 static HRESULT d3dx9_base_effect_set_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float f)
1951 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1953 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1955 DWORD value;
1957 set_number(&value, param->type, &f, D3DXPT_FLOAT);
1958 if (value != *(DWORD *)param->data)
1959 set_dirty(param);
1960 *(DWORD *)param->data = value;
1961 return D3D_OK;
1964 WARN("Parameter not found.\n");
1966 return D3DERR_INVALIDCALL;
1969 static HRESULT d3dx9_base_effect_get_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float *f)
1971 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1973 if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
1975 set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
1976 TRACE("Returning %f\n", *f);
1977 return D3D_OK;
1980 WARN("Parameter not found.\n");
1982 return D3DERR_INVALIDCALL;
1985 static HRESULT d3dx9_base_effect_set_float_array(struct d3dx9_base_effect *base,
1986 D3DXHANDLE parameter, const float *f, UINT count)
1988 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1990 if (param)
1992 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1994 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1996 switch (param->class)
1998 case D3DXPC_SCALAR:
1999 case D3DXPC_VECTOR:
2000 case D3DXPC_MATRIX_ROWS:
2001 for (i = 0; i < size; ++i)
2003 set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
2005 set_dirty(param);
2006 return D3D_OK;
2008 case D3DXPC_OBJECT:
2009 case D3DXPC_STRUCT:
2010 break;
2012 default:
2013 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2014 break;
2018 WARN("Parameter not found.\n");
2020 return D3DERR_INVALIDCALL;
2023 static HRESULT d3dx9_base_effect_get_float_array(struct d3dx9_base_effect *base,
2024 D3DXHANDLE parameter, float *f, UINT count)
2026 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2028 if (f && param && (param->class == D3DXPC_SCALAR
2029 || param->class == D3DXPC_VECTOR
2030 || param->class == D3DXPC_MATRIX_ROWS
2031 || param->class == D3DXPC_MATRIX_COLUMNS))
2033 UINT i, size = min(count, param->bytes / sizeof(DWORD));
2035 for (i = 0; i < size; ++i)
2037 set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
2039 return D3D_OK;
2042 WARN("Parameter not found.\n");
2044 return D3DERR_INVALIDCALL;
2047 static HRESULT d3dx9_base_effect_set_vector(struct d3dx9_base_effect *base,
2048 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2050 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2052 if (param && !param->element_count)
2054 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2056 switch (param->class)
2058 case D3DXPC_SCALAR:
2059 case D3DXPC_VECTOR:
2060 set_dirty(param);
2061 if (param->type == D3DXPT_INT && param->bytes == 4)
2063 DWORD tmp;
2065 TRACE("INT fixup\n");
2066 tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
2067 tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2068 tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2069 tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2071 *(INT *)param->data = tmp;
2072 return D3D_OK;
2074 if (param->type == D3DXPT_FLOAT)
2076 memcpy(param->data, vector, param->columns * sizeof(float));
2077 return D3D_OK;
2080 set_vector(param, vector);
2081 return D3D_OK;
2083 case D3DXPC_MATRIX_ROWS:
2084 case D3DXPC_OBJECT:
2085 case D3DXPC_STRUCT:
2086 break;
2088 default:
2089 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2090 break;
2094 WARN("Parameter not found.\n");
2096 return D3DERR_INVALIDCALL;
2099 static HRESULT d3dx9_base_effect_get_vector(struct d3dx9_base_effect *base,
2100 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2102 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2104 if (vector && param && !param->element_count)
2106 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2108 switch (param->class)
2110 case D3DXPC_SCALAR:
2111 case D3DXPC_VECTOR:
2112 if (param->type == D3DXPT_INT && param->bytes == 4)
2114 TRACE("INT fixup\n");
2115 vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2116 vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2117 vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2118 vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2119 return D3D_OK;
2121 get_vector(param, vector);
2122 return D3D_OK;
2124 case D3DXPC_MATRIX_ROWS:
2125 case D3DXPC_OBJECT:
2126 case D3DXPC_STRUCT:
2127 break;
2129 default:
2130 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2131 break;
2135 WARN("Parameter not found.\n");
2137 return D3DERR_INVALIDCALL;
2140 static HRESULT d3dx9_base_effect_set_vector_array(struct d3dx9_base_effect *base,
2141 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
2143 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2145 if (param && param->element_count && param->element_count >= count)
2147 UINT i;
2149 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2151 switch (param->class)
2153 case D3DXPC_VECTOR:
2154 set_dirty(param);
2155 if (param->type == D3DXPT_FLOAT)
2157 if (param->columns == 4)
2158 memcpy(param->data, vector, count * 4 * sizeof(float));
2159 else
2160 for (i = 0; i < count; ++i)
2161 memcpy((float *)param->data + param->columns * i, vector + i,
2162 param->columns * sizeof(float));
2163 return D3D_OK;
2166 for (i = 0; i < count; ++i)
2168 set_vector(&param->members[i], &vector[i]);
2170 return D3D_OK;
2172 case D3DXPC_SCALAR:
2173 case D3DXPC_MATRIX_ROWS:
2174 case D3DXPC_OBJECT:
2175 case D3DXPC_STRUCT:
2176 break;
2178 default:
2179 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2180 break;
2184 WARN("Parameter not found.\n");
2186 return D3DERR_INVALIDCALL;
2189 static HRESULT d3dx9_base_effect_get_vector_array(struct d3dx9_base_effect *base,
2190 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2192 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2194 if (!count) return D3D_OK;
2196 if (vector && param && count <= param->element_count)
2198 UINT i;
2200 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2202 switch (param->class)
2204 case D3DXPC_VECTOR:
2205 for (i = 0; i < count; ++i)
2207 get_vector(&param->members[i], &vector[i]);
2209 return D3D_OK;
2211 case D3DXPC_SCALAR:
2212 case D3DXPC_MATRIX_ROWS:
2213 case D3DXPC_OBJECT:
2214 case D3DXPC_STRUCT:
2215 break;
2217 default:
2218 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2219 break;
2223 WARN("Parameter not found.\n");
2225 return D3DERR_INVALIDCALL;
2228 static HRESULT d3dx9_base_effect_set_matrix(struct d3dx9_base_effect *base,
2229 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2231 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2233 if (param && !param->element_count)
2235 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2237 switch (param->class)
2239 case D3DXPC_MATRIX_ROWS:
2240 set_matrix(param, matrix);
2241 set_dirty(param);
2242 return D3D_OK;
2244 case D3DXPC_SCALAR:
2245 case D3DXPC_VECTOR:
2246 case D3DXPC_OBJECT:
2247 case D3DXPC_STRUCT:
2248 break;
2250 default:
2251 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2252 break;
2256 WARN("Parameter not found.\n");
2258 return D3DERR_INVALIDCALL;
2261 static HRESULT d3dx9_base_effect_get_matrix(struct d3dx9_base_effect *base,
2262 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2264 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2266 if (matrix && param && !param->element_count)
2268 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2270 switch (param->class)
2272 case D3DXPC_MATRIX_ROWS:
2273 get_matrix(param, matrix, FALSE);
2274 return D3D_OK;
2276 case D3DXPC_SCALAR:
2277 case D3DXPC_VECTOR:
2278 case D3DXPC_OBJECT:
2279 case D3DXPC_STRUCT:
2280 break;
2282 default:
2283 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2284 break;
2288 WARN("Parameter not found.\n");
2290 return D3DERR_INVALIDCALL;
2293 static HRESULT d3dx9_base_effect_set_matrix_array(struct d3dx9_base_effect *base,
2294 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2296 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2298 if (param && param->element_count >= count)
2300 UINT i;
2302 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2304 switch (param->class)
2306 case D3DXPC_MATRIX_ROWS:
2307 set_dirty(param);
2308 for (i = 0; i < count; ++i)
2310 set_matrix(&param->members[i], &matrix[i]);
2312 return D3D_OK;
2314 case D3DXPC_SCALAR:
2315 case D3DXPC_VECTOR:
2316 case D3DXPC_OBJECT:
2317 case D3DXPC_STRUCT:
2318 break;
2320 default:
2321 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2322 break;
2326 WARN("Parameter not found.\n");
2328 return D3DERR_INVALIDCALL;
2331 static HRESULT d3dx9_base_effect_get_matrix_array(struct d3dx9_base_effect *base,
2332 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2334 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2336 if (!count) return D3D_OK;
2338 if (matrix && param && count <= param->element_count)
2340 UINT i;
2342 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2344 switch (param->class)
2346 case D3DXPC_MATRIX_ROWS:
2347 for (i = 0; i < count; ++i)
2349 get_matrix(&param->members[i], &matrix[i], FALSE);
2351 return D3D_OK;
2353 case D3DXPC_SCALAR:
2354 case D3DXPC_VECTOR:
2355 case D3DXPC_OBJECT:
2356 case D3DXPC_STRUCT:
2357 break;
2359 default:
2360 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2361 break;
2365 WARN("Parameter not found.\n");
2367 return D3DERR_INVALIDCALL;
2370 static HRESULT d3dx9_base_effect_set_matrix_pointer_array(struct d3dx9_base_effect *base,
2371 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2373 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2375 if (param && count <= param->element_count)
2377 UINT i;
2379 switch (param->class)
2381 case D3DXPC_MATRIX_ROWS:
2382 set_dirty(param);
2383 for (i = 0; i < count; ++i)
2385 set_matrix(&param->members[i], matrix[i]);
2387 return D3D_OK;
2389 case D3DXPC_SCALAR:
2390 case D3DXPC_VECTOR:
2391 case D3DXPC_OBJECT:
2392 break;
2394 default:
2395 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2396 break;
2400 WARN("Parameter not found.\n");
2402 return D3DERR_INVALIDCALL;
2405 static HRESULT d3dx9_base_effect_get_matrix_pointer_array(struct d3dx9_base_effect *base,
2406 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2408 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2410 if (!count) return D3D_OK;
2412 if (param && matrix && count <= param->element_count)
2414 UINT i;
2416 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2418 switch (param->class)
2420 case D3DXPC_MATRIX_ROWS:
2421 for (i = 0; i < count; ++i)
2423 get_matrix(&param->members[i], matrix[i], FALSE);
2425 return D3D_OK;
2427 case D3DXPC_SCALAR:
2428 case D3DXPC_VECTOR:
2429 case D3DXPC_OBJECT:
2430 break;
2432 default:
2433 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2434 break;
2438 WARN("Parameter not found.\n");
2440 return D3DERR_INVALIDCALL;
2443 static HRESULT d3dx9_base_effect_set_matrix_transpose(struct d3dx9_base_effect *base,
2444 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2446 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2448 if (param && !param->element_count)
2450 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2452 switch (param->class)
2454 case D3DXPC_MATRIX_ROWS:
2455 set_dirty(param);
2456 set_matrix_transpose(param, matrix);
2457 return D3D_OK;
2459 case D3DXPC_SCALAR:
2460 case D3DXPC_VECTOR:
2461 case D3DXPC_OBJECT:
2462 case D3DXPC_STRUCT:
2463 break;
2465 default:
2466 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2467 break;
2471 WARN("Parameter not found.\n");
2473 return D3DERR_INVALIDCALL;
2476 static HRESULT d3dx9_base_effect_get_matrix_transpose(struct d3dx9_base_effect *base,
2477 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2479 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2481 if (matrix && param && !param->element_count)
2483 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2485 switch (param->class)
2487 case D3DXPC_SCALAR:
2488 case D3DXPC_VECTOR:
2489 get_matrix(param, matrix, FALSE);
2490 return D3D_OK;
2492 case D3DXPC_MATRIX_ROWS:
2493 get_matrix(param, matrix, TRUE);
2494 return D3D_OK;
2496 case D3DXPC_OBJECT:
2497 case D3DXPC_STRUCT:
2498 break;
2500 default:
2501 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2502 break;
2506 WARN("Parameter not found.\n");
2508 return D3DERR_INVALIDCALL;
2511 static HRESULT d3dx9_base_effect_set_matrix_transpose_array(struct d3dx9_base_effect *base,
2512 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2514 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2516 if (param && param->element_count >= count)
2518 UINT i;
2520 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2522 switch (param->class)
2524 case D3DXPC_MATRIX_ROWS:
2525 set_dirty(param);
2526 for (i = 0; i < count; ++i)
2528 set_matrix_transpose(&param->members[i], &matrix[i]);
2530 return D3D_OK;
2532 case D3DXPC_SCALAR:
2533 case D3DXPC_VECTOR:
2534 case D3DXPC_OBJECT:
2535 case D3DXPC_STRUCT:
2536 break;
2538 default:
2539 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2540 break;
2544 WARN("Parameter not found.\n");
2546 return D3DERR_INVALIDCALL;
2549 static HRESULT d3dx9_base_effect_get_matrix_transpose_array(struct d3dx9_base_effect *base,
2550 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2552 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2554 if (!count) return D3D_OK;
2556 if (matrix && param && count <= param->element_count)
2558 UINT i;
2560 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2562 switch (param->class)
2564 case D3DXPC_MATRIX_ROWS:
2565 for (i = 0; i < count; ++i)
2567 get_matrix(&param->members[i], &matrix[i], TRUE);
2569 return D3D_OK;
2571 case D3DXPC_SCALAR:
2572 case D3DXPC_VECTOR:
2573 case D3DXPC_OBJECT:
2574 case D3DXPC_STRUCT:
2575 break;
2577 default:
2578 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2579 break;
2583 WARN("Parameter not found.\n");
2585 return D3DERR_INVALIDCALL;
2588 static HRESULT d3dx9_base_effect_set_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2589 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2591 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2593 if (param && count <= param->element_count)
2595 UINT i;
2597 switch (param->class)
2599 case D3DXPC_MATRIX_ROWS:
2600 set_dirty(param);
2601 for (i = 0; i < count; ++i)
2603 set_matrix_transpose(&param->members[i], matrix[i]);
2605 return D3D_OK;
2607 case D3DXPC_SCALAR:
2608 case D3DXPC_VECTOR:
2609 case D3DXPC_OBJECT:
2610 break;
2612 default:
2613 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2614 break;
2618 WARN("Parameter not found.\n");
2620 return D3DERR_INVALIDCALL;
2623 static HRESULT d3dx9_base_effect_get_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2624 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2626 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2628 if (!count) return D3D_OK;
2630 if (matrix && param && count <= param->element_count)
2632 UINT i;
2634 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2636 switch (param->class)
2638 case D3DXPC_MATRIX_ROWS:
2639 for (i = 0; i < count; ++i)
2641 get_matrix(&param->members[i], matrix[i], TRUE);
2643 return D3D_OK;
2645 case D3DXPC_SCALAR:
2646 case D3DXPC_VECTOR:
2647 case D3DXPC_OBJECT:
2648 break;
2650 default:
2651 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2652 break;
2656 WARN("Parameter not found.\n");
2658 return D3DERR_INVALIDCALL;
2661 static HRESULT d3dx9_base_effect_set_string(struct d3dx9_base_effect *base,
2662 D3DXHANDLE parameter, const char *string)
2664 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2666 if (param && param->type == D3DXPT_STRING)
2668 set_dirty(param);
2669 return set_string(param->data, string);
2672 WARN("Parameter not found.\n");
2674 return D3DERR_INVALIDCALL;
2677 static HRESULT d3dx9_base_effect_get_string(struct d3dx9_base_effect *base,
2678 D3DXHANDLE parameter, const char **string)
2680 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2682 if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2684 *string = *(const char **)param->data;
2685 TRACE("Returning %s.\n", debugstr_a(*string));
2686 return D3D_OK;
2689 WARN("Parameter not found.\n");
2691 return D3DERR_INVALIDCALL;
2694 static HRESULT d3dx9_base_effect_set_texture(struct d3dx9_base_effect *base,
2695 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
2697 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2699 if (param && !param->element_count &&
2700 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2701 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2702 || param->type == D3DXPT_TEXTURECUBE))
2704 struct IDirect3DBaseTexture9 *oltexture = *(struct IDirect3DBaseTexture9 **)param->data;
2706 if (texture == oltexture)
2707 return D3D_OK;
2709 if (texture) IDirect3DBaseTexture9_AddRef(texture);
2710 if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2712 *(struct IDirect3DBaseTexture9 **)param->data = texture;
2713 set_dirty(param);
2715 return D3D_OK;
2718 WARN("Parameter not found.\n");
2720 return D3DERR_INVALIDCALL;
2723 static HRESULT d3dx9_base_effect_get_texture(struct d3dx9_base_effect *base,
2724 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
2726 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2728 if (texture && param && !param->element_count &&
2729 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2730 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2731 || param->type == D3DXPT_TEXTURECUBE))
2733 *texture = *(struct IDirect3DBaseTexture9 **)param->data;
2734 if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2735 TRACE("Returning %p\n", *texture);
2736 return D3D_OK;
2739 WARN("Parameter not found.\n");
2741 return D3DERR_INVALIDCALL;
2744 static HRESULT d3dx9_base_effect_get_pixel_shader(struct d3dx9_base_effect *base,
2745 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
2747 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2749 if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2751 if ((*shader = *(struct IDirect3DPixelShader9 **)param->data))
2752 IDirect3DPixelShader9_AddRef(*shader);
2753 TRACE("Returning %p.\n", *shader);
2754 return D3D_OK;
2757 WARN("Parameter not found.\n");
2759 return D3DERR_INVALIDCALL;
2762 static HRESULT d3dx9_base_effect_get_vertex_shader(struct d3dx9_base_effect *base,
2763 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
2765 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2767 if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2769 if ((*shader = *(struct IDirect3DVertexShader9 **)param->data))
2770 IDirect3DVertexShader9_AddRef(*shader);
2771 TRACE("Returning %p.\n", *shader);
2772 return D3D_OK;
2775 WARN("Parameter not found.\n");
2777 return D3DERR_INVALIDCALL;
2780 static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base,
2781 D3DXHANDLE parameter, UINT start, UINT end)
2783 FIXME("stub!\n");
2785 return E_NOTIMPL;
2788 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
2790 static const struct
2792 unsigned int offset;
2793 const char *name;
2795 light_tbl[] =
2797 {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
2798 {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
2799 {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
2800 {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
2801 {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
2802 {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
2803 {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
2804 {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
2805 {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
2806 {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
2807 {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
2808 {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
2809 {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
2811 switch (op)
2813 case LT_TYPE:
2814 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
2815 light->Type = *(D3DLIGHTTYPE *)value;
2816 break;
2817 case LT_DIFFUSE:
2818 case LT_SPECULAR:
2819 case LT_AMBIENT:
2821 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2823 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
2824 *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
2825 break;
2827 case LT_POSITION:
2828 case LT_DIRECTION:
2830 D3DVECTOR v = *(D3DVECTOR *)value;
2832 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
2833 *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
2834 break;
2836 case LT_RANGE:
2837 case LT_FALLOFF:
2838 case LT_ATTENUATION0:
2839 case LT_ATTENUATION1:
2840 case LT_ATTENUATION2:
2841 case LT_THETA:
2842 case LT_PHI:
2844 float v = *(float *)value;
2845 TRACE("%s %.8e.\n", light_tbl[op].name, v);
2846 *(float *)((BYTE *)light + light_tbl[op].offset) = v;
2847 break;
2849 default:
2850 WARN("Unknown light parameter %u.\n", op);
2851 break;
2855 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
2857 static const struct
2859 unsigned int offset;
2860 const char *name;
2862 material_tbl[] =
2864 {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
2865 {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
2866 {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
2867 {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
2868 {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
2871 switch (op)
2873 case MT_POWER:
2875 float v = *(float *)value;
2877 TRACE("%s %.8e.\n", material_tbl[op].name, v);
2878 material->Power = v;
2879 break;
2881 case MT_DIFFUSE:
2882 case MT_AMBIENT:
2883 case MT_SPECULAR:
2884 case MT_EMISSIVE:
2886 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2888 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
2889 *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
2890 break;
2892 default:
2893 WARN("Unknown material parameter %u.\n", op);
2894 break;
2898 static HRESULT d3dx_set_shader_const_state(struct ID3DXEffectImpl *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
2899 struct d3dx_parameter *param, void *value_ptr)
2901 static const struct
2903 D3DXPARAMETER_TYPE type;
2904 UINT elem_size;
2905 const char *name;
2907 const_tbl[] =
2909 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
2910 {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
2911 {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
2912 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
2913 {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
2914 {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
2916 unsigned int element_count;
2918 if (op < 0 || op > SCT_PSINT)
2920 FIXME("Unknown op %u.\n", op);
2921 return D3DERR_INVALIDCALL;
2923 element_count = param->bytes / const_tbl[op].elem_size;
2924 TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
2925 if (param->type != const_tbl[op].type)
2927 FIXME("Unexpected param type %u.\n", param->type);
2928 return D3DERR_INVALIDCALL;
2930 if (param->bytes % const_tbl[op].elem_size != 0)
2932 FIXME("Unexpected param size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
2933 return D3DERR_INVALIDCALL;
2936 switch (op)
2938 case SCT_VSFLOAT:
2939 return SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)value_ptr, element_count);
2940 case SCT_VSBOOL:
2941 return SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2942 case SCT_VSINT:
2943 return SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)value_ptr, element_count);
2944 case SCT_PSFLOAT:
2945 return SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)value_ptr, element_count);
2946 case SCT_PSBOOL:
2947 return SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2948 case SCT_PSINT:
2949 return SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)value_ptr, element_count);
2951 return D3D_OK;
2954 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2955 struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
2957 static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2958 struct d3dx_parameter *param, BOOL vs, BOOL update_all)
2960 HRESULT hr, ret;
2961 struct d3dx_parameter **params;
2962 D3DXCONSTANT_DESC *cdesc;
2963 unsigned int parameters_count;
2964 unsigned int i, j;
2966 if (!param->param_eval)
2968 FIXME("param_eval structure is null.\n");
2969 return D3DERR_INVALIDCALL;
2971 if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
2972 param->param_eval, update_all)))
2973 return hr;
2974 params = param->param_eval->shader_inputs.inputs_param;
2975 cdesc = param->param_eval->shader_inputs.inputs;
2976 parameters_count = param->param_eval->shader_inputs.input_count;
2977 ret = D3D_OK;
2978 for (i = 0; i < parameters_count; ++i)
2980 if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
2982 struct d3dx_sampler *sampler;
2983 unsigned int sampler_idx;
2985 for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
2987 sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
2988 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
2989 cdesc[i].RegisterIndex, sampler->state_count);
2990 for (j = 0; j < sampler->state_count; ++j)
2992 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
2993 cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
2994 update_all)))
2995 ret = hr;
3000 return ret;
3003 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
3004 struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
3006 struct d3dx_parameter *param;
3007 void *param_value;
3008 BOOL param_dirty;
3009 HRESULT hr;
3011 TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
3013 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
3014 update_all, &param_dirty)))
3016 if (!update_all && hr == E_FAIL)
3018 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
3019 * out of bounds array access and does not touch the affected
3020 * states. */
3021 WARN("Returning D3D_OK on out of bounds array access.\n");
3022 return D3D_OK;
3024 return hr;
3027 if (!(update_all || param_dirty
3028 || state_table[state->operation].class == SC_VERTEXSHADER
3029 || state_table[state->operation].class == SC_PIXELSHADER
3030 || state_table[state->operation].class == SC_SETSAMPLER))
3031 return D3D_OK;
3033 switch (state_table[state->operation].class)
3035 case SC_RENDERSTATE:
3036 TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
3037 state_table[state->operation].op, *(DWORD *)param_value);
3038 return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
3039 case SC_FVF:
3040 TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
3041 return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
3042 case SC_TEXTURE:
3044 UINT unit;
3046 unit = parent_index == ~0u ? state->index : parent_index;
3047 TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
3048 *(IDirect3DBaseTexture9 **)param_value);
3049 return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
3051 case SC_TEXTURESTAGE:
3052 TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
3053 return SET_D3D_STATE(effect, SetTextureStageState, state->index,
3054 state_table[state->operation].op, *(DWORD *)param_value);
3055 case SC_SETSAMPLER:
3057 struct d3dx_sampler *sampler;
3058 HRESULT ret, hr;
3059 unsigned int i;
3061 sampler = (struct d3dx_sampler *)param_value;
3062 TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
3063 sampler->state_count);
3064 ret = D3D_OK;
3065 for (i = 0; i < sampler->state_count; i++)
3067 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
3068 ret = hr;
3070 return ret;
3072 case SC_SAMPLERSTATE:
3074 UINT sampler;
3076 sampler = parent_index == ~0u ? state->index : parent_index;
3077 TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
3078 return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
3079 *(DWORD *)param_value);
3081 case SC_VERTEXSHADER:
3082 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
3083 if ((update_all || param_dirty)
3084 && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
3085 *(IDirect3DVertexShader9 **)param_value)))
3086 ERR("Could not set vertex shader, hr %#x.\n", hr);
3087 else if (*(IDirect3DVertexShader9 **)param_value)
3088 hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
3089 return hr;
3090 case SC_PIXELSHADER:
3091 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
3092 if ((update_all || param_dirty)
3093 && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
3094 *(IDirect3DPixelShader9 **)param_value)))
3095 ERR("Could not set pixel shader, hr %#x.\n", hr);
3096 else if (*(IDirect3DPixelShader9 **)param_value)
3097 hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
3098 return hr;
3099 case SC_TRANSFORM:
3100 TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
3101 return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
3102 (D3DMATRIX *)param_value);
3103 case SC_LIGHTENABLE:
3104 TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
3105 return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
3106 case SC_LIGHT:
3108 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3109 state_table[state->operation].op);
3110 d3dx9_set_light_parameter(state_table[state->operation].op,
3111 &effect->current_light[state->index], param_value);
3112 effect->light_updated |= 1u << state->index;
3113 return D3D_OK;
3115 case SC_MATERIAL:
3117 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3118 state_table[state->operation].op);
3119 d3dx9_set_material_parameter(state_table[state->operation].op,
3120 &effect->current_material, param_value);
3121 effect->material_updated = TRUE;
3122 return D3D_OK;
3124 case SC_NPATCHMODE:
3125 TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
3126 return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
3127 case SC_SHADERCONST:
3128 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3129 state_table[state->operation].op);
3130 return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
3131 param, param_value);
3132 default:
3133 FIXME("%s not handled.\n", state_table[state->operation].name);
3134 break;
3136 return D3D_OK;
3139 static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass, BOOL update_all)
3141 unsigned int i;
3142 HRESULT ret;
3143 HRESULT hr;
3144 ULONG64 new_update_version = next_effect_update_version(&effect->base_effect);
3146 TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
3148 ret = D3D_OK;
3149 for (i = 0; i < pass->state_count; ++i)
3151 if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
3153 WARN("Error applying state, hr %#x.\n", hr);
3154 ret = hr;
3158 if (effect->light_updated)
3160 for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
3162 if ((effect->light_updated & (1u << i))
3163 && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
3165 WARN("Error setting light, hr %#x.\n", hr);
3166 ret = hr;
3169 effect->light_updated = 0;
3172 if (effect->material_updated
3173 && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
3175 WARN("Error setting material, hr %#x.\n", hr);
3176 ret = hr;
3178 effect->material_updated = FALSE;
3180 pass->update_version = new_update_version;
3181 return ret;
3184 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
3186 unsigned char *member_data = data;
3187 unsigned int i, count;
3189 count = param->element_count ? param->element_count : param->member_count;
3190 for (i = 0; i < count; ++i)
3192 param_set_data_pointer(&param->members[i], member_data, TRUE, free_data);
3193 if (data)
3194 member_data += param->members[i].bytes;
3196 if (free_data)
3197 free_parameter_data(param, child);
3198 param->data = data;
3201 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
3203 struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
3204 BOOL matches;
3205 unsigned int i, member_count;
3207 matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
3208 && param1->type == param2->type && param1->rows == param2->rows
3209 && param1->columns == param2->columns && param1->element_count == param2->element_count
3210 && param1->member_count == param2->member_count;
3212 member_count = param1->element_count ? param1->element_count : param1->member_count;
3214 if (!matches || !member_count)
3215 return matches;
3217 for (i = 0; i < member_count; ++i)
3219 if (!is_same_parameter(&param1->members[i], &param2->members[i]))
3220 return FALSE;
3222 return TRUE;
3225 static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param)
3227 unsigned int i, free_entry_index;
3228 unsigned int new_size, new_count;
3230 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
3231 return D3D_OK;
3233 free_entry_index = pool->size;
3234 for (i = 0; i < pool->size; ++i)
3236 if (!pool->shared_data[i].count)
3237 free_entry_index = i;
3238 else if (is_same_parameter(&param->param, &pool->shared_data[i].parameters[0]->param))
3239 break;
3241 if (i == pool->size)
3243 i = free_entry_index;
3244 if (i == pool->size)
3246 struct d3dx_shared_data *new_alloc;
3248 if (!pool->size)
3250 new_size = INITIAL_POOL_SIZE;
3251 new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3252 sizeof(*pool->shared_data) * new_size);
3253 if (!new_alloc)
3255 ERR("Out of memory.\n");
3256 return E_OUTOFMEMORY;
3259 else
3261 new_size = pool->size * 2;
3262 new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
3263 sizeof(*pool->shared_data) * new_size);
3264 if (!new_alloc)
3266 ERR("Out of memory.\n");
3267 return E_OUTOFMEMORY;
3269 if (new_alloc != pool->shared_data)
3271 unsigned int j, k;
3273 for (j = 0; j < pool->size; ++j)
3274 for (k = 0; k < new_alloc[j].count; ++k)
3275 new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
3278 pool->shared_data = new_alloc;
3279 pool->size = new_size;
3281 pool->shared_data[i].data = param->param.data;
3283 else
3285 param_set_data_pointer(&param->param, pool->shared_data[i].data, FALSE, TRUE);
3287 new_count = ++pool->shared_data[i].count;
3288 if (new_count >= pool->shared_data[i].size)
3290 if (!pool->shared_data[i].size)
3292 new_size = INITIAL_SHARED_DATA_SIZE;
3293 pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3294 sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
3296 else
3298 new_size = pool->shared_data[i].size * 2;
3299 pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3300 pool->shared_data[i].parameters,
3301 sizeof(*pool->shared_data[i].parameters) * new_size);
3303 pool->shared_data[i].size = new_size;
3306 param->shared_data = &pool->shared_data[i];
3307 pool->shared_data[i].parameters[new_count - 1] = param;
3309 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
3310 new_count);
3312 return D3D_OK;
3315 static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param)
3317 param->data = NULL;
3318 return FALSE;
3321 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param)
3323 unsigned int new_count;
3325 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
3326 return;
3327 new_count = --param->shared_data->count;
3329 TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
3331 if (new_count)
3333 unsigned int i;
3335 for (i = 0; i < new_count; ++i)
3337 if (param->shared_data->parameters[i] == param)
3339 memmove(&param->shared_data->parameters[i],
3340 &param->shared_data->parameters[i + 1],
3341 sizeof(param->shared_data->parameters[i]) * (new_count - i));
3342 break;
3345 walk_parameter_tree(&param->param, param_zero_data_func, NULL);
3347 else
3349 HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
3350 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
3351 param->shared_data->size = 0;
3352 param->shared_data = NULL;
3356 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
3358 return CONTAINING_RECORD(iface, struct d3dx_effect_pool, ID3DXEffectPool_iface);
3361 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
3363 return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
3366 /*** IUnknown methods ***/
3367 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
3369 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
3371 if (IsEqualGUID(riid, &IID_IUnknown) ||
3372 IsEqualGUID(riid, &IID_ID3DXEffect))
3374 iface->lpVtbl->AddRef(iface);
3375 *object = iface;
3376 return S_OK;
3379 ERR("Interface %s not found\n", debugstr_guid(riid));
3381 return E_NOINTERFACE;
3384 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
3386 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3388 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
3390 return InterlockedIncrement(&This->ref);
3393 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
3395 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3396 ULONG ref = InterlockedDecrement(&This->ref);
3398 TRACE("(%p)->(): Release from %u\n", This, ref + 1);
3400 if (!ref)
3402 free_effect(This);
3403 HeapFree(GetProcessHeap(), 0, This);
3406 return ref;
3409 /*** ID3DXBaseEffect methods ***/
3410 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
3412 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3414 TRACE("iface %p, desc %p.\n", iface, desc);
3416 return d3dx9_base_effect_get_desc(&effect->base_effect, desc);
3419 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface,
3420 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3422 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3424 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
3426 return d3dx9_base_effect_get_parameter_desc(&effect->base_effect, parameter, desc);
3429 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface,
3430 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3432 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3434 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
3436 return d3dx9_base_effect_get_technique_desc(&effect->base_effect, technique, desc);
3439 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3441 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3443 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
3445 return d3dx9_base_effect_get_pass_desc(&effect->base_effect, pass, desc);
3448 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3450 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3452 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
3454 return d3dx9_base_effect_get_function_desc(&effect->base_effect, shader, desc);
3457 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3459 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3461 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3463 return d3dx9_base_effect_get_parameter(&effect->base_effect, parameter, index);
3466 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface,
3467 D3DXHANDLE parameter, const char *name)
3469 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3471 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
3473 return d3dx9_base_effect_get_parameter_by_name(&effect->base_effect, parameter, name);
3476 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface,
3477 D3DXHANDLE parameter, const char *semantic)
3479 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3481 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
3483 return d3dx9_base_effect_get_parameter_by_semantic(&effect->base_effect, parameter, semantic);
3486 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3488 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3490 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3492 return d3dx9_base_effect_get_parameter_element(&effect->base_effect, parameter, index);
3495 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
3497 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3499 TRACE("iface %p, index %u.\n", iface, index);
3501 return d3dx9_base_effect_get_technique(&effect->base_effect, index);
3504 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, const char *name)
3506 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3508 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3510 return d3dx9_base_effect_get_technique_by_name(&effect->base_effect, name);
3513 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
3515 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3517 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
3519 return d3dx9_base_effect_get_pass(&effect->base_effect, technique, index);
3522 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface,
3523 D3DXHANDLE technique, const char *name)
3525 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3527 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
3529 return d3dx9_base_effect_get_pass_by_name(&effect->base_effect, technique, name);
3532 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
3534 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3536 TRACE("iface %p, index %u.\n", iface, index);
3538 return d3dx9_base_effect_get_function(&effect->base_effect, index);
3541 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, const char *name)
3543 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3545 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3547 return d3dx9_base_effect_get_function_by_name(&effect->base_effect, name);
3550 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
3552 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3554 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
3556 return d3dx9_base_effect_get_annotation(&effect->base_effect, object, index);
3559 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface,
3560 D3DXHANDLE object, const char *name)
3562 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3564 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
3566 return d3dx9_base_effect_get_annotation_by_name(&effect->base_effect, object, name);
3569 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface,
3570 D3DXHANDLE parameter, const void *data, UINT bytes)
3572 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3574 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3576 return d3dx9_base_effect_set_value(&effect->base_effect, parameter, data, bytes);
3579 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface,
3580 D3DXHANDLE parameter, void *data, UINT bytes)
3582 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3584 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3586 return d3dx9_base_effect_get_value(&effect->base_effect, parameter, data, bytes);
3589 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
3591 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3593 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
3595 return d3dx9_base_effect_set_bool(&effect->base_effect, parameter, b);
3598 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
3600 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3602 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
3604 return d3dx9_base_effect_get_bool(&effect->base_effect, parameter, b);
3607 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface,
3608 D3DXHANDLE parameter, const BOOL *b, UINT count)
3610 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3612 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3614 return d3dx9_base_effect_set_bool_array(&effect->base_effect, parameter, b, count);
3617 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface,
3618 D3DXHANDLE parameter, BOOL *b, UINT count)
3620 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3622 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3624 return d3dx9_base_effect_get_bool_array(&effect->base_effect, parameter, b, count);
3627 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
3629 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3631 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
3633 return d3dx9_base_effect_set_int(&effect->base_effect, parameter, n);
3636 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
3638 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3640 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
3642 return d3dx9_base_effect_get_int(&effect->base_effect, parameter, n);
3645 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface,
3646 D3DXHANDLE parameter, const INT *n, UINT count)
3648 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3650 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3652 return d3dx9_base_effect_set_int_array(&effect->base_effect, parameter, n, count);
3655 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface,
3656 D3DXHANDLE parameter, INT *n, UINT count)
3658 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3660 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3662 return d3dx9_base_effect_get_int_array(&effect->base_effect, parameter, n, count);
3665 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
3667 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3669 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
3671 return d3dx9_base_effect_set_float(&effect->base_effect, parameter, f);
3674 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
3676 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3678 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
3680 return d3dx9_base_effect_get_float(&effect->base_effect, parameter, f);
3683 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface,
3684 D3DXHANDLE parameter, const float *f, UINT count)
3686 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3688 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3690 return d3dx9_base_effect_set_float_array(&effect->base_effect, parameter, f, count);
3693 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface,
3694 D3DXHANDLE parameter, float *f, UINT count)
3696 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3698 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3700 return d3dx9_base_effect_get_float_array(&effect->base_effect, parameter, f, count);
3703 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface,
3704 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
3706 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3708 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3710 return d3dx9_base_effect_set_vector(&effect->base_effect, parameter, vector);
3713 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface,
3714 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3716 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3718 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3720 return d3dx9_base_effect_get_vector(&effect->base_effect, parameter, vector);
3723 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface,
3724 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
3726 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3728 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3730 return d3dx9_base_effect_set_vector_array(&effect->base_effect, parameter, vector, count);
3733 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface,
3734 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3736 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3738 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3740 return d3dx9_base_effect_get_vector_array(&effect->base_effect, parameter, vector, count);
3743 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface,
3744 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3746 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3748 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3750 return d3dx9_base_effect_set_matrix(&effect->base_effect, parameter, matrix);
3753 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface,
3754 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3756 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3758 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3760 return d3dx9_base_effect_get_matrix(&effect->base_effect, parameter, matrix);
3763 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface,
3764 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3766 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3768 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3770 return d3dx9_base_effect_set_matrix_array(&effect->base_effect, parameter, matrix, count);
3773 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface,
3774 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3776 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3778 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3780 return d3dx9_base_effect_get_matrix_array(&effect->base_effect, parameter, matrix, count);
3783 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface,
3784 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3786 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3788 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3790 return d3dx9_base_effect_set_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3793 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface,
3794 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3796 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3798 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3800 return d3dx9_base_effect_get_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3803 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface,
3804 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3806 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3808 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3810 return d3dx9_base_effect_set_matrix_transpose(&effect->base_effect, parameter, matrix);
3813 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface,
3814 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3816 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3818 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3820 return d3dx9_base_effect_get_matrix_transpose(&effect->base_effect, parameter, matrix);
3823 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface,
3824 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3826 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3828 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3830 return d3dx9_base_effect_set_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3833 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface,
3834 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3836 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3838 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3840 return d3dx9_base_effect_get_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3843 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface,
3844 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3846 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3848 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3850 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3853 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface,
3854 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3856 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3858 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3860 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3863 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char *string)
3865 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3867 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
3869 return d3dx9_base_effect_set_string(&effect->base_effect, parameter, string);
3872 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char **string)
3874 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3876 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
3878 return d3dx9_base_effect_get_string(&effect->base_effect, parameter, string);
3881 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(struct ID3DXEffect *iface,
3882 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
3884 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3886 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3888 return d3dx9_base_effect_set_texture(&effect->base_effect, parameter, texture);
3891 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(struct ID3DXEffect *iface,
3892 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
3894 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3896 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3898 return d3dx9_base_effect_get_texture(&effect->base_effect, parameter, texture);
3901 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface,
3902 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
3904 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3906 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3908 return d3dx9_base_effect_get_pixel_shader(&effect->base_effect, parameter, shader);
3911 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(struct ID3DXEffect *iface,
3912 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
3914 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3916 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3918 return d3dx9_base_effect_get_vertex_shader(&effect->base_effect, parameter, shader);
3921 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3923 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3925 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
3927 return d3dx9_base_effect_set_array_range(&effect->base_effect, parameter, start, end);
3930 /*** ID3DXEffect methods ***/
3931 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, ID3DXEffectPool **pool)
3933 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3935 TRACE("iface %p, pool %p\n", This, pool);
3937 if (!pool)
3939 WARN("Invalid argument supplied.\n");
3940 return D3DERR_INVALIDCALL;
3943 if (This->pool)
3945 This->pool->lpVtbl->AddRef(This->pool);
3948 *pool = This->pool;
3950 TRACE("Returning pool %p\n", *pool);
3952 return S_OK;
3955 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3957 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3958 struct d3dx9_base_effect *base = &This->base_effect;
3959 struct d3dx_technique *tech = get_valid_technique(base, technique);
3961 TRACE("iface %p, technique %p\n", This, technique);
3963 if (tech)
3965 This->active_technique = tech;
3966 TRACE("Technique %p\n", tech);
3967 return D3D_OK;
3970 WARN("Technique not found.\n");
3972 return D3DERR_INVALIDCALL;
3975 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
3977 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3979 TRACE("iface %p\n", This);
3981 return get_technique_handle(This->active_technique);
3984 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
3986 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3987 struct d3dx9_base_effect *base = &effect->base_effect;
3988 struct d3dx_technique *tech = get_valid_technique(base, technique);
3989 HRESULT ret = D3D_OK;
3990 unsigned int i, j;
3992 FIXME("iface %p, technique %p semi-stub.\n", iface, technique);
3994 if (!tech)
3996 ret = D3DERR_INVALIDCALL;
3997 goto done;
3999 for (i = 0; i < tech->pass_count; ++i)
4001 struct d3dx_pass *pass = &tech->passes[i];
4003 for (j = 0; j < pass->state_count; ++j)
4005 struct d3dx_state *state = &pass->states[j];
4007 if (state_table[state->operation].class == SC_VERTEXSHADER
4008 || state_table[state->operation].class == SC_PIXELSHADER)
4010 struct d3dx_parameter *param;
4011 void *param_value;
4012 BOOL param_dirty;
4013 HRESULT hr;
4015 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[j], &param_value, &param,
4016 FALSE, &param_dirty)))
4017 return hr;
4019 if (param->object_id && base->objects[param->object_id].creation_failed)
4021 ret = E_FAIL;
4022 goto done;
4027 done:
4028 TRACE("Returning %#x.\n", ret);
4029 return ret;
4032 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect *iface,
4033 D3DXHANDLE technique, D3DXHANDLE *next_technique)
4035 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4036 struct d3dx9_base_effect *base = &effect->base_effect;
4037 struct d3dx_technique *prev_tech, *tech;
4038 unsigned int i;
4040 TRACE("iface %p, technique %p, next_technique %p.\n", iface, technique, next_technique);
4042 if (technique)
4044 if (!(prev_tech = get_valid_technique(base, technique)))
4045 return D3DERR_INVALIDCALL;
4047 for (i = 0; i < base->technique_count; ++i)
4049 tech = &base->techniques[i];
4050 if (tech == prev_tech)
4052 ++i;
4053 break;
4057 else
4059 i = 0;
4062 for (; i < base->technique_count; ++i)
4064 tech = &base->techniques[i];
4065 if (SUCCEEDED(ID3DXEffectImpl_ValidateTechnique(iface, get_technique_handle(tech))))
4067 *next_technique = get_technique_handle(tech);
4068 return D3D_OK;
4072 *next_technique = get_technique_handle(&base->techniques[0]);
4073 return S_FALSE;
4076 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
4077 void *data);
4079 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func,
4080 void *data)
4082 struct d3dx_parameter **params;
4083 unsigned int i, param_count;
4085 if (!param_eval)
4086 return FALSE;
4088 params = param_eval->shader_inputs.inputs_param;
4089 param_count = param_eval->shader_inputs.input_count;
4090 for (i = 0; i < param_count; ++i)
4092 if (walk_parameter_dep(params[i], param_func, data))
4093 return TRUE;
4096 params = param_eval->pres.inputs.inputs_param;
4097 param_count = param_eval->pres.inputs.input_count;
4098 for (i = 0; i < param_count; ++i)
4100 if (walk_parameter_dep(params[i], param_func, data))
4101 return TRUE;
4103 return FALSE;
4106 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func,
4107 void *data)
4109 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type))
4111 if (walk_parameter_dep(&state->parameter, param_func, data))
4112 return TRUE;
4114 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER)
4116 if (walk_parameter_dep(state->referenced_param, param_func, data))
4117 return TRUE;
4119 return walk_param_eval_dep(state->parameter.param_eval, param_func, data);
4122 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
4123 void *data)
4125 unsigned int i;
4126 unsigned int member_count;
4128 param = &param->top_level_param->param;
4129 if (param_func(data, param))
4130 return TRUE;
4132 if (walk_param_eval_dep(param->param_eval, param_func, data))
4133 return TRUE;
4135 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
4137 struct d3dx_sampler *sampler;
4138 unsigned int sampler_idx;
4139 unsigned int samplers_count = max(param->element_count, 1);
4141 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx)
4143 sampler = param->element_count ? param->members[sampler_idx].data : param->data;
4144 for (i = 0; i < sampler->state_count; ++i)
4146 if (walk_state_dep(&sampler->states[i], param_func, data))
4147 return TRUE;
4150 return FALSE;
4153 member_count = param->element_count ? param->element_count : param->member_count;
4154 for (i = 0; i < member_count; ++i)
4156 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data))
4157 return TRUE;
4160 return FALSE;
4163 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech)
4165 unsigned int i, j;
4166 struct d3dx_pass *pass;
4168 if (!tech || !param)
4169 return FALSE;
4171 for (i = 0; i < tech->pass_count; ++i)
4173 pass = &tech->passes[i];
4174 for (j = 0; j < pass->state_count; ++j)
4176 if (walk_state_dep(&pass->states[j], is_same_parameter, param))
4177 return TRUE;
4180 return FALSE;
4183 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
4185 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4186 struct d3dx_parameter *param = get_valid_parameter(&effect->base_effect, parameter);
4187 struct d3dx_technique *tech = get_valid_technique(&effect->base_effect, technique);
4188 BOOL ret;
4190 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique);
4191 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech);
4193 ret = is_parameter_used(param, tech);
4194 TRACE("Returning %#x.\n", ret);
4195 return ret;
4198 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
4200 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4201 struct d3dx_technique *technique = effect->active_technique;
4203 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags);
4205 if (technique)
4207 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE))
4208 WARN("Invalid flags (%#x) specified.\n", flags);
4210 if (flags & D3DXFX_DONOTSAVESTATE)
4212 TRACE("State capturing disabled.\n");
4214 else
4216 HRESULT hr;
4217 unsigned int i;
4219 if (!technique->saved_state)
4221 ID3DXEffectStateManager *manager;
4223 manager = effect->manager;
4224 effect->manager = NULL;
4225 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
4226 ERR("BeginStateBlock failed, hr %#x.\n", hr);
4227 for (i = 0; i < technique->pass_count; i++)
4228 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE);
4229 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
4230 ERR("EndStateBlock failed, hr %#x.\n", hr);
4231 effect->manager = manager;
4233 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
4234 ERR("StateBlock Capture failed, hr %#x.\n", hr);
4237 if (passes)
4238 *passes = technique->pass_count;
4239 effect->started = TRUE;
4240 effect->begin_flags = flags;
4242 return D3D_OK;
4245 WARN("Invalid argument supplied.\n");
4247 return D3DERR_INVALIDCALL;
4250 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
4252 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4253 struct d3dx_technique *technique = effect->active_technique;
4255 TRACE("iface %p, pass %u\n", effect, pass);
4257 if (technique && pass < technique->pass_count && !effect->active_pass)
4259 HRESULT hr;
4261 memset(effect->current_light, 0, sizeof(effect->current_light));
4262 memset(&effect->current_material, 0, sizeof(effect->current_material));
4264 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE)))
4265 effect->active_pass = &technique->passes[pass];
4266 return hr;
4269 WARN("Invalid argument supplied.\n");
4271 return D3DERR_INVALIDCALL;
4274 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect *iface)
4276 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4278 TRACE("iface %p.\n", iface);
4280 if (!effect->active_pass)
4282 WARN("Called without an active pass.\n");
4283 return D3D_OK;
4285 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE);
4288 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
4290 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4292 TRACE("iface %p\n", This);
4294 if (This->active_pass)
4296 This->active_pass = NULL;
4297 return D3D_OK;
4300 WARN("Invalid call.\n");
4302 return D3DERR_INVALIDCALL;
4305 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect *iface)
4307 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4308 struct d3dx_technique *technique = effect->active_technique;
4310 TRACE("iface %p.\n", iface);
4312 if (!effect->started)
4313 return D3D_OK;
4315 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE)
4317 TRACE("State restoring disabled.\n");
4319 else
4321 HRESULT hr;
4323 if (technique && technique->saved_state)
4325 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
4326 ERR("State block apply failed, hr %#x.\n", hr);
4328 else
4329 ERR("No saved state.\n");
4332 effect->started = FALSE;
4334 return D3D_OK;
4337 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device)
4339 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4341 TRACE("iface %p, device %p\n", This, device);
4343 if (!device)
4345 WARN("Invalid argument supplied.\n");
4346 return D3DERR_INVALIDCALL;
4349 IDirect3DDevice9_AddRef(This->device);
4351 *device = This->device;
4353 TRACE("Returning device %p\n", *device);
4355 return S_OK;
4358 static BOOL param_on_lost_device(void *data, struct d3dx_parameter *param)
4360 struct IDirect3DVolumeTexture9 *volume_texture;
4361 struct IDirect3DCubeTexture9 *cube_texture;
4362 struct IDirect3DTexture9 *texture;
4363 D3DSURFACE_DESC surface_desc;
4364 D3DVOLUME_DESC volume_desc;
4366 if (param->class == D3DXPC_OBJECT && !param->element_count)
4368 switch (param->type)
4370 case D3DXPT_TEXTURE:
4371 case D3DXPT_TEXTURE1D:
4372 case D3DXPT_TEXTURE2D:
4373 texture = *(IDirect3DTexture9 **)param->data;
4374 if (!texture)
4375 return FALSE;
4376 IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
4377 if (surface_desc.Pool != D3DPOOL_DEFAULT)
4378 return FALSE;
4379 break;
4380 case D3DXPT_TEXTURE3D:
4381 volume_texture = *(IDirect3DVolumeTexture9 **)param->data;
4382 if (!volume_texture)
4383 return FALSE;
4384 IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
4385 if (volume_desc.Pool != D3DPOOL_DEFAULT)
4386 return FALSE;
4387 break;
4388 case D3DXPT_TEXTURECUBE:
4389 cube_texture = *(IDirect3DCubeTexture9 **)param->data;
4390 if (!cube_texture)
4391 return FALSE;
4392 IDirect3DTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
4393 if (surface_desc.Pool != D3DPOOL_DEFAULT)
4394 return FALSE;
4395 break;
4396 default:
4397 return FALSE;
4399 IUnknown_Release(*(IUnknown **)param->data);
4400 *(IUnknown **)param->data = NULL;
4402 return FALSE;
4405 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
4407 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4408 struct d3dx9_base_effect *base = &effect->base_effect;
4409 unsigned int i;
4411 TRACE("iface %p.\n", iface);
4413 for (i = 0; i < base->parameter_count; ++i)
4414 walk_parameter_tree(&base->parameters[i].param, param_on_lost_device, NULL);
4416 return D3D_OK;
4419 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
4421 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4423 FIXME("(%p)->(): stub\n", This);
4425 return E_NOTIMPL;
4428 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager)
4430 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4432 TRACE("iface %p, manager %p\n", This, manager);
4434 if (manager) IUnknown_AddRef(manager);
4435 if (This->manager) IUnknown_Release(This->manager);
4437 This->manager = manager;
4439 return D3D_OK;
4442 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager)
4444 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4446 TRACE("iface %p, manager %p\n", This, manager);
4448 if (!manager)
4450 WARN("Invalid argument supplied.\n");
4451 return D3DERR_INVALIDCALL;
4454 if (This->manager) IUnknown_AddRef(This->manager);
4455 *manager = This->manager;
4457 return D3D_OK;
4460 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
4462 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4464 FIXME("(%p)->(): stub\n", This);
4466 return E_NOTIMPL;
4469 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
4471 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4473 FIXME("(%p)->(): stub\n", This);
4475 return NULL;
4478 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4480 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4482 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4484 return E_NOTIMPL;
4487 #if D3DX_SDK_VERSION >= 26
4488 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4490 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4492 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4494 return E_NOTIMPL;
4496 #endif
4498 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
4499 struct IDirect3DDevice9 *device, struct ID3DXEffect **effect)
4501 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4503 FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
4505 if (!effect)
4506 return D3DERR_INVALIDCALL;
4508 if (This->base_effect.flags & D3DXFX_NOT_CLONEABLE)
4509 return E_FAIL;
4511 if (!device)
4512 return D3DERR_INVALIDCALL;
4514 return E_NOTIMPL;
4517 #if D3DX_SDK_VERSION >= 27
4518 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface,
4519 D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes)
4521 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4522 iface, parameter, data, byte_offset, bytes);
4524 return E_NOTIMPL;
4526 #endif
4528 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
4530 /*** IUnknown methods ***/
4531 ID3DXEffectImpl_QueryInterface,
4532 ID3DXEffectImpl_AddRef,
4533 ID3DXEffectImpl_Release,
4534 /*** ID3DXBaseEffect methods ***/
4535 ID3DXEffectImpl_GetDesc,
4536 ID3DXEffectImpl_GetParameterDesc,
4537 ID3DXEffectImpl_GetTechniqueDesc,
4538 ID3DXEffectImpl_GetPassDesc,
4539 ID3DXEffectImpl_GetFunctionDesc,
4540 ID3DXEffectImpl_GetParameter,
4541 ID3DXEffectImpl_GetParameterByName,
4542 ID3DXEffectImpl_GetParameterBySemantic,
4543 ID3DXEffectImpl_GetParameterElement,
4544 ID3DXEffectImpl_GetTechnique,
4545 ID3DXEffectImpl_GetTechniqueByName,
4546 ID3DXEffectImpl_GetPass,
4547 ID3DXEffectImpl_GetPassByName,
4548 ID3DXEffectImpl_GetFunction,
4549 ID3DXEffectImpl_GetFunctionByName,
4550 ID3DXEffectImpl_GetAnnotation,
4551 ID3DXEffectImpl_GetAnnotationByName,
4552 ID3DXEffectImpl_SetValue,
4553 ID3DXEffectImpl_GetValue,
4554 ID3DXEffectImpl_SetBool,
4555 ID3DXEffectImpl_GetBool,
4556 ID3DXEffectImpl_SetBoolArray,
4557 ID3DXEffectImpl_GetBoolArray,
4558 ID3DXEffectImpl_SetInt,
4559 ID3DXEffectImpl_GetInt,
4560 ID3DXEffectImpl_SetIntArray,
4561 ID3DXEffectImpl_GetIntArray,
4562 ID3DXEffectImpl_SetFloat,
4563 ID3DXEffectImpl_GetFloat,
4564 ID3DXEffectImpl_SetFloatArray,
4565 ID3DXEffectImpl_GetFloatArray,
4566 ID3DXEffectImpl_SetVector,
4567 ID3DXEffectImpl_GetVector,
4568 ID3DXEffectImpl_SetVectorArray,
4569 ID3DXEffectImpl_GetVectorArray,
4570 ID3DXEffectImpl_SetMatrix,
4571 ID3DXEffectImpl_GetMatrix,
4572 ID3DXEffectImpl_SetMatrixArray,
4573 ID3DXEffectImpl_GetMatrixArray,
4574 ID3DXEffectImpl_SetMatrixPointerArray,
4575 ID3DXEffectImpl_GetMatrixPointerArray,
4576 ID3DXEffectImpl_SetMatrixTranspose,
4577 ID3DXEffectImpl_GetMatrixTranspose,
4578 ID3DXEffectImpl_SetMatrixTransposeArray,
4579 ID3DXEffectImpl_GetMatrixTransposeArray,
4580 ID3DXEffectImpl_SetMatrixTransposePointerArray,
4581 ID3DXEffectImpl_GetMatrixTransposePointerArray,
4582 ID3DXEffectImpl_SetString,
4583 ID3DXEffectImpl_GetString,
4584 ID3DXEffectImpl_SetTexture,
4585 ID3DXEffectImpl_GetTexture,
4586 ID3DXEffectImpl_GetPixelShader,
4587 ID3DXEffectImpl_GetVertexShader,
4588 ID3DXEffectImpl_SetArrayRange,
4589 /*** ID3DXEffect methods ***/
4590 ID3DXEffectImpl_GetPool,
4591 ID3DXEffectImpl_SetTechnique,
4592 ID3DXEffectImpl_GetCurrentTechnique,
4593 ID3DXEffectImpl_ValidateTechnique,
4594 ID3DXEffectImpl_FindNextValidTechnique,
4595 ID3DXEffectImpl_IsParameterUsed,
4596 ID3DXEffectImpl_Begin,
4597 ID3DXEffectImpl_BeginPass,
4598 ID3DXEffectImpl_CommitChanges,
4599 ID3DXEffectImpl_EndPass,
4600 ID3DXEffectImpl_End,
4601 ID3DXEffectImpl_GetDevice,
4602 ID3DXEffectImpl_OnLostDevice,
4603 ID3DXEffectImpl_OnResetDevice,
4604 ID3DXEffectImpl_SetStateManager,
4605 ID3DXEffectImpl_GetStateManager,
4606 ID3DXEffectImpl_BeginParameterBlock,
4607 ID3DXEffectImpl_EndParameterBlock,
4608 ID3DXEffectImpl_ApplyParameterBlock,
4609 #if D3DX_SDK_VERSION >= 26
4610 ID3DXEffectImpl_DeleteParameterBlock,
4611 #endif
4612 ID3DXEffectImpl_CloneEffect,
4613 #if D3DX_SDK_VERSION >= 27
4614 ID3DXEffectImpl_SetRawValue
4615 #endif
4618 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
4620 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
4623 /*** IUnknown methods ***/
4624 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
4626 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
4628 if (IsEqualGUID(riid, &IID_IUnknown) ||
4629 IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
4631 iface->lpVtbl->AddRef(iface);
4632 *object = iface;
4633 return S_OK;
4636 ERR("Interface %s not found\n", debugstr_guid(riid));
4638 return E_NOINTERFACE;
4641 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
4643 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4645 TRACE("iface %p: AddRef from %u\n", iface, This->ref);
4647 return InterlockedIncrement(&This->ref);
4650 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
4652 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4653 ULONG ref = InterlockedDecrement(&This->ref);
4655 TRACE("iface %p: Release from %u\n", iface, ref + 1);
4657 if (!ref)
4659 HeapFree(GetProcessHeap(), 0, This);
4662 return ref;
4665 /*** ID3DXBaseEffect methods ***/
4666 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
4668 FIXME("iface %p, desc %p stub!\n", iface, desc);
4670 return E_NOTIMPL;
4673 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface,
4674 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
4676 FIXME("iface %p, parameter %p, desc %p stub!\n", iface, parameter, desc);
4678 return E_NOTIMPL;
4681 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface,
4682 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
4684 FIXME("iface %p, technique %p, desc %p stub!\n", iface, technique, desc);
4686 return E_NOTIMPL;
4689 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface,
4690 D3DXHANDLE pass, D3DXPASS_DESC *desc)
4692 FIXME("iface %p, pass %p, desc %p stub!\n", iface, pass, desc);
4694 return E_NOTIMPL;
4697 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface,
4698 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
4700 FIXME("iface %p, shader %p, desc %p stub!\n", iface, shader, desc);
4702 return E_NOTIMPL;
4705 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface,
4706 D3DXHANDLE parameter, UINT index)
4708 FIXME("iface %p, parameter %p, index %u stub!\n", iface, parameter, index);
4710 return NULL;
4713 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface,
4714 D3DXHANDLE parameter, const char *name)
4716 FIXME("iface %p, parameter %p, name %s stub!\n", iface, parameter, debugstr_a(name));
4718 return NULL;
4721 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface,
4722 D3DXHANDLE parameter, const char *semantic)
4724 FIXME("iface %p, parameter %p, semantic %s stub!\n", iface, parameter, debugstr_a(semantic));
4726 return NULL;
4729 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface,
4730 D3DXHANDLE parameter, UINT index)
4732 FIXME("iface %p, parameter %p, index %u stub!\n", iface, parameter, index);
4734 return NULL;
4737 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
4739 FIXME("iface %p, index %u stub!\n", iface, index);
4741 return NULL;
4744 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name)
4746 FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name));
4748 return NULL;
4751 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
4753 FIXME("iface %p, technique %p, index %u stub!\n", iface, technique, index);
4755 return NULL;
4758 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface,
4759 D3DXHANDLE technique, const char *name)
4761 FIXME("iface %p, technique %p, name %s stub!\n", iface, technique, debugstr_a(name));
4763 return NULL;
4766 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
4768 FIXME("iface %p, index %u stub!\n", iface, index);
4770 return NULL;
4773 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name)
4775 FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name));
4777 return NULL;
4780 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface,
4781 D3DXHANDLE object, UINT index)
4783 FIXME("iface %p, object %p, index %u stub!\n", iface, object, index);
4785 return NULL;
4788 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface,
4789 D3DXHANDLE object, const char *name)
4791 FIXME("iface %p, object %p, name %s stub!\n", iface, object, debugstr_a(name));
4793 return NULL;
4796 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface,
4797 D3DXHANDLE parameter, const void *data, UINT bytes)
4799 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface, parameter, data, bytes);
4801 return E_NOTIMPL;
4804 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface,
4805 D3DXHANDLE parameter, void *data, UINT bytes)
4807 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface, parameter, data, bytes);
4809 return E_NOTIMPL;
4812 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4814 FIXME("iface %p, parameter %p, b %#x stub!\n", iface, parameter, b);
4816 return E_NOTIMPL;
4819 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4821 FIXME("iface %p, parameter %p, b %p stub!\n", iface, parameter, b);
4823 return E_NOTIMPL;
4826 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface,
4827 D3DXHANDLE parameter, const BOOL *b, UINT count)
4829 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface, parameter, b, count);
4831 return E_NOTIMPL;
4834 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface,
4835 D3DXHANDLE parameter, BOOL *b, UINT count)
4837 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface, parameter, b, count);
4839 return E_NOTIMPL;
4842 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4844 FIXME("iface %p, parameter %p, n %d stub!\n", iface, parameter, n);
4846 return E_NOTIMPL;
4849 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4851 FIXME("iface %p, parameter %p, n %p stub!\n", iface, parameter, n);
4853 return E_NOTIMPL;
4856 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface,
4857 D3DXHANDLE parameter, const INT *n, UINT count)
4859 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface, parameter, n, count);
4861 return E_NOTIMPL;
4864 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface,
4865 D3DXHANDLE parameter, INT *n, UINT count)
4867 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface, parameter, n, count);
4869 return E_NOTIMPL;
4872 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f)
4874 FIXME("iface %p, parameter %p, f %.8e stub!\n", iface, parameter, f);
4876 return E_NOTIMPL;
4879 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f)
4881 FIXME("iface %p, parameter %p, f %p stub!\n", iface, parameter, f);
4883 return E_NOTIMPL;
4886 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface,
4887 D3DXHANDLE parameter, const float *f, UINT count)
4889 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface, parameter, f, count);
4891 return E_NOTIMPL;
4894 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface,
4895 D3DXHANDLE parameter, float *f, UINT count)
4897 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface, parameter, f, count);
4899 return E_NOTIMPL;
4902 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface,
4903 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
4905 FIXME("iface %p, parameter %p, vector %p stub!\n", iface, parameter, vector);
4907 return E_NOTIMPL;
4910 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface,
4911 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4913 FIXME("iface %p, parameter %p, vector %p stub!\n", iface, parameter, vector);
4915 return E_NOTIMPL;
4918 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface,
4919 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
4921 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface, parameter, vector, count);
4923 return E_NOTIMPL;
4926 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface,
4927 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4929 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface, parameter, vector, count);
4931 return E_NOTIMPL;
4934 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface,
4935 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4937 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4939 return E_NOTIMPL;
4942 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface,
4943 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4945 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4947 return E_NOTIMPL;
4950 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface,
4951 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4953 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4955 return E_NOTIMPL;
4958 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface,
4959 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4961 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4963 return E_NOTIMPL;
4966 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface,
4967 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4969 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4971 return E_NOTIMPL;
4974 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface,
4975 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4977 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4979 return E_NOTIMPL;
4982 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface,
4983 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4985 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4987 return E_NOTIMPL;
4990 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface,
4991 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4993 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4995 return E_NOTIMPL;
4998 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4999 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
5001 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
5003 return E_NOTIMPL;
5006 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface,
5007 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
5009 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
5011 return E_NOTIMPL;
5014 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
5015 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
5017 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
5019 return E_NOTIMPL;
5022 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
5023 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
5025 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
5027 return E_NOTIMPL;
5030 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface,
5031 D3DXHANDLE parameter, const char *string)
5033 FIXME("iface %p, parameter %p, string %s stub!\n", iface, parameter, debugstr_a(string));
5035 return E_NOTIMPL;
5038 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface,
5039 D3DXHANDLE parameter, const char **string)
5041 FIXME("iface %p, parameter %p, string %p stub!\n", iface, parameter, string);
5043 return E_NOTIMPL;
5046 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
5047 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
5049 FIXME("iface %p, parameter %p, texture %p stub!\n", iface, parameter, texture);
5051 return E_NOTIMPL;
5054 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
5055 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
5057 FIXME("iface %p, parameter %p, texture %p stub!\n", iface, parameter, texture);
5059 return E_NOTIMPL;
5062 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
5063 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
5065 FIXME("iface %p, parameter %p, shader %p stub!\n", iface, parameter, shader);
5067 return E_NOTIMPL;
5070 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
5071 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
5073 FIXME("iface %p, parameter %p, shader %p stub!\n", iface, parameter, shader);
5075 return E_NOTIMPL;
5078 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface,
5079 D3DXHANDLE parameter, UINT start, UINT end)
5081 FIXME("iface %p, parameter %p, start %u, end %u stub!\n", iface, parameter, start, end);
5083 return E_NOTIMPL;
5086 /*** ID3DXEffectCompiler methods ***/
5087 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
5089 FIXME("iface %p, parameter %p, literal %#x stub!\n", iface, parameter, literal);
5091 return E_NOTIMPL;
5094 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
5096 FIXME("iface %p, parameter %p, literal %p stub!\n", iface, parameter, literal);
5098 return E_NOTIMPL;
5101 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
5102 ID3DXBuffer **effect, ID3DXBuffer **error_msgs)
5104 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub!\n", iface, flags, effect, error_msgs);
5106 return E_NOTIMPL;
5109 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
5110 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs,
5111 ID3DXConstantTable **constant_table)
5113 FIXME("iface %p, function %p, target %s, flags %#x, shader %p, error_msgs %p, constant_table %p stub!\n",
5114 iface, function, debugstr_a(target), flags, shader, error_msgs, constant_table);
5116 return E_NOTIMPL;
5119 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
5121 /*** IUnknown methods ***/
5122 ID3DXEffectCompilerImpl_QueryInterface,
5123 ID3DXEffectCompilerImpl_AddRef,
5124 ID3DXEffectCompilerImpl_Release,
5125 /*** ID3DXBaseEffect methods ***/
5126 ID3DXEffectCompilerImpl_GetDesc,
5127 ID3DXEffectCompilerImpl_GetParameterDesc,
5128 ID3DXEffectCompilerImpl_GetTechniqueDesc,
5129 ID3DXEffectCompilerImpl_GetPassDesc,
5130 ID3DXEffectCompilerImpl_GetFunctionDesc,
5131 ID3DXEffectCompilerImpl_GetParameter,
5132 ID3DXEffectCompilerImpl_GetParameterByName,
5133 ID3DXEffectCompilerImpl_GetParameterBySemantic,
5134 ID3DXEffectCompilerImpl_GetParameterElement,
5135 ID3DXEffectCompilerImpl_GetTechnique,
5136 ID3DXEffectCompilerImpl_GetTechniqueByName,
5137 ID3DXEffectCompilerImpl_GetPass,
5138 ID3DXEffectCompilerImpl_GetPassByName,
5139 ID3DXEffectCompilerImpl_GetFunction,
5140 ID3DXEffectCompilerImpl_GetFunctionByName,
5141 ID3DXEffectCompilerImpl_GetAnnotation,
5142 ID3DXEffectCompilerImpl_GetAnnotationByName,
5143 ID3DXEffectCompilerImpl_SetValue,
5144 ID3DXEffectCompilerImpl_GetValue,
5145 ID3DXEffectCompilerImpl_SetBool,
5146 ID3DXEffectCompilerImpl_GetBool,
5147 ID3DXEffectCompilerImpl_SetBoolArray,
5148 ID3DXEffectCompilerImpl_GetBoolArray,
5149 ID3DXEffectCompilerImpl_SetInt,
5150 ID3DXEffectCompilerImpl_GetInt,
5151 ID3DXEffectCompilerImpl_SetIntArray,
5152 ID3DXEffectCompilerImpl_GetIntArray,
5153 ID3DXEffectCompilerImpl_SetFloat,
5154 ID3DXEffectCompilerImpl_GetFloat,
5155 ID3DXEffectCompilerImpl_SetFloatArray,
5156 ID3DXEffectCompilerImpl_GetFloatArray,
5157 ID3DXEffectCompilerImpl_SetVector,
5158 ID3DXEffectCompilerImpl_GetVector,
5159 ID3DXEffectCompilerImpl_SetVectorArray,
5160 ID3DXEffectCompilerImpl_GetVectorArray,
5161 ID3DXEffectCompilerImpl_SetMatrix,
5162 ID3DXEffectCompilerImpl_GetMatrix,
5163 ID3DXEffectCompilerImpl_SetMatrixArray,
5164 ID3DXEffectCompilerImpl_GetMatrixArray,
5165 ID3DXEffectCompilerImpl_SetMatrixPointerArray,
5166 ID3DXEffectCompilerImpl_GetMatrixPointerArray,
5167 ID3DXEffectCompilerImpl_SetMatrixTranspose,
5168 ID3DXEffectCompilerImpl_GetMatrixTranspose,
5169 ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
5170 ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
5171 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
5172 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
5173 ID3DXEffectCompilerImpl_SetString,
5174 ID3DXEffectCompilerImpl_GetString,
5175 ID3DXEffectCompilerImpl_SetTexture,
5176 ID3DXEffectCompilerImpl_GetTexture,
5177 ID3DXEffectCompilerImpl_GetPixelShader,
5178 ID3DXEffectCompilerImpl_GetVertexShader,
5179 ID3DXEffectCompilerImpl_SetArrayRange,
5180 /*** ID3DXEffectCompiler methods ***/
5181 ID3DXEffectCompilerImpl_SetLiteral,
5182 ID3DXEffectCompilerImpl_GetLiteral,
5183 ID3DXEffectCompilerImpl_CompileEffect,
5184 ID3DXEffectCompilerImpl_CompileShader,
5187 static HRESULT d3dx9_parse_sampler(struct d3dx9_base_effect *base, struct d3dx_sampler *sampler,
5188 const char *data, const char **ptr, struct d3dx_object *objects)
5190 HRESULT hr;
5191 UINT i;
5193 read_dword(ptr, &sampler->state_count);
5194 TRACE("Count: %u\n", sampler->state_count);
5196 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count);
5197 if (!sampler->states)
5199 ERR("Out of memory\n");
5200 return E_OUTOFMEMORY;
5203 for (i = 0; i < sampler->state_count; ++i)
5205 hr = d3dx9_parse_state(base, &sampler->states[i], data, ptr, objects);
5206 if (hr != D3D_OK)
5208 WARN("Failed to parse state %u\n", i);
5209 goto err_out;
5213 return D3D_OK;
5215 err_out:
5217 for (i = 0; i < sampler->state_count; ++i)
5219 free_state(&sampler->states[i]);
5221 HeapFree(GetProcessHeap(), 0, sampler->states);
5222 sampler->states = NULL;
5224 return hr;
5227 static HRESULT d3dx9_parse_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5228 void *value, const char *data, const char **ptr, struct d3dx_object *objects)
5230 unsigned int i;
5231 HRESULT hr;
5232 UINT old_size = 0;
5234 if (param->element_count)
5236 param->data = value;
5238 for (i = 0; i < param->element_count; ++i)
5240 struct d3dx_parameter *member = &param->members[i];
5242 hr = d3dx9_parse_value(base, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
5243 if (hr != D3D_OK)
5245 WARN("Failed to parse value %u\n", i);
5246 return hr;
5249 old_size += member->bytes;
5252 return D3D_OK;
5255 switch(param->class)
5257 case D3DXPC_SCALAR:
5258 case D3DXPC_VECTOR:
5259 case D3DXPC_MATRIX_ROWS:
5260 case D3DXPC_MATRIX_COLUMNS:
5261 param->data = value;
5262 break;
5264 case D3DXPC_STRUCT:
5265 param->data = value;
5267 for (i = 0; i < param->member_count; ++i)
5269 struct d3dx_parameter *member = &param->members[i];
5271 hr = d3dx9_parse_value(base, member, (char *)value + old_size, data, ptr, objects);
5272 if (hr != D3D_OK)
5274 WARN("Failed to parse value %u\n", i);
5275 return hr;
5278 old_size += member->bytes;
5280 break;
5282 case D3DXPC_OBJECT:
5283 switch (param->type)
5285 case D3DXPT_STRING:
5286 case D3DXPT_TEXTURE:
5287 case D3DXPT_TEXTURE1D:
5288 case D3DXPT_TEXTURE2D:
5289 case D3DXPT_TEXTURE3D:
5290 case D3DXPT_TEXTURECUBE:
5291 case D3DXPT_PIXELSHADER:
5292 case D3DXPT_VERTEXSHADER:
5293 read_dword(ptr, &param->object_id);
5294 TRACE("Id: %u\n", param->object_id);
5295 objects[param->object_id].param = param;
5296 param->data = value;
5297 break;
5299 case D3DXPT_SAMPLER:
5300 case D3DXPT_SAMPLER1D:
5301 case D3DXPT_SAMPLER2D:
5302 case D3DXPT_SAMPLER3D:
5303 case D3DXPT_SAMPLERCUBE:
5305 struct d3dx_sampler *sampler;
5307 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
5308 if (!sampler)
5309 return E_OUTOFMEMORY;
5311 hr = d3dx9_parse_sampler(base, sampler, data, ptr, objects);
5312 if (hr != D3D_OK)
5314 HeapFree(GetProcessHeap(), 0, sampler);
5315 WARN("Failed to parse sampler\n");
5316 return hr;
5319 param->data = sampler;
5320 break;
5323 default:
5324 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5325 break;
5327 break;
5329 default:
5330 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5331 break;
5334 return D3D_OK;
5337 static HRESULT d3dx9_parse_init_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5338 const char *data, const char *ptr, struct d3dx_object *objects)
5340 UINT size = param->bytes;
5341 HRESULT hr;
5342 void *value = NULL;
5344 TRACE("param size: %u\n", size);
5346 if (size)
5348 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5349 if (!value)
5351 ERR("Failed to allocate data memory.\n");
5352 return E_OUTOFMEMORY;
5355 switch(param->class)
5357 case D3DXPC_OBJECT:
5358 break;
5360 case D3DXPC_SCALAR:
5361 case D3DXPC_VECTOR:
5362 case D3DXPC_MATRIX_ROWS:
5363 case D3DXPC_MATRIX_COLUMNS:
5364 case D3DXPC_STRUCT:
5365 TRACE("Data: %s.\n", debugstr_an(ptr, size));
5366 memcpy(value, ptr, size);
5367 break;
5369 default:
5370 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5371 break;
5375 hr = d3dx9_parse_value(base, param, value, data, &ptr, objects);
5376 if (hr != D3D_OK)
5378 WARN("Failed to parse value\n");
5379 HeapFree(GetProcessHeap(), 0, value);
5380 return hr;
5383 return D3D_OK;
5386 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
5388 DWORD size;
5390 read_dword(&ptr, &size);
5391 TRACE("Name size: %#x\n", size);
5393 if (!size)
5395 return D3D_OK;
5398 *name = HeapAlloc(GetProcessHeap(), 0, size);
5399 if (!*name)
5401 ERR("Failed to allocate name memory.\n");
5402 return E_OUTOFMEMORY;
5405 TRACE("Name: %s.\n", debugstr_an(ptr, size));
5406 memcpy(*name, ptr, size);
5408 return D3D_OK;
5411 static HRESULT d3dx9_copy_data(struct d3dx9_base_effect *base, unsigned int object_id, const char **ptr)
5413 struct d3dx_object *object = &base->objects[object_id];
5415 if (object->size || object->data)
5417 if (object_id)
5418 FIXME("Overwriting object id %u!\n", object_id);
5419 else
5420 TRACE("Overwriting object id 0.\n");
5422 HeapFree(GetProcessHeap(), 0, object->data);
5423 object->data = NULL;
5426 read_dword(ptr, &object->size);
5427 TRACE("Data size: %#x.\n", object->size);
5429 if (!object->size)
5430 return D3D_OK;
5432 object->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5433 if (!object->data)
5435 ERR("Failed to allocate object memory.\n");
5436 return E_OUTOFMEMORY;
5439 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size));
5440 memcpy(object->data, *ptr, object->size);
5442 *ptr += ((object->size + 3) & ~3);
5444 return D3D_OK;
5447 static void param_set_magic_number(struct d3dx_parameter *param)
5449 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string));
5452 static int param_rb_compare(const void *key, const struct wine_rb_entry *entry)
5454 const char *name = key;
5455 struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
5457 return strcmp(name, param->full_name);
5460 static void add_param_to_tree(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5461 struct d3dx_parameter *parent, char separator, unsigned int element)
5463 const char *parent_name = parent ? parent->full_name : NULL;
5464 unsigned int i;
5466 TRACE("Adding parameter %p (%s - parent %p, element %u) to the rbtree.\n",
5467 param, debugstr_a(param->name), parent, element);
5469 if (parent_name)
5471 unsigned int parent_name_len = strlen(parent_name);
5472 unsigned int name_len = strlen(param->name);
5473 unsigned int part_str_len;
5474 unsigned int len;
5475 char part_str[16];
5477 if (separator == '[')
5479 sprintf(part_str, "[%u]", element);
5480 part_str_len = strlen(part_str);
5481 name_len = 0;
5483 else
5485 part_str[0] = separator;
5486 part_str[1] = 0;
5487 part_str_len = 1;
5489 len = parent_name_len + part_str_len + name_len + 1;
5491 if (!(param->full_name = heap_alloc(len)))
5493 ERR("Out of memory.\n");
5494 return;
5497 memcpy(param->full_name, parent_name, parent_name_len);
5498 memcpy(param->full_name + parent_name_len, part_str, part_str_len);
5499 memcpy(param->full_name + parent_name_len + part_str_len, param->name, name_len);
5500 param->full_name[len - 1] = 0;
5502 else
5504 unsigned int len = strlen(param->name) + 1;
5506 if (!(param->full_name = heap_alloc(len)))
5508 ERR("Out of memory.\n");
5509 return;
5512 memcpy(param->full_name, param->name, len);
5514 TRACE("Full name is %s.\n", param->full_name);
5515 wine_rb_put(&base->param_tree, param->full_name, &param->rb_entry);
5517 if (is_top_level_parameter(param))
5518 for (i = 0; i < param->top_level_param->annotation_count; ++i)
5519 add_param_to_tree(base, &param->top_level_param->annotations[i], param, '@', 0);
5521 if (param->element_count)
5522 for (i = 0; i < param->element_count; ++i)
5523 add_param_to_tree(base, &param->members[i], param, '[', i);
5524 else
5525 for (i = 0; i < param->member_count; ++i)
5526 add_param_to_tree(base, &param->members[i], param, '.', 0);
5529 static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5530 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
5532 DWORD offset;
5533 HRESULT hr;
5534 UINT i;
5536 param->flags = flags;
5538 if (!parent)
5540 read_dword(ptr, (DWORD *)&param->type);
5541 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
5543 read_dword(ptr, (DWORD *)&param->class);
5544 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
5546 read_dword(ptr, &offset);
5547 TRACE("Type name offset: %#x\n", offset);
5548 hr = d3dx9_parse_name(&param->name, data + offset);
5549 if (hr != D3D_OK)
5551 WARN("Failed to parse name\n");
5552 goto err_out;
5555 read_dword(ptr, &offset);
5556 TRACE("Type semantic offset: %#x\n", offset);
5557 hr = d3dx9_parse_name(&param->semantic, data + offset);
5558 if (hr != D3D_OK)
5560 WARN("Failed to parse semantic\n");
5561 goto err_out;
5564 read_dword(ptr, &param->element_count);
5565 TRACE("Elements: %u\n", param->element_count);
5567 switch (param->class)
5569 case D3DXPC_VECTOR:
5570 read_dword(ptr, &param->columns);
5571 TRACE("Columns: %u\n", param->columns);
5573 read_dword(ptr, &param->rows);
5574 TRACE("Rows: %u\n", param->rows);
5576 /* sizeof(DWORD) * rows * columns */
5577 param->bytes = 4 * param->rows * param->columns;
5578 break;
5580 case D3DXPC_SCALAR:
5581 case D3DXPC_MATRIX_ROWS:
5582 case D3DXPC_MATRIX_COLUMNS:
5583 read_dword(ptr, &param->rows);
5584 TRACE("Rows: %u\n", param->rows);
5586 read_dword(ptr, &param->columns);
5587 TRACE("Columns: %u\n", param->columns);
5589 /* sizeof(DWORD) * rows * columns */
5590 param->bytes = 4 * param->rows * param->columns;
5591 break;
5593 case D3DXPC_STRUCT:
5594 read_dword(ptr, &param->member_count);
5595 TRACE("Members: %u\n", param->member_count);
5596 break;
5598 case D3DXPC_OBJECT:
5599 switch (param->type)
5601 case D3DXPT_STRING:
5602 case D3DXPT_PIXELSHADER:
5603 case D3DXPT_VERTEXSHADER:
5604 case D3DXPT_TEXTURE:
5605 case D3DXPT_TEXTURE1D:
5606 case D3DXPT_TEXTURE2D:
5607 case D3DXPT_TEXTURE3D:
5608 case D3DXPT_TEXTURECUBE:
5609 param->bytes = sizeof(void *);
5610 break;
5612 case D3DXPT_SAMPLER:
5613 case D3DXPT_SAMPLER1D:
5614 case D3DXPT_SAMPLER2D:
5615 case D3DXPT_SAMPLER3D:
5616 case D3DXPT_SAMPLERCUBE:
5617 param->bytes = 0;
5618 break;
5620 default:
5621 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5622 break;
5624 break;
5626 default:
5627 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5628 break;
5631 else
5633 /* elements */
5634 param->type = parent->type;
5635 param->class = parent->class;
5636 param->name = parent->name;
5637 param->semantic = parent->semantic;
5638 param->element_count = 0;
5639 param->member_count = parent->member_count;
5640 param->bytes = parent->bytes;
5641 param->rows = parent->rows;
5642 param->columns = parent->columns;
5645 if (param->element_count)
5647 unsigned int param_bytes = 0;
5648 const char *save_ptr = *ptr;
5650 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count);
5651 if (!param->members)
5653 ERR("Out of memory\n");
5654 hr = E_OUTOFMEMORY;
5655 goto err_out;
5658 for (i = 0; i < param->element_count; ++i)
5660 *ptr = save_ptr;
5662 param_set_magic_number(&param->members[i]);
5663 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, param, flags);
5664 if (hr != D3D_OK)
5666 WARN("Failed to parse member %u\n", i);
5667 goto err_out;
5670 param_bytes += param->members[i].bytes;
5673 param->bytes = param_bytes;
5675 else if (param->member_count)
5677 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count);
5678 if (!param->members)
5680 ERR("Out of memory\n");
5681 hr = E_OUTOFMEMORY;
5682 goto err_out;
5685 for (i = 0; i < param->member_count; ++i)
5687 param_set_magic_number(&param->members[i]);
5688 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, NULL, flags);
5689 if (hr != D3D_OK)
5691 WARN("Failed to parse member %u\n", i);
5692 goto err_out;
5695 param->bytes += param->members[i].bytes;
5698 return D3D_OK;
5700 err_out:
5702 if (param->members)
5704 unsigned int count = param->element_count ? param->element_count : param->member_count;
5706 for (i = 0; i < count; ++i)
5707 free_parameter(&param->members[i], param->element_count != 0, TRUE);
5708 HeapFree(GetProcessHeap(), 0, param->members);
5709 param->members = NULL;
5712 if (!parent)
5714 HeapFree(GetProcessHeap(), 0, param->name);
5715 HeapFree(GetProcessHeap(), 0, param->semantic);
5717 param->name = NULL;
5718 param->semantic = NULL;
5720 return hr;
5723 static HRESULT d3dx9_parse_effect_annotation(struct d3dx9_base_effect *base, struct d3dx_parameter *anno,
5724 const char *data, const char **ptr, struct d3dx_object *objects)
5726 DWORD offset;
5727 const char *ptr2;
5728 HRESULT hr;
5730 anno->flags = D3DX_PARAMETER_ANNOTATION;
5732 read_dword(ptr, &offset);
5733 TRACE("Typedef offset: %#x\n", offset);
5734 ptr2 = data + offset;
5735 hr = d3dx9_parse_effect_typedef(base, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5736 if (hr != D3D_OK)
5738 WARN("Failed to parse type definition\n");
5739 return hr;
5742 read_dword(ptr, &offset);
5743 TRACE("Value offset: %#x\n", offset);
5744 hr = d3dx9_parse_init_value(base, anno, data, data + offset, objects);
5745 if (hr != D3D_OK)
5747 WARN("Failed to parse value\n");
5748 return hr;
5751 return D3D_OK;
5754 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
5755 const char *data, const char **ptr, struct d3dx_object *objects)
5757 DWORD offset;
5758 const char *ptr2;
5759 HRESULT hr;
5761 state->type = ST_CONSTANT;
5763 read_dword(ptr, &state->operation);
5764 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5766 read_dword(ptr, &state->index);
5767 TRACE("Index: %#x\n", state->index);
5769 read_dword(ptr, &offset);
5770 TRACE("Typedef offset: %#x\n", offset);
5771 ptr2 = data + offset;
5772 hr = d3dx9_parse_effect_typedef(base, &state->parameter, data, &ptr2, NULL, 0);
5773 if (hr != D3D_OK)
5775 WARN("Failed to parse type definition\n");
5776 goto err_out;
5779 read_dword(ptr, &offset);
5780 TRACE("Value offset: %#x\n", offset);
5781 hr = d3dx9_parse_init_value(base, &state->parameter, data, data + offset, objects);
5782 if (hr != D3D_OK)
5784 WARN("Failed to parse value\n");
5785 goto err_out;
5788 return D3D_OK;
5790 err_out:
5792 free_parameter(&state->parameter, FALSE, FALSE);
5794 return hr;
5797 static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_top_level_parameter *param,
5798 const char *data, const char **ptr, struct d3dx_object *objects)
5800 DWORD offset;
5801 HRESULT hr;
5802 unsigned int i;
5803 const char *ptr2;
5805 read_dword(ptr, &offset);
5806 TRACE("Typedef offset: %#x.\n", offset);
5807 ptr2 = data + offset;
5809 read_dword(ptr, &offset);
5810 TRACE("Value offset: %#x.\n", offset);
5812 read_dword(ptr, &param->param.flags);
5813 TRACE("Flags: %#x.\n", param->param.flags);
5815 read_dword(ptr, &param->annotation_count);
5816 TRACE("Annotation count: %u.\n", param->annotation_count);
5818 hr = d3dx9_parse_effect_typedef(base, &param->param, data, &ptr2, NULL, param->param.flags);
5819 if (hr != D3D_OK)
5821 WARN("Failed to parse type definition.\n");
5822 return hr;
5825 hr = d3dx9_parse_init_value(base, &param->param, data, data + offset, objects);
5826 if (hr != D3D_OK)
5828 WARN("Failed to parse value.\n");
5829 return hr;
5832 if (param->annotation_count)
5834 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5835 sizeof(*param->annotations) * param->annotation_count);
5836 if (!param->annotations)
5838 ERR("Out of memory.\n");
5839 hr = E_OUTOFMEMORY;
5840 goto err_out;
5843 for (i = 0; i < param->annotation_count; ++i)
5845 param_set_magic_number(&param->annotations[i]);
5846 hr = d3dx9_parse_effect_annotation(base, &param->annotations[i], data, ptr, objects);
5847 if (hr != D3D_OK)
5849 WARN("Failed to parse annotation.\n");
5850 goto err_out;
5855 return D3D_OK;
5857 err_out:
5859 if (param->annotations)
5861 for (i = 0; i < param->annotation_count; ++i)
5862 free_parameter(&param->annotations[i], FALSE, FALSE);
5863 HeapFree(GetProcessHeap(), 0, param->annotations);
5864 param->annotations = NULL;
5867 return hr;
5870 static HRESULT d3dx9_parse_effect_pass(struct d3dx9_base_effect *base, struct d3dx_pass *pass,
5871 const char *data, const char **ptr, struct d3dx_object *objects)
5873 DWORD offset;
5874 HRESULT hr;
5875 unsigned int i;
5876 struct d3dx_state *states = NULL;
5877 char *name = NULL;
5879 read_dword(ptr, &offset);
5880 TRACE("Pass name offset: %#x\n", offset);
5881 hr = d3dx9_parse_name(&name, data + offset);
5882 if (hr != D3D_OK)
5884 WARN("Failed to parse name\n");
5885 goto err_out;
5888 read_dword(ptr, &pass->annotation_count);
5889 TRACE("Annotation count: %u\n", pass->annotation_count);
5891 read_dword(ptr, &pass->state_count);
5892 TRACE("State count: %u\n", pass->state_count);
5894 if (pass->annotation_count)
5896 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5897 sizeof(*pass->annotations) * pass->annotation_count);
5898 if (!pass->annotations)
5900 ERR("Out of memory\n");
5901 hr = E_OUTOFMEMORY;
5902 goto err_out;
5905 for (i = 0; i < pass->annotation_count; ++i)
5907 param_set_magic_number(&pass->annotations[i]);
5908 hr = d3dx9_parse_effect_annotation(base, &pass->annotations[i], data, ptr, objects);
5909 if (hr != D3D_OK)
5911 WARN("Failed to parse annotation %u\n", i);
5912 goto err_out;
5917 if (pass->state_count)
5919 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5920 if (!states)
5922 ERR("Out of memory\n");
5923 hr = E_OUTOFMEMORY;
5924 goto err_out;
5927 for (i = 0; i < pass->state_count; ++i)
5929 hr = d3dx9_parse_state(base, &states[i], data, ptr, objects);
5930 if (hr != D3D_OK)
5932 WARN("Failed to parse annotation %u\n", i);
5933 goto err_out;
5938 pass->name = name;
5939 pass->states = states;
5941 return D3D_OK;
5943 err_out:
5945 if (pass->annotations)
5947 for (i = 0; i < pass->annotation_count; ++i)
5948 free_parameter(&pass->annotations[i], FALSE, FALSE);
5949 HeapFree(GetProcessHeap(), 0, pass->annotations);
5950 pass->annotations = NULL;
5953 if (states)
5955 for (i = 0; i < pass->state_count; ++i)
5957 free_state(&states[i]);
5959 HeapFree(GetProcessHeap(), 0, states);
5962 HeapFree(GetProcessHeap(), 0, name);
5964 return hr;
5967 static HRESULT d3dx9_parse_effect_technique(struct d3dx9_base_effect *base, struct d3dx_technique *technique,
5968 const char *data, const char **ptr, struct d3dx_object *objects)
5970 DWORD offset;
5971 HRESULT hr;
5972 unsigned int i;
5973 char *name = NULL;
5975 read_dword(ptr, &offset);
5976 TRACE("Technique name offset: %#x\n", offset);
5977 hr = d3dx9_parse_name(&name, data + offset);
5978 if (hr != D3D_OK)
5980 WARN("Failed to parse name\n");
5981 goto err_out;
5984 read_dword(ptr, &technique->annotation_count);
5985 TRACE("Annotation count: %u\n", technique->annotation_count);
5987 read_dword(ptr, &technique->pass_count);
5988 TRACE("Pass count: %u\n", technique->pass_count);
5990 if (technique->annotation_count)
5992 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5993 sizeof(*technique->annotations) * technique->annotation_count);
5994 if (!technique->annotations)
5996 ERR("Out of memory\n");
5997 hr = E_OUTOFMEMORY;
5998 goto err_out;
6001 for (i = 0; i < technique->annotation_count; ++i)
6003 param_set_magic_number(&technique->annotations[i]);
6004 hr = d3dx9_parse_effect_annotation(base, &technique->annotations[i], data, ptr, objects);
6005 if (hr != D3D_OK)
6007 WARN("Failed to parse annotation %u\n", i);
6008 goto err_out;
6013 if (technique->pass_count)
6015 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6016 sizeof(*technique->passes) * technique->pass_count);
6017 if (!technique->passes)
6019 ERR("Out of memory\n");
6020 hr = E_OUTOFMEMORY;
6021 goto err_out;
6024 for (i = 0; i < technique->pass_count; ++i)
6026 hr = d3dx9_parse_effect_pass(base, &technique->passes[i], data, ptr, objects);
6027 if (hr != D3D_OK)
6029 WARN("Failed to parse pass %u\n", i);
6030 goto err_out;
6035 technique->name = name;
6037 return D3D_OK;
6039 err_out:
6041 if (technique->passes)
6043 for (i = 0; i < technique->pass_count; ++i)
6044 free_pass(&technique->passes[i]);
6045 HeapFree(GetProcessHeap(), 0, technique->passes);
6046 technique->passes = NULL;
6049 if (technique->annotations)
6051 for (i = 0; i < technique->annotation_count; ++i)
6052 free_parameter(&technique->annotations[i], FALSE, FALSE);
6053 HeapFree(GetProcessHeap(), 0, technique->annotations);
6054 technique->annotations = NULL;
6057 HeapFree(GetProcessHeap(), 0, name);
6059 return hr;
6062 static HRESULT d3dx9_create_object(struct d3dx9_base_effect *base, struct d3dx_object *object)
6064 struct d3dx_parameter *param = object->param;
6065 struct IDirect3DDevice9 *device = base->effect->device;
6066 HRESULT hr;
6068 if (*(char **)param->data)
6069 ERR("Parameter data already allocated.\n");
6071 switch (param->type)
6073 case D3DXPT_STRING:
6074 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size);
6075 if (!*(char **)param->data)
6077 ERR("Out of memory.\n");
6078 return E_OUTOFMEMORY;
6080 memcpy(*(char **)param->data, object->data, object->size);
6081 break;
6082 case D3DXPT_VERTEXSHADER:
6083 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data,
6084 (IDirect3DVertexShader9 **)param->data)))
6086 WARN("Failed to create vertex shader.\n");
6087 object->creation_failed = TRUE;
6089 break;
6090 case D3DXPT_PIXELSHADER:
6091 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data,
6092 (IDirect3DPixelShader9 **)param->data)))
6094 WARN("Failed to create pixel shader.\n");
6095 object->creation_failed = TRUE;
6097 break;
6098 default:
6099 break;
6101 return D3D_OK;
6104 static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct d3dx_state *state,
6105 const char **skip_constants, unsigned int skip_constants_count)
6107 DWORD string_size;
6108 struct d3dx_parameter *param = &state->parameter;
6109 struct d3dx_object *object = &base->objects[param->object_id];
6110 char *ptr = object->data;
6111 HRESULT ret;
6113 TRACE("Parsing array entry selection state for parameter %p.\n", param);
6115 string_size = *(DWORD *)ptr;
6116 state->referenced_param = get_parameter_by_name(base, NULL, ptr + 4);
6117 if (state->referenced_param)
6119 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
6121 else
6123 FIXME("Referenced parameter %s not found.\n", ptr + 4);
6124 return D3DXERR_INVALIDDATA;
6126 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
6128 if (string_size % sizeof(DWORD))
6129 FIXME("Unaligned string_size %u.\n", string_size);
6130 if (FAILED(ret = d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1,
6131 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, &param->param_eval,
6132 get_version_counter_ptr(base), NULL, 0)))
6133 return ret;
6134 ret = D3D_OK;
6135 param = state->referenced_param;
6136 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
6138 unsigned int i;
6140 for (i = 0; i < param->element_count; i++)
6142 if (param->members[i].type != param->type)
6144 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
6145 return D3DXERR_INVALIDDATA;
6147 if (!param->members[i].param_eval)
6149 TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
6150 object = &base->objects[param->members[i].object_id];
6151 if (FAILED(ret = d3dx_create_param_eval(base, object->data, object->size, param->type,
6152 &param->members[i].param_eval, get_version_counter_ptr(base),
6153 skip_constants, skip_constants_count)))
6154 break;
6158 return ret;
6161 static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr,
6162 const char **skip_constants, unsigned int skip_constants_count)
6164 DWORD technique_index;
6165 DWORD index, state_index, usage, element_index;
6166 struct d3dx_state *state;
6167 struct d3dx_parameter *param;
6168 struct d3dx_object *object;
6169 HRESULT hr = E_FAIL;
6171 read_dword(ptr, &technique_index);
6172 TRACE("technique_index: %u\n", technique_index);
6174 read_dword(ptr, &index);
6175 TRACE("index: %u\n", index);
6177 read_dword(ptr, &element_index);
6178 TRACE("element_index: %u\n", element_index);
6180 read_dword(ptr, &state_index);
6181 TRACE("state_index: %u\n", state_index);
6183 read_dword(ptr, &usage);
6184 TRACE("usage: %u\n", usage);
6186 if (technique_index == 0xffffffff)
6188 struct d3dx_parameter *parameter;
6189 struct d3dx_sampler *sampler;
6191 if (index >= base->parameter_count)
6193 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
6194 return E_FAIL;
6197 parameter = &base->parameters[index].param;
6198 if (element_index != 0xffffffff)
6200 if (element_index >= parameter->element_count && parameter->element_count != 0)
6202 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
6203 return E_FAIL;
6206 if (parameter->element_count)
6207 parameter = &parameter->members[element_index];
6210 sampler = parameter->data;
6211 if (state_index >= sampler->state_count)
6213 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
6214 return E_FAIL;
6217 state = &sampler->states[state_index];
6219 else
6221 struct d3dx_technique *technique;
6222 struct d3dx_pass *pass;
6224 if (technique_index >= base->technique_count)
6226 FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
6227 return E_FAIL;
6230 technique = &base->techniques[technique_index];
6231 if (index >= technique->pass_count)
6233 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
6234 return E_FAIL;
6237 pass = &technique->passes[index];
6238 if (state_index >= pass->state_count)
6240 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
6241 return E_FAIL;
6244 state = &pass->states[state_index];
6247 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name);
6248 param = &state->parameter;
6249 TRACE("Using object id %u.\n", param->object_id);
6250 object = &base->objects[param->object_id];
6252 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class),
6253 debug_d3dxparameter_type(param->type));
6254 switch (usage)
6256 case 0:
6257 switch (param->type)
6259 case D3DXPT_VERTEXSHADER:
6260 case D3DXPT_PIXELSHADER:
6261 state->type = ST_CONSTANT;
6262 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6263 return hr;
6265 if (object->data)
6267 if (FAILED(hr = d3dx9_create_object(base, object)))
6268 return hr;
6269 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6270 &param->param_eval, get_version_counter_ptr(base),
6271 skip_constants, skip_constants_count)))
6272 return hr;
6274 break;
6276 case D3DXPT_BOOL:
6277 case D3DXPT_INT:
6278 case D3DXPT_FLOAT:
6279 case D3DXPT_STRING:
6280 state->type = ST_FXLC;
6281 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6282 return hr;
6283 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6284 &param->param_eval, get_version_counter_ptr(base), NULL, 0)))
6285 return hr;
6286 break;
6288 default:
6289 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
6290 break;
6292 break;
6294 case 1:
6295 state->type = ST_PARAMETER;
6296 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6297 return hr;
6299 TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
6300 state->referenced_param = get_parameter_by_name(base, NULL, object->data);
6301 if (state->referenced_param)
6303 struct d3dx_parameter *refpar = state->referenced_param;
6305 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
6306 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
6308 struct d3dx_object *refobj = &base->objects[refpar->object_id];
6310 if (!refpar->param_eval)
6312 if (FAILED(hr = d3dx_create_param_eval(base, refobj->data, refobj->size,
6313 refpar->type, &refpar->param_eval, get_version_counter_ptr(base),
6314 skip_constants, skip_constants_count)))
6315 return hr;
6319 else
6321 FIXME("Referenced parameter %s not found.\n", (char *)object->data);
6322 return D3DXERR_INVALIDDATA;
6324 break;
6326 case 2:
6327 state->type = ST_ARRAY_SELECTOR;
6328 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6329 return hr;
6330 hr = d3dx9_parse_array_selector(base, state, skip_constants, skip_constants_count);
6331 break;
6333 default:
6334 FIXME("Unknown usage %x\n", usage);
6335 break;
6338 return hr;
6341 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param)
6343 param->top_level_param = top_level_param;
6344 return FALSE;
6347 static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *data, UINT data_size,
6348 DWORD start, const char **skip_constants, unsigned int skip_constants_count)
6350 const char *ptr = data + start;
6351 UINT stringcount, resourcecount;
6352 HRESULT hr;
6353 UINT i;
6355 read_dword(&ptr, &base->parameter_count);
6356 TRACE("Parameter count: %u.\n", base->parameter_count);
6358 read_dword(&ptr, &base->technique_count);
6359 TRACE("Technique count: %u.\n", base->technique_count);
6361 skip_dword_unknown(&ptr, 1);
6363 read_dword(&ptr, &base->object_count);
6364 TRACE("Object count: %u.\n", base->object_count);
6366 base->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base->objects) * base->object_count);
6367 if (!base->objects)
6369 ERR("Out of memory.\n");
6370 hr = E_OUTOFMEMORY;
6371 goto err_out;
6374 wine_rb_init(&base->param_tree, param_rb_compare);
6375 if (base->parameter_count)
6377 base->parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6378 sizeof(*base->parameters) * base->parameter_count);
6379 if (!base->parameters)
6381 ERR("Out of memory.\n");
6382 hr = E_OUTOFMEMORY;
6383 goto err_out;
6386 for (i = 0; i < base->parameter_count; ++i)
6388 param_set_magic_number(&base->parameters[i].param);
6389 hr = d3dx9_parse_effect_parameter(base, &base->parameters[i], data, &ptr, base->objects);
6390 if (hr != D3D_OK)
6392 WARN("Failed to parse parameter %u.\n", i);
6393 goto err_out;
6395 walk_parameter_tree(&base->parameters[i].param, param_set_top_level_param,
6396 &base->parameters[i]);
6397 add_param_to_tree(base, &base->parameters[i].param, NULL, 0, 0);
6401 if (base->technique_count)
6403 base->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6404 sizeof(*base->techniques) * base->technique_count);
6405 if (!base->techniques)
6407 ERR("Out of memory.\n");
6408 hr = E_OUTOFMEMORY;
6409 goto err_out;
6412 for (i = 0; i < base->technique_count; ++i)
6414 TRACE("Parsing technique %u.\n", i);
6415 hr = d3dx9_parse_effect_technique(base, &base->techniques[i], data, &ptr, base->objects);
6416 if (hr != D3D_OK)
6418 WARN("Failed to parse technique %u.\n", i);
6419 goto err_out;
6424 read_dword(&ptr, &stringcount);
6425 TRACE("String count: %u.\n", stringcount);
6427 read_dword(&ptr, &resourcecount);
6428 TRACE("Resource count: %u.\n", resourcecount);
6430 for (i = 0; i < stringcount; ++i)
6432 DWORD id;
6434 read_dword(&ptr, &id);
6435 TRACE("id: %u.\n", id);
6437 if (FAILED(hr = d3dx9_copy_data(base, id, &ptr)))
6438 goto err_out;
6440 if (base->objects[id].data)
6442 if (FAILED(hr = d3dx9_create_object(base, &base->objects[id])))
6443 goto err_out;
6447 for (i = 0; i < resourcecount; ++i)
6449 TRACE("parse resource %u.\n", i);
6451 hr = d3dx9_parse_resource(base, data, &ptr, skip_constants, skip_constants_count);
6452 if (hr != D3D_OK)
6454 WARN("Failed to parse resource %u.\n", i);
6455 goto err_out;
6459 for (i = 0; i < base->parameter_count; ++i)
6461 if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i])))
6462 goto err_out;
6463 base->parameters[i].version_counter = base->pool
6464 ? &base->pool->version_counter
6465 : &base->version_counter;
6466 set_dirty(&base->parameters[i].param);
6468 return D3D_OK;
6470 err_out:
6472 if (base->techniques)
6474 for (i = 0; i < base->technique_count; ++i)
6475 free_technique(&base->techniques[i]);
6476 HeapFree(GetProcessHeap(), 0, base->techniques);
6477 base->techniques = NULL;
6480 if (base->parameters)
6482 for (i = 0; i < base->parameter_count; ++i)
6484 free_top_level_parameter(&base->parameters[i]);
6486 HeapFree(GetProcessHeap(), 0, base->parameters);
6487 base->parameters = NULL;
6490 if (base->objects)
6492 for (i = 0; i < base->object_count; ++i)
6494 free_object(&base->objects[i]);
6496 HeapFree(GetProcessHeap(), 0, base->objects);
6497 base->objects = NULL;
6500 return hr;
6503 #define INITIAL_CONST_NAMES_SIZE 4
6505 static char *next_valid_constant_name(char **string)
6507 char *ret = *string;
6508 char *next;
6510 while (*ret && !isalpha(*ret) && *ret != '_')
6511 ++ret;
6512 if (!*ret)
6513 return NULL;
6515 next = ret + 1;
6516 while (isalpha(*next) || isdigit(*next) || *next == '_')
6517 ++next;
6518 if (*next)
6519 *next++ = 0;
6520 *string = next;
6521 return ret;
6524 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count)
6526 const char **names, **new_alloc;
6527 const char *name;
6528 char *s;
6529 unsigned int size = INITIAL_CONST_NAMES_SIZE;
6531 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size);
6532 if (!names)
6533 return NULL;
6535 *names_count = 0;
6536 s = skip_constants_string;
6537 while ((name = next_valid_constant_name(&s)))
6539 if (*names_count == size)
6541 size *= 2;
6542 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size);
6543 if (!new_alloc)
6545 HeapFree(GetProcessHeap(), 0, names);
6546 return NULL;
6548 names = new_alloc;
6550 names[(*names_count)++] = name;
6552 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names));
6553 if (!new_alloc)
6554 return names;
6555 return new_alloc;
6558 static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
6559 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6560 UINT eflags, ID3DBlob **errors, struct ID3DXEffectImpl *effect, struct d3dx_effect_pool *pool,
6561 const char *skip_constants_string)
6563 DWORD tag, offset;
6564 const char *ptr = data;
6565 HRESULT hr;
6566 ID3DBlob *bytecode = NULL, *temp_errors = NULL;
6567 char *skip_constants_buffer = NULL;
6568 const char **skip_constants = NULL;
6569 unsigned int skip_constants_count = 0;
6570 #if D3DX_SDK_VERSION <= 36
6571 UINT compile_flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
6572 #else
6573 UINT compile_flags = 0;
6574 #endif
6575 unsigned int i, j;
6577 TRACE("base %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, errors %p, "
6578 "effect %p, pool %p, skip_constants %s.\n",
6579 base, data, data_size, defines, include, eflags, errors, effect, pool,
6580 debugstr_a(skip_constants_string));
6582 base->effect = effect;
6583 base->pool = pool;
6584 base->flags = eflags;
6586 read_dword(&ptr, &tag);
6587 TRACE("Tag: %x\n", tag);
6589 if (tag != d3dx9_effect_version(9, 1))
6591 TRACE("HLSL ASCII effect, trying to compile it.\n");
6592 hr = D3DCompile(data, data_size, NULL, defines, include,
6593 NULL, "fx_2_0", compile_flags, eflags, &bytecode, &temp_errors);
6594 if (FAILED(hr))
6596 WARN("Failed to compile ASCII effect.\n");
6597 if (bytecode)
6598 ID3D10Blob_Release(bytecode);
6599 if (temp_errors)
6601 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors);
6602 const char *string_ptr;
6604 while (*error_string)
6606 string_ptr = error_string;
6607 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r'
6608 && string_ptr - error_string < 80)
6609 ++string_ptr;
6610 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string));
6611 error_string = string_ptr;
6612 while (*error_string == '\n' || *error_string == '\r')
6613 ++error_string;
6616 if (errors)
6617 *errors = temp_errors;
6618 else if (temp_errors)
6619 ID3D10Blob_Release(temp_errors);
6620 return hr;
6622 if (!bytecode)
6624 FIXME("No output from effect compilation.\n");
6625 return D3DERR_INVALIDCALL;
6627 if (errors)
6628 *errors = temp_errors;
6629 else if (temp_errors)
6630 ID3D10Blob_Release(temp_errors);
6632 ptr = ID3D10Blob_GetBufferPointer(bytecode);
6633 read_dword(&ptr, &tag);
6634 TRACE("Tag: %x\n", tag);
6637 if (skip_constants_string)
6639 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0,
6640 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1));
6641 if (!skip_constants_buffer)
6643 if (bytecode)
6644 ID3D10Blob_Release(bytecode);
6645 return E_OUTOFMEMORY;
6647 strcpy(skip_constants_buffer, skip_constants_string);
6649 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count)))
6651 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6652 if (bytecode)
6653 ID3D10Blob_Release(bytecode);
6654 return E_OUTOFMEMORY;
6657 read_dword(&ptr, &offset);
6658 TRACE("Offset: %x\n", offset);
6660 hr = d3dx9_parse_effect(base, ptr, data_size, offset, skip_constants, skip_constants_count);
6661 if (bytecode)
6662 ID3D10Blob_Release(bytecode);
6663 if (hr != D3D_OK)
6665 FIXME("Failed to parse effect.\n");
6666 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6667 HeapFree(GetProcessHeap(), 0, skip_constants);
6668 return hr;
6671 for (i = 0; i < skip_constants_count; ++i)
6673 struct d3dx_parameter *param;
6674 param = get_parameter_by_name(base, NULL, skip_constants[i]);
6675 if (param)
6677 for (j = 0; j < base->technique_count; ++j)
6679 if (is_parameter_used(param, &base->techniques[j]))
6681 WARN("skip_constants parameter %s is used in technique %u.\n",
6682 debugstr_a(skip_constants[i]), j);
6683 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6684 HeapFree(GetProcessHeap(), 0, skip_constants);
6685 d3dx9_base_effect_cleanup(base);
6686 return D3DERR_INVALIDCALL;
6690 else
6692 TRACE("skip_constants parameter %s not found.\n",
6693 debugstr_a(skip_constants[i]));
6697 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6698 HeapFree(GetProcessHeap(), 0, skip_constants);
6700 return D3D_OK;
6703 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, struct IDirect3DDevice9 *device,
6704 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6705 UINT eflags, ID3DBlob **error_messages, struct ID3DXEffectPool *pool, const char *skip_constants)
6707 HRESULT hr;
6708 struct d3dx_effect_pool *pool_impl = NULL;
6710 TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
6712 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
6713 effect->ref = 1;
6715 if (pool)
6717 pool->lpVtbl->AddRef(pool);
6718 pool_impl = impl_from_ID3DXEffectPool(pool);
6720 effect->pool = pool;
6722 IDirect3DDevice9_AddRef(device);
6723 effect->device = device;
6725 if (FAILED(hr = d3dx9_base_effect_init(&effect->base_effect, data, data_size, defines, include,
6726 eflags, error_messages, effect, pool_impl, skip_constants)))
6728 FIXME("Failed to parse effect, hr %#x.\n", hr);
6729 free_effect(effect);
6730 return hr;
6733 /* initialize defaults - check because of unsupported ascii effects */
6734 if (effect->base_effect.techniques)
6736 effect->active_technique = &effect->base_effect.techniques[0];
6737 effect->active_pass = NULL;
6740 return D3D_OK;
6743 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6744 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags,
6745 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6747 struct ID3DXEffectImpl *object;
6748 HRESULT hr;
6750 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p,"
6751 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n",
6752 device, srcdata, srcdatalen, defines, include,
6753 skip_constants, flags, pool, effect, compilation_errors);
6755 if (compilation_errors)
6756 *compilation_errors = NULL;
6758 if (!device || !srcdata)
6759 return D3DERR_INVALIDCALL;
6761 if (!srcdatalen)
6762 return E_FAIL;
6764 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6765 if (!effect)
6766 return D3D_OK;
6768 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6769 if (!object)
6770 return E_OUTOFMEMORY;
6772 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6773 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants);
6774 if (FAILED(hr))
6776 WARN("Failed to create effect object.\n");
6777 HeapFree(GetProcessHeap(), 0, object);
6778 return hr;
6781 *effect = &object->ID3DXEffect_iface;
6783 TRACE("Created ID3DXEffect %p\n", object);
6785 return D3D_OK;
6788 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6789 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6790 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6792 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
6793 include, flags, pool, effect, compilation_errors);
6795 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
6798 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler,
6799 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6800 UINT eflags, ID3DBlob **error_messages)
6802 TRACE("compiler %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, error_messages %p.\n",
6803 compiler, data, data_size, defines, include, eflags, error_messages);
6805 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
6806 compiler->ref = 1;
6808 FIXME("ID3DXEffectCompiler implementation is only a stub.\n");
6810 return D3D_OK;
6813 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines,
6814 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors)
6816 struct ID3DXEffectCompilerImpl *object;
6817 HRESULT hr;
6819 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
6820 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
6822 if (!srcdata || !compiler)
6824 WARN("Invalid arguments supplied\n");
6825 return D3DERR_INVALIDCALL;
6828 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6829 if (!object)
6830 return E_OUTOFMEMORY;
6832 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6833 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors);
6834 if (FAILED(hr))
6836 WARN("Failed to initialize effect compiler\n");
6837 HeapFree(GetProcessHeap(), 0, object);
6838 return hr;
6841 *compiler = &object->ID3DXEffectCompiler_iface;
6843 TRACE("Created ID3DXEffectCompiler %p\n", object);
6845 return D3D_OK;
6848 /*** IUnknown methods ***/
6849 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
6851 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
6853 if (IsEqualGUID(riid, &IID_IUnknown) ||
6854 IsEqualGUID(riid, &IID_ID3DXEffectPool))
6856 iface->lpVtbl->AddRef(iface);
6857 *object = iface;
6858 return S_OK;
6861 WARN("Interface %s not found\n", debugstr_guid(riid));
6863 return E_NOINTERFACE;
6866 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface)
6868 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6869 ULONG refcount = InterlockedIncrement(&pool->refcount);
6871 TRACE("%p increasing refcount to %u.\n", pool, refcount);
6873 return refcount;
6876 static void free_effect_pool(struct d3dx_effect_pool *pool)
6878 unsigned int i;
6880 for (i = 0; i < pool->size; ++i)
6882 if (pool->shared_data[i].count)
6884 unsigned int j;
6886 WARN("Releasing pool with referenced parameters.\n");
6888 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE);
6889 pool->shared_data[i].parameters[0]->shared_data = NULL;
6891 for (j = 1; j < pool->shared_data[i].count; ++j)
6893 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL);
6894 pool->shared_data[i].parameters[j]->shared_data = NULL;
6896 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);
6899 HeapFree(GetProcessHeap(), 0, pool->shared_data);
6900 HeapFree(GetProcessHeap(), 0, pool);
6903 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface)
6905 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6906 ULONG refcount = InterlockedDecrement(&pool->refcount);
6908 TRACE("%p decreasing refcount to %u.\n", pool, refcount);
6910 if (!refcount)
6911 free_effect_pool(pool);
6913 return refcount;
6916 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
6918 /*** IUnknown methods ***/
6919 d3dx_effect_pool_QueryInterface,
6920 d3dx_effect_pool_AddRef,
6921 d3dx_effect_pool_Release
6924 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool)
6926 struct d3dx_effect_pool *object;
6928 TRACE("pool %p.\n", pool);
6930 if (!pool)
6931 return D3DERR_INVALIDCALL;
6933 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6934 if (!object)
6935 return E_OUTOFMEMORY;
6937 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6938 object->refcount = 1;
6940 *pool = &object->ID3DXEffectPool_iface;
6942 return S_OK;
6945 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6946 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6947 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6949 struct d3dx_include_from_file include_from_file;
6950 const void *buffer;
6951 unsigned int size;
6952 char *filename_a;
6953 HRESULT ret;
6955 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6956 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6957 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants),
6958 flags, pool, effect, compilationerrors);
6960 if (!device || !srcfile)
6961 return D3DERR_INVALIDCALL;
6963 if (!include)
6965 include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
6966 include = &include_from_file.ID3DXInclude_iface;
6969 size = WideCharToMultiByte(CP_ACP, 0, srcfile, -1, NULL, 0, NULL, NULL);
6970 filename_a = heap_alloc(size);
6971 if (!filename_a)
6972 return E_OUTOFMEMORY;
6973 WideCharToMultiByte(CP_ACP, 0, srcfile, -1, filename_a, size, NULL, NULL);
6975 EnterCriticalSection(&from_file_mutex);
6976 ret = ID3DXInclude_Open(include, D3DXINC_LOCAL, filename_a, NULL, &buffer, &size);
6977 if (FAILED(ret))
6979 LeaveCriticalSection(&from_file_mutex);
6980 heap_free(filename_a);
6981 return D3DXERR_INVALIDDATA;
6984 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool,
6985 effect, compilationerrors);
6987 ID3DXInclude_Close(include, buffer);
6988 LeaveCriticalSection(&from_file_mutex);
6989 heap_free(filename_a);
6990 return ret;
6993 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
6994 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6995 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6997 WCHAR *srcfileW;
6998 HRESULT ret;
6999 DWORD len;
7001 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
7002 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
7003 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants),
7004 flags, pool, effect, compilationerrors);
7006 if (!srcfile)
7007 return D3DERR_INVALIDCALL;
7009 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
7010 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
7011 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
7013 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
7014 HeapFree(GetProcessHeap(), 0, srcfileW);
7016 return ret;
7019 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
7020 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
7021 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
7023 TRACE("(void): relay\n");
7024 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
7027 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile,
7028 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
7029 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
7031 TRACE("(void): relay\n");
7032 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
7035 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
7036 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
7037 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
7039 HRSRC resinfo;
7040 void *buffer;
7041 DWORD size;
7043 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
7044 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
7045 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants),
7046 flags, pool, effect, compilationerrors);
7048 if (!device)
7049 return D3DERR_INVALIDCALL;
7051 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
7052 return D3DXERR_INVALIDDATA;
7054 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7055 return D3DXERR_INVALIDDATA;
7057 return D3DXCreateEffectEx(device, buffer, size, defines, include,
7058 skipconstants, flags, pool, effect, compilationerrors);
7061 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
7062 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
7063 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
7065 HRSRC resinfo;
7066 void *buffer;
7067 DWORD size;
7069 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
7070 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
7071 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants),
7072 flags, pool, effect, compilationerrors);
7074 if (!device)
7075 return D3DERR_INVALIDCALL;
7077 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
7078 return D3DXERR_INVALIDDATA;
7080 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7081 return D3DXERR_INVALIDDATA;
7083 return D3DXCreateEffectEx(device, buffer, size, defines, include,
7084 skipconstants, flags, pool, effect, compilationerrors);
7087 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
7088 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
7089 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
7091 TRACE("(void): relay\n");
7092 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
7095 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
7096 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
7097 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
7099 TRACE("(void): relay\n");
7100 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
7103 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines,
7104 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7106 void *buffer;
7107 HRESULT ret;
7108 DWORD size;
7110 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7111 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors);
7113 if (!srcfile)
7114 return D3DERR_INVALIDCALL;
7116 ret = map_view_of_file(srcfile, &buffer, &size);
7118 if (FAILED(ret))
7119 return D3DXERR_INVALIDDATA;
7121 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7122 UnmapViewOfFile(buffer);
7124 return ret;
7127 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines,
7128 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7130 WCHAR *srcfileW;
7131 HRESULT ret;
7132 DWORD len;
7134 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7135 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors);
7137 if (!srcfile)
7138 return D3DERR_INVALIDCALL;
7140 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
7141 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
7142 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
7144 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
7145 HeapFree(GetProcessHeap(), 0, srcfileW);
7147 return ret;
7150 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource,
7151 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
7152 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7154 HRSRC resinfo;
7155 void *buffer;
7156 DWORD size;
7158 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7159 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors);
7161 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
7162 return D3DXERR_INVALIDDATA;
7164 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7165 return D3DXERR_INVALIDDATA;
7167 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7170 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource,
7171 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
7172 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7174 HRSRC resinfo;
7175 void *buffer;
7176 DWORD size;
7178 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7179 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors);
7181 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
7182 return D3DXERR_INVALIDDATA;
7184 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7185 return D3DXERR_INVALIDDATA;
7187 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7190 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly)
7192 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly);
7194 return D3DXERR_INVALIDDATA;