d2d1/tests: Add a test for bezier intersections.
[wine.git] / dlls / d3dx9_36 / effect.c
blob8095a0ee33dae5e792e0ab4178624aefaac5bff3
1 /*
2 * Copyright 2010 Christian Costa
3 * Copyright 2011 Rico Schüller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
21 #include "wine/port.h"
23 #include "d3dx9_private.h"
24 #include "d3dcompiler.h"
26 /* Constants for special INT/FLOAT conversation */
27 #define INT_FLOAT_MULTI 255.0f
28 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
30 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
32 #define PARAMETER_FLAG_SHARED 1
34 #define INITIAL_POOL_SIZE 16
36 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
38 enum STATE_CLASS
40 SC_LIGHTENABLE,
41 SC_FVF,
42 SC_LIGHT,
43 SC_MATERIAL,
44 SC_NPATCHMODE,
45 SC_PIXELSHADER,
46 SC_RENDERSTATE,
47 SC_SETSAMPLER,
48 SC_SAMPLERSTATE,
49 SC_TEXTURE,
50 SC_TEXTURESTAGE,
51 SC_TRANSFORM,
52 SC_VERTEXSHADER,
53 SC_SHADERCONST,
54 SC_UNKNOWN,
57 enum MATERIAL_TYPE
59 MT_DIFFUSE,
60 MT_AMBIENT,
61 MT_SPECULAR,
62 MT_EMISSIVE,
63 MT_POWER,
66 enum LIGHT_TYPE
68 LT_TYPE,
69 LT_DIFFUSE,
70 LT_SPECULAR,
71 LT_AMBIENT,
72 LT_POSITION,
73 LT_DIRECTION,
74 LT_RANGE,
75 LT_FALLOFF,
76 LT_ATTENUATION0,
77 LT_ATTENUATION1,
78 LT_ATTENUATION2,
79 LT_THETA,
80 LT_PHI,
83 enum SHADER_CONSTANT_TYPE
85 SCT_VSFLOAT,
86 SCT_VSBOOL,
87 SCT_VSINT,
88 SCT_PSFLOAT,
89 SCT_PSBOOL,
90 SCT_PSINT,
93 enum STATE_TYPE
95 ST_CONSTANT,
96 ST_PARAMETER,
97 ST_FXLC,
98 ST_ARRAY_SELECTOR,
101 struct d3dx_object
103 UINT size;
104 void *data;
105 struct d3dx_parameter *param;
108 struct d3dx_state
110 UINT operation;
111 UINT index;
112 enum STATE_TYPE type;
113 struct d3dx_parameter parameter;
114 struct d3dx_parameter *referenced_param;
117 struct d3dx_sampler
119 UINT state_count;
120 struct d3dx_state *states;
123 struct d3dx_pass
125 char *name;
126 UINT state_count;
127 UINT annotation_count;
129 struct d3dx_state *states;
130 struct d3dx_parameter *annotations;
132 ULONG64 update_version;
135 struct d3dx_technique
137 char *name;
138 UINT pass_count;
139 UINT annotation_count;
141 struct d3dx_parameter *annotations;
142 struct d3dx_pass *passes;
144 struct IDirect3DStateBlock9 *saved_state;
147 struct d3dx9_base_effect
149 struct ID3DXEffectImpl *effect;
151 UINT parameter_count;
152 UINT technique_count;
153 UINT object_count;
155 struct d3dx_top_level_parameter *parameters;
156 struct d3dx_technique *techniques;
157 struct d3dx_object *objects;
159 struct d3dx_effect_pool *pool;
160 DWORD flags;
162 ULONG64 version_counter;
165 struct ID3DXEffectImpl
167 ID3DXEffect ID3DXEffect_iface;
168 LONG ref;
170 struct d3dx9_base_effect base_effect;
172 struct ID3DXEffectStateManager *manager;
173 struct IDirect3DDevice9 *device;
174 struct ID3DXEffectPool *pool;
175 struct d3dx_technique *active_technique;
176 struct d3dx_pass *active_pass;
177 BOOL started;
178 DWORD begin_flags;
180 D3DLIGHT9 current_light[8];
181 BOOL light_updated[8];
182 D3DMATERIAL9 current_material;
183 BOOL material_updated;
186 #define INITIAL_SHARED_DATA_SIZE 4
188 struct d3dx_effect_pool
190 ID3DXEffectPool ID3DXEffectPool_iface;
191 LONG refcount;
193 struct d3dx_shared_data *shared_data;
194 unsigned int size;
196 ULONG64 version_counter;
199 struct ID3DXEffectCompilerImpl
201 ID3DXEffectCompiler ID3DXEffectCompiler_iface;
202 LONG ref;
204 struct d3dx9_base_effect base_effect;
207 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *parameters,
208 const char *name);
209 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
210 const char *data, const char **ptr, struct d3dx_object *objects);
211 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
213 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param);
215 static const struct
217 enum STATE_CLASS class;
218 UINT op;
219 const char *name;
221 state_table[] =
223 /* Render states */
224 {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
225 {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
226 {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
227 {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
228 {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
229 {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
230 {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
231 {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
232 {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
233 {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
234 {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
235 {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
236 {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
237 {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
238 {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
239 {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
240 {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
241 {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
242 {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
243 {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
244 {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
245 {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
246 {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
247 {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
248 {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
249 {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
250 {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
251 {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
252 {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
253 {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
254 {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
255 {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
256 {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
257 {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
258 {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
259 {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
260 {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
261 {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
262 {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
263 {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
264 {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
265 {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
266 {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
267 {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
268 {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
269 {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
270 {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
271 {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
272 {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
273 {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
274 {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
275 {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
276 {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
277 {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
278 {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
279 {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
280 {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
281 {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
282 {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
283 {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
284 {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
285 {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
286 {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
287 {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
288 {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
289 {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
290 {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
291 {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
292 {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
293 {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
294 {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
295 {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
296 {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
297 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
298 {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
299 {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
300 {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
301 {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
302 {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
303 {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
304 {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
305 {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
306 {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
307 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
308 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
309 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
310 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
311 {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
312 {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
313 {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
314 {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
315 {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
316 {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
317 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
318 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
319 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
320 {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
321 {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
322 {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
323 {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
324 {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
325 {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
326 {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
327 /* Texture stages */
328 {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
329 {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
330 {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
331 {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
332 {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
333 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
334 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
335 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
336 {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
337 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
338 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
339 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
340 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
341 {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
342 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
343 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
344 {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
345 {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
346 /* NPatchMode */
347 {SC_NPATCHMODE, 0, "NPatchMode"},
348 /* FVF */
349 {SC_FVF, 0, "FVF"},
350 /* Transform */
351 {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
352 {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
353 {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
354 {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
355 /* Material */
356 {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
357 {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
358 {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
359 {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
360 {SC_MATERIAL, MT_POWER, "MaterialPower"},
361 /* Light */
362 {SC_LIGHT, LT_TYPE, "LightType"},
363 {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
364 {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
365 {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
366 {SC_LIGHT, LT_POSITION, "LightPosition"},
367 {SC_LIGHT, LT_DIRECTION, "LightDirection"},
368 {SC_LIGHT, LT_RANGE, "LightRange"},
369 {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
370 {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
371 {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
372 {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
373 {SC_LIGHT, LT_THETA, "LightTheta"},
374 {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
375 /* Lightenable */
376 {SC_LIGHTENABLE, 0, "LightEnable"},
377 /* Vertexshader */
378 {SC_VERTEXSHADER, 0, "Vertexshader"},
379 /* Pixelshader */
380 {SC_PIXELSHADER, 0, "Pixelshader"},
381 /* Shader constants */
382 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
383 {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
384 {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
385 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
386 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
387 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
388 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
389 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
390 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
391 {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
392 {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
393 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
394 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
395 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
396 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
397 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
398 /* Texture */
399 {SC_TEXTURE, 0, "Texture"},
400 /* Sampler states */
401 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
402 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
403 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
404 {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
405 {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
406 {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
407 {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
408 {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
409 {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
410 {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
411 {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
412 {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
413 {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
414 /* Set sampler */
415 {SC_SETSAMPLER, 0, "Sampler"},
418 static inline void read_dword(const char **ptr, DWORD *d)
420 memcpy(d, *ptr, sizeof(*d));
421 *ptr += sizeof(*d);
424 static void skip_dword_unknown(const char **ptr, unsigned int count)
426 unsigned int i;
427 DWORD d;
429 WARN("Skipping %u unknown DWORDs:\n", count);
430 for (i = 0; i < count; ++i)
432 read_dword(ptr, &d);
433 WARN("\t0x%08x\n", d);
437 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
439 return (D3DXHANDLE)parameter;
442 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
444 return (D3DXHANDLE)technique;
447 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
449 return (D3DXHANDLE)pass;
452 static struct d3dx_technique *get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
454 UINT i;
456 if (!name) return NULL;
458 for (i = 0; i < base->technique_count; ++i)
460 if (!strcmp(base->techniques[i].name, name))
461 return &base->techniques[i];
464 return NULL;
467 static struct d3dx_technique *get_valid_technique(struct d3dx9_base_effect *base, D3DXHANDLE technique)
469 unsigned int i;
471 for (i = 0; i < base->technique_count; ++i)
473 if (get_technique_handle(&base->techniques[i]) == technique)
474 return &base->techniques[i];
477 return get_technique_by_name(base, technique);
480 static struct d3dx_pass *get_valid_pass(struct d3dx9_base_effect *base, D3DXHANDLE pass)
482 unsigned int i, k;
484 for (i = 0; i < base->technique_count; ++i)
486 struct d3dx_technique *technique = &base->techniques[i];
488 for (k = 0; k < technique->pass_count; ++k)
490 if (get_pass_handle(&technique->passes[k]) == pass)
491 return &technique->passes[k];
495 return NULL;
498 static struct d3dx_parameter *get_valid_parameter(struct d3dx9_base_effect *base, D3DXHANDLE parameter)
500 struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter;
502 if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string,
503 sizeof(parameter_magic_string)))
504 return handle_param;
506 return base->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(base, NULL, parameter);
509 static void free_state(struct d3dx_state *state)
511 free_parameter(&state->parameter, FALSE, FALSE);
514 static void free_object(struct d3dx_object *object)
516 HeapFree(GetProcessHeap(), 0, object->data);
519 static void free_sampler(struct d3dx_sampler *sampler)
521 UINT i;
523 for (i = 0; i < sampler->state_count; ++i)
525 free_state(&sampler->states[i]);
527 HeapFree(GetProcessHeap(), 0, sampler->states);
530 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param);
532 static void free_parameter_data(struct d3dx_parameter *param, BOOL child)
534 if (!param->data)
535 return;
536 if (param->class == D3DXPC_OBJECT && !param->element_count)
538 switch (param->type)
540 case D3DXPT_STRING:
541 HeapFree(GetProcessHeap(), 0, *(char **)param->data);
542 break;
544 case D3DXPT_TEXTURE:
545 case D3DXPT_TEXTURE1D:
546 case D3DXPT_TEXTURE2D:
547 case D3DXPT_TEXTURE3D:
548 case D3DXPT_TEXTURECUBE:
549 case D3DXPT_PIXELSHADER:
550 case D3DXPT_VERTEXSHADER:
551 if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
552 break;
554 case D3DXPT_SAMPLER:
555 case D3DXPT_SAMPLER1D:
556 case D3DXPT_SAMPLER2D:
557 case D3DXPT_SAMPLER3D:
558 case D3DXPT_SAMPLERCUBE:
559 free_sampler((struct d3dx_sampler *)param->data);
560 break;
562 default:
563 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
564 break;
567 if (!child)
568 HeapFree(GetProcessHeap(), 0, param->data);
571 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child)
573 unsigned int i;
575 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name,
576 debug_d3dxparameter_type(param->type), element, child);
578 if (param->param_eval)
579 d3dx_free_param_eval(param->param_eval);
581 if (param->members)
583 unsigned int count = param->element_count ? param->element_count : param->member_count;
585 for (i = 0; i < count; ++i)
586 free_parameter(&param->members[i], param->element_count != 0, TRUE);
587 HeapFree(GetProcessHeap(), 0, param->members);
590 free_parameter_data(param, child);
592 /* only the parent has to release name and semantic */
593 if (!element)
595 HeapFree(GetProcessHeap(), 0, param->name);
596 HeapFree(GetProcessHeap(), 0, param->semantic);
600 static void free_top_level_parameter(struct d3dx_top_level_parameter *param)
602 if (param->annotations)
604 unsigned int i;
606 for (i = 0; i < param->annotation_count; ++i)
607 free_parameter(&param->annotations[i], FALSE, FALSE);
608 HeapFree(GetProcessHeap(), 0, param->annotations);
610 d3dx_pool_release_shared_parameter(param);
611 free_parameter(&param->param, FALSE, FALSE);
614 static void free_pass(struct d3dx_pass *pass)
616 unsigned int i;
618 TRACE("Free pass %p\n", pass);
620 if (!pass)
621 return;
623 if (pass->annotations)
625 for (i = 0; i < pass->annotation_count; ++i)
626 free_parameter(&pass->annotations[i], FALSE, FALSE);
627 HeapFree(GetProcessHeap(), 0, pass->annotations);
628 pass->annotations = NULL;
631 if (pass->states)
633 for (i = 0; i < pass->state_count; ++i)
634 free_state(&pass->states[i]);
635 HeapFree(GetProcessHeap(), 0, pass->states);
636 pass->states = NULL;
639 HeapFree(GetProcessHeap(), 0, pass->name);
640 pass->name = NULL;
643 static void free_technique(struct d3dx_technique *technique)
645 unsigned int i;
647 TRACE("Free technique %p\n", technique);
649 if (!technique)
650 return;
652 if (technique->saved_state)
654 IDirect3DStateBlock9_Release(technique->saved_state);
655 technique->saved_state = NULL;
658 if (technique->annotations)
660 for (i = 0; i < technique->annotation_count; ++i)
661 free_parameter(&technique->annotations[i], FALSE, FALSE);
662 HeapFree(GetProcessHeap(), 0, technique->annotations);
663 technique->annotations = NULL;
666 if (technique->passes)
668 for (i = 0; i < technique->pass_count; ++i)
669 free_pass(&technique->passes[i]);
670 HeapFree(GetProcessHeap(), 0, technique->passes);
671 technique->passes = NULL;
674 HeapFree(GetProcessHeap(), 0, technique->name);
675 technique->name = NULL;
678 static void d3dx9_base_effect_cleanup(struct d3dx9_base_effect *base)
680 unsigned int i;
682 TRACE("base %p.\n", base);
684 if (base->parameters)
686 for (i = 0; i < base->parameter_count; ++i)
687 free_top_level_parameter(&base->parameters[i]);
688 HeapFree(GetProcessHeap(), 0, base->parameters);
689 base->parameters = NULL;
692 if (base->techniques)
694 for (i = 0; i < base->technique_count; ++i)
695 free_technique(&base->techniques[i]);
696 HeapFree(GetProcessHeap(), 0, base->techniques);
697 base->techniques = NULL;
700 if (base->objects)
702 for (i = 0; i < base->object_count; ++i)
704 free_object(&base->objects[i]);
706 HeapFree(GetProcessHeap(), 0, base->objects);
707 base->objects = NULL;
711 static void free_effect(struct ID3DXEffectImpl *effect)
713 TRACE("Free effect %p\n", effect);
715 d3dx9_base_effect_cleanup(&effect->base_effect);
717 if (effect->pool)
719 effect->pool->lpVtbl->Release(effect->pool);
722 if (effect->manager)
724 IUnknown_Release(effect->manager);
727 IDirect3DDevice9_Release(effect->device);
730 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
732 TRACE("Free effect compiler %p\n", compiler);
734 d3dx9_base_effect_cleanup(&compiler->base_effect);
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 d3dx_parameter *parameter, const char *name)
818 UINT element;
819 struct d3dx_parameter *temp_parameter;
820 const char *part;
822 TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
824 if (!name || !*name) return NULL;
826 element = atoi(name);
827 part = strchr(name, ']') + 1;
829 /* check for empty [] && element range */
830 if ((part - name) > 1 && parameter->element_count > element)
832 temp_parameter = &parameter->members[element];
834 switch (*part++)
836 case '.':
837 return get_parameter_by_name(NULL, temp_parameter, part);
839 case '\0':
840 TRACE("Returning parameter %p\n", temp_parameter);
841 return temp_parameter;
843 default:
844 FIXME("Unhandled case \"%c\"\n", *--part);
845 break;
849 TRACE("Parameter not found\n");
850 return NULL;
853 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *annotations,
854 const char *name)
856 UINT i, length;
857 struct d3dx_parameter *temp_parameter;
858 const char *part;
860 TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name));
862 if (!name || !*name) return NULL;
864 length = strcspn( name, "[.@" );
865 part = name + length;
867 for (i = 0; i < count; ++i)
869 temp_parameter = &annotations[i];
871 if (!strcmp(temp_parameter->name, name))
873 TRACE("Returning annotation %p\n", temp_parameter);
874 return temp_parameter;
876 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
878 switch (*part++)
880 case '.':
881 return get_parameter_by_name(NULL, temp_parameter, part);
883 case '[':
884 return get_parameter_element_by_name(temp_parameter, part);
886 default:
887 FIXME("Unhandled case \"%c\"\n", *--part);
888 break;
893 TRACE("Annotation not found\n");
894 return NULL;
897 struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
898 struct d3dx_parameter *parameter, const char *name)
900 UINT i, count, length;
901 struct d3dx_parameter *temp_parameter;
902 const char *part;
904 TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
906 if (!name || !*name) return NULL;
908 count = parameter ? parameter->member_count : base->parameter_count;
909 length = strcspn( name, "[.@" );
910 part = name + length;
912 for (i = 0; i < count; i++)
914 temp_parameter = !parameter ? &base->parameters[i].param
915 : &parameter->members[i];
917 if (!strcmp(temp_parameter->name, name))
919 TRACE("Returning parameter %p\n", temp_parameter);
920 return temp_parameter;
922 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
924 switch (*part++)
926 case '.':
927 return get_parameter_by_name(NULL, temp_parameter, part);
929 case '@':
931 struct d3dx_top_level_parameter *top_param
932 = top_level_parameter_from_parameter(temp_parameter);
934 return parameter ? NULL : get_annotation_by_name(top_param->annotation_count,
935 top_param->annotations, part);
937 case '[':
938 return get_parameter_element_by_name(temp_parameter, part);
940 default:
941 FIXME("Unhandled case \"%c\"\n", *--part);
942 break;
947 TRACE("Parameter not found\n");
948 return NULL;
951 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
953 return (0xfeff0000 | ((major) << 8) | (minor));
956 static HRESULT d3dx9_base_effect_get_desc(struct d3dx9_base_effect *base, D3DXEFFECT_DESC *desc)
958 if (!desc)
960 WARN("Invalid argument specified.\n");
961 return D3DERR_INVALIDCALL;
964 FIXME("partial stub!\n");
966 /* TODO: add creator and function count. */
967 desc->Creator = NULL;
968 desc->Functions = 0;
969 desc->Parameters = base->parameter_count;
970 desc->Techniques = base->technique_count;
972 return D3D_OK;
975 static HRESULT d3dx9_base_effect_get_parameter_desc(struct d3dx9_base_effect *base,
976 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
978 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
980 if (!desc || !param)
982 WARN("Invalid argument specified.\n");
983 return D3DERR_INVALIDCALL;
986 desc->Name = param->name;
987 desc->Semantic = param->semantic;
988 desc->Class = param->class;
989 desc->Type = param->type;
990 desc->Rows = param->rows;
991 desc->Columns = param->columns;
992 desc->Elements = param->element_count;
993 desc->Annotations = is_top_level_parameter(param)
994 ? top_level_parameter_from_parameter(param)->annotation_count : 0;
995 desc->StructMembers = param->member_count;
996 desc->Flags = param->flags;
997 desc->Bytes = param->bytes;
999 return D3D_OK;
1002 static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *base,
1003 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1005 struct d3dx_technique *tech = technique ? get_valid_technique(base, technique) : &base->techniques[0];
1007 if (!desc || !tech)
1009 WARN("Invalid argument specified.\n");
1010 return D3DERR_INVALIDCALL;
1013 desc->Name = tech->name;
1014 desc->Passes = tech->pass_count;
1015 desc->Annotations = tech->annotation_count;
1017 return D3D_OK;
1020 static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
1021 void **param_value, struct d3dx_parameter **out_param,
1022 BOOL update_all, BOOL *param_dirty)
1024 struct d3dx_parameter *param = &state->parameter;
1026 *param_value = NULL;
1027 *out_param = NULL;
1028 *param_dirty = FALSE;
1030 switch (state->type)
1032 case ST_PARAMETER:
1033 param = state->referenced_param;
1034 *param_dirty = is_param_dirty(param, pass->update_version);
1035 /* fallthrough */
1036 case ST_CONSTANT:
1037 *out_param = param;
1038 *param_value = param->data;
1039 return D3D_OK;
1040 case ST_ARRAY_SELECTOR:
1042 unsigned int array_idx;
1043 static const struct d3dx_parameter array_idx_param =
1044 {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)};
1045 HRESULT hr;
1046 struct d3dx_parameter *ref_param, *selected_param;
1048 if (!param->param_eval)
1050 FIXME("Preshader structure is null.\n");
1051 return D3DERR_INVALIDCALL;
1053 /* We override with the update_version of the pass because we want
1054 * to force index recomputation and check for out of bounds. */
1055 if (is_param_eval_input_dirty(param->param_eval, pass->update_version))
1057 if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
1058 return hr;
1060 else
1062 array_idx = state->index;
1064 ref_param = state->referenced_param;
1065 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
1066 ref_param->element_count);
1067 /* According to the tests, native d3dx handles the case of array index evaluated to -1
1068 * in a specific way, always selecting first array element and not returning error. */
1069 if (array_idx == ~0u)
1071 WARN("Array index is -1, setting to 0.\n");
1072 array_idx = 0;
1075 if (array_idx >= ref_param->element_count)
1077 WARN("Computed array index %u is larger than array size %u.\n",
1078 array_idx, ref_param->element_count);
1079 return E_FAIL;
1081 selected_param = &ref_param->members[array_idx];
1082 *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
1083 state->index = array_idx;
1085 *param_value = selected_param->data;
1086 *out_param = selected_param;
1087 return D3D_OK;
1089 case ST_FXLC:
1090 if (param->param_eval)
1092 *out_param = param;
1093 *param_value = param->data;
1094 /* We check with the update_version of the pass because the
1095 * same preshader might be used by both the vertex and the
1096 * pixel shader (that can happen e.g. for sampler states). */
1097 if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version))
1099 *param_dirty = TRUE;
1100 return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
1102 else
1103 return D3D_OK;
1105 else
1107 FIXME("No preshader for FXLC parameter.\n");
1108 return D3DERR_INVALIDCALL;
1111 return E_NOTIMPL;
1114 static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
1115 D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
1117 struct d3dx_pass *pass = get_valid_pass(base, pass_handle);
1118 unsigned int i;
1120 if (!desc || !pass)
1122 WARN("Invalid argument specified.\n");
1123 return D3DERR_INVALIDCALL;
1126 desc->Name = pass->name;
1127 desc->Annotations = pass->annotation_count;
1129 desc->pVertexShaderFunction = NULL;
1130 desc->pPixelShaderFunction = NULL;
1132 if (base->flags & D3DXFX_NOT_CLONEABLE)
1133 return D3D_OK;
1135 for (i = 0; i < pass->state_count; ++i)
1137 struct d3dx_state *state = &pass->states[i];
1139 if (state_table[state->operation].class == SC_VERTEXSHADER
1140 || state_table[state->operation].class == SC_PIXELSHADER)
1142 struct d3dx_parameter *param;
1143 void *param_value;
1144 BOOL param_dirty;
1145 HRESULT hr;
1147 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
1148 FALSE, &param_dirty)))
1149 return hr;
1151 if (!param->object_id)
1153 FIXME("Zero object ID in shader parameter.\n");
1154 return E_FAIL;
1157 if (state_table[state->operation].class == SC_VERTEXSHADER)
1158 desc->pVertexShaderFunction = base->objects[param->object_id].data;
1159 else
1160 desc->pPixelShaderFunction = base->objects[param->object_id].data;
1164 return D3D_OK;
1167 static HRESULT d3dx9_base_effect_get_function_desc(struct d3dx9_base_effect *base,
1168 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
1170 FIXME("stub!\n");
1172 return E_NOTIMPL;
1175 static D3DXHANDLE d3dx9_base_effect_get_parameter(struct d3dx9_base_effect *base,
1176 D3DXHANDLE parameter, UINT index)
1178 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1180 if (!parameter)
1182 if (index < base->parameter_count)
1184 TRACE("Returning parameter %p.\n", &base->parameters[index]);
1185 return get_parameter_handle(&base->parameters[index].param);
1188 else
1190 if (param && !param->element_count && index < param->member_count)
1192 TRACE("Returning parameter %p.\n", &param->members[index]);
1193 return get_parameter_handle(&param->members[index]);
1197 WARN("Parameter not found.\n");
1199 return NULL;
1202 static D3DXHANDLE d3dx9_base_effect_get_parameter_by_name(struct d3dx9_base_effect *base,
1203 D3DXHANDLE parameter, const char *name)
1205 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1206 D3DXHANDLE handle;
1208 if (!name)
1210 handle = get_parameter_handle(param);
1211 TRACE("Returning parameter %p.\n", handle);
1212 return handle;
1215 handle = get_parameter_handle(get_parameter_by_name(base, param, name));
1216 TRACE("Returning parameter %p.\n", handle);
1218 return handle;
1221 static D3DXHANDLE d3dx9_base_effect_get_parameter_by_semantic(struct d3dx9_base_effect *base,
1222 D3DXHANDLE parameter, const char *semantic)
1224 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1225 struct d3dx_parameter *temp_param;
1226 UINT i;
1228 if (!parameter)
1230 for (i = 0; i < base->parameter_count; ++i)
1232 temp_param = &base->parameters[i].param;
1234 if (!temp_param->semantic)
1236 if (!semantic)
1238 TRACE("Returning parameter %p\n", temp_param);
1239 return get_parameter_handle(temp_param);
1241 continue;
1244 if (!strcasecmp(temp_param->semantic, semantic))
1246 TRACE("Returning parameter %p\n", temp_param);
1247 return get_parameter_handle(temp_param);
1251 else if (param)
1253 for (i = 0; i < param->member_count; ++i)
1255 temp_param = &param->members[i];
1257 if (!temp_param->semantic)
1259 if (!semantic)
1261 TRACE("Returning parameter %p\n", temp_param);
1262 return get_parameter_handle(temp_param);
1264 continue;
1267 if (!strcasecmp(temp_param->semantic, semantic))
1269 TRACE("Returning parameter %p\n", temp_param);
1270 return get_parameter_handle(temp_param);
1275 WARN("Parameter not found.\n");
1277 return NULL;
1280 static D3DXHANDLE d3dx9_base_effect_get_parameter_element(struct d3dx9_base_effect *base,
1281 D3DXHANDLE parameter, UINT index)
1283 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1285 if (!param)
1287 if (index < base->parameter_count)
1289 TRACE("Returning parameter %p.\n", &base->parameters[index]);
1290 return get_parameter_handle(&base->parameters[index].param);
1293 else
1295 if (index < param->element_count)
1297 TRACE("Returning parameter %p.\n", &param->members[index]);
1298 return get_parameter_handle(&param->members[index]);
1302 WARN("Parameter not found.\n");
1304 return NULL;
1307 static D3DXHANDLE d3dx9_base_effect_get_technique(struct d3dx9_base_effect *base, UINT index)
1309 if (index >= base->technique_count)
1311 WARN("Invalid argument specified.\n");
1312 return NULL;
1315 TRACE("Returning technique %p.\n", &base->techniques[index]);
1317 return get_technique_handle(&base->techniques[index]);
1320 static D3DXHANDLE d3dx9_base_effect_get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
1322 struct d3dx_technique *tech = get_technique_by_name(base, name);
1324 if (tech)
1326 D3DXHANDLE t = get_technique_handle(tech);
1327 TRACE("Returning technique %p\n", t);
1328 return t;
1331 WARN("Technique not found.\n");
1333 return NULL;
1336 static D3DXHANDLE d3dx9_base_effect_get_pass(struct d3dx9_base_effect *base,
1337 D3DXHANDLE technique, UINT index)
1339 struct d3dx_technique *tech = get_valid_technique(base, technique);
1341 if (tech && index < tech->pass_count)
1343 TRACE("Returning pass %p\n", &tech->passes[index]);
1344 return get_pass_handle(&tech->passes[index]);
1347 WARN("Pass not found.\n");
1349 return NULL;
1352 static D3DXHANDLE d3dx9_base_effect_get_pass_by_name(struct d3dx9_base_effect *base,
1353 D3DXHANDLE technique, const char *name)
1355 struct d3dx_technique *tech = get_valid_technique(base, technique);
1357 if (tech && name)
1359 unsigned int i;
1361 for (i = 0; i < tech->pass_count; ++i)
1363 struct d3dx_pass *pass = &tech->passes[i];
1365 if (!strcmp(pass->name, name))
1367 TRACE("Returning pass %p\n", pass);
1368 return get_pass_handle(pass);
1373 WARN("Pass not found.\n");
1375 return NULL;
1378 static D3DXHANDLE d3dx9_base_effect_get_function(struct d3dx9_base_effect *base, UINT index)
1380 FIXME("stub!\n");
1382 return NULL;
1385 static D3DXHANDLE d3dx9_base_effect_get_function_by_name(struct d3dx9_base_effect *base, const char *name)
1387 FIXME("stub!\n");
1389 return NULL;
1392 static UINT get_annotation_from_object(struct d3dx9_base_effect *base,
1393 D3DXHANDLE object, struct d3dx_parameter **annotations)
1395 struct d3dx_parameter *param = get_valid_parameter(base, object);
1396 struct d3dx_pass *pass = get_valid_pass(base, object);
1397 struct d3dx_technique *technique = get_valid_technique(base, object);
1399 if (pass)
1401 *annotations = pass->annotations;
1402 return pass->annotation_count;
1404 else if (technique)
1406 *annotations = technique->annotations;
1407 return technique->annotation_count;
1409 else if (param)
1411 if (is_top_level_parameter(param))
1413 struct d3dx_top_level_parameter *top_param
1414 = top_level_parameter_from_parameter(param);
1416 *annotations = top_param->annotations;
1417 return top_param->annotation_count;
1419 else
1421 *annotations = NULL;
1422 return 0;
1425 else
1427 FIXME("Functions are not handled, yet!\n");
1428 return 0;
1432 static D3DXHANDLE d3dx9_base_effect_get_annotation(struct d3dx9_base_effect *base,
1433 D3DXHANDLE object, UINT index)
1435 struct d3dx_parameter *annotations = NULL;
1436 UINT annotation_count = 0;
1438 annotation_count = get_annotation_from_object(base, object, &annotations);
1440 if (index < annotation_count)
1442 TRACE("Returning parameter %p\n", &annotations[index]);
1443 return get_parameter_handle(&annotations[index]);
1446 WARN("Annotation not found.\n");
1448 return NULL;
1451 static D3DXHANDLE d3dx9_base_effect_get_annotation_by_name(struct d3dx9_base_effect *base,
1452 D3DXHANDLE object, const char *name)
1454 struct d3dx_parameter *annotation = NULL;
1455 struct d3dx_parameter *annotations = NULL;
1456 UINT annotation_count = 0;
1458 if (!name)
1460 WARN("Invalid argument specified\n");
1461 return NULL;
1464 annotation_count = get_annotation_from_object(base, object, &annotations);
1466 annotation = get_annotation_by_name(annotation_count, annotations, name);
1467 if (annotation)
1469 TRACE("Returning parameter %p\n", annotation);
1470 return get_parameter_handle(annotation);
1473 WARN("Annotation not found.\n");
1475 return NULL;
1478 static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
1479 void *data)
1481 unsigned int i;
1482 unsigned int member_count;
1484 if (param_func(data, param))
1485 return TRUE;
1487 member_count = param->element_count ? param->element_count : param->member_count;
1488 for (i = 0; i < member_count; ++i)
1490 if (walk_parameter_tree(&param->members[i], param_func, data))
1491 return TRUE;
1493 return FALSE;
1496 static ULONG64 *get_version_counter_ptr(struct d3dx9_base_effect *base)
1498 return base->pool ? &base->pool->version_counter : &base->version_counter;
1501 static ULONG64 next_effect_update_version(struct d3dx9_base_effect *base)
1503 return next_update_version(get_version_counter_ptr(base));
1506 static void set_dirty(struct d3dx_parameter *param)
1508 struct d3dx_shared_data *shared_data;
1509 struct d3dx_top_level_parameter *top_param = param->top_level_param;
1510 ULONG64 new_update_version = next_update_version(top_param->version_counter);
1512 if ((shared_data = top_param->shared_data))
1513 shared_data->update_version = new_update_version;
1514 else
1515 top_param->update_version = new_update_version;
1518 static HRESULT set_string(char **param_data, const char *string)
1520 HeapFree(GetProcessHeap(), 0, *param_data);
1521 *param_data = HeapAlloc(GetProcessHeap(), 0, strlen(string) + 1);
1522 if (!*param_data)
1524 ERR("Out of memory.\n");
1525 return E_OUTOFMEMORY;
1527 strcpy(*param_data, string);
1528 return D3D_OK;
1531 static HRESULT d3dx9_base_effect_set_value(struct d3dx9_base_effect *base,
1532 D3DXHANDLE parameter, const void *data, UINT bytes)
1534 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1535 unsigned int i;
1537 if (!param)
1539 WARN("Invalid parameter %p specified\n", parameter);
1540 return D3DERR_INVALIDCALL;
1543 /* samplers don't touch data */
1544 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1546 TRACE("Sampler: returning E_FAIL\n");
1547 return E_FAIL;
1550 if (data && param->bytes <= bytes)
1552 switch (param->type)
1554 case D3DXPT_TEXTURE:
1555 case D3DXPT_TEXTURE1D:
1556 case D3DXPT_TEXTURE2D:
1557 case D3DXPT_TEXTURE3D:
1558 case D3DXPT_TEXTURECUBE:
1559 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1561 IUnknown *unk = ((IUnknown **)data)[i];
1562 if (unk)
1563 IUnknown_AddRef(unk);
1565 unk = ((IUnknown **)param->data)[i];
1566 if (unk)
1567 IUnknown_Release(unk);
1569 /* fallthrough */
1570 case D3DXPT_VOID:
1571 case D3DXPT_BOOL:
1572 case D3DXPT_INT:
1573 case D3DXPT_FLOAT:
1574 TRACE("Copy %u bytes.\n", param->bytes);
1575 memcpy(param->data, data, param->bytes);
1576 set_dirty(param);
1577 break;
1579 case D3DXPT_STRING:
1581 HRESULT hr;
1583 set_dirty(param);
1584 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1586 if (FAILED(hr = set_string(&((char **)param->data)[i], ((const char **)data)[i])))
1587 return hr;
1589 break;
1592 default:
1593 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
1594 break;
1597 return D3D_OK;
1600 WARN("Invalid argument specified\n");
1602 return D3DERR_INVALIDCALL;
1605 static HRESULT d3dx9_base_effect_get_value(struct d3dx9_base_effect *base,
1606 D3DXHANDLE parameter, void *data, UINT bytes)
1608 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1610 if (!param)
1612 WARN("Invalid parameter %p specified\n", parameter);
1613 return D3DERR_INVALIDCALL;
1616 /* samplers don't touch data */
1617 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1619 TRACE("Sampler: returning E_FAIL\n");
1620 return E_FAIL;
1623 if (data && param->bytes <= bytes)
1625 TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1627 switch (param->type)
1629 case D3DXPT_VOID:
1630 case D3DXPT_BOOL:
1631 case D3DXPT_INT:
1632 case D3DXPT_FLOAT:
1633 case D3DXPT_STRING:
1634 break;
1636 case D3DXPT_VERTEXSHADER:
1637 case D3DXPT_PIXELSHADER:
1638 case D3DXPT_TEXTURE:
1639 case D3DXPT_TEXTURE1D:
1640 case D3DXPT_TEXTURE2D:
1641 case D3DXPT_TEXTURE3D:
1642 case D3DXPT_TEXTURECUBE:
1644 UINT i;
1646 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1648 IUnknown *unk = ((IUnknown **)param->data)[i];
1649 if (unk) IUnknown_AddRef(unk);
1651 break;
1654 default:
1655 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1656 break;
1659 TRACE("Copy %u bytes\n", param->bytes);
1660 memcpy(data, param->data, param->bytes);
1661 return D3D_OK;
1664 WARN("Parameter not found.\n");
1666 return D3DERR_INVALIDCALL;
1669 static HRESULT d3dx9_base_effect_set_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL b)
1671 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1673 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1675 set_number(param->data, param->type, &b, D3DXPT_BOOL);
1676 set_dirty(param);
1677 return D3D_OK;
1680 WARN("Parameter not found.\n");
1682 return D3DERR_INVALIDCALL;
1685 static HRESULT d3dx9_base_effect_get_bool(struct d3dx9_base_effect *base, D3DXHANDLE parameter, BOOL *b)
1687 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1689 if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
1691 set_number(b, D3DXPT_BOOL, param->data, param->type);
1692 TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1693 return D3D_OK;
1696 WARN("Parameter not found.\n");
1698 return D3DERR_INVALIDCALL;
1701 static HRESULT d3dx9_base_effect_set_bool_array(struct d3dx9_base_effect *base,
1702 D3DXHANDLE parameter, const BOOL *b, UINT count)
1704 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1706 if (param)
1708 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1710 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1712 switch (param->class)
1714 case D3DXPC_SCALAR:
1715 case D3DXPC_VECTOR:
1716 case D3DXPC_MATRIX_ROWS:
1717 for (i = 0; i < size; ++i)
1719 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
1720 set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
1722 set_dirty(param);
1723 return D3D_OK;
1725 case D3DXPC_OBJECT:
1726 case D3DXPC_STRUCT:
1727 break;
1729 default:
1730 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1731 break;
1735 WARN("Parameter not found.\n");
1737 return D3DERR_INVALIDCALL;
1740 static HRESULT d3dx9_base_effect_get_bool_array(struct d3dx9_base_effect *base,
1741 D3DXHANDLE parameter, BOOL *b, UINT count)
1743 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1745 if (b && param && (param->class == D3DXPC_SCALAR
1746 || param->class == D3DXPC_VECTOR
1747 || param->class == D3DXPC_MATRIX_ROWS
1748 || param->class == D3DXPC_MATRIX_COLUMNS))
1750 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1752 for (i = 0; i < size; ++i)
1754 set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
1756 return D3D_OK;
1759 WARN("Parameter not found.\n");
1761 return D3DERR_INVALIDCALL;
1764 static HRESULT d3dx9_base_effect_set_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT n)
1766 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1768 if (param && !param->element_count)
1770 if (param->rows == 1 && param->columns == 1)
1772 DWORD value;
1774 set_number(&value, param->type, &n, D3DXPT_INT);
1775 if (value != *(DWORD *)param->data)
1776 set_dirty(param);
1777 *(DWORD *)param->data = value;
1778 return D3D_OK;
1782 * Split the value, if parameter is a vector with dimension 3 or 4.
1784 if (param->type == D3DXPT_FLOAT &&
1785 ((param->class == D3DXPC_VECTOR && param->columns != 2) ||
1786 (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1788 TRACE("Vector fixup\n");
1790 *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
1791 ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
1792 ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
1793 if (param->rows * param->columns > 3)
1795 ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
1797 set_dirty(param);
1798 return D3D_OK;
1802 WARN("Parameter not found.\n");
1804 return D3DERR_INVALIDCALL;
1807 static HRESULT d3dx9_base_effect_get_int(struct d3dx9_base_effect *base, D3DXHANDLE parameter, INT *n)
1809 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1811 if (n && param && !param->element_count)
1813 if (param->columns == 1 && param->rows == 1)
1815 set_number(n, D3DXPT_INT, param->data, param->type);
1816 TRACE("Returning %i\n", *n);
1817 return D3D_OK;
1820 if (param->type == D3DXPT_FLOAT &&
1821 ((param->class == D3DXPC_VECTOR && param->columns != 2)
1822 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1824 TRACE("Vector fixup\n");
1826 /* all components (3,4) are clamped (0,255) and put in the INT */
1827 *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
1828 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
1829 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
1830 if (param->columns * param->rows > 3)
1832 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
1835 TRACE("Returning %i\n", *n);
1836 return D3D_OK;
1840 WARN("Parameter not found.\n");
1842 return D3DERR_INVALIDCALL;
1845 static HRESULT d3dx9_base_effect_set_int_array(struct d3dx9_base_effect *base,
1846 D3DXHANDLE parameter, const INT *n, UINT count)
1848 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1850 if (param)
1852 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1854 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1856 switch (param->class)
1858 case D3DXPC_SCALAR:
1859 case D3DXPC_VECTOR:
1860 case D3DXPC_MATRIX_ROWS:
1861 for (i = 0; i < size; ++i)
1863 set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
1865 set_dirty(param);
1866 return D3D_OK;
1868 case D3DXPC_OBJECT:
1869 case D3DXPC_STRUCT:
1870 break;
1872 default:
1873 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1874 break;
1878 WARN("Parameter not found.\n");
1880 return D3DERR_INVALIDCALL;
1883 static HRESULT d3dx9_base_effect_get_int_array(struct d3dx9_base_effect *base,
1884 D3DXHANDLE parameter, INT *n, UINT count)
1886 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1888 if (n && param && (param->class == D3DXPC_SCALAR
1889 || param->class == D3DXPC_VECTOR
1890 || param->class == D3DXPC_MATRIX_ROWS
1891 || param->class == D3DXPC_MATRIX_COLUMNS))
1893 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1895 for (i = 0; i < size; ++i)
1897 set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
1899 return D3D_OK;
1902 WARN("Parameter not found.\n");
1904 return D3DERR_INVALIDCALL;
1907 static HRESULT d3dx9_base_effect_set_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float f)
1909 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1911 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1913 DWORD value;
1915 set_number(&value, param->type, &f, D3DXPT_FLOAT);
1916 if (value != *(DWORD *)param->data)
1917 set_dirty(param);
1918 *(DWORD *)param->data = value;
1919 return D3D_OK;
1922 WARN("Parameter not found.\n");
1924 return D3DERR_INVALIDCALL;
1927 static HRESULT d3dx9_base_effect_get_float(struct d3dx9_base_effect *base, D3DXHANDLE parameter, float *f)
1929 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1931 if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
1933 set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
1934 TRACE("Returning %f\n", *f);
1935 return D3D_OK;
1938 WARN("Parameter not found.\n");
1940 return D3DERR_INVALIDCALL;
1943 static HRESULT d3dx9_base_effect_set_float_array(struct d3dx9_base_effect *base,
1944 D3DXHANDLE parameter, const float *f, UINT count)
1946 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1948 if (param)
1950 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1952 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1954 switch (param->class)
1956 case D3DXPC_SCALAR:
1957 case D3DXPC_VECTOR:
1958 case D3DXPC_MATRIX_ROWS:
1959 for (i = 0; i < size; ++i)
1961 set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
1963 set_dirty(param);
1964 return D3D_OK;
1966 case D3DXPC_OBJECT:
1967 case D3DXPC_STRUCT:
1968 break;
1970 default:
1971 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1972 break;
1976 WARN("Parameter not found.\n");
1978 return D3DERR_INVALIDCALL;
1981 static HRESULT d3dx9_base_effect_get_float_array(struct d3dx9_base_effect *base,
1982 D3DXHANDLE parameter, float *f, UINT count)
1984 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1986 if (f && param && (param->class == D3DXPC_SCALAR
1987 || param->class == D3DXPC_VECTOR
1988 || param->class == D3DXPC_MATRIX_ROWS
1989 || param->class == D3DXPC_MATRIX_COLUMNS))
1991 UINT i, size = min(count, param->bytes / sizeof(DWORD));
1993 for (i = 0; i < size; ++i)
1995 set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
1997 return D3D_OK;
2000 WARN("Parameter not found.\n");
2002 return D3DERR_INVALIDCALL;
2005 static HRESULT d3dx9_base_effect_set_vector(struct d3dx9_base_effect *base,
2006 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2008 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2010 if (param && !param->element_count)
2012 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2014 switch (param->class)
2016 case D3DXPC_SCALAR:
2017 case D3DXPC_VECTOR:
2018 set_dirty(param);
2019 if (param->type == D3DXPT_INT && param->bytes == 4)
2021 DWORD tmp;
2023 TRACE("INT fixup\n");
2024 tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
2025 tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2026 tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2027 tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2029 *(INT *)param->data = tmp;
2030 return D3D_OK;
2032 if (param->type == D3DXPT_FLOAT)
2034 memcpy(param->data, vector, param->columns * sizeof(float));
2035 return D3D_OK;
2038 set_vector(param, vector);
2039 return D3D_OK;
2041 case D3DXPC_MATRIX_ROWS:
2042 case D3DXPC_OBJECT:
2043 case D3DXPC_STRUCT:
2044 break;
2046 default:
2047 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2048 break;
2052 WARN("Parameter not found.\n");
2054 return D3DERR_INVALIDCALL;
2057 static HRESULT d3dx9_base_effect_get_vector(struct d3dx9_base_effect *base,
2058 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2060 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2062 if (vector && param && !param->element_count)
2064 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2066 switch (param->class)
2068 case D3DXPC_SCALAR:
2069 case D3DXPC_VECTOR:
2070 if (param->type == D3DXPT_INT && param->bytes == 4)
2072 TRACE("INT fixup\n");
2073 vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2074 vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2075 vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2076 vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2077 return D3D_OK;
2079 get_vector(param, vector);
2080 return D3D_OK;
2082 case D3DXPC_MATRIX_ROWS:
2083 case D3DXPC_OBJECT:
2084 case D3DXPC_STRUCT:
2085 break;
2087 default:
2088 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2089 break;
2093 WARN("Parameter not found.\n");
2095 return D3DERR_INVALIDCALL;
2098 static HRESULT d3dx9_base_effect_set_vector_array(struct d3dx9_base_effect *base,
2099 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
2101 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2103 if (param && param->element_count && param->element_count >= count)
2105 UINT i;
2107 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2109 switch (param->class)
2111 case D3DXPC_VECTOR:
2112 set_dirty(param);
2113 if (param->type == D3DXPT_FLOAT)
2115 if (param->columns == 4)
2116 memcpy(param->data, vector, count * 4 * sizeof(float));
2117 else
2118 for (i = 0; i < count; ++i)
2119 memcpy((float *)param->data + param->columns * i, vector + i,
2120 param->columns * sizeof(float));
2121 return D3D_OK;
2124 for (i = 0; i < count; ++i)
2126 set_vector(&param->members[i], &vector[i]);
2128 return D3D_OK;
2130 case D3DXPC_SCALAR:
2131 case D3DXPC_MATRIX_ROWS:
2132 case D3DXPC_OBJECT:
2133 case D3DXPC_STRUCT:
2134 break;
2136 default:
2137 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2138 break;
2142 WARN("Parameter not found.\n");
2144 return D3DERR_INVALIDCALL;
2147 static HRESULT d3dx9_base_effect_get_vector_array(struct d3dx9_base_effect *base,
2148 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2150 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2152 if (!count) return D3D_OK;
2154 if (vector && param && count <= param->element_count)
2156 UINT i;
2158 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2160 switch (param->class)
2162 case D3DXPC_VECTOR:
2163 for (i = 0; i < count; ++i)
2165 get_vector(&param->members[i], &vector[i]);
2167 return D3D_OK;
2169 case D3DXPC_SCALAR:
2170 case D3DXPC_MATRIX_ROWS:
2171 case D3DXPC_OBJECT:
2172 case D3DXPC_STRUCT:
2173 break;
2175 default:
2176 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2177 break;
2181 WARN("Parameter not found.\n");
2183 return D3DERR_INVALIDCALL;
2186 static HRESULT d3dx9_base_effect_set_matrix(struct d3dx9_base_effect *base,
2187 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2189 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2191 if (param && !param->element_count)
2193 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2195 switch (param->class)
2197 case D3DXPC_MATRIX_ROWS:
2198 set_matrix(param, matrix);
2199 set_dirty(param);
2200 return D3D_OK;
2202 case D3DXPC_SCALAR:
2203 case D3DXPC_VECTOR:
2204 case D3DXPC_OBJECT:
2205 case D3DXPC_STRUCT:
2206 break;
2208 default:
2209 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2210 break;
2214 WARN("Parameter not found.\n");
2216 return D3DERR_INVALIDCALL;
2219 static HRESULT d3dx9_base_effect_get_matrix(struct d3dx9_base_effect *base,
2220 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2222 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2224 if (matrix && param && !param->element_count)
2226 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2228 switch (param->class)
2230 case D3DXPC_MATRIX_ROWS:
2231 get_matrix(param, matrix, FALSE);
2232 return D3D_OK;
2234 case D3DXPC_SCALAR:
2235 case D3DXPC_VECTOR:
2236 case D3DXPC_OBJECT:
2237 case D3DXPC_STRUCT:
2238 break;
2240 default:
2241 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2242 break;
2246 WARN("Parameter not found.\n");
2248 return D3DERR_INVALIDCALL;
2251 static HRESULT d3dx9_base_effect_set_matrix_array(struct d3dx9_base_effect *base,
2252 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2254 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2256 if (param && param->element_count >= count)
2258 UINT i;
2260 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2262 switch (param->class)
2264 case D3DXPC_MATRIX_ROWS:
2265 set_dirty(param);
2266 for (i = 0; i < count; ++i)
2268 set_matrix(&param->members[i], &matrix[i]);
2270 return D3D_OK;
2272 case D3DXPC_SCALAR:
2273 case D3DXPC_VECTOR:
2274 case D3DXPC_OBJECT:
2275 case D3DXPC_STRUCT:
2276 break;
2278 default:
2279 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2280 break;
2284 WARN("Parameter not found.\n");
2286 return D3DERR_INVALIDCALL;
2289 static HRESULT d3dx9_base_effect_get_matrix_array(struct d3dx9_base_effect *base,
2290 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2292 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2294 if (!count) return D3D_OK;
2296 if (matrix && param && count <= param->element_count)
2298 UINT i;
2300 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2302 switch (param->class)
2304 case D3DXPC_MATRIX_ROWS:
2305 for (i = 0; i < count; ++i)
2307 get_matrix(&param->members[i], &matrix[i], FALSE);
2309 return D3D_OK;
2311 case D3DXPC_SCALAR:
2312 case D3DXPC_VECTOR:
2313 case D3DXPC_OBJECT:
2314 case D3DXPC_STRUCT:
2315 break;
2317 default:
2318 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2319 break;
2323 WARN("Parameter not found.\n");
2325 return D3DERR_INVALIDCALL;
2328 static HRESULT d3dx9_base_effect_set_matrix_pointer_array(struct d3dx9_base_effect *base,
2329 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2331 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2333 if (param && count <= param->element_count)
2335 UINT i;
2337 switch (param->class)
2339 case D3DXPC_MATRIX_ROWS:
2340 set_dirty(param);
2341 for (i = 0; i < count; ++i)
2343 set_matrix(&param->members[i], matrix[i]);
2345 return D3D_OK;
2347 case D3DXPC_SCALAR:
2348 case D3DXPC_VECTOR:
2349 case D3DXPC_OBJECT:
2350 break;
2352 default:
2353 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2354 break;
2358 WARN("Parameter not found.\n");
2360 return D3DERR_INVALIDCALL;
2363 static HRESULT d3dx9_base_effect_get_matrix_pointer_array(struct d3dx9_base_effect *base,
2364 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2366 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2368 if (!count) return D3D_OK;
2370 if (param && matrix && count <= param->element_count)
2372 UINT i;
2374 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2376 switch (param->class)
2378 case D3DXPC_MATRIX_ROWS:
2379 for (i = 0; i < count; ++i)
2381 get_matrix(&param->members[i], matrix[i], FALSE);
2383 return D3D_OK;
2385 case D3DXPC_SCALAR:
2386 case D3DXPC_VECTOR:
2387 case D3DXPC_OBJECT:
2388 break;
2390 default:
2391 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2392 break;
2396 WARN("Parameter not found.\n");
2398 return D3DERR_INVALIDCALL;
2401 static HRESULT d3dx9_base_effect_set_matrix_transpose(struct d3dx9_base_effect *base,
2402 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2404 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2406 if (param && !param->element_count)
2408 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2410 switch (param->class)
2412 case D3DXPC_MATRIX_ROWS:
2413 set_dirty(param);
2414 set_matrix_transpose(param, matrix);
2415 return D3D_OK;
2417 case D3DXPC_SCALAR:
2418 case D3DXPC_VECTOR:
2419 case D3DXPC_OBJECT:
2420 case D3DXPC_STRUCT:
2421 break;
2423 default:
2424 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2425 break;
2429 WARN("Parameter not found.\n");
2431 return D3DERR_INVALIDCALL;
2434 static HRESULT d3dx9_base_effect_get_matrix_transpose(struct d3dx9_base_effect *base,
2435 D3DXHANDLE parameter, D3DXMATRIX *matrix)
2437 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2439 if (matrix && param && !param->element_count)
2441 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2443 switch (param->class)
2445 case D3DXPC_SCALAR:
2446 case D3DXPC_VECTOR:
2447 get_matrix(param, matrix, FALSE);
2448 return D3D_OK;
2450 case D3DXPC_MATRIX_ROWS:
2451 get_matrix(param, matrix, TRUE);
2452 return D3D_OK;
2454 case D3DXPC_OBJECT:
2455 case D3DXPC_STRUCT:
2456 break;
2458 default:
2459 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2460 break;
2464 WARN("Parameter not found.\n");
2466 return D3DERR_INVALIDCALL;
2469 static HRESULT d3dx9_base_effect_set_matrix_transpose_array(struct d3dx9_base_effect *base,
2470 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2472 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2474 if (param && param->element_count >= count)
2476 UINT i;
2478 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2480 switch (param->class)
2482 case D3DXPC_MATRIX_ROWS:
2483 set_dirty(param);
2484 for (i = 0; i < count; ++i)
2486 set_matrix_transpose(&param->members[i], &matrix[i]);
2488 return D3D_OK;
2490 case D3DXPC_SCALAR:
2491 case D3DXPC_VECTOR:
2492 case D3DXPC_OBJECT:
2493 case D3DXPC_STRUCT:
2494 break;
2496 default:
2497 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2498 break;
2502 WARN("Parameter not found.\n");
2504 return D3DERR_INVALIDCALL;
2507 static HRESULT d3dx9_base_effect_get_matrix_transpose_array(struct d3dx9_base_effect *base,
2508 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2510 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2512 if (!count) return D3D_OK;
2514 if (matrix && param && count <= param->element_count)
2516 UINT i;
2518 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2520 switch (param->class)
2522 case D3DXPC_MATRIX_ROWS:
2523 for (i = 0; i < count; ++i)
2525 get_matrix(&param->members[i], &matrix[i], TRUE);
2527 return D3D_OK;
2529 case D3DXPC_SCALAR:
2530 case D3DXPC_VECTOR:
2531 case D3DXPC_OBJECT:
2532 case D3DXPC_STRUCT:
2533 break;
2535 default:
2536 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2537 break;
2541 WARN("Parameter not found.\n");
2543 return D3DERR_INVALIDCALL;
2546 static HRESULT d3dx9_base_effect_set_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2547 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2549 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2551 if (param && count <= param->element_count)
2553 UINT i;
2555 switch (param->class)
2557 case D3DXPC_MATRIX_ROWS:
2558 set_dirty(param);
2559 for (i = 0; i < count; ++i)
2561 set_matrix_transpose(&param->members[i], matrix[i]);
2563 return D3D_OK;
2565 case D3DXPC_SCALAR:
2566 case D3DXPC_VECTOR:
2567 case D3DXPC_OBJECT:
2568 break;
2570 default:
2571 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2572 break;
2576 WARN("Parameter not found.\n");
2578 return D3DERR_INVALIDCALL;
2581 static HRESULT d3dx9_base_effect_get_matrix_transpose_pointer_array(struct d3dx9_base_effect *base,
2582 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2584 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2586 if (!count) return D3D_OK;
2588 if (matrix && param && count <= param->element_count)
2590 UINT i;
2592 TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2594 switch (param->class)
2596 case D3DXPC_MATRIX_ROWS:
2597 for (i = 0; i < count; ++i)
2599 get_matrix(&param->members[i], matrix[i], TRUE);
2601 return D3D_OK;
2603 case D3DXPC_SCALAR:
2604 case D3DXPC_VECTOR:
2605 case D3DXPC_OBJECT:
2606 break;
2608 default:
2609 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2610 break;
2614 WARN("Parameter not found.\n");
2616 return D3DERR_INVALIDCALL;
2619 static HRESULT d3dx9_base_effect_set_string(struct d3dx9_base_effect *base,
2620 D3DXHANDLE parameter, const char *string)
2622 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2624 if (param && param->type == D3DXPT_STRING)
2626 set_dirty(param);
2627 return set_string(param->data, string);
2630 WARN("Parameter not found.\n");
2632 return D3DERR_INVALIDCALL;
2635 static HRESULT d3dx9_base_effect_get_string(struct d3dx9_base_effect *base,
2636 D3DXHANDLE parameter, const char **string)
2638 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2640 if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2642 *string = *(const char **)param->data;
2643 TRACE("Returning %s.\n", debugstr_a(*string));
2644 return D3D_OK;
2647 WARN("Parameter not found.\n");
2649 return D3DERR_INVALIDCALL;
2652 static HRESULT d3dx9_base_effect_set_texture(struct d3dx9_base_effect *base,
2653 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
2655 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2657 if (param && !param->element_count &&
2658 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2659 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2660 || param->type == D3DXPT_TEXTURECUBE))
2662 struct IDirect3DBaseTexture9 *oltexture = *(struct IDirect3DBaseTexture9 **)param->data;
2664 if (texture == oltexture)
2665 return D3D_OK;
2667 if (texture) IDirect3DBaseTexture9_AddRef(texture);
2668 if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2670 *(struct IDirect3DBaseTexture9 **)param->data = texture;
2671 set_dirty(param);
2673 return D3D_OK;
2676 WARN("Parameter not found.\n");
2678 return D3DERR_INVALIDCALL;
2681 static HRESULT d3dx9_base_effect_get_texture(struct d3dx9_base_effect *base,
2682 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
2684 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2686 if (texture && param && !param->element_count &&
2687 (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2688 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2689 || param->type == D3DXPT_TEXTURECUBE))
2691 *texture = *(struct IDirect3DBaseTexture9 **)param->data;
2692 if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2693 TRACE("Returning %p\n", *texture);
2694 return D3D_OK;
2697 WARN("Parameter not found.\n");
2699 return D3DERR_INVALIDCALL;
2702 static HRESULT d3dx9_base_effect_get_pixel_shader(struct d3dx9_base_effect *base,
2703 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
2705 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2707 if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2709 if ((*shader = *(struct IDirect3DPixelShader9 **)param->data))
2710 IDirect3DPixelShader9_AddRef(*shader);
2711 TRACE("Returning %p.\n", *shader);
2712 return D3D_OK;
2715 WARN("Parameter not found.\n");
2717 return D3DERR_INVALIDCALL;
2720 static HRESULT d3dx9_base_effect_get_vertex_shader(struct d3dx9_base_effect *base,
2721 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
2723 struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2725 if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2727 if ((*shader = *(struct IDirect3DVertexShader9 **)param->data))
2728 IDirect3DVertexShader9_AddRef(*shader);
2729 TRACE("Returning %p.\n", *shader);
2730 return D3D_OK;
2733 WARN("Parameter not found.\n");
2735 return D3DERR_INVALIDCALL;
2738 static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base,
2739 D3DXHANDLE parameter, UINT start, UINT end)
2741 FIXME("stub!\n");
2743 return E_NOTIMPL;
2746 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
2748 static const struct
2750 unsigned int offset;
2751 const char *name;
2753 light_tbl[] =
2755 {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
2756 {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
2757 {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
2758 {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
2759 {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
2760 {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
2761 {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
2762 {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
2763 {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
2764 {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
2765 {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
2766 {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
2767 {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
2769 switch (op)
2771 case LT_TYPE:
2772 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
2773 light->Type = *(D3DLIGHTTYPE *)value;
2774 break;
2775 case LT_DIFFUSE:
2776 case LT_SPECULAR:
2777 case LT_AMBIENT:
2779 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2781 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
2782 *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
2783 break;
2785 case LT_POSITION:
2786 case LT_DIRECTION:
2788 D3DVECTOR v = *(D3DVECTOR *)value;
2790 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
2791 *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
2792 break;
2794 case LT_RANGE:
2795 case LT_FALLOFF:
2796 case LT_ATTENUATION0:
2797 case LT_ATTENUATION1:
2798 case LT_ATTENUATION2:
2799 case LT_THETA:
2800 case LT_PHI:
2802 float v = *(float *)value;
2803 TRACE("%s %.8e.\n", light_tbl[op].name, v);
2804 *(float *)((BYTE *)light + light_tbl[op].offset) = v;
2805 break;
2807 default:
2808 WARN("Unknown light parameter %u.\n", op);
2809 break;
2813 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
2815 static const struct
2817 unsigned int offset;
2818 const char *name;
2820 material_tbl[] =
2822 {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
2823 {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
2824 {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
2825 {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
2826 {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
2829 switch (op)
2831 case MT_POWER:
2833 float v = *(float *)value;
2835 TRACE("%s %.8e.\n", material_tbl[op].name, v);
2836 material->Power = v;
2837 break;
2839 case MT_DIFFUSE:
2840 case MT_AMBIENT:
2841 case MT_SPECULAR:
2842 case MT_EMISSIVE:
2844 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
2846 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
2847 *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
2848 break;
2850 default:
2851 WARN("Unknown material parameter %u.\n", op);
2852 break;
2856 static HRESULT d3dx_set_shader_const_state(struct ID3DXEffectImpl *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
2857 struct d3dx_parameter *param, void *value_ptr)
2859 static const struct
2861 D3DXPARAMETER_TYPE type;
2862 UINT elem_size;
2863 const char *name;
2865 const_tbl[] =
2867 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
2868 {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
2869 {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
2870 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
2871 {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
2872 {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
2874 unsigned int element_count;
2876 if (op < 0 || op > SCT_PSINT)
2878 FIXME("Unknown op %u.\n", op);
2879 return D3DERR_INVALIDCALL;
2881 element_count = param->bytes / const_tbl[op].elem_size;
2882 TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
2883 if (param->type != const_tbl[op].type)
2885 FIXME("Unexpected param type %u.\n", param->type);
2886 return D3DERR_INVALIDCALL;
2888 if (param->bytes % const_tbl[op].elem_size != 0)
2890 FIXME("Unexpected param size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
2891 return D3DERR_INVALIDCALL;
2894 switch (op)
2896 case SCT_VSFLOAT:
2897 return SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)value_ptr, element_count);
2898 case SCT_VSBOOL:
2899 return SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2900 case SCT_VSINT:
2901 return SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)value_ptr, element_count);
2902 case SCT_PSFLOAT:
2903 return SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)value_ptr, element_count);
2904 case SCT_PSBOOL:
2905 return SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)value_ptr, element_count);
2906 case SCT_PSINT:
2907 return SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)value_ptr, element_count);
2909 return D3D_OK;
2912 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2913 struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
2915 static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2916 struct d3dx_parameter *param, BOOL vs, BOOL update_all)
2918 HRESULT hr, ret;
2919 struct d3dx_parameter **params;
2920 D3DXCONSTANT_DESC *cdesc;
2921 unsigned int parameters_count;
2922 unsigned int i, j;
2924 if (!param->param_eval)
2926 FIXME("param_eval structure is null.\n");
2927 return D3DERR_INVALIDCALL;
2929 if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
2930 param->param_eval, update_all)))
2931 return hr;
2932 params = param->param_eval->shader_inputs.inputs_param;
2933 cdesc = param->param_eval->shader_inputs.inputs;
2934 parameters_count = param->param_eval->shader_inputs.input_count;
2935 ret = D3D_OK;
2936 for (i = 0; i < parameters_count; ++i)
2938 if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
2940 struct d3dx_sampler *sampler;
2941 unsigned int sampler_idx;
2943 for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
2945 sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
2946 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
2947 cdesc[i].RegisterIndex, sampler->state_count);
2948 for (j = 0; j < sampler->state_count; ++j)
2950 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
2951 cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
2952 update_all)))
2953 ret = hr;
2958 return ret;
2961 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2962 struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
2964 struct d3dx_parameter *param;
2965 void *param_value;
2966 BOOL param_dirty;
2967 HRESULT hr;
2969 TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
2971 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
2972 update_all, &param_dirty)))
2974 if (!update_all && hr == E_FAIL)
2976 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
2977 * out of bounds array access and does not touch the affected
2978 * states. */
2979 WARN("Returning D3D_OK on out of bounds array access.\n");
2980 return D3D_OK;
2982 return hr;
2985 if (!(update_all || param_dirty
2986 || state_table[state->operation].class == SC_VERTEXSHADER
2987 || state_table[state->operation].class == SC_PIXELSHADER
2988 || state_table[state->operation].class == SC_SETSAMPLER))
2989 return D3D_OK;
2991 switch (state_table[state->operation].class)
2993 case SC_RENDERSTATE:
2994 TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
2995 state_table[state->operation].op, *(DWORD *)param_value);
2996 return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
2997 case SC_FVF:
2998 TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
2999 return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
3000 case SC_TEXTURE:
3002 UINT unit;
3004 unit = parent_index == ~0u ? state->index : parent_index;
3005 TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
3006 *(IDirect3DBaseTexture9 **)param_value);
3007 return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
3009 case SC_TEXTURESTAGE:
3010 TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
3011 return SET_D3D_STATE(effect, SetTextureStageState, state->index,
3012 state_table[state->operation].op, *(DWORD *)param_value);
3013 case SC_SETSAMPLER:
3015 struct d3dx_sampler *sampler;
3016 HRESULT ret, hr;
3017 unsigned int i;
3019 sampler = (struct d3dx_sampler *)param_value;
3020 TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
3021 sampler->state_count);
3022 ret = D3D_OK;
3023 for (i = 0; i < sampler->state_count; i++)
3025 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
3026 ret = hr;
3028 return ret;
3030 case SC_SAMPLERSTATE:
3032 UINT sampler;
3034 sampler = parent_index == ~0u ? state->index : parent_index;
3035 TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
3036 return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
3037 *(DWORD *)param_value);
3039 case SC_VERTEXSHADER:
3040 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
3041 if ((update_all || param_dirty)
3042 && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
3043 *(IDirect3DVertexShader9 **)param_value)))
3044 ERR("Could not set vertex shader, hr %#x.\n", hr);
3045 else if (*(IDirect3DVertexShader9 **)param_value)
3046 hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
3047 return hr;
3048 case SC_PIXELSHADER:
3049 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
3050 if ((update_all || param_dirty)
3051 && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
3052 *(IDirect3DPixelShader9 **)param_value)))
3053 ERR("Could not set pixel shader, hr %#x.\n", hr);
3054 else if (*(IDirect3DPixelShader9 **)param_value)
3055 hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
3056 return hr;
3057 case SC_TRANSFORM:
3058 TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
3059 return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
3060 (D3DMATRIX *)param_value);
3061 case SC_LIGHTENABLE:
3062 TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
3063 return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
3064 case SC_LIGHT:
3066 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3067 state_table[state->operation].op);
3068 d3dx9_set_light_parameter(state_table[state->operation].op,
3069 &effect->current_light[state->index], param_value);
3070 effect->light_updated[state->index] = TRUE;
3071 return D3D_OK;
3073 case SC_MATERIAL:
3075 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3076 state_table[state->operation].op);
3077 d3dx9_set_material_parameter(state_table[state->operation].op,
3078 &effect->current_material, param_value);
3079 effect->material_updated = TRUE;
3080 return D3D_OK;
3082 case SC_NPATCHMODE:
3083 TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
3084 return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
3085 case SC_SHADERCONST:
3086 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3087 state_table[state->operation].op);
3088 return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
3089 param, param_value);
3090 default:
3091 FIXME("%s not handled.\n", state_table[state->operation].name);
3092 break;
3094 return D3D_OK;
3097 static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass, BOOL update_all)
3099 unsigned int i;
3100 HRESULT ret;
3101 HRESULT hr;
3102 ULONG64 new_update_version = next_effect_update_version(&effect->base_effect);
3104 TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
3106 ret = D3D_OK;
3107 for (i = 0; i < pass->state_count; ++i)
3109 if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
3111 WARN("Error applying state, hr %#x.\n", hr);
3112 ret = hr;
3115 for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
3117 if (effect->light_updated[i]
3118 && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
3120 WARN("Error setting light, hr %#x.\n", hr);
3121 ret = hr;
3123 effect->light_updated[i] = FALSE;
3126 if (effect->material_updated
3127 && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
3129 WARN("Error setting material, hr %#x.\n", hr);
3130 ret = hr;
3132 effect->material_updated = FALSE;
3134 pass->update_version = new_update_version;
3135 return ret;
3138 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
3140 unsigned char *member_data = data;
3141 unsigned int i, count;
3143 count = param->element_count ? param->element_count : param->member_count;
3144 for (i = 0; i < count; ++i)
3146 param_set_data_pointer(&param->members[i], member_data, TRUE, free_data);
3147 if (data)
3148 member_data += param->members[i].bytes;
3150 if (free_data)
3151 free_parameter_data(param, child);
3152 param->data = data;
3155 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
3157 struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
3158 BOOL matches;
3159 unsigned int i, member_count;
3161 matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
3162 && param1->type == param2->type && param1->rows == param2->rows
3163 && param1->columns == param2->columns && param1->element_count == param2->element_count
3164 && param1->member_count == param2->member_count;
3166 member_count = param1->element_count ? param1->element_count : param1->member_count;
3168 if (!matches || !member_count)
3169 return matches;
3171 for (i = 0; i < member_count; ++i)
3173 if (!is_same_parameter(&param1->members[i], &param2->members[i]))
3174 return FALSE;
3176 return TRUE;
3179 static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param)
3181 unsigned int i, free_entry_index;
3182 unsigned int new_size, new_count;
3184 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
3185 return D3D_OK;
3187 free_entry_index = pool->size;
3188 for (i = 0; i < pool->size; ++i)
3190 if (!pool->shared_data[i].count)
3191 free_entry_index = i;
3192 else if (is_same_parameter(&param->param, &pool->shared_data[i].parameters[0]->param))
3193 break;
3195 if (i == pool->size)
3197 i = free_entry_index;
3198 if (i == pool->size)
3200 struct d3dx_shared_data *new_alloc;
3202 if (!pool->size)
3204 new_size = INITIAL_POOL_SIZE;
3205 new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3206 sizeof(*pool->shared_data) * new_size);
3207 if (!new_alloc)
3209 ERR("Out of memory.\n");
3210 return E_OUTOFMEMORY;
3213 else
3215 new_size = pool->size * 2;
3216 new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
3217 sizeof(*pool->shared_data) * new_size);
3218 if (!new_alloc)
3220 ERR("Out of memory.\n");
3221 return E_OUTOFMEMORY;
3223 if (new_alloc != pool->shared_data)
3225 unsigned int j, k;
3227 for (j = 0; j < pool->size; ++j)
3228 for (k = 0; k < new_alloc[j].count; ++k)
3229 new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
3232 pool->shared_data = new_alloc;
3233 pool->size = new_size;
3235 pool->shared_data[i].data = param->param.data;
3237 else
3239 param_set_data_pointer(&param->param, pool->shared_data[i].data, FALSE, TRUE);
3241 new_count = ++pool->shared_data[i].count;
3242 if (new_count >= pool->shared_data[i].size)
3244 if (!pool->shared_data[i].size)
3246 new_size = INITIAL_SHARED_DATA_SIZE;
3247 pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3248 sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
3250 else
3252 new_size = pool->shared_data[i].size * 2;
3253 pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3254 pool->shared_data[i].parameters,
3255 sizeof(*pool->shared_data[i].parameters) * new_size);
3257 pool->shared_data[i].size = new_size;
3260 param->shared_data = &pool->shared_data[i];
3261 pool->shared_data[i].parameters[new_count - 1] = param;
3263 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
3264 new_count);
3266 return D3D_OK;
3269 static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param)
3271 param->data = NULL;
3272 return FALSE;
3275 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param)
3277 unsigned int new_count;
3279 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
3280 return;
3281 new_count = --param->shared_data->count;
3283 TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
3285 if (new_count)
3287 unsigned int i;
3289 for (i = 0; i < new_count; ++i)
3291 if (param->shared_data->parameters[i] == param)
3293 memmove(&param->shared_data->parameters[i],
3294 &param->shared_data->parameters[i + 1],
3295 sizeof(param->shared_data->parameters[i]) * (new_count - i));
3296 break;
3299 walk_parameter_tree(&param->param, param_zero_data_func, NULL);
3301 else
3303 HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
3304 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
3305 param->shared_data->size = 0;
3306 param->shared_data = NULL;
3310 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
3312 return CONTAINING_RECORD(iface, struct d3dx_effect_pool, ID3DXEffectPool_iface);
3315 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
3317 return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
3320 /*** IUnknown methods ***/
3321 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
3323 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
3325 if (IsEqualGUID(riid, &IID_IUnknown) ||
3326 IsEqualGUID(riid, &IID_ID3DXEffect))
3328 iface->lpVtbl->AddRef(iface);
3329 *object = iface;
3330 return S_OK;
3333 ERR("Interface %s not found\n", debugstr_guid(riid));
3335 return E_NOINTERFACE;
3338 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
3340 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3342 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
3344 return InterlockedIncrement(&This->ref);
3347 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
3349 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3350 ULONG ref = InterlockedDecrement(&This->ref);
3352 TRACE("(%p)->(): Release from %u\n", This, ref + 1);
3354 if (!ref)
3356 free_effect(This);
3357 HeapFree(GetProcessHeap(), 0, This);
3360 return ref;
3363 /*** ID3DXBaseEffect methods ***/
3364 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
3366 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3368 TRACE("iface %p, desc %p.\n", iface, desc);
3370 return d3dx9_base_effect_get_desc(&effect->base_effect, desc);
3373 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface,
3374 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3376 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3378 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
3380 return d3dx9_base_effect_get_parameter_desc(&effect->base_effect, parameter, desc);
3383 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface,
3384 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3386 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3388 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
3390 return d3dx9_base_effect_get_technique_desc(&effect->base_effect, technique, desc);
3393 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3395 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3397 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
3399 return d3dx9_base_effect_get_pass_desc(&effect->base_effect, pass, desc);
3402 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3404 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3406 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
3408 return d3dx9_base_effect_get_function_desc(&effect->base_effect, shader, desc);
3411 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3413 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3415 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3417 return d3dx9_base_effect_get_parameter(&effect->base_effect, parameter, index);
3420 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface,
3421 D3DXHANDLE parameter, const char *name)
3423 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3425 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
3427 return d3dx9_base_effect_get_parameter_by_name(&effect->base_effect, parameter, name);
3430 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface,
3431 D3DXHANDLE parameter, const char *semantic)
3433 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3435 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
3437 return d3dx9_base_effect_get_parameter_by_semantic(&effect->base_effect, parameter, semantic);
3440 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3442 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3444 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3446 return d3dx9_base_effect_get_parameter_element(&effect->base_effect, parameter, index);
3449 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
3451 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3453 TRACE("iface %p, index %u.\n", iface, index);
3455 return d3dx9_base_effect_get_technique(&effect->base_effect, index);
3458 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, const char *name)
3460 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3462 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3464 return d3dx9_base_effect_get_technique_by_name(&effect->base_effect, name);
3467 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
3469 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3471 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
3473 return d3dx9_base_effect_get_pass(&effect->base_effect, technique, index);
3476 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface,
3477 D3DXHANDLE technique, const char *name)
3479 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3481 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
3483 return d3dx9_base_effect_get_pass_by_name(&effect->base_effect, technique, name);
3486 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
3488 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3490 TRACE("iface %p, index %u.\n", iface, index);
3492 return d3dx9_base_effect_get_function(&effect->base_effect, index);
3495 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, const char *name)
3497 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3499 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3501 return d3dx9_base_effect_get_function_by_name(&effect->base_effect, name);
3504 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
3506 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3508 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
3510 return d3dx9_base_effect_get_annotation(&effect->base_effect, object, index);
3513 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface,
3514 D3DXHANDLE object, const char *name)
3516 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3518 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
3520 return d3dx9_base_effect_get_annotation_by_name(&effect->base_effect, object, name);
3523 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface,
3524 D3DXHANDLE parameter, const void *data, UINT bytes)
3526 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3528 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3530 return d3dx9_base_effect_set_value(&effect->base_effect, parameter, data, bytes);
3533 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface,
3534 D3DXHANDLE parameter, void *data, UINT bytes)
3536 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3538 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3540 return d3dx9_base_effect_get_value(&effect->base_effect, parameter, data, bytes);
3543 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
3545 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3547 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
3549 return d3dx9_base_effect_set_bool(&effect->base_effect, parameter, b);
3552 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
3554 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3556 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
3558 return d3dx9_base_effect_get_bool(&effect->base_effect, parameter, b);
3561 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface,
3562 D3DXHANDLE parameter, const BOOL *b, UINT count)
3564 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3566 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3568 return d3dx9_base_effect_set_bool_array(&effect->base_effect, parameter, b, count);
3571 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface,
3572 D3DXHANDLE parameter, BOOL *b, UINT count)
3574 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3576 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3578 return d3dx9_base_effect_get_bool_array(&effect->base_effect, parameter, b, count);
3581 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
3583 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3585 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
3587 return d3dx9_base_effect_set_int(&effect->base_effect, parameter, n);
3590 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
3592 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3594 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
3596 return d3dx9_base_effect_get_int(&effect->base_effect, parameter, n);
3599 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface,
3600 D3DXHANDLE parameter, const INT *n, UINT count)
3602 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3604 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3606 return d3dx9_base_effect_set_int_array(&effect->base_effect, parameter, n, count);
3609 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface,
3610 D3DXHANDLE parameter, INT *n, UINT count)
3612 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3614 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3616 return d3dx9_base_effect_get_int_array(&effect->base_effect, parameter, n, count);
3619 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
3621 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3623 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
3625 return d3dx9_base_effect_set_float(&effect->base_effect, parameter, f);
3628 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
3630 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3632 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
3634 return d3dx9_base_effect_get_float(&effect->base_effect, parameter, f);
3637 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface,
3638 D3DXHANDLE parameter, const float *f, UINT count)
3640 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3642 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3644 return d3dx9_base_effect_set_float_array(&effect->base_effect, parameter, f, count);
3647 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface,
3648 D3DXHANDLE parameter, float *f, UINT count)
3650 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3652 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3654 return d3dx9_base_effect_get_float_array(&effect->base_effect, parameter, f, count);
3657 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface,
3658 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
3660 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3662 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3664 return d3dx9_base_effect_set_vector(&effect->base_effect, parameter, vector);
3667 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface,
3668 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3670 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3672 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3674 return d3dx9_base_effect_get_vector(&effect->base_effect, parameter, vector);
3677 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface,
3678 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
3680 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3682 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3684 return d3dx9_base_effect_set_vector_array(&effect->base_effect, parameter, vector, count);
3687 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface,
3688 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3690 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3692 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3694 return d3dx9_base_effect_get_vector_array(&effect->base_effect, parameter, vector, count);
3697 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface,
3698 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3700 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3702 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3704 return d3dx9_base_effect_set_matrix(&effect->base_effect, parameter, matrix);
3707 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface,
3708 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3710 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3712 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3714 return d3dx9_base_effect_get_matrix(&effect->base_effect, parameter, matrix);
3717 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface,
3718 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3720 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3722 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3724 return d3dx9_base_effect_set_matrix_array(&effect->base_effect, parameter, matrix, count);
3727 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface,
3728 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3730 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3732 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3734 return d3dx9_base_effect_get_matrix_array(&effect->base_effect, parameter, matrix, count);
3737 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface,
3738 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3740 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3742 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3744 return d3dx9_base_effect_set_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3747 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface,
3748 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3750 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3752 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3754 return d3dx9_base_effect_get_matrix_pointer_array(&effect->base_effect, parameter, matrix, count);
3757 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface,
3758 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3760 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3762 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3764 return d3dx9_base_effect_set_matrix_transpose(&effect->base_effect, parameter, matrix);
3767 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface,
3768 D3DXHANDLE parameter, D3DXMATRIX *matrix)
3770 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3772 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3774 return d3dx9_base_effect_get_matrix_transpose(&effect->base_effect, parameter, matrix);
3777 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface,
3778 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3780 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3782 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3784 return d3dx9_base_effect_set_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3787 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface,
3788 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3790 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3792 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3794 return d3dx9_base_effect_get_matrix_transpose_array(&effect->base_effect, parameter, matrix, count);
3797 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface,
3798 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3800 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3802 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3804 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3807 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface,
3808 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3810 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3812 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3814 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&effect->base_effect, parameter, matrix, count);
3817 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char *string)
3819 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3821 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
3823 return d3dx9_base_effect_set_string(&effect->base_effect, parameter, string);
3826 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char **string)
3828 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3830 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
3832 return d3dx9_base_effect_get_string(&effect->base_effect, parameter, string);
3835 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(struct ID3DXEffect *iface,
3836 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
3838 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3840 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3842 return d3dx9_base_effect_set_texture(&effect->base_effect, parameter, texture);
3845 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(struct ID3DXEffect *iface,
3846 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
3848 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3850 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3852 return d3dx9_base_effect_get_texture(&effect->base_effect, parameter, texture);
3855 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface,
3856 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
3858 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3860 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3862 return d3dx9_base_effect_get_pixel_shader(&effect->base_effect, parameter, shader);
3865 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(struct ID3DXEffect *iface,
3866 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
3868 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3870 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3872 return d3dx9_base_effect_get_vertex_shader(&effect->base_effect, parameter, shader);
3875 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3877 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3879 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
3881 return d3dx9_base_effect_set_array_range(&effect->base_effect, parameter, start, end);
3884 /*** ID3DXEffect methods ***/
3885 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, ID3DXEffectPool **pool)
3887 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3889 TRACE("iface %p, pool %p\n", This, pool);
3891 if (!pool)
3893 WARN("Invalid argument supplied.\n");
3894 return D3DERR_INVALIDCALL;
3897 if (This->pool)
3899 This->pool->lpVtbl->AddRef(This->pool);
3902 *pool = This->pool;
3904 TRACE("Returning pool %p\n", *pool);
3906 return S_OK;
3909 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3911 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3912 struct d3dx9_base_effect *base = &This->base_effect;
3913 struct d3dx_technique *tech = get_valid_technique(base, technique);
3915 TRACE("iface %p, technique %p\n", This, technique);
3917 if (tech)
3919 This->active_technique = tech;
3920 TRACE("Technique %p\n", tech);
3921 return D3D_OK;
3924 WARN("Technique not found.\n");
3926 return D3DERR_INVALIDCALL;
3929 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
3931 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3933 TRACE("iface %p\n", This);
3935 return get_technique_handle(This->active_technique);
3938 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
3940 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3942 FIXME("(%p)->(%p): stub\n", This, technique);
3944 return D3D_OK;
3947 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
3949 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3951 FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
3953 return E_NOTIMPL;
3956 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
3957 void *data);
3959 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func,
3960 void *data)
3962 struct d3dx_parameter **params;
3963 unsigned int i, param_count;
3965 if (!param_eval)
3966 return FALSE;
3968 params = param_eval->shader_inputs.inputs_param;
3969 param_count = param_eval->shader_inputs.input_count;
3970 for (i = 0; i < param_count; ++i)
3972 if (walk_parameter_dep(params[i], param_func, data))
3973 return TRUE;
3976 params = param_eval->pres.inputs.inputs_param;
3977 param_count = param_eval->pres.inputs.input_count;
3978 for (i = 0; i < param_count; ++i)
3980 if (walk_parameter_dep(params[i], param_func, data))
3981 return TRUE;
3983 return FALSE;
3986 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func,
3987 void *data)
3989 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type))
3991 if (walk_parameter_dep(&state->parameter, param_func, data))
3992 return TRUE;
3994 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER)
3996 if (walk_parameter_dep(state->referenced_param, param_func, data))
3997 return TRUE;
3999 return walk_param_eval_dep(state->parameter.param_eval, param_func, data);
4002 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
4003 void *data)
4005 unsigned int i;
4006 unsigned int member_count;
4008 param = &param->top_level_param->param;
4009 if (param_func(data, param))
4010 return TRUE;
4012 if (walk_param_eval_dep(param->param_eval, param_func, data))
4013 return TRUE;
4015 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
4017 struct d3dx_sampler *sampler;
4018 unsigned int sampler_idx;
4019 unsigned int samplers_count = max(param->element_count, 1);
4021 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx)
4023 sampler = param->element_count ? param->members[sampler_idx].data : param->data;
4024 for (i = 0; i < sampler->state_count; ++i)
4026 if (walk_state_dep(&sampler->states[i], param_func, data))
4027 return TRUE;
4030 return FALSE;
4033 member_count = param->element_count ? param->element_count : param->member_count;
4034 for (i = 0; i < member_count; ++i)
4036 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data))
4037 return TRUE;
4040 return FALSE;
4043 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech)
4045 unsigned int i, j;
4046 struct d3dx_pass *pass;
4048 if (!tech || !param)
4049 return FALSE;
4051 for (i = 0; i < tech->pass_count; ++i)
4053 pass = &tech->passes[i];
4054 for (j = 0; j < pass->state_count; ++j)
4056 if (walk_state_dep(&pass->states[j], is_same_parameter, param))
4057 return TRUE;
4060 return FALSE;
4063 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
4065 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4066 struct d3dx_parameter *param = get_valid_parameter(&effect->base_effect, parameter);
4067 struct d3dx_technique *tech = get_valid_technique(&effect->base_effect, technique);
4068 BOOL ret;
4070 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique);
4071 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech);
4073 ret = is_parameter_used(param, tech);
4074 TRACE("Returning %#x.\n", ret);
4075 return ret;
4078 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
4080 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4081 struct d3dx_technique *technique = effect->active_technique;
4083 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags);
4085 if (passes && technique)
4087 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE))
4088 WARN("Invalid flags (%#x) specified.\n", flags);
4090 if (flags & D3DXFX_DONOTSAVESTATE)
4092 TRACE("State capturing disabled.\n");
4094 else
4096 HRESULT hr;
4097 unsigned int i;
4099 if (!technique->saved_state)
4101 ID3DXEffectStateManager *manager;
4103 manager = effect->manager;
4104 effect->manager = NULL;
4105 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
4106 ERR("BeginStateBlock failed, hr %#x.\n", hr);
4107 for (i = 0; i < technique->pass_count; i++)
4108 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE);
4109 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
4110 ERR("EndStateBlock failed, hr %#x.\n", hr);
4111 effect->manager = manager;
4113 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
4114 ERR("StateBlock Capture failed, hr %#x.\n", hr);
4117 *passes = technique->pass_count;
4118 effect->started = TRUE;
4119 effect->begin_flags = flags;
4121 return D3D_OK;
4124 WARN("Invalid argument supplied.\n");
4126 return D3DERR_INVALIDCALL;
4129 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
4131 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4132 struct d3dx_technique *technique = effect->active_technique;
4134 TRACE("iface %p, pass %u\n", effect, pass);
4136 if (technique && pass < technique->pass_count && !effect->active_pass)
4138 HRESULT hr;
4140 memset(effect->current_light, 0, sizeof(effect->current_light));
4141 memset(&effect->current_material, 0, sizeof(effect->current_material));
4143 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE)))
4144 effect->active_pass = &technique->passes[pass];
4145 return hr;
4148 WARN("Invalid argument supplied.\n");
4150 return D3DERR_INVALIDCALL;
4153 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect *iface)
4155 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4157 TRACE("iface %p.\n", iface);
4159 if (!effect->active_pass)
4161 WARN("Called without an active pass.\n");
4162 return D3D_OK;
4164 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE);
4167 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
4169 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4171 TRACE("iface %p\n", This);
4173 if (This->active_pass)
4175 This->active_pass = NULL;
4176 return D3D_OK;
4179 WARN("Invalid call.\n");
4181 return D3DERR_INVALIDCALL;
4184 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect *iface)
4186 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
4187 struct d3dx_technique *technique = effect->active_technique;
4189 TRACE("iface %p.\n", iface);
4191 if (!effect->started)
4192 return D3D_OK;
4194 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE)
4196 TRACE("State restoring disabled.\n");
4198 else
4200 HRESULT hr;
4202 if (technique && technique->saved_state)
4204 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
4205 ERR("State block apply failed, hr %#x.\n", hr);
4207 else
4208 ERR("No saved state.\n");
4211 effect->started = FALSE;
4213 return D3D_OK;
4216 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device)
4218 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4220 TRACE("iface %p, device %p\n", This, device);
4222 if (!device)
4224 WARN("Invalid argument supplied.\n");
4225 return D3DERR_INVALIDCALL;
4228 IDirect3DDevice9_AddRef(This->device);
4230 *device = This->device;
4232 TRACE("Returning device %p\n", *device);
4234 return S_OK;
4237 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
4239 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4241 FIXME("(%p)->(): stub\n", This);
4243 return E_NOTIMPL;
4246 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
4248 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4250 FIXME("(%p)->(): stub\n", This);
4252 return E_NOTIMPL;
4255 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager)
4257 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4259 TRACE("iface %p, manager %p\n", This, manager);
4261 if (manager) IUnknown_AddRef(manager);
4262 if (This->manager) IUnknown_Release(This->manager);
4264 This->manager = manager;
4266 return D3D_OK;
4269 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager)
4271 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4273 TRACE("iface %p, manager %p\n", This, manager);
4275 if (!manager)
4277 WARN("Invalid argument supplied.\n");
4278 return D3DERR_INVALIDCALL;
4281 if (This->manager) IUnknown_AddRef(This->manager);
4282 *manager = This->manager;
4284 return D3D_OK;
4287 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
4289 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4291 FIXME("(%p)->(): stub\n", This);
4293 return E_NOTIMPL;
4296 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
4298 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4300 FIXME("(%p)->(): stub\n", This);
4302 return NULL;
4305 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4307 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4309 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4311 return E_NOTIMPL;
4314 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
4316 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4318 FIXME("(%p)->(%p): stub\n", This, parameter_block);
4320 return E_NOTIMPL;
4323 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
4324 struct IDirect3DDevice9 *device, struct ID3DXEffect **effect)
4326 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
4328 FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
4330 return E_NOTIMPL;
4333 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface,
4334 D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes)
4336 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4337 iface, parameter, data, byte_offset, bytes);
4339 return E_NOTIMPL;
4342 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
4344 /*** IUnknown methods ***/
4345 ID3DXEffectImpl_QueryInterface,
4346 ID3DXEffectImpl_AddRef,
4347 ID3DXEffectImpl_Release,
4348 /*** ID3DXBaseEffect methods ***/
4349 ID3DXEffectImpl_GetDesc,
4350 ID3DXEffectImpl_GetParameterDesc,
4351 ID3DXEffectImpl_GetTechniqueDesc,
4352 ID3DXEffectImpl_GetPassDesc,
4353 ID3DXEffectImpl_GetFunctionDesc,
4354 ID3DXEffectImpl_GetParameter,
4355 ID3DXEffectImpl_GetParameterByName,
4356 ID3DXEffectImpl_GetParameterBySemantic,
4357 ID3DXEffectImpl_GetParameterElement,
4358 ID3DXEffectImpl_GetTechnique,
4359 ID3DXEffectImpl_GetTechniqueByName,
4360 ID3DXEffectImpl_GetPass,
4361 ID3DXEffectImpl_GetPassByName,
4362 ID3DXEffectImpl_GetFunction,
4363 ID3DXEffectImpl_GetFunctionByName,
4364 ID3DXEffectImpl_GetAnnotation,
4365 ID3DXEffectImpl_GetAnnotationByName,
4366 ID3DXEffectImpl_SetValue,
4367 ID3DXEffectImpl_GetValue,
4368 ID3DXEffectImpl_SetBool,
4369 ID3DXEffectImpl_GetBool,
4370 ID3DXEffectImpl_SetBoolArray,
4371 ID3DXEffectImpl_GetBoolArray,
4372 ID3DXEffectImpl_SetInt,
4373 ID3DXEffectImpl_GetInt,
4374 ID3DXEffectImpl_SetIntArray,
4375 ID3DXEffectImpl_GetIntArray,
4376 ID3DXEffectImpl_SetFloat,
4377 ID3DXEffectImpl_GetFloat,
4378 ID3DXEffectImpl_SetFloatArray,
4379 ID3DXEffectImpl_GetFloatArray,
4380 ID3DXEffectImpl_SetVector,
4381 ID3DXEffectImpl_GetVector,
4382 ID3DXEffectImpl_SetVectorArray,
4383 ID3DXEffectImpl_GetVectorArray,
4384 ID3DXEffectImpl_SetMatrix,
4385 ID3DXEffectImpl_GetMatrix,
4386 ID3DXEffectImpl_SetMatrixArray,
4387 ID3DXEffectImpl_GetMatrixArray,
4388 ID3DXEffectImpl_SetMatrixPointerArray,
4389 ID3DXEffectImpl_GetMatrixPointerArray,
4390 ID3DXEffectImpl_SetMatrixTranspose,
4391 ID3DXEffectImpl_GetMatrixTranspose,
4392 ID3DXEffectImpl_SetMatrixTransposeArray,
4393 ID3DXEffectImpl_GetMatrixTransposeArray,
4394 ID3DXEffectImpl_SetMatrixTransposePointerArray,
4395 ID3DXEffectImpl_GetMatrixTransposePointerArray,
4396 ID3DXEffectImpl_SetString,
4397 ID3DXEffectImpl_GetString,
4398 ID3DXEffectImpl_SetTexture,
4399 ID3DXEffectImpl_GetTexture,
4400 ID3DXEffectImpl_GetPixelShader,
4401 ID3DXEffectImpl_GetVertexShader,
4402 ID3DXEffectImpl_SetArrayRange,
4403 /*** ID3DXEffect methods ***/
4404 ID3DXEffectImpl_GetPool,
4405 ID3DXEffectImpl_SetTechnique,
4406 ID3DXEffectImpl_GetCurrentTechnique,
4407 ID3DXEffectImpl_ValidateTechnique,
4408 ID3DXEffectImpl_FindNextValidTechnique,
4409 ID3DXEffectImpl_IsParameterUsed,
4410 ID3DXEffectImpl_Begin,
4411 ID3DXEffectImpl_BeginPass,
4412 ID3DXEffectImpl_CommitChanges,
4413 ID3DXEffectImpl_EndPass,
4414 ID3DXEffectImpl_End,
4415 ID3DXEffectImpl_GetDevice,
4416 ID3DXEffectImpl_OnLostDevice,
4417 ID3DXEffectImpl_OnResetDevice,
4418 ID3DXEffectImpl_SetStateManager,
4419 ID3DXEffectImpl_GetStateManager,
4420 ID3DXEffectImpl_BeginParameterBlock,
4421 ID3DXEffectImpl_EndParameterBlock,
4422 ID3DXEffectImpl_ApplyParameterBlock,
4423 ID3DXEffectImpl_DeleteParameterBlock,
4424 ID3DXEffectImpl_CloneEffect,
4425 ID3DXEffectImpl_SetRawValue
4428 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
4430 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
4433 /*** IUnknown methods ***/
4434 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
4436 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
4438 if (IsEqualGUID(riid, &IID_IUnknown) ||
4439 IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
4441 iface->lpVtbl->AddRef(iface);
4442 *object = iface;
4443 return S_OK;
4446 ERR("Interface %s not found\n", debugstr_guid(riid));
4448 return E_NOINTERFACE;
4451 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
4453 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4455 TRACE("iface %p: AddRef from %u\n", iface, This->ref);
4457 return InterlockedIncrement(&This->ref);
4460 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
4462 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4463 ULONG ref = InterlockedDecrement(&This->ref);
4465 TRACE("iface %p: Release from %u\n", iface, ref + 1);
4467 if (!ref)
4469 free_effect_compiler(This);
4470 HeapFree(GetProcessHeap(), 0, This);
4473 return ref;
4476 /*** ID3DXBaseEffect methods ***/
4477 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
4479 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4481 TRACE("iface %p, desc %p.\n", iface, desc);
4483 return d3dx9_base_effect_get_desc(&compiler->base_effect, desc);
4486 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface,
4487 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
4489 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4491 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
4493 return d3dx9_base_effect_get_parameter_desc(&compiler->base_effect, parameter, desc);
4496 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface,
4497 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
4499 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4501 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
4503 return d3dx9_base_effect_get_technique_desc(&compiler->base_effect, technique, desc);
4506 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface,
4507 D3DXHANDLE pass, D3DXPASS_DESC *desc)
4509 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4511 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
4513 return d3dx9_base_effect_get_pass_desc(&compiler->base_effect, pass, desc);
4516 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface,
4517 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
4519 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4521 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
4523 return d3dx9_base_effect_get_function_desc(&compiler->base_effect, shader, desc);
4526 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface,
4527 D3DXHANDLE parameter, UINT index)
4529 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4531 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
4533 return d3dx9_base_effect_get_parameter(&compiler->base_effect, parameter, index);
4536 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface,
4537 D3DXHANDLE parameter, const char *name)
4539 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4541 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
4543 return d3dx9_base_effect_get_parameter_by_name(&compiler->base_effect, parameter, name);
4546 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface,
4547 D3DXHANDLE parameter, const char *semantic)
4549 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4551 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
4553 return d3dx9_base_effect_get_parameter_by_semantic(&compiler->base_effect, parameter, semantic);
4556 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface,
4557 D3DXHANDLE parameter, UINT index)
4559 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4561 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
4563 return d3dx9_base_effect_get_parameter_element(&compiler->base_effect, parameter, index);
4566 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
4568 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4570 TRACE("iface %p, index %u.\n", iface, index);
4572 return d3dx9_base_effect_get_technique(&compiler->base_effect, index);
4575 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name)
4577 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4579 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
4581 return d3dx9_base_effect_get_technique_by_name(&compiler->base_effect, name);
4584 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
4586 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4588 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
4590 return d3dx9_base_effect_get_pass(&compiler->base_effect, technique, index);
4593 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface,
4594 D3DXHANDLE technique, const char *name)
4596 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4598 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
4600 return d3dx9_base_effect_get_pass_by_name(&compiler->base_effect, technique, name);
4603 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
4605 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4607 TRACE("iface %p, index %u.\n", iface, index);
4609 return d3dx9_base_effect_get_function(&compiler->base_effect, index);
4612 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name)
4614 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4616 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
4618 return d3dx9_base_effect_get_function_by_name(&compiler->base_effect, name);
4621 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface,
4622 D3DXHANDLE object, UINT index)
4624 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4626 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
4628 return d3dx9_base_effect_get_annotation(&compiler->base_effect, object, index);
4631 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface,
4632 D3DXHANDLE object, const char *name)
4634 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4636 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
4638 return d3dx9_base_effect_get_annotation_by_name(&compiler->base_effect, object, name);
4641 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface,
4642 D3DXHANDLE parameter, const void *data, UINT bytes)
4644 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4646 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
4648 return d3dx9_base_effect_set_value(&compiler->base_effect, parameter, data, bytes);
4651 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface,
4652 D3DXHANDLE parameter, void *data, UINT bytes)
4654 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4656 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
4658 return d3dx9_base_effect_get_value(&compiler->base_effect, parameter, data, bytes);
4661 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4663 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4665 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
4667 return d3dx9_base_effect_set_bool(&compiler->base_effect, parameter, b);
4670 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4672 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4674 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
4676 return d3dx9_base_effect_get_bool(&compiler->base_effect, parameter, b);
4679 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface,
4680 D3DXHANDLE parameter, const BOOL *b, UINT count)
4682 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4684 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
4686 return d3dx9_base_effect_set_bool_array(&compiler->base_effect, parameter, b, count);
4689 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface,
4690 D3DXHANDLE parameter, BOOL *b, UINT count)
4692 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4694 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
4696 return d3dx9_base_effect_get_bool_array(&compiler->base_effect, parameter, b, count);
4699 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4701 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4703 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
4705 return d3dx9_base_effect_set_int(&compiler->base_effect, parameter, n);
4708 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4710 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4712 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
4714 return d3dx9_base_effect_get_int(&compiler->base_effect, parameter, n);
4717 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface,
4718 D3DXHANDLE parameter, const INT *n, UINT count)
4720 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4722 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
4724 return d3dx9_base_effect_set_int_array(&compiler->base_effect, parameter, n, count);
4727 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface,
4728 D3DXHANDLE parameter, INT *n, UINT count)
4730 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4732 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
4734 return d3dx9_base_effect_get_int_array(&compiler->base_effect, parameter, n, count);
4737 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f)
4739 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4741 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
4743 return d3dx9_base_effect_set_float(&compiler->base_effect, parameter, f);
4746 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f)
4748 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4750 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
4752 return d3dx9_base_effect_get_float(&compiler->base_effect, parameter, f);
4755 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface,
4756 D3DXHANDLE parameter, const float *f, UINT count)
4758 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4760 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
4762 return d3dx9_base_effect_set_float_array(&compiler->base_effect, parameter, f, count);
4765 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface,
4766 D3DXHANDLE parameter, float *f, UINT count)
4768 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4770 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
4772 return d3dx9_base_effect_get_float_array(&compiler->base_effect, parameter, f, count);
4775 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface,
4776 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
4778 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4780 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
4782 return d3dx9_base_effect_set_vector(&compiler->base_effect, parameter, vector);
4785 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface,
4786 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4788 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4790 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
4792 return d3dx9_base_effect_get_vector(&compiler->base_effect, parameter, vector);
4795 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface,
4796 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
4798 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4800 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
4802 return d3dx9_base_effect_set_vector_array(&compiler->base_effect, parameter, vector, count);
4805 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface,
4806 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4808 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4810 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
4812 return d3dx9_base_effect_get_vector_array(&compiler->base_effect, parameter, vector, count);
4815 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface,
4816 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4818 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4820 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4822 return d3dx9_base_effect_set_matrix(&compiler->base_effect, parameter, matrix);
4825 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface,
4826 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4828 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4830 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4832 return d3dx9_base_effect_get_matrix(&compiler->base_effect, parameter, matrix);
4835 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface,
4836 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4838 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4840 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4842 return d3dx9_base_effect_set_matrix_array(&compiler->base_effect, parameter, matrix, count);
4845 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface,
4846 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4848 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4850 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4852 return d3dx9_base_effect_get_matrix_array(&compiler->base_effect, parameter, matrix, count);
4855 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface,
4856 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4858 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4860 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4862 return d3dx9_base_effect_set_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count);
4865 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface,
4866 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4868 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4870 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4872 return d3dx9_base_effect_get_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count);
4875 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface,
4876 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4878 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4880 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4882 return d3dx9_base_effect_set_matrix_transpose(&compiler->base_effect, parameter, matrix);
4885 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface,
4886 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4888 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4890 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
4892 return d3dx9_base_effect_get_matrix_transpose(&compiler->base_effect, parameter, matrix);
4895 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4896 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4898 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4900 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4902 return d3dx9_base_effect_set_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count);
4905 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4906 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4908 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4910 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4912 return d3dx9_base_effect_get_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count);
4915 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4916 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4918 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4920 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4922 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count);
4925 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4926 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4928 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4930 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
4932 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count);
4935 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface,
4936 D3DXHANDLE parameter, const char *string)
4938 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4940 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
4942 return d3dx9_base_effect_set_string(&compiler->base_effect, parameter, string);
4945 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface,
4946 D3DXHANDLE parameter, const char **string)
4948 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4950 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
4952 return d3dx9_base_effect_get_string(&compiler->base_effect, parameter, string);
4955 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
4956 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
4958 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4960 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
4962 return d3dx9_base_effect_set_texture(&compiler->base_effect, parameter, texture);
4965 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
4966 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
4968 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4970 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
4972 return d3dx9_base_effect_get_texture(&compiler->base_effect, parameter, texture);
4975 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
4976 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
4978 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4980 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
4982 return d3dx9_base_effect_get_pixel_shader(&compiler->base_effect, parameter, shader);
4985 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
4986 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
4988 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4990 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
4992 return d3dx9_base_effect_get_vertex_shader(&compiler->base_effect, parameter, shader);
4995 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface,
4996 D3DXHANDLE parameter, UINT start, UINT end)
4998 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
5000 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end);
5002 return d3dx9_base_effect_set_array_range(&compiler->base_effect, parameter, start, end);
5005 /*** ID3DXEffectCompiler methods ***/
5006 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
5008 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5010 FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
5012 return E_NOTIMPL;
5015 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
5017 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5019 FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
5021 return E_NOTIMPL;
5024 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
5025 ID3DXBuffer **effect, ID3DXBuffer **error_msgs)
5027 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5029 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
5031 return E_NOTIMPL;
5034 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
5035 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs,
5036 ID3DXConstantTable **constant_table)
5038 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
5040 FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
5041 This, function, target, flags, shader, error_msgs, constant_table);
5043 return E_NOTIMPL;
5046 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
5048 /*** IUnknown methods ***/
5049 ID3DXEffectCompilerImpl_QueryInterface,
5050 ID3DXEffectCompilerImpl_AddRef,
5051 ID3DXEffectCompilerImpl_Release,
5052 /*** ID3DXBaseEffect methods ***/
5053 ID3DXEffectCompilerImpl_GetDesc,
5054 ID3DXEffectCompilerImpl_GetParameterDesc,
5055 ID3DXEffectCompilerImpl_GetTechniqueDesc,
5056 ID3DXEffectCompilerImpl_GetPassDesc,
5057 ID3DXEffectCompilerImpl_GetFunctionDesc,
5058 ID3DXEffectCompilerImpl_GetParameter,
5059 ID3DXEffectCompilerImpl_GetParameterByName,
5060 ID3DXEffectCompilerImpl_GetParameterBySemantic,
5061 ID3DXEffectCompilerImpl_GetParameterElement,
5062 ID3DXEffectCompilerImpl_GetTechnique,
5063 ID3DXEffectCompilerImpl_GetTechniqueByName,
5064 ID3DXEffectCompilerImpl_GetPass,
5065 ID3DXEffectCompilerImpl_GetPassByName,
5066 ID3DXEffectCompilerImpl_GetFunction,
5067 ID3DXEffectCompilerImpl_GetFunctionByName,
5068 ID3DXEffectCompilerImpl_GetAnnotation,
5069 ID3DXEffectCompilerImpl_GetAnnotationByName,
5070 ID3DXEffectCompilerImpl_SetValue,
5071 ID3DXEffectCompilerImpl_GetValue,
5072 ID3DXEffectCompilerImpl_SetBool,
5073 ID3DXEffectCompilerImpl_GetBool,
5074 ID3DXEffectCompilerImpl_SetBoolArray,
5075 ID3DXEffectCompilerImpl_GetBoolArray,
5076 ID3DXEffectCompilerImpl_SetInt,
5077 ID3DXEffectCompilerImpl_GetInt,
5078 ID3DXEffectCompilerImpl_SetIntArray,
5079 ID3DXEffectCompilerImpl_GetIntArray,
5080 ID3DXEffectCompilerImpl_SetFloat,
5081 ID3DXEffectCompilerImpl_GetFloat,
5082 ID3DXEffectCompilerImpl_SetFloatArray,
5083 ID3DXEffectCompilerImpl_GetFloatArray,
5084 ID3DXEffectCompilerImpl_SetVector,
5085 ID3DXEffectCompilerImpl_GetVector,
5086 ID3DXEffectCompilerImpl_SetVectorArray,
5087 ID3DXEffectCompilerImpl_GetVectorArray,
5088 ID3DXEffectCompilerImpl_SetMatrix,
5089 ID3DXEffectCompilerImpl_GetMatrix,
5090 ID3DXEffectCompilerImpl_SetMatrixArray,
5091 ID3DXEffectCompilerImpl_GetMatrixArray,
5092 ID3DXEffectCompilerImpl_SetMatrixPointerArray,
5093 ID3DXEffectCompilerImpl_GetMatrixPointerArray,
5094 ID3DXEffectCompilerImpl_SetMatrixTranspose,
5095 ID3DXEffectCompilerImpl_GetMatrixTranspose,
5096 ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
5097 ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
5098 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
5099 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
5100 ID3DXEffectCompilerImpl_SetString,
5101 ID3DXEffectCompilerImpl_GetString,
5102 ID3DXEffectCompilerImpl_SetTexture,
5103 ID3DXEffectCompilerImpl_GetTexture,
5104 ID3DXEffectCompilerImpl_GetPixelShader,
5105 ID3DXEffectCompilerImpl_GetVertexShader,
5106 ID3DXEffectCompilerImpl_SetArrayRange,
5107 /*** ID3DXEffectCompiler methods ***/
5108 ID3DXEffectCompilerImpl_SetLiteral,
5109 ID3DXEffectCompilerImpl_GetLiteral,
5110 ID3DXEffectCompilerImpl_CompileEffect,
5111 ID3DXEffectCompilerImpl_CompileShader,
5114 static HRESULT d3dx9_parse_sampler(struct d3dx9_base_effect *base, struct d3dx_sampler *sampler,
5115 const char *data, const char **ptr, struct d3dx_object *objects)
5117 HRESULT hr;
5118 UINT i;
5120 read_dword(ptr, &sampler->state_count);
5121 TRACE("Count: %u\n", sampler->state_count);
5123 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count);
5124 if (!sampler->states)
5126 ERR("Out of memory\n");
5127 return E_OUTOFMEMORY;
5130 for (i = 0; i < sampler->state_count; ++i)
5132 hr = d3dx9_parse_state(base, &sampler->states[i], data, ptr, objects);
5133 if (hr != D3D_OK)
5135 WARN("Failed to parse state %u\n", i);
5136 goto err_out;
5140 return D3D_OK;
5142 err_out:
5144 for (i = 0; i < sampler->state_count; ++i)
5146 free_state(&sampler->states[i]);
5148 HeapFree(GetProcessHeap(), 0, sampler->states);
5149 sampler->states = NULL;
5151 return hr;
5154 static HRESULT d3dx9_parse_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5155 void *value, const char *data, const char **ptr, struct d3dx_object *objects)
5157 unsigned int i;
5158 HRESULT hr;
5159 UINT old_size = 0;
5161 if (param->element_count)
5163 param->data = value;
5165 for (i = 0; i < param->element_count; ++i)
5167 struct d3dx_parameter *member = &param->members[i];
5169 hr = d3dx9_parse_value(base, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
5170 if (hr != D3D_OK)
5172 WARN("Failed to parse value %u\n", i);
5173 return hr;
5176 old_size += member->bytes;
5179 return D3D_OK;
5182 switch(param->class)
5184 case D3DXPC_SCALAR:
5185 case D3DXPC_VECTOR:
5186 case D3DXPC_MATRIX_ROWS:
5187 case D3DXPC_MATRIX_COLUMNS:
5188 param->data = value;
5189 break;
5191 case D3DXPC_STRUCT:
5192 param->data = value;
5194 for (i = 0; i < param->member_count; ++i)
5196 struct d3dx_parameter *member = &param->members[i];
5198 hr = d3dx9_parse_value(base, member, (char *)value + old_size, data, ptr, objects);
5199 if (hr != D3D_OK)
5201 WARN("Failed to parse value %u\n", i);
5202 return hr;
5205 old_size += member->bytes;
5207 break;
5209 case D3DXPC_OBJECT:
5210 switch (param->type)
5212 case D3DXPT_STRING:
5213 case D3DXPT_TEXTURE:
5214 case D3DXPT_TEXTURE1D:
5215 case D3DXPT_TEXTURE2D:
5216 case D3DXPT_TEXTURE3D:
5217 case D3DXPT_TEXTURECUBE:
5218 case D3DXPT_PIXELSHADER:
5219 case D3DXPT_VERTEXSHADER:
5220 read_dword(ptr, &param->object_id);
5221 TRACE("Id: %u\n", param->object_id);
5222 objects[param->object_id].param = param;
5223 param->data = value;
5224 break;
5226 case D3DXPT_SAMPLER:
5227 case D3DXPT_SAMPLER1D:
5228 case D3DXPT_SAMPLER2D:
5229 case D3DXPT_SAMPLER3D:
5230 case D3DXPT_SAMPLERCUBE:
5232 struct d3dx_sampler *sampler;
5234 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
5235 if (!sampler)
5236 return E_OUTOFMEMORY;
5238 hr = d3dx9_parse_sampler(base, sampler, data, ptr, objects);
5239 if (hr != D3D_OK)
5241 HeapFree(GetProcessHeap(), 0, sampler);
5242 WARN("Failed to parse sampler\n");
5243 return hr;
5246 param->data = sampler;
5247 break;
5250 default:
5251 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5252 break;
5254 break;
5256 default:
5257 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5258 break;
5261 return D3D_OK;
5264 static HRESULT d3dx9_parse_init_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5265 const char *data, const char *ptr, struct d3dx_object *objects)
5267 UINT size = param->bytes;
5268 HRESULT hr;
5269 void *value = NULL;
5271 TRACE("param size: %u\n", size);
5273 if (size)
5275 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5276 if (!value)
5278 ERR("Failed to allocate data memory.\n");
5279 return E_OUTOFMEMORY;
5282 switch(param->class)
5284 case D3DXPC_OBJECT:
5285 break;
5287 case D3DXPC_SCALAR:
5288 case D3DXPC_VECTOR:
5289 case D3DXPC_MATRIX_ROWS:
5290 case D3DXPC_MATRIX_COLUMNS:
5291 case D3DXPC_STRUCT:
5292 TRACE("Data: %s.\n", debugstr_an(ptr, size));
5293 memcpy(value, ptr, size);
5294 break;
5296 default:
5297 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5298 break;
5302 hr = d3dx9_parse_value(base, param, value, data, &ptr, objects);
5303 if (hr != D3D_OK)
5305 WARN("Failed to parse value\n");
5306 HeapFree(GetProcessHeap(), 0, value);
5307 return hr;
5310 return D3D_OK;
5313 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
5315 DWORD size;
5317 read_dword(&ptr, &size);
5318 TRACE("Name size: %#x\n", size);
5320 if (!size)
5322 return D3D_OK;
5325 *name = HeapAlloc(GetProcessHeap(), 0, size);
5326 if (!*name)
5328 ERR("Failed to allocate name memory.\n");
5329 return E_OUTOFMEMORY;
5332 TRACE("Name: %s.\n", debugstr_an(ptr, size));
5333 memcpy(*name, ptr, size);
5335 return D3D_OK;
5338 static HRESULT d3dx9_copy_data(struct d3dx9_base_effect *base, unsigned int object_id, const char **ptr)
5340 struct d3dx_object *object = &base->objects[object_id];
5342 if (object->size || object->data)
5344 if (object_id)
5345 FIXME("Overwriting object id %u!\n", object_id);
5346 else
5347 TRACE("Overwriting object id 0.\n");
5349 HeapFree(GetProcessHeap(), 0, object->data);
5350 object->data = NULL;
5353 read_dword(ptr, &object->size);
5354 TRACE("Data size: %#x.\n", object->size);
5356 if (!object->size)
5357 return D3D_OK;
5359 object->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5360 if (!object->data)
5362 ERR("Failed to allocate object memory.\n");
5363 return E_OUTOFMEMORY;
5366 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size));
5367 memcpy(object->data, *ptr, object->size);
5369 *ptr += ((object->size + 3) & ~3);
5371 return D3D_OK;
5374 static void param_set_magic_number(struct d3dx_parameter *param)
5376 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string));
5379 static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct d3dx_parameter *param,
5380 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
5382 DWORD offset;
5383 HRESULT hr;
5384 UINT i;
5386 param->flags = flags;
5388 if (!parent)
5390 read_dword(ptr, (DWORD *)&param->type);
5391 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
5393 read_dword(ptr, (DWORD *)&param->class);
5394 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
5396 read_dword(ptr, &offset);
5397 TRACE("Type name offset: %#x\n", offset);
5398 hr = d3dx9_parse_name(&param->name, data + offset);
5399 if (hr != D3D_OK)
5401 WARN("Failed to parse name\n");
5402 goto err_out;
5405 read_dword(ptr, &offset);
5406 TRACE("Type semantic offset: %#x\n", offset);
5407 hr = d3dx9_parse_name(&param->semantic, data + offset);
5408 if (hr != D3D_OK)
5410 WARN("Failed to parse semantic\n");
5411 goto err_out;
5414 read_dword(ptr, &param->element_count);
5415 TRACE("Elements: %u\n", param->element_count);
5417 switch (param->class)
5419 case D3DXPC_VECTOR:
5420 read_dword(ptr, &param->columns);
5421 TRACE("Columns: %u\n", param->columns);
5423 read_dword(ptr, &param->rows);
5424 TRACE("Rows: %u\n", param->rows);
5426 /* sizeof(DWORD) * rows * columns */
5427 param->bytes = 4 * param->rows * param->columns;
5428 break;
5430 case D3DXPC_SCALAR:
5431 case D3DXPC_MATRIX_ROWS:
5432 case D3DXPC_MATRIX_COLUMNS:
5433 read_dword(ptr, &param->rows);
5434 TRACE("Rows: %u\n", param->rows);
5436 read_dword(ptr, &param->columns);
5437 TRACE("Columns: %u\n", param->columns);
5439 /* sizeof(DWORD) * rows * columns */
5440 param->bytes = 4 * param->rows * param->columns;
5441 break;
5443 case D3DXPC_STRUCT:
5444 read_dword(ptr, &param->member_count);
5445 TRACE("Members: %u\n", param->member_count);
5446 break;
5448 case D3DXPC_OBJECT:
5449 switch (param->type)
5451 case D3DXPT_STRING:
5452 case D3DXPT_PIXELSHADER:
5453 case D3DXPT_VERTEXSHADER:
5454 case D3DXPT_TEXTURE:
5455 case D3DXPT_TEXTURE1D:
5456 case D3DXPT_TEXTURE2D:
5457 case D3DXPT_TEXTURE3D:
5458 case D3DXPT_TEXTURECUBE:
5459 param->bytes = sizeof(void *);
5460 break;
5462 case D3DXPT_SAMPLER:
5463 case D3DXPT_SAMPLER1D:
5464 case D3DXPT_SAMPLER2D:
5465 case D3DXPT_SAMPLER3D:
5466 case D3DXPT_SAMPLERCUBE:
5467 param->bytes = 0;
5468 break;
5470 default:
5471 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5472 break;
5474 break;
5476 default:
5477 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5478 break;
5481 else
5483 /* elements */
5484 param->type = parent->type;
5485 param->class = parent->class;
5486 param->name = parent->name;
5487 param->semantic = parent->semantic;
5488 param->element_count = 0;
5489 param->member_count = parent->member_count;
5490 param->bytes = parent->bytes;
5491 param->rows = parent->rows;
5492 param->columns = parent->columns;
5495 if (param->element_count)
5497 unsigned int param_bytes = 0;
5498 const char *save_ptr = *ptr;
5500 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count);
5501 if (!param->members)
5503 ERR("Out of memory\n");
5504 hr = E_OUTOFMEMORY;
5505 goto err_out;
5508 for (i = 0; i < param->element_count; ++i)
5510 *ptr = save_ptr;
5512 param_set_magic_number(&param->members[i]);
5513 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, param, flags);
5514 if (hr != D3D_OK)
5516 WARN("Failed to parse member %u\n", i);
5517 goto err_out;
5520 param_bytes += param->members[i].bytes;
5523 param->bytes = param_bytes;
5525 else if (param->member_count)
5527 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count);
5528 if (!param->members)
5530 ERR("Out of memory\n");
5531 hr = E_OUTOFMEMORY;
5532 goto err_out;
5535 for (i = 0; i < param->member_count; ++i)
5537 param_set_magic_number(&param->members[i]);
5538 hr = d3dx9_parse_effect_typedef(base, &param->members[i], data, ptr, NULL, flags);
5539 if (hr != D3D_OK)
5541 WARN("Failed to parse member %u\n", i);
5542 goto err_out;
5545 param->bytes += param->members[i].bytes;
5548 return D3D_OK;
5550 err_out:
5552 if (param->members)
5554 unsigned int count = param->element_count ? param->element_count : param->member_count;
5556 for (i = 0; i < count; ++i)
5557 free_parameter(&param->members[i], param->element_count != 0, TRUE);
5558 HeapFree(GetProcessHeap(), 0, param->members);
5559 param->members = NULL;
5562 if (!parent)
5564 HeapFree(GetProcessHeap(), 0, param->name);
5565 HeapFree(GetProcessHeap(), 0, param->semantic);
5567 param->name = NULL;
5568 param->semantic = NULL;
5570 return hr;
5573 static HRESULT d3dx9_parse_effect_annotation(struct d3dx9_base_effect *base, struct d3dx_parameter *anno,
5574 const char *data, const char **ptr, struct d3dx_object *objects)
5576 DWORD offset;
5577 const char *ptr2;
5578 HRESULT hr;
5580 anno->flags = D3DX_PARAMETER_ANNOTATION;
5582 read_dword(ptr, &offset);
5583 TRACE("Typedef offset: %#x\n", offset);
5584 ptr2 = data + offset;
5585 hr = d3dx9_parse_effect_typedef(base, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5586 if (hr != D3D_OK)
5588 WARN("Failed to parse type definition\n");
5589 return hr;
5592 read_dword(ptr, &offset);
5593 TRACE("Value offset: %#x\n", offset);
5594 hr = d3dx9_parse_init_value(base, anno, data, data + offset, objects);
5595 if (hr != D3D_OK)
5597 WARN("Failed to parse value\n");
5598 return hr;
5601 return D3D_OK;
5604 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
5605 const char *data, const char **ptr, struct d3dx_object *objects)
5607 DWORD offset;
5608 const char *ptr2;
5609 HRESULT hr;
5611 state->type = ST_CONSTANT;
5613 read_dword(ptr, &state->operation);
5614 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5616 read_dword(ptr, &state->index);
5617 TRACE("Index: %#x\n", state->index);
5619 read_dword(ptr, &offset);
5620 TRACE("Typedef offset: %#x\n", offset);
5621 ptr2 = data + offset;
5622 hr = d3dx9_parse_effect_typedef(base, &state->parameter, data, &ptr2, NULL, 0);
5623 if (hr != D3D_OK)
5625 WARN("Failed to parse type definition\n");
5626 goto err_out;
5629 read_dword(ptr, &offset);
5630 TRACE("Value offset: %#x\n", offset);
5631 hr = d3dx9_parse_init_value(base, &state->parameter, data, data + offset, objects);
5632 if (hr != D3D_OK)
5634 WARN("Failed to parse value\n");
5635 goto err_out;
5638 return D3D_OK;
5640 err_out:
5642 free_parameter(&state->parameter, FALSE, FALSE);
5644 return hr;
5647 static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_top_level_parameter *param,
5648 const char *data, const char **ptr, struct d3dx_object *objects)
5650 DWORD offset;
5651 HRESULT hr;
5652 unsigned int i;
5653 const char *ptr2;
5655 read_dword(ptr, &offset);
5656 TRACE("Typedef offset: %#x.\n", offset);
5657 ptr2 = data + offset;
5659 read_dword(ptr, &offset);
5660 TRACE("Value offset: %#x.\n", offset);
5662 read_dword(ptr, &param->param.flags);
5663 TRACE("Flags: %#x.\n", param->param.flags);
5665 read_dword(ptr, &param->annotation_count);
5666 TRACE("Annotation count: %u.\n", param->annotation_count);
5668 hr = d3dx9_parse_effect_typedef(base, &param->param, data, &ptr2, NULL, param->param.flags);
5669 if (hr != D3D_OK)
5671 WARN("Failed to parse type definition.\n");
5672 return hr;
5675 hr = d3dx9_parse_init_value(base, &param->param, data, data + offset, objects);
5676 if (hr != D3D_OK)
5678 WARN("Failed to parse value.\n");
5679 return hr;
5682 if (param->annotation_count)
5684 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5685 sizeof(*param->annotations) * param->annotation_count);
5686 if (!param->annotations)
5688 ERR("Out of memory.\n");
5689 hr = E_OUTOFMEMORY;
5690 goto err_out;
5693 for (i = 0; i < param->annotation_count; ++i)
5695 param_set_magic_number(&param->annotations[i]);
5696 hr = d3dx9_parse_effect_annotation(base, &param->annotations[i], data, ptr, objects);
5697 if (hr != D3D_OK)
5699 WARN("Failed to parse annotation.\n");
5700 goto err_out;
5705 return D3D_OK;
5707 err_out:
5709 if (param->annotations)
5711 for (i = 0; i < param->annotation_count; ++i)
5712 free_parameter(&param->annotations[i], FALSE, FALSE);
5713 HeapFree(GetProcessHeap(), 0, param->annotations);
5714 param->annotations = NULL;
5717 return hr;
5720 static HRESULT d3dx9_parse_effect_pass(struct d3dx9_base_effect *base, struct d3dx_pass *pass,
5721 const char *data, const char **ptr, struct d3dx_object *objects)
5723 DWORD offset;
5724 HRESULT hr;
5725 unsigned int i;
5726 struct d3dx_state *states = NULL;
5727 char *name = NULL;
5729 read_dword(ptr, &offset);
5730 TRACE("Pass name offset: %#x\n", offset);
5731 hr = d3dx9_parse_name(&name, data + offset);
5732 if (hr != D3D_OK)
5734 WARN("Failed to parse name\n");
5735 goto err_out;
5738 read_dword(ptr, &pass->annotation_count);
5739 TRACE("Annotation count: %u\n", pass->annotation_count);
5741 read_dword(ptr, &pass->state_count);
5742 TRACE("State count: %u\n", pass->state_count);
5744 if (pass->annotation_count)
5746 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5747 sizeof(*pass->annotations) * pass->annotation_count);
5748 if (!pass->annotations)
5750 ERR("Out of memory\n");
5751 hr = E_OUTOFMEMORY;
5752 goto err_out;
5755 for (i = 0; i < pass->annotation_count; ++i)
5757 param_set_magic_number(&pass->annotations[i]);
5758 hr = d3dx9_parse_effect_annotation(base, &pass->annotations[i], data, ptr, objects);
5759 if (hr != D3D_OK)
5761 WARN("Failed to parse annotation %u\n", i);
5762 goto err_out;
5767 if (pass->state_count)
5769 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5770 if (!states)
5772 ERR("Out of memory\n");
5773 hr = E_OUTOFMEMORY;
5774 goto err_out;
5777 for (i = 0; i < pass->state_count; ++i)
5779 hr = d3dx9_parse_state(base, &states[i], data, ptr, objects);
5780 if (hr != D3D_OK)
5782 WARN("Failed to parse annotation %u\n", i);
5783 goto err_out;
5788 pass->name = name;
5789 pass->states = states;
5791 return D3D_OK;
5793 err_out:
5795 if (pass->annotations)
5797 for (i = 0; i < pass->annotation_count; ++i)
5798 free_parameter(&pass->annotations[i], FALSE, FALSE);
5799 HeapFree(GetProcessHeap(), 0, pass->annotations);
5800 pass->annotations = NULL;
5803 if (states)
5805 for (i = 0; i < pass->state_count; ++i)
5807 free_state(&states[i]);
5809 HeapFree(GetProcessHeap(), 0, states);
5812 HeapFree(GetProcessHeap(), 0, name);
5814 return hr;
5817 static HRESULT d3dx9_parse_effect_technique(struct d3dx9_base_effect *base, struct d3dx_technique *technique,
5818 const char *data, const char **ptr, struct d3dx_object *objects)
5820 DWORD offset;
5821 HRESULT hr;
5822 unsigned int i;
5823 char *name = NULL;
5825 read_dword(ptr, &offset);
5826 TRACE("Technique name offset: %#x\n", offset);
5827 hr = d3dx9_parse_name(&name, data + offset);
5828 if (hr != D3D_OK)
5830 WARN("Failed to parse name\n");
5831 goto err_out;
5834 read_dword(ptr, &technique->annotation_count);
5835 TRACE("Annotation count: %u\n", technique->annotation_count);
5837 read_dword(ptr, &technique->pass_count);
5838 TRACE("Pass count: %u\n", technique->pass_count);
5840 if (technique->annotation_count)
5842 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5843 sizeof(*technique->annotations) * technique->annotation_count);
5844 if (!technique->annotations)
5846 ERR("Out of memory\n");
5847 hr = E_OUTOFMEMORY;
5848 goto err_out;
5851 for (i = 0; i < technique->annotation_count; ++i)
5853 param_set_magic_number(&technique->annotations[i]);
5854 hr = d3dx9_parse_effect_annotation(base, &technique->annotations[i], data, ptr, objects);
5855 if (hr != D3D_OK)
5857 WARN("Failed to parse annotation %u\n", i);
5858 goto err_out;
5863 if (technique->pass_count)
5865 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5866 sizeof(*technique->passes) * technique->pass_count);
5867 if (!technique->passes)
5869 ERR("Out of memory\n");
5870 hr = E_OUTOFMEMORY;
5871 goto err_out;
5874 for (i = 0; i < technique->pass_count; ++i)
5876 hr = d3dx9_parse_effect_pass(base, &technique->passes[i], data, ptr, objects);
5877 if (hr != D3D_OK)
5879 WARN("Failed to parse pass %u\n", i);
5880 goto err_out;
5885 technique->name = name;
5887 return D3D_OK;
5889 err_out:
5891 if (technique->passes)
5893 for (i = 0; i < technique->pass_count; ++i)
5894 free_pass(&technique->passes[i]);
5895 HeapFree(GetProcessHeap(), 0, technique->passes);
5896 technique->passes = NULL;
5899 if (technique->annotations)
5901 for (i = 0; i < technique->annotation_count; ++i)
5902 free_parameter(&technique->annotations[i], FALSE, FALSE);
5903 HeapFree(GetProcessHeap(), 0, technique->annotations);
5904 technique->annotations = NULL;
5907 HeapFree(GetProcessHeap(), 0, name);
5909 return hr;
5912 static HRESULT d3dx9_create_object(struct d3dx9_base_effect *base, struct d3dx_object *object)
5914 struct d3dx_parameter *param = object->param;
5915 struct IDirect3DDevice9 *device = base->effect->device;
5916 HRESULT hr;
5918 if (*(char **)param->data)
5919 ERR("Parameter data already allocated.\n");
5921 switch (param->type)
5923 case D3DXPT_STRING:
5924 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5925 if (!*(char **)param->data)
5927 ERR("Out of memory.\n");
5928 return E_OUTOFMEMORY;
5930 memcpy(*(char **)param->data, object->data, object->size);
5931 break;
5932 case D3DXPT_VERTEXSHADER:
5933 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data,
5934 (IDirect3DVertexShader9 **)param->data)))
5936 WARN("Failed to create vertex shader.\n");
5937 return hr;
5939 break;
5940 case D3DXPT_PIXELSHADER:
5941 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data,
5942 (IDirect3DPixelShader9 **)param->data)))
5944 WARN("Failed to create pixel shader.\n");
5945 return hr;
5947 break;
5948 default:
5949 break;
5951 return D3D_OK;
5954 static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct d3dx_state *state,
5955 const char **skip_constants, unsigned int skip_constants_count)
5957 DWORD string_size;
5958 struct d3dx_parameter *param = &state->parameter;
5959 struct d3dx_object *object = &base->objects[param->object_id];
5960 char *ptr = object->data;
5961 HRESULT ret;
5963 TRACE("Parsing array entry selection state for parameter %p.\n", param);
5965 string_size = *(DWORD *)ptr;
5966 state->referenced_param = get_parameter_by_name(base, NULL, ptr + 4);
5967 if (state->referenced_param)
5969 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
5971 else
5973 FIXME("Referenced parameter %s not found.\n", ptr + 4);
5974 return D3DXERR_INVALIDDATA;
5976 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
5978 if (string_size % sizeof(DWORD))
5979 FIXME("Unaligned string_size %u.\n", string_size);
5980 if (FAILED(ret = d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1,
5981 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, &param->param_eval,
5982 get_version_counter_ptr(base), NULL, 0)))
5983 return ret;
5984 ret = D3D_OK;
5985 param = state->referenced_param;
5986 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
5988 unsigned int i;
5990 for (i = 0; i < param->element_count; i++)
5992 if (param->members[i].type != param->type)
5994 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
5995 return D3DXERR_INVALIDDATA;
5997 if (!param->members[i].param_eval)
5999 TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
6000 object = &base->objects[param->members[i].object_id];
6001 if (FAILED(ret = d3dx_create_param_eval(base, object->data, object->size, param->type,
6002 &param->members[i].param_eval, get_version_counter_ptr(base),
6003 skip_constants, skip_constants_count)))
6004 break;
6008 return ret;
6011 static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr,
6012 const char **skip_constants, unsigned int skip_constants_count)
6014 DWORD technique_index;
6015 DWORD index, state_index, usage, element_index;
6016 struct d3dx_state *state;
6017 struct d3dx_parameter *param;
6018 struct d3dx_object *object;
6019 HRESULT hr = E_FAIL;
6021 read_dword(ptr, &technique_index);
6022 TRACE("technique_index: %u\n", technique_index);
6024 read_dword(ptr, &index);
6025 TRACE("index: %u\n", index);
6027 read_dword(ptr, &element_index);
6028 TRACE("element_index: %u\n", element_index);
6030 read_dword(ptr, &state_index);
6031 TRACE("state_index: %u\n", state_index);
6033 read_dword(ptr, &usage);
6034 TRACE("usage: %u\n", usage);
6036 if (technique_index == 0xffffffff)
6038 struct d3dx_parameter *parameter;
6039 struct d3dx_sampler *sampler;
6041 if (index >= base->parameter_count)
6043 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
6044 return E_FAIL;
6047 parameter = &base->parameters[index].param;
6048 if (element_index != 0xffffffff)
6050 if (element_index >= parameter->element_count && parameter->element_count != 0)
6052 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
6053 return E_FAIL;
6056 if (parameter->element_count)
6057 parameter = &parameter->members[element_index];
6060 sampler = parameter->data;
6061 if (state_index >= sampler->state_count)
6063 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
6064 return E_FAIL;
6067 state = &sampler->states[state_index];
6069 else
6071 struct d3dx_technique *technique;
6072 struct d3dx_pass *pass;
6074 if (technique_index >= base->technique_count)
6076 FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
6077 return E_FAIL;
6080 technique = &base->techniques[technique_index];
6081 if (index >= technique->pass_count)
6083 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
6084 return E_FAIL;
6087 pass = &technique->passes[index];
6088 if (state_index >= pass->state_count)
6090 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
6091 return E_FAIL;
6094 state = &pass->states[state_index];
6097 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name);
6098 param = &state->parameter;
6099 TRACE("Using object id %u.\n", param->object_id);
6100 object = &base->objects[param->object_id];
6102 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class),
6103 debug_d3dxparameter_type(param->type));
6104 switch (usage)
6106 case 0:
6107 switch (param->type)
6109 case D3DXPT_VERTEXSHADER:
6110 case D3DXPT_PIXELSHADER:
6111 state->type = ST_CONSTANT;
6112 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6113 return hr;
6115 if (object->data)
6117 if (FAILED(hr = d3dx9_create_object(base, object)))
6118 return hr;
6119 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6120 &param->param_eval, get_version_counter_ptr(base),
6121 skip_constants, skip_constants_count)))
6122 return hr;
6124 break;
6126 case D3DXPT_BOOL:
6127 case D3DXPT_INT:
6128 case D3DXPT_FLOAT:
6129 case D3DXPT_STRING:
6130 state->type = ST_FXLC;
6131 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6132 return hr;
6133 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type,
6134 &param->param_eval, get_version_counter_ptr(base), NULL, 0)))
6135 return hr;
6136 break;
6138 default:
6139 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
6140 break;
6142 break;
6144 case 1:
6145 state->type = ST_PARAMETER;
6146 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6147 return hr;
6149 TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
6150 state->referenced_param = get_parameter_by_name(base, NULL, object->data);
6151 if (state->referenced_param)
6153 struct d3dx_parameter *refpar = state->referenced_param;
6155 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
6156 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
6158 struct d3dx_object *refobj = &base->objects[refpar->object_id];
6160 if (!refpar->param_eval)
6162 if (FAILED(hr = d3dx_create_param_eval(base, refobj->data, refobj->size,
6163 refpar->type, &refpar->param_eval, get_version_counter_ptr(base),
6164 skip_constants, skip_constants_count)))
6165 return hr;
6169 else
6171 FIXME("Referenced parameter %s not found.\n", (char *)object->data);
6172 return D3DXERR_INVALIDDATA;
6174 break;
6176 case 2:
6177 state->type = ST_ARRAY_SELECTOR;
6178 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr)))
6179 return hr;
6180 hr = d3dx9_parse_array_selector(base, state, skip_constants, skip_constants_count);
6181 break;
6183 default:
6184 FIXME("Unknown usage %x\n", usage);
6185 break;
6188 return hr;
6191 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param)
6193 param->top_level_param = top_level_param;
6194 return FALSE;
6197 static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *data, UINT data_size,
6198 DWORD start, const char **skip_constants, unsigned int skip_constants_count)
6200 const char *ptr = data + start;
6201 UINT stringcount, resourcecount;
6202 HRESULT hr;
6203 UINT i;
6205 read_dword(&ptr, &base->parameter_count);
6206 TRACE("Parameter count: %u.\n", base->parameter_count);
6208 read_dword(&ptr, &base->technique_count);
6209 TRACE("Technique count: %u.\n", base->technique_count);
6211 skip_dword_unknown(&ptr, 1);
6213 read_dword(&ptr, &base->object_count);
6214 TRACE("Object count: %u.\n", base->object_count);
6216 base->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base->objects) * base->object_count);
6217 if (!base->objects)
6219 ERR("Out of memory.\n");
6220 hr = E_OUTOFMEMORY;
6221 goto err_out;
6224 if (base->parameter_count)
6226 base->parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6227 sizeof(*base->parameters) * base->parameter_count);
6228 if (!base->parameters)
6230 ERR("Out of memory.\n");
6231 hr = E_OUTOFMEMORY;
6232 goto err_out;
6235 for (i = 0; i < base->parameter_count; ++i)
6237 param_set_magic_number(&base->parameters[i].param);
6238 hr = d3dx9_parse_effect_parameter(base, &base->parameters[i], data, &ptr, base->objects);
6239 if (hr != D3D_OK)
6241 WARN("Failed to parse parameter %u.\n", i);
6242 goto err_out;
6244 walk_parameter_tree(&base->parameters[i].param, param_set_top_level_param,
6245 &base->parameters[i]);
6249 if (base->technique_count)
6251 base->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6252 sizeof(*base->techniques) * base->technique_count);
6253 if (!base->techniques)
6255 ERR("Out of memory.\n");
6256 hr = E_OUTOFMEMORY;
6257 goto err_out;
6260 for (i = 0; i < base->technique_count; ++i)
6262 TRACE("Parsing technique %u.\n", i);
6263 hr = d3dx9_parse_effect_technique(base, &base->techniques[i], data, &ptr, base->objects);
6264 if (hr != D3D_OK)
6266 WARN("Failed to parse technique %u.\n", i);
6267 goto err_out;
6272 read_dword(&ptr, &stringcount);
6273 TRACE("String count: %u.\n", stringcount);
6275 read_dword(&ptr, &resourcecount);
6276 TRACE("Resource count: %u.\n", resourcecount);
6278 for (i = 0; i < stringcount; ++i)
6280 DWORD id;
6282 read_dword(&ptr, &id);
6283 TRACE("id: %u.\n", id);
6285 if (FAILED(hr = d3dx9_copy_data(base, id, &ptr)))
6286 goto err_out;
6288 if (base->objects[id].data)
6290 if (FAILED(hr = d3dx9_create_object(base, &base->objects[id])))
6291 goto err_out;
6295 for (i = 0; i < resourcecount; ++i)
6297 TRACE("parse resource %u.\n", i);
6299 hr = d3dx9_parse_resource(base, data, &ptr, skip_constants, skip_constants_count);
6300 if (hr != D3D_OK)
6302 WARN("Failed to parse resource %u.\n", i);
6303 goto err_out;
6307 for (i = 0; i < base->parameter_count; ++i)
6309 if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i])))
6310 goto err_out;
6311 base->parameters[i].version_counter = base->pool
6312 ? &base->pool->version_counter
6313 : &base->version_counter;
6314 set_dirty(&base->parameters[i].param);
6316 return D3D_OK;
6318 err_out:
6320 if (base->techniques)
6322 for (i = 0; i < base->technique_count; ++i)
6323 free_technique(&base->techniques[i]);
6324 HeapFree(GetProcessHeap(), 0, base->techniques);
6325 base->techniques = NULL;
6328 if (base->parameters)
6330 for (i = 0; i < base->parameter_count; ++i)
6332 free_top_level_parameter(&base->parameters[i]);
6334 HeapFree(GetProcessHeap(), 0, base->parameters);
6335 base->parameters = NULL;
6338 if (base->objects)
6340 for (i = 0; i < base->object_count; ++i)
6342 free_object(&base->objects[i]);
6344 HeapFree(GetProcessHeap(), 0, base->objects);
6345 base->objects = NULL;
6348 return hr;
6351 #define INITIAL_CONST_NAMES_SIZE 4
6353 static char *next_valid_constant_name(char **string)
6355 char *ret = *string;
6356 char *next;
6358 while (*ret && !isalpha(*ret) && *ret != '_')
6359 ++ret;
6360 if (!*ret)
6361 return NULL;
6363 next = ret + 1;
6364 while (isalpha(*next) || isdigit(*next) || *next == '_')
6365 ++next;
6366 if (*next)
6367 *next++ = 0;
6368 *string = next;
6369 return ret;
6372 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count)
6374 const char **names, **new_alloc;
6375 const char *name;
6376 char *s;
6377 unsigned int size = INITIAL_CONST_NAMES_SIZE;
6379 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size);
6380 if (!names)
6381 return NULL;
6383 *names_count = 0;
6384 s = skip_constants_string;
6385 while ((name = next_valid_constant_name(&s)))
6387 if (*names_count == size)
6389 size *= 2;
6390 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size);
6391 if (!new_alloc)
6393 HeapFree(GetProcessHeap(), 0, names);
6394 return NULL;
6396 names = new_alloc;
6398 names[(*names_count)++] = name;
6400 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names));
6401 if (!new_alloc)
6402 return names;
6403 return new_alloc;
6406 static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
6407 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6408 UINT eflags, ID3DBlob **errors, struct ID3DXEffectImpl *effect, struct d3dx_effect_pool *pool,
6409 const char *skip_constants_string)
6411 DWORD tag, offset;
6412 const char *ptr = data;
6413 HRESULT hr;
6414 ID3DBlob *bytecode = NULL, *temp_errors = NULL;
6415 char *skip_constants_buffer = NULL;
6416 const char **skip_constants = NULL;
6417 unsigned int skip_constants_count = 0;
6418 unsigned int i, j;
6420 TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n",
6421 base, data, data_size, effect, pool, debugstr_a(skip_constants_string));
6423 base->effect = effect;
6424 base->pool = pool;
6425 base->flags = eflags;
6427 read_dword(&ptr, &tag);
6428 TRACE("Tag: %x\n", tag);
6430 if (tag != d3dx9_effect_version(9, 1))
6432 TRACE("HLSL ASCII effect, trying to compile it.\n");
6433 hr = D3DCompile(data, data_size, NULL, defines, include,
6434 "main", "fx_2_0", 0, eflags, &bytecode, &temp_errors);
6435 if (FAILED(hr))
6437 WARN("Failed to compile ASCII effect.\n");
6438 if (bytecode)
6439 ID3D10Blob_Release(bytecode);
6440 if (temp_errors)
6442 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors);
6443 const char *string_ptr;
6445 while (*error_string)
6447 string_ptr = error_string;
6448 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r'
6449 && string_ptr - error_string < 80)
6450 ++string_ptr;
6451 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string));
6452 error_string = string_ptr;
6453 while (*error_string == '\n' || *error_string == '\r')
6454 ++error_string;
6457 if (errors)
6458 *errors = temp_errors;
6459 else if (temp_errors)
6460 ID3D10Blob_Release(temp_errors);
6461 return hr;
6463 if (!bytecode)
6465 FIXME("No output from effect compilation.\n");
6466 return D3DERR_INVALIDCALL;
6468 if (errors)
6469 *errors = temp_errors;
6470 else if (temp_errors)
6471 ID3D10Blob_Release(temp_errors);
6473 ptr = ID3D10Blob_GetBufferPointer(bytecode);
6474 read_dword(&ptr, &tag);
6475 TRACE("Tag: %x\n", tag);
6478 if (skip_constants_string)
6480 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0,
6481 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1));
6482 if (!skip_constants_buffer)
6484 if (bytecode)
6485 ID3D10Blob_Release(bytecode);
6486 return E_OUTOFMEMORY;
6488 strcpy(skip_constants_buffer, skip_constants_string);
6490 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count)))
6492 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6493 if (bytecode)
6494 ID3D10Blob_Release(bytecode);
6495 return E_OUTOFMEMORY;
6498 read_dword(&ptr, &offset);
6499 TRACE("Offset: %x\n", offset);
6501 hr = d3dx9_parse_effect(base, ptr, data_size, offset, skip_constants, skip_constants_count);
6502 if (bytecode)
6503 ID3D10Blob_Release(bytecode);
6504 if (hr != D3D_OK)
6506 FIXME("Failed to parse effect.\n");
6507 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6508 HeapFree(GetProcessHeap(), 0, skip_constants);
6509 return hr;
6512 for (i = 0; i < skip_constants_count; ++i)
6514 struct d3dx_parameter *param;
6515 param = get_parameter_by_name(base, NULL, skip_constants[i]);
6516 if (param)
6518 for (j = 0; j < base->technique_count; ++j)
6520 if (is_parameter_used(param, &base->techniques[j]))
6522 WARN("skip_constants parameter %s is used in technique %u.\n",
6523 debugstr_a(skip_constants[i]), j);
6524 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6525 HeapFree(GetProcessHeap(), 0, skip_constants);
6526 d3dx9_base_effect_cleanup(base);
6527 return D3DERR_INVALIDCALL;
6531 else
6533 TRACE("skip_constants parameter %s not found.\n",
6534 debugstr_a(skip_constants[i]));
6538 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6539 HeapFree(GetProcessHeap(), 0, skip_constants);
6541 return D3D_OK;
6544 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, struct IDirect3DDevice9 *device,
6545 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6546 UINT eflags, ID3DBlob **error_messages, struct ID3DXEffectPool *pool, const char *skip_constants)
6548 HRESULT hr;
6549 struct d3dx_effect_pool *pool_impl = NULL;
6551 TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
6553 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
6554 effect->ref = 1;
6556 if (pool)
6558 pool->lpVtbl->AddRef(pool);
6559 pool_impl = impl_from_ID3DXEffectPool(pool);
6561 effect->pool = pool;
6563 IDirect3DDevice9_AddRef(device);
6564 effect->device = device;
6566 if (FAILED(hr = d3dx9_base_effect_init(&effect->base_effect, data, data_size, defines, include,
6567 eflags, error_messages, effect, pool_impl, skip_constants)))
6569 FIXME("Failed to parse effect, hr %#x.\n", hr);
6570 free_effect(effect);
6571 return hr;
6574 /* initialize defaults - check because of unsupported ascii effects */
6575 if (effect->base_effect.techniques)
6577 effect->active_technique = &effect->base_effect.techniques[0];
6578 effect->active_pass = NULL;
6581 return D3D_OK;
6584 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6585 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags,
6586 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6588 struct ID3DXEffectImpl *object;
6589 HRESULT hr;
6591 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p,"
6592 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n",
6593 device, srcdata, srcdatalen, defines, include,
6594 skip_constants, flags, pool, effect, compilation_errors);
6596 if (compilation_errors)
6597 *compilation_errors = NULL;
6599 if (!device || !srcdata)
6600 return D3DERR_INVALIDCALL;
6602 if (!srcdatalen)
6603 return E_FAIL;
6605 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6606 if (!effect)
6607 return D3D_OK;
6609 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6610 if (!object)
6611 return E_OUTOFMEMORY;
6613 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6614 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants);
6615 if (FAILED(hr))
6617 WARN("Failed to create effect object.\n");
6618 HeapFree(GetProcessHeap(), 0, object);
6619 return hr;
6622 *effect = &object->ID3DXEffect_iface;
6624 TRACE("Created ID3DXEffect %p\n", object);
6626 return D3D_OK;
6629 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6630 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6631 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6633 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
6634 include, flags, pool, effect, compilation_errors);
6636 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
6639 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler,
6640 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6641 UINT eflags, ID3DBlob **error_messages)
6643 HRESULT hr;
6645 TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
6647 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
6648 compiler->ref = 1;
6650 if (FAILED(hr = d3dx9_base_effect_init(&compiler->base_effect, data, data_size, defines,
6651 include, eflags, error_messages, NULL, NULL, NULL)))
6653 FIXME("Failed to parse effect, hr %#x.\n", hr);
6654 free_effect_compiler(compiler);
6655 return hr;
6658 return D3D_OK;
6661 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines,
6662 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors)
6664 struct ID3DXEffectCompilerImpl *object;
6665 HRESULT hr;
6667 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
6668 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
6670 if (!srcdata || !compiler)
6672 WARN("Invalid arguments supplied\n");
6673 return D3DERR_INVALIDCALL;
6676 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6677 if (!object)
6678 return E_OUTOFMEMORY;
6680 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6681 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors);
6682 if (FAILED(hr))
6684 WARN("Failed to initialize effect compiler\n");
6685 HeapFree(GetProcessHeap(), 0, object);
6686 return hr;
6689 *compiler = &object->ID3DXEffectCompiler_iface;
6691 TRACE("Created ID3DXEffectCompiler %p\n", object);
6693 return D3D_OK;
6696 /*** IUnknown methods ***/
6697 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
6699 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
6701 if (IsEqualGUID(riid, &IID_IUnknown) ||
6702 IsEqualGUID(riid, &IID_ID3DXEffectPool))
6704 iface->lpVtbl->AddRef(iface);
6705 *object = iface;
6706 return S_OK;
6709 WARN("Interface %s not found\n", debugstr_guid(riid));
6711 return E_NOINTERFACE;
6714 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface)
6716 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6717 ULONG refcount = InterlockedIncrement(&pool->refcount);
6719 TRACE("%p increasing refcount to %u.\n", pool, refcount);
6721 return refcount;
6724 static void free_effect_pool(struct d3dx_effect_pool *pool)
6726 unsigned int i;
6728 for (i = 0; i < pool->size; ++i)
6730 if (pool->shared_data[i].count)
6732 unsigned int j;
6734 WARN("Releasing pool with referenced parameters.\n");
6736 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE);
6737 pool->shared_data[i].parameters[0]->shared_data = NULL;
6739 for (j = 1; j < pool->shared_data[i].count; ++j)
6741 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL);
6742 pool->shared_data[i].parameters[j]->shared_data = NULL;
6744 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);
6747 HeapFree(GetProcessHeap(), 0, pool->shared_data);
6748 HeapFree(GetProcessHeap(), 0, pool);
6751 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface)
6753 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6754 ULONG refcount = InterlockedDecrement(&pool->refcount);
6756 TRACE("%p decreasing refcount to %u.\n", pool, refcount);
6758 if (!refcount)
6759 free_effect_pool(pool);
6761 return refcount;
6764 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
6766 /*** IUnknown methods ***/
6767 d3dx_effect_pool_QueryInterface,
6768 d3dx_effect_pool_AddRef,
6769 d3dx_effect_pool_Release
6772 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool)
6774 struct d3dx_effect_pool *object;
6776 TRACE("pool %p.\n", pool);
6778 if (!pool)
6779 return D3DERR_INVALIDCALL;
6781 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6782 if (!object)
6783 return E_OUTOFMEMORY;
6785 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6786 object->refcount = 1;
6788 *pool = &object->ID3DXEffectPool_iface;
6790 return S_OK;
6793 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6794 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6795 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6797 void *buffer;
6798 HRESULT ret;
6799 DWORD size;
6801 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6802 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6803 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants),
6804 flags, pool, effect, compilationerrors);
6806 if (!device || !srcfile)
6807 return D3DERR_INVALIDCALL;
6809 ret = map_view_of_file(srcfile, &buffer, &size);
6811 if (FAILED(ret))
6812 return D3DXERR_INVALIDDATA;
6814 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6815 UnmapViewOfFile(buffer);
6817 return ret;
6820 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
6821 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6822 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6824 WCHAR *srcfileW;
6825 HRESULT ret;
6826 DWORD len;
6828 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6829 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6830 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants),
6831 flags, pool, effect, compilationerrors);
6833 if (!srcfile)
6834 return D3DERR_INVALIDCALL;
6836 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6837 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6838 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6840 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6841 HeapFree(GetProcessHeap(), 0, srcfileW);
6843 return ret;
6846 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6847 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6848 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6850 TRACE("(void): relay\n");
6851 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6854 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile,
6855 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6856 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6858 TRACE("(void): relay\n");
6859 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6862 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6863 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6864 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6866 HRSRC resinfo;
6867 void *buffer;
6868 DWORD size;
6870 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6871 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6872 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants),
6873 flags, pool, effect, compilationerrors);
6875 if (!device)
6876 return D3DERR_INVALIDCALL;
6878 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
6879 return D3DXERR_INVALIDDATA;
6881 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6882 return D3DXERR_INVALIDDATA;
6884 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6885 skipconstants, flags, pool, effect, compilationerrors);
6888 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6889 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6890 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6892 HRSRC resinfo;
6893 void *buffer;
6894 DWORD size;
6896 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6897 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6898 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants),
6899 flags, pool, effect, compilationerrors);
6901 if (!device)
6902 return D3DERR_INVALIDCALL;
6904 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6905 return D3DXERR_INVALIDDATA;
6907 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6908 return D3DXERR_INVALIDDATA;
6910 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6911 skipconstants, flags, pool, effect, compilationerrors);
6914 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6915 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6916 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6918 TRACE("(void): relay\n");
6919 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6922 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6923 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6924 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6926 TRACE("(void): relay\n");
6927 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6930 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines,
6931 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6933 void *buffer;
6934 HRESULT ret;
6935 DWORD size;
6937 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6938 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors);
6940 if (!srcfile)
6941 return D3DERR_INVALIDCALL;
6943 ret = map_view_of_file(srcfile, &buffer, &size);
6945 if (FAILED(ret))
6946 return D3DXERR_INVALIDDATA;
6948 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6949 UnmapViewOfFile(buffer);
6951 return ret;
6954 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines,
6955 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6957 WCHAR *srcfileW;
6958 HRESULT ret;
6959 DWORD len;
6961 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6962 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors);
6964 if (!srcfile)
6965 return D3DERR_INVALIDCALL;
6967 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6968 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6969 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6971 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
6972 HeapFree(GetProcessHeap(), 0, srcfileW);
6974 return ret;
6977 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource,
6978 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
6979 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6981 HRSRC resinfo;
6982 void *buffer;
6983 DWORD size;
6985 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6986 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors);
6988 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6989 return D3DXERR_INVALIDDATA;
6991 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6992 return D3DXERR_INVALIDDATA;
6994 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6997 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource,
6998 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
6999 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
7001 HRSRC resinfo;
7002 void *buffer;
7003 DWORD size;
7005 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7006 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors);
7008 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
7009 return D3DXERR_INVALIDDATA;
7011 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7012 return D3DXERR_INVALIDDATA;
7014 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7017 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly)
7019 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly);
7021 return D3DXERR_INVALIDDATA;