1 #ifdef __REACTOS__
2 #include "precomp.h"
3 #else
4 /*
5 * Copyright 2010 Christian Costa
6 * Copyright 2011 Rico Schüller
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23
24 #include <stdio.h>
25 #include <assert.h>
26
27 #include "d3dx9_private.h"
28 #include "d3dcompiler.h"
29 #include "winternl.h"
30 #include "wine/list.h"
31 #endif /* __REACTOS__ */
32
33 /* Constants for special INT/FLOAT conversation */
34 #define INT_FLOAT_MULTI 255.0f
35 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
36
37 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
38 static const char parameter_block_magic_string[4] = {'@', '!', '#', '\xFE'};
39
40 #define PARAMETER_FLAG_SHARED 1
41
42 #define INITIAL_POOL_SIZE 16
43 #define INITIAL_PARAM_BLOCK_SIZE 1024
44
45 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
46
47 enum STATE_CLASS
48 {
49 SC_LIGHTENABLE,
50 SC_FVF,
51 SC_LIGHT,
52 SC_MATERIAL,
53 SC_NPATCHMODE,
54 SC_PIXELSHADER,
55 SC_RENDERSTATE,
56 SC_SETSAMPLER,
57 SC_SAMPLERSTATE,
58 SC_TEXTURE,
59 SC_TEXTURESTAGE,
60 SC_TRANSFORM,
61 SC_VERTEXSHADER,
62 SC_SHADERCONST,
63 SC_UNKNOWN,
64 };
65
66 enum MATERIAL_TYPE
67 {
68 MT_DIFFUSE,
69 MT_AMBIENT,
70 MT_SPECULAR,
71 MT_EMISSIVE,
72 MT_POWER,
73 };
74
75 enum LIGHT_TYPE
76 {
77 LT_TYPE,
78 LT_DIFFUSE,
79 LT_SPECULAR,
80 LT_AMBIENT,
81 LT_POSITION,
82 LT_DIRECTION,
83 LT_RANGE,
84 LT_FALLOFF,
85 LT_ATTENUATION0,
86 LT_ATTENUATION1,
87 LT_ATTENUATION2,
88 LT_THETA,
89 LT_PHI,
90 };
91
92 enum SHADER_CONSTANT_TYPE
93 {
94 SCT_VSFLOAT,
95 SCT_VSBOOL,
96 SCT_VSINT,
97 SCT_PSFLOAT,
98 SCT_PSBOOL,
99 SCT_PSINT,
100 };
101
102 enum STATE_TYPE
103 {
104 ST_CONSTANT,
105 ST_PARAMETER,
106 ST_FXLC,
107 ST_ARRAY_SELECTOR,
108 };
109
110 struct d3dx_object
111 {
112 UINT size;
113 void *data;
114 struct d3dx_parameter *param;
115 BOOL creation_failed;
116 };
117
118 struct d3dx_state
119 {
120 UINT operation;
121 UINT index;
122 enum STATE_TYPE type;
123 struct d3dx_parameter parameter;
124 struct d3dx_parameter *referenced_param;
125 };
126
127 struct d3dx_sampler
128 {
129 UINT state_count;
130 struct d3dx_state *states;
131 };
132
133 struct d3dx_pass
134 {
135 char *name;
136 UINT state_count;
137 UINT annotation_count;
138
139 struct d3dx_state *states;
140 struct d3dx_parameter *annotations;
141
142 ULONG64 update_version;
143 };
144
145 struct d3dx_technique
146 {
147 char *name;
148 UINT pass_count;
149 UINT annotation_count;
150
151 struct d3dx_parameter *annotations;
152 struct d3dx_pass *passes;
153
154 struct IDirect3DStateBlock9 *saved_state;
155 };
156
157 struct d3dx_parameter_block
158 {
159 char magic_string[ARRAY_SIZE(parameter_block_magic_string)];
160 struct d3dx_effect *effect;
161 struct list entry;
162 size_t size;
163 size_t offset;
164 BYTE *buffer;
165 };
166
167 struct d3dx_recorded_parameter
168 {
169 struct d3dx_parameter *param;
170 unsigned int bytes;
171 };
172
173 struct d3dx_effect
174 {
175 ID3DXEffect ID3DXEffect_iface;
176 LONG ref;
177
178 unsigned int parameter_count;
179 unsigned int technique_count;
180 unsigned int object_count;
181 struct d3dx_top_level_parameter *parameters;
182 struct d3dx_technique *techniques;
183 struct d3dx_object *objects;
184 DWORD flags;
185
186 struct wine_rb_tree param_tree;
187 char *full_name_tmp;
188 unsigned int full_name_tmp_size;
189
190 struct ID3DXEffectStateManager *manager;
191 struct IDirect3DDevice9 *device;
192 struct d3dx_effect_pool *pool;
193 struct d3dx_technique *active_technique;
194 struct d3dx_pass *active_pass;
195 BOOL started;
196 DWORD begin_flags;
197 ULONG64 version_counter;
198
199 D3DLIGHT9 current_light[8];
200 unsigned int light_updated;
201 D3DMATERIAL9 current_material;
202 BOOL material_updated;
203
204 struct list parameter_block_list;
205 struct d3dx_parameter_block *current_parameter_block;
206 };
207
208 #define INITIAL_SHARED_DATA_SIZE 4
209
210 struct d3dx_effect_pool
211 {
212 ID3DXEffectPool ID3DXEffectPool_iface;
213 LONG refcount;
214
215 struct d3dx_shared_data *shared_data;
216 unsigned int size;
217
218 ULONG64 version_counter;
219 };
220
221 struct ID3DXEffectCompilerImpl
222 {
223 ID3DXEffectCompiler ID3DXEffectCompiler_iface;
224 LONG ref;
225 };
226
227 static HRESULT d3dx_parse_state(struct d3dx_effect *effect, struct d3dx_state *state,
228 const char *data, const char **ptr, struct d3dx_object *objects);
229 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
230
231 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param);
232
233 static const struct
234 {
235 enum STATE_CLASS class;
236 UINT op;
237 const char *name;
238 }
239 state_table[] =
240 {
241 /* Render states */
242 {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
243 {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
244 {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
245 {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
246 {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
247 {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
248 {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
249 {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
250 {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
251 {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
252 {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
253 {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
254 {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
255 {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
256 {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
257 {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
258 {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
259 {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
260 {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
261 {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
262 {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
263 {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
264 {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
265 {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
266 {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
267 {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
268 {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
269 {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
270 {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
271 {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
272 {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
273 {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
274 {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
275 {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
276 {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
277 {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
278 {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
279 {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
280 {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
281 {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
282 {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
283 {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
284 {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
285 {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
286 {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
287 {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
288 {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
289 {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
290 {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
291 {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
292 {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
293 {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
294 {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
295 {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
296 {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
297 {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
298 {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
299 {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
300 {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
301 {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
302 {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
303 {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
304 {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
305 {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
306 {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
307 {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
308 {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
309 {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
310 {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
311 {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
312 {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
313 {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
314 {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
315 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
316 {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
317 {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
318 {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
319 {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
320 {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
321 {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
322 {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
323 {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
324 {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
325 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
326 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
327 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
328 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
329 {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
330 {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
331 {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
332 {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
333 {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
334 {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
335 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
336 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
337 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
338 {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
339 {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
340 {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
341 {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
342 {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
343 {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
344 {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
345 /* Texture stages */
346 {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
347 {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
348 {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
349 {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
350 {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
351 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
352 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
353 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
354 {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
355 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
356 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
357 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
358 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
359 {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
360 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
361 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
362 {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
363 {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
364 /* NPatchMode */
365 {SC_NPATCHMODE, 0, "NPatchMode"},
366 /* FVF */
367 {SC_FVF, 0, "FVF"},
368 /* Transform */
369 {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
370 {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
371 {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
372 {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
373 /* Material */
374 {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
375 {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
376 {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
377 {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
378 {SC_MATERIAL, MT_POWER, "MaterialPower"},
379 /* Light */
380 {SC_LIGHT, LT_TYPE, "LightType"},
381 {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
382 {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
383 {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
384 {SC_LIGHT, LT_POSITION, "LightPosition"},
385 {SC_LIGHT, LT_DIRECTION, "LightDirection"},
386 {SC_LIGHT, LT_RANGE, "LightRange"},
387 {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
388 {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
389 {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
390 {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
391 {SC_LIGHT, LT_THETA, "LightTheta"},
392 {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
393 /* Lightenable */
394 {SC_LIGHTENABLE, 0, "LightEnable"},
395 /* Vertexshader */
396 {SC_VERTEXSHADER, 0, "Vertexshader"},
397 /* Pixelshader */
398 {SC_PIXELSHADER, 0, "Pixelshader"},
399 /* Shader constants */
400 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
401 {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
402 {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
403 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
404 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
405 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
406 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
407 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
408 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
409 {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
410 {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
411 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
412 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
413 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
414 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
415 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
416 /* Texture */
417 {SC_TEXTURE, 0, "Texture"},
418 /* Sampler states */
419 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
420 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
421 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
422 {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
423 {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
424 {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
425 {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
426 {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
427 {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
428 {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
429 {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
430 {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
431 {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
432 /* Set sampler */
433 {SC_SETSAMPLER, 0, "Sampler"},
434 };
435
read_dword(const char ** ptr,DWORD * d)436 static inline void read_dword(const char **ptr, DWORD *d)
437 {
438 memcpy(d, *ptr, sizeof(*d));
439 *ptr += sizeof(*d);
440 }
441
skip_dword_unknown(const char ** ptr,unsigned int count)442 static void skip_dword_unknown(const char **ptr, unsigned int count)
443 {
444 unsigned int i;
445 DWORD d;
446
447 WARN("Skipping %u unknown DWORDs:\n", count);
448 for (i = 0; i < count; ++i)
449 {
450 read_dword(ptr, &d);
451 WARN("\t0x%08x\n", d);
452 }
453 }
454
get_parameter_handle(struct d3dx_parameter * parameter)455 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
456 {
457 return (D3DXHANDLE)parameter;
458 }
459
get_technique_handle(struct d3dx_technique * technique)460 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
461 {
462 return (D3DXHANDLE)technique;
463 }
464
get_pass_handle(struct d3dx_pass * pass)465 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
466 {
467 return (D3DXHANDLE)pass;
468 }
469
get_technique_by_name(struct d3dx_effect * effect,const char * name)470 static struct d3dx_technique *get_technique_by_name(struct d3dx_effect *effect, const char *name)
471 {
472 unsigned int i;
473
474 if (!name) return NULL;
475
476 for (i = 0; i < effect->technique_count; ++i)
477 {
478 if (!strcmp(effect->techniques[i].name, name))
479 return &effect->techniques[i];
480 }
481
482 return NULL;
483 }
484
get_valid_technique(struct d3dx_effect * effect,D3DXHANDLE technique)485 static struct d3dx_technique *get_valid_technique(struct d3dx_effect *effect, D3DXHANDLE technique)
486 {
487 unsigned int i;
488
489 for (i = 0; i < effect->technique_count; ++i)
490 {
491 if (get_technique_handle(&effect->techniques[i]) == technique)
492 return &effect->techniques[i];
493 }
494
495 return get_technique_by_name(effect, technique);
496 }
497
get_valid_pass(struct d3dx_effect * effect,D3DXHANDLE pass)498 static struct d3dx_pass *get_valid_pass(struct d3dx_effect *effect, D3DXHANDLE pass)
499 {
500 unsigned int i, k;
501
502 for (i = 0; i < effect->technique_count; ++i)
503 {
504 struct d3dx_technique *technique = &effect->techniques[i];
505
506 for (k = 0; k < technique->pass_count; ++k)
507 {
508 if (get_pass_handle(&technique->passes[k]) == pass)
509 return &technique->passes[k];
510 }
511 }
512
513 return NULL;
514 }
515
get_valid_parameter(struct d3dx_effect * effect,D3DXHANDLE parameter)516 static struct d3dx_parameter *get_valid_parameter(struct d3dx_effect *effect, D3DXHANDLE parameter)
517 {
518 struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter;
519
520 if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string,
521 sizeof(parameter_magic_string)))
522 return handle_param;
523
524 return effect->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(effect, NULL, parameter);
525 }
526
get_valid_parameter_block(D3DXHANDLE handle)527 static struct d3dx_parameter_block *get_valid_parameter_block(D3DXHANDLE handle)
528 {
529 struct d3dx_parameter_block *block = (struct d3dx_parameter_block *)handle;
530
531 return block && !strncmp(block->magic_string, parameter_block_magic_string,
532 sizeof(parameter_block_magic_string)) ? block : NULL;
533 }
534
free_state(struct d3dx_state * state)535 static void free_state(struct d3dx_state *state)
536 {
537 free_parameter(&state->parameter, FALSE, FALSE);
538 }
539
free_object(struct d3dx_object * object)540 static void free_object(struct d3dx_object *object)
541 {
542 HeapFree(GetProcessHeap(), 0, object->data);
543 }
544
free_sampler(struct d3dx_sampler * sampler)545 static void free_sampler(struct d3dx_sampler *sampler)
546 {
547 UINT i;
548
549 for (i = 0; i < sampler->state_count; ++i)
550 {
551 free_state(&sampler->states[i]);
552 }
553 heap_free(sampler->states);
554 }
555
556 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param);
557
free_parameter_object_data(struct d3dx_parameter * param,const void * data,unsigned int bytes)558 static void free_parameter_object_data(struct d3dx_parameter *param, const void *data, unsigned int bytes)
559 {
560 unsigned int i, count;
561
562 if (param->class != D3DXPC_OBJECT)
563 return;
564
565 count = min(param->element_count ? param->element_count : 1, bytes / sizeof(void *));
566
567 for (i = 0; i < count; ++i)
568 {
569 switch (param->type)
570 {
571 case D3DXPT_STRING:
572 heap_free(((char **)data)[i]);
573 break;
574
575 case D3DXPT_TEXTURE:
576 case D3DXPT_TEXTURE1D:
577 case D3DXPT_TEXTURE2D:
578 case D3DXPT_TEXTURE3D:
579 case D3DXPT_TEXTURECUBE:
580 case D3DXPT_PIXELSHADER:
581 case D3DXPT_VERTEXSHADER:
582 if (*(IUnknown **)data)
583 IUnknown_Release(((IUnknown **)data)[i]);
584 break;
585
586 case D3DXPT_SAMPLER:
587 case D3DXPT_SAMPLER1D:
588 case D3DXPT_SAMPLER2D:
589 case D3DXPT_SAMPLER3D:
590 case D3DXPT_SAMPLERCUBE:
591 assert(count == 1);
592 free_sampler((struct d3dx_sampler *)data);
593 return;
594
595 default:
596 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
597 break;
598 }
599 }
600 }
601
free_parameter_data(struct d3dx_parameter * param,BOOL child)602 static void free_parameter_data(struct d3dx_parameter *param, BOOL child)
603 {
604 if (!param->data)
605 return;
606
607 if (!param->element_count)
608 free_parameter_object_data(param, param->data, param->bytes);
609
610 if (!child || is_param_type_sampler(param->type))
611 heap_free(param->data);
612 }
613
free_parameter(struct d3dx_parameter * param,BOOL element,BOOL child)614 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child)
615 {
616 unsigned int i;
617
618 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name,
619 debug_d3dxparameter_type(param->type), element, child);
620
621 if (param->param_eval)
622 d3dx_free_param_eval(param->param_eval);
623
624 if (param->members)
625 {
626 unsigned int count = param->element_count ? param->element_count : param->member_count;
627
628 for (i = 0; i < count; ++i)
629 free_parameter(¶m->members[i], param->element_count != 0, TRUE);
630 HeapFree(GetProcessHeap(), 0, param->members);
631 }
632
633 heap_free(param->full_name);
634 free_parameter_data(param, child);
635
636 /* only the parent has to release name and semantic */
637 if (!element)
638 {
639 HeapFree(GetProcessHeap(), 0, param->name);
640 HeapFree(GetProcessHeap(), 0, param->semantic);
641 }
642 }
643
free_top_level_parameter(struct d3dx_top_level_parameter * param)644 static void free_top_level_parameter(struct d3dx_top_level_parameter *param)
645 {
646 if (param->annotations)
647 {
648 unsigned int i;
649
650 for (i = 0; i < param->annotation_count; ++i)
651 free_parameter(¶m->annotations[i], FALSE, FALSE);
652 HeapFree(GetProcessHeap(), 0, param->annotations);
653 }
654 d3dx_pool_release_shared_parameter(param);
655 free_parameter(¶m->param, FALSE, FALSE);
656 }
657
free_pass(struct d3dx_pass * pass)658 static void free_pass(struct d3dx_pass *pass)
659 {
660 unsigned int i;
661
662 TRACE("Free pass %p\n", pass);
663
664 if (!pass)
665 return;
666
667 if (pass->annotations)
668 {
669 for (i = 0; i < pass->annotation_count; ++i)
670 free_parameter(&pass->annotations[i], FALSE, FALSE);
671 HeapFree(GetProcessHeap(), 0, pass->annotations);
672 pass->annotations = NULL;
673 }
674
675 if (pass->states)
676 {
677 for (i = 0; i < pass->state_count; ++i)
678 free_state(&pass->states[i]);
679 HeapFree(GetProcessHeap(), 0, pass->states);
680 pass->states = NULL;
681 }
682
683 HeapFree(GetProcessHeap(), 0, pass->name);
684 pass->name = NULL;
685 }
686
free_technique(struct d3dx_technique * technique)687 static void free_technique(struct d3dx_technique *technique)
688 {
689 unsigned int i;
690
691 TRACE("Free technique %p\n", technique);
692
693 if (!technique)
694 return;
695
696 if (technique->saved_state)
697 {
698 IDirect3DStateBlock9_Release(technique->saved_state);
699 technique->saved_state = NULL;
700 }
701
702 if (technique->annotations)
703 {
704 for (i = 0; i < technique->annotation_count; ++i)
705 free_parameter(&technique->annotations[i], FALSE, FALSE);
706 HeapFree(GetProcessHeap(), 0, technique->annotations);
707 technique->annotations = NULL;
708 }
709
710 if (technique->passes)
711 {
712 for (i = 0; i < technique->pass_count; ++i)
713 free_pass(&technique->passes[i]);
714 HeapFree(GetProcessHeap(), 0, technique->passes);
715 technique->passes = NULL;
716 }
717
718 HeapFree(GetProcessHeap(), 0, technique->name);
719 technique->name = NULL;
720 }
721
get_recorded_parameter_size(const struct d3dx_recorded_parameter * record)722 static unsigned int get_recorded_parameter_size(const struct d3dx_recorded_parameter *record)
723 {
724 return sizeof(*record) + record->bytes;
725 }
726
free_parameter_block(struct d3dx_parameter_block * block)727 static void free_parameter_block(struct d3dx_parameter_block *block)
728 {
729 struct d3dx_recorded_parameter *record;
730
731 if (!block)
732 return;
733
734 record = (struct d3dx_recorded_parameter *)block->buffer;
735 while ((BYTE *)record < block->buffer + block->offset)
736 {
737 free_parameter_object_data(record->param, record + 1, record->bytes);
738 record = (struct d3dx_recorded_parameter *)((BYTE *)record + get_recorded_parameter_size(record));
739 }
740 assert((BYTE *)record == block->buffer + block->offset);
741
742 heap_free(block->buffer);
743 heap_free(block);
744 }
745
d3dx_effect_cleanup(struct d3dx_effect * effect)746 static void d3dx_effect_cleanup(struct d3dx_effect *effect)
747 {
748 struct d3dx_parameter_block *block, *cursor;
749 ID3DXEffectPool *pool;
750 unsigned int i;
751
752 TRACE("effect %p.\n", effect);
753
754 free_parameter_block(effect->current_parameter_block);
755 LIST_FOR_EACH_ENTRY_SAFE(block, cursor, &effect->parameter_block_list, struct d3dx_parameter_block, entry)
756 {
757 list_remove(&block->entry);
758 free_parameter_block(block);
759 }
760
761 heap_free(effect->full_name_tmp);
762
763 if (effect->parameters)
764 {
765 for (i = 0; i < effect->parameter_count; ++i)
766 free_top_level_parameter(&effect->parameters[i]);
767 heap_free(effect->parameters);
768 }
769
770 if (effect->techniques)
771 {
772 for (i = 0; i < effect->technique_count; ++i)
773 free_technique(&effect->techniques[i]);
774 heap_free(effect->techniques);
775 }
776
777 if (effect->objects)
778 {
779 for (i = 0; i < effect->object_count; ++i)
780 free_object(&effect->objects[i]);
781 heap_free(effect->objects);
782 }
783
784 if (effect->pool)
785 {
786 pool = &effect->pool->ID3DXEffectPool_iface;
787 pool->lpVtbl->Release(pool);
788 }
789
790 if (effect->manager)
791 IUnknown_Release(effect->manager);
792
793 IDirect3DDevice9_Release(effect->device);
794 heap_free(effect);
795 }
796
get_vector(struct d3dx_parameter * param,D3DXVECTOR4 * vector)797 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
798 {
799 UINT i;
800
801 for (i = 0; i < 4; ++i)
802 {
803 if (i < param->columns)
804 set_number((FLOAT *)vector + i, D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
805 else
806 ((FLOAT *)vector)[i] = 0.0f;
807 }
808 }
809
set_vector(struct d3dx_parameter * param,const D3DXVECTOR4 * vector,void * dst_data)810 static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector, void *dst_data)
811 {
812 UINT i;
813
814 for (i = 0; i < param->columns; ++i)
815 set_number((FLOAT *)dst_data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
816 }
817
get_matrix(struct d3dx_parameter * param,D3DXMATRIX * matrix,BOOL transpose)818 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
819 {
820 UINT i, k;
821
822 for (i = 0; i < 4; ++i)
823 {
824 for (k = 0; k < 4; ++k)
825 {
826 FLOAT *tmp = transpose ? (FLOAT *)&matrix->u.m[k][i] : (FLOAT *)&matrix->u.m[i][k];
827
828 if ((i < param->rows) && (k < param->columns))
829 set_number(tmp, D3DXPT_FLOAT, (DWORD *)param->data + i * param->columns + k, param->type);
830 else
831 *tmp = 0.0f;
832 }
833 }
834 }
835
set_matrix(struct d3dx_parameter * param,const D3DXMATRIX * matrix,void * dst_data)836 static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix, void *dst_data)
837 {
838 UINT i, k;
839
840 if (param->type == D3DXPT_FLOAT)
841 {
842 if (param->columns == 4)
843 {
844 memcpy(dst_data, matrix->u.m, param->rows * 4 * sizeof(float));
845 }
846 else
847 {
848 for (i = 0; i < param->rows; ++i)
849 memcpy((float *)dst_data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float));
850 }
851 return;
852 }
853
854 for (i = 0; i < param->rows; ++i)
855 {
856 for (k = 0; k < param->columns; ++k)
857 set_number((FLOAT *)dst_data + i * param->columns + k, param->type,
858 &matrix->u.m[i][k], D3DXPT_FLOAT);
859 }
860 }
861
set_matrix_transpose(struct d3dx_parameter * param,const D3DXMATRIX * matrix,void * dst_data)862 static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix, void *dst_data)
863 {
864 UINT i, k;
865
866 for (i = 0; i < param->rows; ++i)
867 {
868 for (k = 0; k < param->columns; ++k)
869 {
870 set_number((FLOAT *)dst_data + i * param->columns + k, param->type,
871 &matrix->u.m[k][i], D3DXPT_FLOAT);
872 }
873 }
874 }
875
set_string(char ** param_data,const char * string)876 static HRESULT set_string(char **param_data, const char *string)
877 {
878 heap_free(*param_data);
879 *param_data = heap_alloc(strlen(string) + 1);
880 if (!*param_data)
881 {
882 ERR("Out of memory.\n");
883 return E_OUTOFMEMORY;
884 }
885 strcpy(*param_data, string);
886 return D3D_OK;
887 }
888
set_value(struct d3dx_parameter * param,const void * data,unsigned int bytes,void * dst_data)889 static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigned int bytes,
890 void *dst_data)
891 {
892 unsigned int i, count;
893
894 bytes = min(bytes, param->bytes);
895 count = min(param->element_count ? param->element_count : 1, bytes / sizeof(void *));
896
897 switch (param->type)
898 {
899 case D3DXPT_TEXTURE:
900 case D3DXPT_TEXTURE1D:
901 case D3DXPT_TEXTURE2D:
902 case D3DXPT_TEXTURE3D:
903 case D3DXPT_TEXTURECUBE:
904 for (i = 0; i < count; ++i)
905 {
906 IUnknown *old_texture = ((IUnknown **)dst_data)[i];
907 IUnknown *new_texture = ((IUnknown **)data)[i];
908
909 if (new_texture == old_texture)
910 continue;
911
912 if (new_texture)
913 IUnknown_AddRef(new_texture);
914 if (old_texture)
915 IUnknown_Release(old_texture);
916 }
917 /* fallthrough */
918 case D3DXPT_VOID:
919 case D3DXPT_BOOL:
920 case D3DXPT_INT:
921 case D3DXPT_FLOAT:
922 TRACE("Copy %u bytes.\n", bytes);
923 memcpy(dst_data, data, bytes);
924 break;
925
926 case D3DXPT_STRING:
927 {
928 HRESULT hr;
929
930 for (i = 0; i < count; ++i)
931 if (FAILED(hr = set_string(&((char **)dst_data)[i], ((const char **)data)[i])))
932 return hr;
933 break;
934 }
935
936 default:
937 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
938 break;
939 }
940
941 return D3D_OK;
942 }
943
get_parameter_element_by_name(struct d3dx_effect * effect,struct d3dx_parameter * parameter,const char * name)944 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_effect *effect,
945 struct d3dx_parameter *parameter, const char *name)
946 {
947 UINT element;
948 struct d3dx_parameter *temp_parameter;
949 const char *part;
950
951 TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
952
953 if (!name || !*name) return NULL;
954
955 element = atoi(name);
956 part = strchr(name, ']') + 1;
957
958 /* check for empty [] && element range */
959 if ((part - name) > 1 && parameter->element_count > element)
960 {
961 temp_parameter = ¶meter->members[element];
962
963 switch (*part++)
964 {
965 case '.':
966 return get_parameter_by_name(effect, temp_parameter, part);
967
968 case '\0':
969 TRACE("Returning parameter %p\n", temp_parameter);
970 return temp_parameter;
971
972 default:
973 FIXME("Unhandled case \"%c\"\n", *--part);
974 break;
975 }
976 }
977
978 TRACE("Parameter not found\n");
979 return NULL;
980 }
981
get_annotation_by_name(struct d3dx_effect * effect,unsigned int count,struct d3dx_parameter * annotations,const char * name)982 static struct d3dx_parameter *get_annotation_by_name(struct d3dx_effect *effect, unsigned int count,
983 struct d3dx_parameter *annotations, const char *name)
984 {
985 UINT i, length;
986 struct d3dx_parameter *temp_parameter;
987 const char *part;
988
989 TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name));
990
991 if (!name || !*name) return NULL;
992
993 length = strcspn( name, "[.@" );
994 part = name + length;
995
996 for (i = 0; i < count; ++i)
997 {
998 temp_parameter = &annotations[i];
999
1000 if (!strcmp(temp_parameter->name, name))
1001 {
1002 TRACE("Returning annotation %p\n", temp_parameter);
1003 return temp_parameter;
1004 }
1005 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1006 {
1007 switch (*part++)
1008 {
1009 case '.':
1010 return get_parameter_by_name(effect, temp_parameter, part);
1011
1012 case '[':
1013 return get_parameter_element_by_name(effect, temp_parameter, part);
1014
1015 default:
1016 FIXME("Unhandled case \"%c\"\n", *--part);
1017 break;
1018 }
1019 }
1020 }
1021
1022 TRACE("Annotation not found\n");
1023 return NULL;
1024 }
1025
get_parameter_by_name(struct d3dx_effect * effect,struct d3dx_parameter * parameter,const char * name)1026 struct d3dx_parameter *get_parameter_by_name(struct d3dx_effect* effect,
1027 struct d3dx_parameter *parameter, const char *name)
1028 {
1029 struct d3dx_parameter *temp_parameter;
1030 unsigned int name_len, param_name_len;
1031 unsigned int i, count, length;
1032 struct wine_rb_entry *entry;
1033 unsigned int full_name_size;
1034 const char *part;
1035 char *full_name;
1036
1037 TRACE("effect %p, parameter %p, name %s.\n", effect, parameter, debugstr_a(name));
1038
1039 if (!name || !*name) return NULL;
1040
1041 if (!parameter)
1042 {
1043 if ((entry = wine_rb_get(&effect->param_tree, name)))
1044 return WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
1045 return NULL;
1046 }
1047
1048 if (parameter->full_name)
1049 {
1050 name_len = strlen(name);
1051 param_name_len = strlen(parameter->full_name);
1052 full_name_size = name_len + param_name_len + 2;
1053 if (effect->full_name_tmp_size < full_name_size)
1054 {
1055 if (!(full_name = heap_realloc(effect->full_name_tmp, full_name_size)))
1056 {
1057 ERR("Out of memory.\n");
1058 return NULL;
1059 }
1060 effect->full_name_tmp = full_name;
1061 effect->full_name_tmp_size = full_name_size;
1062 }
1063 else
1064 {
1065 full_name = effect->full_name_tmp;
1066 }
1067 memcpy(full_name, parameter->full_name, param_name_len);
1068 full_name[param_name_len] = '.';
1069 memcpy(full_name + param_name_len + 1, name, name_len);
1070 full_name[param_name_len + 1 + name_len] = 0;
1071
1072 if ((entry = wine_rb_get(&effect->param_tree, full_name)))
1073 return WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
1074 return NULL;
1075 }
1076
1077 /* Pass / technique annotations are not stored in the parameters tree,
1078 * do a linear search. */
1079 count = parameter->member_count;
1080
1081 length = strcspn( name, "[." );
1082 part = name + length;
1083
1084 for (i = 0; i < count; i++)
1085 {
1086 temp_parameter = ¶meter->members[i];
1087
1088 if (!strcmp(temp_parameter->name, name))
1089 {
1090 TRACE("Returning parameter %p\n", temp_parameter);
1091 return temp_parameter;
1092 }
1093 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1094 {
1095 switch (*part++)
1096 {
1097 case '.':
1098 return get_parameter_by_name(effect, temp_parameter, part);
1099
1100 case '[':
1101 return get_parameter_element_by_name(effect, temp_parameter, part);
1102
1103 default:
1104 FIXME("Unhandled case \"%c\"\n", *--part);
1105 break;
1106 }
1107 }
1108 }
1109
1110 TRACE("Parameter not found\n");
1111 return NULL;
1112 }
1113
d3dx9_effect_version(DWORD major,DWORD minor)1114 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
1115 {
1116 return (0xfeff0000 | ((major) << 8) | (minor));
1117 }
1118
d3dx9_get_param_value_ptr(struct d3dx_pass * pass,struct d3dx_state * state,void ** param_value,struct d3dx_parameter ** out_param,BOOL update_all,BOOL * param_dirty)1119 static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
1120 void **param_value, struct d3dx_parameter **out_param,
1121 BOOL update_all, BOOL *param_dirty)
1122 {
1123 struct d3dx_parameter *param = &state->parameter;
1124
1125 *param_value = NULL;
1126 *out_param = NULL;
1127 *param_dirty = FALSE;
1128
1129 switch (state->type)
1130 {
1131 case ST_PARAMETER:
1132 param = state->referenced_param;
1133 *param_dirty = is_param_dirty(param, pass->update_version);
1134 /* fallthrough */
1135 case ST_CONSTANT:
1136 *out_param = param;
1137 *param_value = param->data;
1138 return D3D_OK;
1139 case ST_ARRAY_SELECTOR:
1140 {
1141 unsigned int array_idx;
1142 static const struct d3dx_parameter array_idx_param =
1143 {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)};
1144 HRESULT hr;
1145 struct d3dx_parameter *ref_param, *selected_param;
1146
1147 if (!param->param_eval)
1148 {
1149 FIXME("Preshader structure is null.\n");
1150 return D3DERR_INVALIDCALL;
1151 }
1152 /* We override with the update_version of the pass because we want
1153 * to force index recomputation and check for out of bounds. */
1154 if (is_param_eval_input_dirty(param->param_eval, pass->update_version))
1155 {
1156 if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
1157 return hr;
1158 }
1159 else
1160 {
1161 array_idx = state->index;
1162 }
1163 ref_param = state->referenced_param;
1164 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
1165 ref_param->element_count);
1166 /* According to the tests, native d3dx handles the case of array index evaluated to -1
1167 * in a specific way, always selecting first array element and not returning error. */
1168 if (array_idx == ~0u)
1169 {
1170 WARN("Array index is -1, setting to 0.\n");
1171 array_idx = 0;
1172 }
1173
1174 if (array_idx >= ref_param->element_count)
1175 {
1176 WARN("Computed array index %u is larger than array size %u.\n",
1177 array_idx, ref_param->element_count);
1178 return E_FAIL;
1179 }
1180 selected_param = &ref_param->members[array_idx];
1181 *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
1182 state->index = array_idx;
1183
1184 *param_value = selected_param->data;
1185 *out_param = selected_param;
1186 return D3D_OK;
1187 }
1188 case ST_FXLC:
1189 if (param->param_eval)
1190 {
1191 *out_param = param;
1192 *param_value = param->data;
1193 /* We check with the update_version of the pass because the
1194 * same preshader might be used by both the vertex and the
1195 * pixel shader (that can happen e.g. for sampler states). */
1196 if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version))
1197 {
1198 *param_dirty = TRUE;
1199 return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
1200 }
1201 else
1202 return D3D_OK;
1203 }
1204 else
1205 {
1206 FIXME("No preshader for FXLC parameter.\n");
1207 return D3DERR_INVALIDCALL;
1208 }
1209 }
1210 return E_NOTIMPL;
1211 }
1212
get_annotation_from_object(struct d3dx_effect * effect,D3DXHANDLE object,struct d3dx_parameter ** annotations)1213 static unsigned int get_annotation_from_object(struct d3dx_effect *effect, D3DXHANDLE object,
1214 struct d3dx_parameter **annotations)
1215 {
1216 struct d3dx_parameter *param = get_valid_parameter(effect, object);
1217 struct d3dx_pass *pass = get_valid_pass(effect, object);
1218 struct d3dx_technique *technique = get_valid_technique(effect, object);
1219
1220 if (pass)
1221 {
1222 *annotations = pass->annotations;
1223 return pass->annotation_count;
1224 }
1225 else if (technique)
1226 {
1227 *annotations = technique->annotations;
1228 return technique->annotation_count;
1229 }
1230 else if (param)
1231 {
1232 if (is_top_level_parameter(param))
1233 {
1234 struct d3dx_top_level_parameter *top_param
1235 = top_level_parameter_from_parameter(param);
1236
1237 *annotations = top_param->annotations;
1238 return top_param->annotation_count;
1239 }
1240 else
1241 {
1242 *annotations = NULL;
1243 return 0;
1244 }
1245 }
1246 else
1247 {
1248 FIXME("Functions are not handled, yet!\n");
1249 return 0;
1250 }
1251 }
1252
walk_parameter_tree(struct d3dx_parameter * param,walk_parameter_dep_func param_func,void * data)1253 static BOOL walk_parameter_tree(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
1254 void *data)
1255 {
1256 unsigned int i;
1257 unsigned int member_count;
1258
1259 if (param_func(data, param))
1260 return TRUE;
1261
1262 member_count = param->element_count ? param->element_count : param->member_count;
1263 for (i = 0; i < member_count; ++i)
1264 {
1265 if (walk_parameter_tree(¶m->members[i], param_func, data))
1266 return TRUE;
1267 }
1268 return FALSE;
1269 }
1270
get_version_counter_ptr(struct d3dx_effect * effect)1271 static ULONG64 *get_version_counter_ptr(struct d3dx_effect *effect)
1272 {
1273 return effect->pool ? &effect->pool->version_counter : &effect->version_counter;
1274 }
1275
next_effect_update_version(struct d3dx_effect * effect)1276 static ULONG64 next_effect_update_version(struct d3dx_effect *effect)
1277 {
1278 return next_update_version(get_version_counter_ptr(effect));
1279 }
1280
record_parameter(struct d3dx_effect * effect,struct d3dx_parameter * param,unsigned int bytes)1281 static void *record_parameter(struct d3dx_effect *effect, struct d3dx_parameter *param, unsigned int bytes)
1282 {
1283 struct d3dx_parameter_block *block = effect->current_parameter_block;
1284 struct d3dx_recorded_parameter new_record, *record;
1285 unsigned int new_size, alloc_size;
1286
1287 new_record.param = param;
1288 new_record.bytes = bytes;
1289 new_size = block->offset + get_recorded_parameter_size(&new_record);
1290
1291 if (new_size > block->size)
1292 {
1293 BYTE *new_alloc;
1294
1295 alloc_size = max(block->size * 2, max(new_size, INITIAL_PARAM_BLOCK_SIZE));
1296 if (block->size)
1297 new_alloc = heap_realloc(block->buffer, alloc_size);
1298 else
1299 new_alloc = heap_alloc(alloc_size);
1300
1301 if (!new_alloc)
1302 {
1303 ERR("Out of memory.\n");
1304 return param->data;
1305 }
1306 /* Data update functions may want to free some references upon setting value. */
1307 memset(new_alloc + block->size, 0, alloc_size - block->size);
1308
1309 block->size = alloc_size;
1310 block->buffer = new_alloc;
1311 }
1312 record = (struct d3dx_recorded_parameter *)(block->buffer + block->offset);
1313 *record = new_record;
1314 block->offset = new_size;
1315 return record + 1;
1316 }
1317
set_dirty(struct d3dx_parameter * param)1318 static void set_dirty(struct d3dx_parameter *param)
1319 {
1320 struct d3dx_shared_data *shared_data;
1321 struct d3dx_top_level_parameter *top_param = param->top_level_param;
1322 ULONG64 new_update_version = next_update_version(top_param->version_counter);
1323
1324 if ((shared_data = top_param->shared_data))
1325 shared_data->update_version = new_update_version;
1326 else
1327 top_param->update_version = new_update_version;
1328 }
1329
param_get_data_and_dirtify(struct d3dx_effect * effect,struct d3dx_parameter * param,unsigned int bytes,BOOL value_changed)1330 static void *param_get_data_and_dirtify(struct d3dx_effect *effect, struct d3dx_parameter *param,
1331 unsigned int bytes, BOOL value_changed)
1332 {
1333 assert(bytes <= param->bytes);
1334
1335 if (value_changed && !effect->current_parameter_block)
1336 set_dirty(param);
1337
1338 return effect->current_parameter_block ? record_parameter(effect, param, bytes) : param->data;
1339 }
1340
d3dx9_set_light_parameter(enum LIGHT_TYPE op,D3DLIGHT9 * light,void * value)1341 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
1342 {
1343 static const struct
1344 {
1345 unsigned int offset;
1346 const char *name;
1347 }
1348 light_tbl[] =
1349 {
1350 {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
1351 {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
1352 {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
1353 {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
1354 {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
1355 {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
1356 {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
1357 {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
1358 {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
1359 {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
1360 {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
1361 {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
1362 {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
1363 };
1364 switch (op)
1365 {
1366 case LT_TYPE:
1367 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
1368 light->Type = *(D3DLIGHTTYPE *)value;
1369 break;
1370 case LT_DIFFUSE:
1371 case LT_SPECULAR:
1372 case LT_AMBIENT:
1373 {
1374 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
1375
1376 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
1377 *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
1378 break;
1379 }
1380 case LT_POSITION:
1381 case LT_DIRECTION:
1382 {
1383 D3DVECTOR v = *(D3DVECTOR *)value;
1384
1385 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
1386 *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
1387 break;
1388 }
1389 case LT_RANGE:
1390 case LT_FALLOFF:
1391 case LT_ATTENUATION0:
1392 case LT_ATTENUATION1:
1393 case LT_ATTENUATION2:
1394 case LT_THETA:
1395 case LT_PHI:
1396 {
1397 float v = *(float *)value;
1398 TRACE("%s %.8e.\n", light_tbl[op].name, v);
1399 *(float *)((BYTE *)light + light_tbl[op].offset) = v;
1400 break;
1401 }
1402 default:
1403 WARN("Unknown light parameter %u.\n", op);
1404 break;
1405 }
1406 }
1407
d3dx9_set_material_parameter(enum MATERIAL_TYPE op,D3DMATERIAL9 * material,void * value)1408 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
1409 {
1410 static const struct
1411 {
1412 unsigned int offset;
1413 const char *name;
1414 }
1415 material_tbl[] =
1416 {
1417 {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
1418 {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
1419 {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
1420 {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
1421 {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
1422 };
1423
1424 switch (op)
1425 {
1426 case MT_POWER:
1427 {
1428 float v = *(float *)value;
1429
1430 TRACE("%s %.8e.\n", material_tbl[op].name, v);
1431 material->Power = v;
1432 break;
1433 }
1434 case MT_DIFFUSE:
1435 case MT_AMBIENT:
1436 case MT_SPECULAR:
1437 case MT_EMISSIVE:
1438 {
1439 D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
1440
1441 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
1442 *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
1443 break;
1444 }
1445 default:
1446 WARN("Unknown material parameter %u.\n", op);
1447 break;
1448 }
1449 }
1450
d3dx_set_shader_const_state(struct d3dx_effect * effect,enum SHADER_CONSTANT_TYPE op,UINT index,struct d3dx_parameter * param,void * value_ptr)1451 static HRESULT d3dx_set_shader_const_state(struct d3dx_effect *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
1452 struct d3dx_parameter *param, void *value_ptr)
1453 {
1454 static const struct
1455 {
1456 D3DXPARAMETER_TYPE type;
1457 UINT elem_size;
1458 const char *name;
1459 }
1460 const_tbl[] =
1461 {
1462 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
1463 {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
1464 {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
1465 {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
1466 {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
1467 {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
1468 };
1469
1470 BOOL is_heap_buffer = FALSE;
1471 unsigned int element_count;
1472 void *buffer = value_ptr;
1473 D3DXVECTOR4 value;
1474 HRESULT ret;
1475
1476 assert(op < ARRAY_SIZE(const_tbl));
1477 element_count = param->bytes / const_tbl[op].elem_size;
1478 TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
1479 if (param->type != const_tbl[op].type)
1480 {
1481 FIXME("Unexpected param type %u.\n", param->type);
1482 return D3DERR_INVALIDCALL;
1483 }
1484
1485 if (param->bytes % const_tbl[op].elem_size || element_count > 1)
1486 {
1487 unsigned int param_data_size;
1488
1489 TRACE("Parameter size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
1490
1491 if (param->bytes % const_tbl[op].elem_size)
1492 ++element_count;
1493 if (element_count > 1)
1494 {
1495 WARN("Setting %u elements.\n", element_count);
1496 buffer = HeapAlloc(GetProcessHeap(), 0, const_tbl[op].elem_size * element_count);
1497 if (!buffer)
1498 {
1499 ERR("Out of memory.\n");
1500 return E_OUTOFMEMORY;
1501 }
1502 is_heap_buffer = TRUE;
1503 }
1504 else
1505 {
1506 assert(const_tbl[op].elem_size <= sizeof(value));
1507 buffer = &value;
1508 }
1509 param_data_size = min(param->bytes, const_tbl[op].elem_size);
1510 memcpy(buffer, value_ptr, param_data_size);
1511 memset((unsigned char *)buffer + param_data_size, 0,
1512 const_tbl[op].elem_size * element_count - param_data_size);
1513 }
1514
1515 switch (op)
1516 {
1517 case SCT_VSFLOAT:
1518 ret = SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)buffer, element_count);
1519 break;
1520 case SCT_VSBOOL:
1521 ret = SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)buffer, element_count);
1522 break;
1523 case SCT_VSINT:
1524 ret = SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)buffer, element_count);
1525 break;
1526 case SCT_PSFLOAT:
1527 ret = SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)buffer, element_count);
1528 break;
1529 case SCT_PSBOOL:
1530 ret = SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)buffer, element_count);
1531 break;
1532 case SCT_PSINT:
1533 ret = SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)buffer, element_count);
1534 break;
1535 default:
1536 ret = D3DERR_INVALIDCALL;
1537 break;
1538 }
1539
1540 if (is_heap_buffer)
1541 HeapFree(GetProcessHeap(), 0, buffer);
1542
1543 return ret;
1544 }
1545
1546 static HRESULT d3dx9_apply_state(struct d3dx_effect *effect, struct d3dx_pass *pass,
1547 struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
1548
d3dx_set_shader_constants(struct d3dx_effect * effect,struct d3dx_pass * pass,struct d3dx_parameter * param,BOOL vs,BOOL update_all)1549 static HRESULT d3dx_set_shader_constants(struct d3dx_effect *effect, struct d3dx_pass *pass,
1550 struct d3dx_parameter *param, BOOL vs, BOOL update_all)
1551 {
1552 HRESULT hr, ret;
1553 struct d3dx_parameter **params;
1554 D3DXCONSTANT_DESC *cdesc;
1555 unsigned int parameters_count;
1556 unsigned int i, j;
1557
1558 if (!param->param_eval)
1559 {
1560 FIXME("param_eval structure is null.\n");
1561 return D3DERR_INVALIDCALL;
1562 }
1563 if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
1564 param->param_eval, update_all)))
1565 return hr;
1566 params = param->param_eval->shader_inputs.inputs_param;
1567 cdesc = param->param_eval->shader_inputs.inputs;
1568 parameters_count = param->param_eval->shader_inputs.input_count;
1569 ret = D3D_OK;
1570 for (i = 0; i < parameters_count; ++i)
1571 {
1572 if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
1573 {
1574 struct d3dx_sampler *sampler;
1575 unsigned int sampler_idx;
1576
1577 for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
1578 {
1579 sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
1580 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
1581 cdesc[i].RegisterIndex, sampler->state_count);
1582 for (j = 0; j < sampler->state_count; ++j)
1583 {
1584 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
1585 cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
1586 update_all)))
1587 ret = hr;
1588 }
1589 }
1590 }
1591 }
1592 return ret;
1593 }
1594
d3dx9_apply_state(struct d3dx_effect * effect,struct d3dx_pass * pass,struct d3dx_state * state,unsigned int parent_index,BOOL update_all)1595 static HRESULT d3dx9_apply_state(struct d3dx_effect *effect, struct d3dx_pass *pass,
1596 struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
1597 {
1598 struct d3dx_parameter *param;
1599 void *param_value;
1600 BOOL param_dirty;
1601 HRESULT hr;
1602
1603 TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
1604
1605 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, ¶m_value, ¶m,
1606 update_all, ¶m_dirty)))
1607 {
1608 if (!update_all && hr == E_FAIL)
1609 {
1610 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
1611 * out of bounds array access and does not touch the affected
1612 * states. */
1613 WARN("Returning D3D_OK on out of bounds array access.\n");
1614 return D3D_OK;
1615 }
1616 return hr;
1617 }
1618
1619 if (!(update_all || param_dirty
1620 || state_table[state->operation].class == SC_VERTEXSHADER
1621 || state_table[state->operation].class == SC_PIXELSHADER
1622 || state_table[state->operation].class == SC_SETSAMPLER))
1623 return D3D_OK;
1624
1625 switch (state_table[state->operation].class)
1626 {
1627 case SC_RENDERSTATE:
1628 TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
1629 state_table[state->operation].op, *(DWORD *)param_value);
1630 return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
1631 case SC_FVF:
1632 TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
1633 return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
1634 case SC_TEXTURE:
1635 {
1636 UINT unit;
1637
1638 unit = parent_index == ~0u ? state->index : parent_index;
1639 TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
1640 *(IDirect3DBaseTexture9 **)param_value);
1641 return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
1642 }
1643 case SC_TEXTURESTAGE:
1644 TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
1645 return SET_D3D_STATE(effect, SetTextureStageState, state->index,
1646 state_table[state->operation].op, *(DWORD *)param_value);
1647 case SC_SETSAMPLER:
1648 {
1649 struct d3dx_sampler *sampler;
1650 HRESULT ret, hr;
1651 unsigned int i;
1652
1653 sampler = (struct d3dx_sampler *)param_value;
1654 TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
1655 sampler->state_count);
1656 ret = D3D_OK;
1657 for (i = 0; i < sampler->state_count; i++)
1658 {
1659 if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
1660 ret = hr;
1661 }
1662 return ret;
1663 }
1664 case SC_SAMPLERSTATE:
1665 {
1666 UINT sampler;
1667
1668 sampler = parent_index == ~0u ? state->index : parent_index;
1669 TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
1670 return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
1671 *(DWORD *)param_value);
1672 }
1673 case SC_VERTEXSHADER:
1674 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
1675 if ((update_all || param_dirty)
1676 && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
1677 *(IDirect3DVertexShader9 **)param_value)))
1678 ERR("Could not set vertex shader, hr %#x.\n", hr);
1679 else if (*(IDirect3DVertexShader9 **)param_value)
1680 hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
1681 return hr;
1682 case SC_PIXELSHADER:
1683 TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
1684 if ((update_all || param_dirty)
1685 && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
1686 *(IDirect3DPixelShader9 **)param_value)))
1687 ERR("Could not set pixel shader, hr %#x.\n", hr);
1688 else if (*(IDirect3DPixelShader9 **)param_value)
1689 hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
1690 return hr;
1691 case SC_TRANSFORM:
1692 TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
1693 return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
1694 (D3DMATRIX *)param_value);
1695 case SC_LIGHTENABLE:
1696 TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
1697 return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
1698 case SC_LIGHT:
1699 {
1700 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
1701 state_table[state->operation].op);
1702 d3dx9_set_light_parameter(state_table[state->operation].op,
1703 &effect->current_light[state->index], param_value);
1704 effect->light_updated |= 1u << state->index;
1705 return D3D_OK;
1706 }
1707 case SC_MATERIAL:
1708 {
1709 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
1710 state_table[state->operation].op);
1711 d3dx9_set_material_parameter(state_table[state->operation].op,
1712 &effect->current_material, param_value);
1713 effect->material_updated = TRUE;
1714 return D3D_OK;
1715 }
1716 case SC_NPATCHMODE:
1717 TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
1718 return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
1719 case SC_SHADERCONST:
1720 TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
1721 state_table[state->operation].op);
1722 return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
1723 param, param_value);
1724 default:
1725 FIXME("%s not handled.\n", state_table[state->operation].name);
1726 break;
1727 }
1728 return D3D_OK;
1729 }
1730
d3dx9_apply_pass_states(struct d3dx_effect * effect,struct d3dx_pass * pass,BOOL update_all)1731 static HRESULT d3dx9_apply_pass_states(struct d3dx_effect *effect, struct d3dx_pass *pass, BOOL update_all)
1732 {
1733 unsigned int i;
1734 HRESULT ret;
1735 HRESULT hr;
1736 ULONG64 new_update_version = next_effect_update_version(effect);
1737
1738 TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
1739
1740 ret = D3D_OK;
1741 for (i = 0; i < pass->state_count; ++i)
1742 {
1743 if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
1744 {
1745 WARN("Error applying state, hr %#x.\n", hr);
1746 ret = hr;
1747 }
1748 }
1749
1750 if (effect->light_updated)
1751 {
1752 for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
1753 {
1754 if ((effect->light_updated & (1u << i))
1755 && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
1756 {
1757 WARN("Error setting light, hr %#x.\n", hr);
1758 ret = hr;
1759 }
1760 }
1761 effect->light_updated = 0;
1762 }
1763
1764 if (effect->material_updated
1765 && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
1766 {
1767 WARN("Error setting material, hr %#x.\n", hr);
1768 ret = hr;
1769 }
1770 effect->material_updated = FALSE;
1771
1772 pass->update_version = new_update_version;
1773 return ret;
1774 }
1775
param_set_data_pointer(struct d3dx_parameter * param,unsigned char * data,BOOL child,BOOL free_data)1776 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
1777 {
1778 unsigned char *member_data = data;
1779 unsigned int i, count;
1780
1781 count = param->element_count ? param->element_count : param->member_count;
1782 for (i = 0; i < count; ++i)
1783 {
1784 param_set_data_pointer(¶m->members[i], member_data, TRUE, free_data);
1785 if (data)
1786 member_data += param->members[i].bytes;
1787 }
1788 if (free_data)
1789 free_parameter_data(param, child);
1790 param->data = data;
1791 }
1792
is_same_parameter(void * param1_,struct d3dx_parameter * param2)1793 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
1794 {
1795 struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
1796 BOOL matches;
1797 unsigned int i, member_count;
1798
1799 matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
1800 && param1->type == param2->type && param1->rows == param2->rows
1801 && param1->columns == param2->columns && param1->element_count == param2->element_count
1802 && param1->member_count == param2->member_count;
1803
1804 member_count = param1->element_count ? param1->element_count : param1->member_count;
1805
1806 if (!matches || !member_count)
1807 return matches;
1808
1809 for (i = 0; i < member_count; ++i)
1810 {
1811 if (!is_same_parameter(¶m1->members[i], ¶m2->members[i]))
1812 return FALSE;
1813 }
1814 return TRUE;
1815 }
1816
d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool * pool,struct d3dx_top_level_parameter * param)1817 static HRESULT d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool *pool, struct d3dx_top_level_parameter *param)
1818 {
1819 unsigned int i, free_entry_index;
1820 unsigned int new_size, new_count;
1821
1822 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
1823 return D3D_OK;
1824
1825 free_entry_index = pool->size;
1826 for (i = 0; i < pool->size; ++i)
1827 {
1828 if (!pool->shared_data[i].count)
1829 free_entry_index = i;
1830 else if (is_same_parameter(¶m->param, &pool->shared_data[i].parameters[0]->param))
1831 break;
1832 }
1833 if (i == pool->size)
1834 {
1835 i = free_entry_index;
1836 if (i == pool->size)
1837 {
1838 struct d3dx_shared_data *new_alloc;
1839
1840 if (!pool->size)
1841 {
1842 new_size = INITIAL_POOL_SIZE;
1843 new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1844 sizeof(*pool->shared_data) * new_size);
1845 if (!new_alloc)
1846 {
1847 ERR("Out of memory.\n");
1848 return E_OUTOFMEMORY;
1849 }
1850 }
1851 else
1852 {
1853 new_size = pool->size * 2;
1854 new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
1855 sizeof(*pool->shared_data) * new_size);
1856 if (!new_alloc)
1857 {
1858 ERR("Out of memory.\n");
1859 return E_OUTOFMEMORY;
1860 }
1861 if (new_alloc != pool->shared_data)
1862 {
1863 unsigned int j, k;
1864
1865 for (j = 0; j < pool->size; ++j)
1866 for (k = 0; k < new_alloc[j].count; ++k)
1867 new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
1868 }
1869 }
1870 pool->shared_data = new_alloc;
1871 pool->size = new_size;
1872 }
1873 pool->shared_data[i].data = param->param.data;
1874 }
1875 else
1876 {
1877 param_set_data_pointer(¶m->param, pool->shared_data[i].data, FALSE, TRUE);
1878 }
1879 new_count = ++pool->shared_data[i].count;
1880 if (new_count >= pool->shared_data[i].size)
1881 {
1882 if (!pool->shared_data[i].size)
1883 {
1884 new_size = INITIAL_SHARED_DATA_SIZE;
1885 pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1886 sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
1887 }
1888 else
1889 {
1890 new_size = pool->shared_data[i].size * 2;
1891 pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1892 pool->shared_data[i].parameters,
1893 sizeof(*pool->shared_data[i].parameters) * new_size);
1894 }
1895 pool->shared_data[i].size = new_size;
1896 }
1897
1898 param->shared_data = &pool->shared_data[i];
1899 pool->shared_data[i].parameters[new_count - 1] = param;
1900
1901 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
1902 new_count);
1903
1904 return D3D_OK;
1905 }
1906
param_zero_data_func(void * dummy,struct d3dx_parameter * param)1907 static BOOL param_zero_data_func(void *dummy, struct d3dx_parameter *param)
1908 {
1909 param->data = NULL;
1910 return FALSE;
1911 }
1912
d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter * param)1913 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param)
1914 {
1915 unsigned int new_count;
1916
1917 if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
1918 return;
1919 new_count = --param->shared_data->count;
1920
1921 TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
1922
1923 if (new_count)
1924 {
1925 unsigned int i;
1926
1927 for (i = 0; i < new_count; ++i)
1928 {
1929 if (param->shared_data->parameters[i] == param)
1930 {
1931 memmove(¶m->shared_data->parameters[i],
1932 ¶m->shared_data->parameters[i + 1],
1933 sizeof(param->shared_data->parameters[i]) * (new_count - i));
1934 break;
1935 }
1936 }
1937 walk_parameter_tree(¶m->param, param_zero_data_func, NULL);
1938 }
1939 else
1940 {
1941 HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
1942 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
1943 param->shared_data->size = 0;
1944 param->shared_data = NULL;
1945 }
1946 }
1947
impl_from_ID3DXEffectPool(ID3DXEffectPool * iface)1948 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
1949 {
1950 return CONTAINING_RECORD(iface, struct d3dx_effect_pool, ID3DXEffectPool_iface);
1951 }
1952
1953 static inline struct d3dx_effect_pool *unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool *iface);
1954
impl_from_ID3DXEffect(ID3DXEffect * iface)1955 static inline struct d3dx_effect *impl_from_ID3DXEffect(ID3DXEffect *iface)
1956 {
1957 return CONTAINING_RECORD(iface, struct d3dx_effect, ID3DXEffect_iface);
1958 }
1959
1960 /*** IUnknown methods ***/
d3dx_effect_QueryInterface(ID3DXEffect * iface,REFIID riid,void ** object)1961 static HRESULT WINAPI d3dx_effect_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
1962 {
1963 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
1964
1965 if (IsEqualGUID(riid, &IID_IUnknown) ||
1966 IsEqualGUID(riid, &IID_ID3DXEffect))
1967 {
1968 iface->lpVtbl->AddRef(iface);
1969 *object = iface;
1970 return S_OK;
1971 }
1972
1973 ERR("Interface %s not found\n", debugstr_guid(riid));
1974
1975 return E_NOINTERFACE;
1976 }
1977
d3dx_effect_AddRef(ID3DXEffect * iface)1978 static ULONG WINAPI d3dx_effect_AddRef(ID3DXEffect *iface)
1979 {
1980 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
1981
1982 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
1983
1984 return InterlockedIncrement(&This->ref);
1985 }
1986
d3dx_effect_Release(ID3DXEffect * iface)1987 static ULONG WINAPI d3dx_effect_Release(ID3DXEffect *iface)
1988 {
1989 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
1990 ULONG refcount = InterlockedDecrement(&effect->ref);
1991
1992 TRACE("%p decreasing refcount to %u.\n", effect, refcount);
1993
1994 if (!refcount)
1995 d3dx_effect_cleanup(effect);
1996
1997 return refcount;
1998 }
1999
2000 /*** ID3DXBaseEffect methods ***/
d3dx_effect_GetDesc(ID3DXEffect * iface,D3DXEFFECT_DESC * desc)2001 static HRESULT WINAPI d3dx_effect_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
2002 {
2003 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2004
2005 FIXME("iface %p, desc %p partial stub.\n", iface, desc);
2006
2007 if (!desc)
2008 {
2009 WARN("Invalid argument specified.\n");
2010 return D3DERR_INVALIDCALL;
2011 }
2012
2013 /* TODO: add creator and function count. */
2014 desc->Creator = NULL;
2015 desc->Functions = 0;
2016 desc->Parameters = effect->parameter_count;
2017 desc->Techniques = effect->technique_count;
2018
2019 return D3D_OK;
2020 }
2021
d3dx_effect_GetParameterDesc(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXPARAMETER_DESC * desc)2022 static HRESULT WINAPI d3dx_effect_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter,
2023 D3DXPARAMETER_DESC *desc)
2024 {
2025 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2026 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2027
2028 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
2029
2030 if (!desc || !param)
2031 {
2032 WARN("Invalid argument specified.\n");
2033 return D3DERR_INVALIDCALL;
2034 }
2035
2036 desc->Name = param->name;
2037 desc->Semantic = param->semantic;
2038 desc->Class = param->class;
2039 desc->Type = param->type;
2040 desc->Rows = param->rows;
2041 desc->Columns = param->columns;
2042 desc->Elements = param->element_count;
2043 desc->Annotations = is_top_level_parameter(param)
2044 ? top_level_parameter_from_parameter(param)->annotation_count : 0;
2045 desc->StructMembers = param->member_count;
2046 desc->Flags = param->flags;
2047 desc->Bytes = param->bytes;
2048
2049 return D3D_OK;
2050 }
2051
d3dx_effect_GetTechniqueDesc(ID3DXEffect * iface,D3DXHANDLE technique,D3DXTECHNIQUE_DESC * desc)2052 static HRESULT WINAPI d3dx_effect_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique,
2053 D3DXTECHNIQUE_DESC *desc)
2054 {
2055 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2056 struct d3dx_technique *tech = technique ? get_valid_technique(effect, technique) : &effect->techniques[0];
2057
2058 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
2059
2060 if (!desc || !tech)
2061 {
2062 WARN("Invalid argument specified.\n");
2063 return D3DERR_INVALIDCALL;
2064 }
2065
2066 desc->Name = tech->name;
2067 desc->Passes = tech->pass_count;
2068 desc->Annotations = tech->annotation_count;
2069
2070 return D3D_OK;
2071 }
2072
d3dx_effect_GetPassDesc(ID3DXEffect * iface,D3DXHANDLE pass_handle,D3DXPASS_DESC * desc)2073 static HRESULT WINAPI d3dx_effect_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
2074 {
2075 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2076 struct d3dx_pass *pass = get_valid_pass(effect, pass_handle);
2077 unsigned int i;
2078
2079 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
2080
2081 if (!desc || !pass)
2082 {
2083 WARN("Invalid argument specified.\n");
2084 return D3DERR_INVALIDCALL;
2085 }
2086
2087 desc->Name = pass->name;
2088 desc->Annotations = pass->annotation_count;
2089
2090 desc->pVertexShaderFunction = NULL;
2091 desc->pPixelShaderFunction = NULL;
2092
2093 if (effect->flags & D3DXFX_NOT_CLONEABLE)
2094 return D3D_OK;
2095
2096 for (i = 0; i < pass->state_count; ++i)
2097 {
2098 struct d3dx_state *state = &pass->states[i];
2099
2100 if (state_table[state->operation].class == SC_VERTEXSHADER
2101 || state_table[state->operation].class == SC_PIXELSHADER)
2102 {
2103 struct d3dx_parameter *param;
2104 void *param_value;
2105 BOOL param_dirty;
2106 HRESULT hr;
2107 void *data;
2108
2109 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], ¶m_value, ¶m,
2110 FALSE, ¶m_dirty)))
2111 return hr;
2112
2113 data = param->object_id ? effect->objects[param->object_id].data : NULL;
2114 if (state_table[state->operation].class == SC_VERTEXSHADER)
2115 desc->pVertexShaderFunction = data;
2116 else
2117 desc->pPixelShaderFunction = data;
2118 }
2119 }
2120
2121 return D3D_OK;
2122 }
2123
d3dx_effect_GetFunctionDesc(ID3DXEffect * iface,D3DXHANDLE shader,D3DXFUNCTION_DESC * desc)2124 static HRESULT WINAPI d3dx_effect_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader,
2125 D3DXFUNCTION_DESC *desc)
2126 {
2127 FIXME("iface %p, shader %p, desc %p stub.\n", iface, shader, desc);
2128
2129 return E_NOTIMPL;
2130 }
2131
d3dx_effect_GetParameter(ID3DXEffect * iface,D3DXHANDLE parameter,UINT index)2132 static D3DXHANDLE WINAPI d3dx_effect_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2133 {
2134 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2135 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2136
2137 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
2138
2139 if (!parameter)
2140 {
2141 if (index < effect->parameter_count)
2142 {
2143 TRACE("Returning parameter %p.\n", &effect->parameters[index]);
2144 return get_parameter_handle(&effect->parameters[index].param);
2145 }
2146 }
2147 else
2148 {
2149 if (param && !param->element_count && index < param->member_count)
2150 {
2151 TRACE("Returning parameter %p.\n", ¶m->members[index]);
2152 return get_parameter_handle(¶m->members[index]);
2153 }
2154 }
2155
2156 WARN("Parameter not found.\n");
2157
2158 return NULL;
2159 }
2160
d3dx_effect_GetParameterByName(ID3DXEffect * iface,D3DXHANDLE parameter,const char * name)2161 static D3DXHANDLE WINAPI d3dx_effect_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter,
2162 const char *name)
2163 {
2164 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2165 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2166 D3DXHANDLE handle;
2167
2168 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
2169
2170 if (!name)
2171 {
2172 handle = get_parameter_handle(param);
2173 TRACE("Returning parameter %p.\n", handle);
2174 return handle;
2175 }
2176
2177 handle = get_parameter_handle(get_parameter_by_name(effect, param, name));
2178 TRACE("Returning parameter %p.\n", handle);
2179
2180 return handle;
2181 }
2182
d3dx_effect_GetParameterBySemantic(ID3DXEffect * iface,D3DXHANDLE parameter,const char * semantic)2183 static D3DXHANDLE WINAPI d3dx_effect_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter,
2184 const char *semantic)
2185 {
2186 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2187 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2188 struct d3dx_parameter *temp_param;
2189 unsigned int i;
2190
2191 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
2192
2193 if (!parameter)
2194 {
2195 for (i = 0; i < effect->parameter_count; ++i)
2196 {
2197 temp_param = &effect->parameters[i].param;
2198
2199 if (!temp_param->semantic)
2200 {
2201 if (!semantic)
2202 {
2203 TRACE("Returning parameter %p\n", temp_param);
2204 return get_parameter_handle(temp_param);
2205 }
2206 continue;
2207 }
2208
2209 if (!stricmp(temp_param->semantic, semantic))
2210 {
2211 TRACE("Returning parameter %p\n", temp_param);
2212 return get_parameter_handle(temp_param);
2213 }
2214 }
2215 }
2216 else if (param)
2217 {
2218 for (i = 0; i < param->member_count; ++i)
2219 {
2220 temp_param = ¶m->members[i];
2221
2222 if (!temp_param->semantic)
2223 {
2224 if (!semantic)
2225 {
2226 TRACE("Returning parameter %p\n", temp_param);
2227 return get_parameter_handle(temp_param);
2228 }
2229 continue;
2230 }
2231
2232 if (!stricmp(temp_param->semantic, semantic))
2233 {
2234 TRACE("Returning parameter %p\n", temp_param);
2235 return get_parameter_handle(temp_param);
2236 }
2237 }
2238 }
2239
2240 WARN("Parameter not found.\n");
2241
2242 return NULL;
2243 }
2244
d3dx_effect_GetParameterElement(ID3DXEffect * iface,D3DXHANDLE parameter,UINT index)2245 static D3DXHANDLE WINAPI d3dx_effect_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2246 {
2247 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2248 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2249
2250 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
2251
2252 if (!param)
2253 {
2254 if (index < effect->parameter_count)
2255 {
2256 TRACE("Returning parameter %p.\n", &effect->parameters[index]);
2257 return get_parameter_handle(&effect->parameters[index].param);
2258 }
2259 }
2260 else
2261 {
2262 if (index < param->element_count)
2263 {
2264 TRACE("Returning parameter %p.\n", ¶m->members[index]);
2265 return get_parameter_handle(¶m->members[index]);
2266 }
2267 }
2268
2269 WARN("Parameter not found.\n");
2270
2271 return NULL;
2272 }
2273
d3dx_effect_GetTechnique(ID3DXEffect * iface,UINT index)2274 static D3DXHANDLE WINAPI d3dx_effect_GetTechnique(ID3DXEffect *iface, UINT index)
2275 {
2276 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2277
2278 TRACE("iface %p, index %u.\n", iface, index);
2279
2280 if (index >= effect->technique_count)
2281 {
2282 WARN("Invalid argument specified.\n");
2283 return NULL;
2284 }
2285
2286 TRACE("Returning technique %p.\n", &effect->techniques[index]);
2287
2288 return get_technique_handle(&effect->techniques[index]);
2289 }
2290
d3dx_effect_GetTechniqueByName(ID3DXEffect * iface,const char * name)2291 static D3DXHANDLE WINAPI d3dx_effect_GetTechniqueByName(ID3DXEffect *iface, const char *name)
2292 {
2293 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2294 struct d3dx_technique *tech = get_technique_by_name(effect, name);
2295
2296 TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
2297
2298 if (tech)
2299 {
2300 D3DXHANDLE t = get_technique_handle(tech);
2301 TRACE("Returning technique %p\n", t);
2302 return t;
2303 }
2304
2305 WARN("Technique not found.\n");
2306
2307 return NULL;
2308 }
2309
d3dx_effect_GetPass(ID3DXEffect * iface,D3DXHANDLE technique,UINT index)2310 static D3DXHANDLE WINAPI d3dx_effect_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
2311 {
2312 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2313 struct d3dx_technique *tech = get_valid_technique(effect, technique);
2314
2315 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
2316
2317 if (tech && index < tech->pass_count)
2318 {
2319 TRACE("Returning pass %p\n", &tech->passes[index]);
2320 return get_pass_handle(&tech->passes[index]);
2321 }
2322
2323 WARN("Pass not found.\n");
2324
2325 return NULL;
2326 }
2327
d3dx_effect_GetPassByName(ID3DXEffect * iface,D3DXHANDLE technique,const char * name)2328 static D3DXHANDLE WINAPI d3dx_effect_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, const char *name)
2329 {
2330 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2331 struct d3dx_technique *tech = get_valid_technique(effect, technique);
2332
2333 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
2334
2335 if (tech && name)
2336 {
2337 unsigned int i;
2338
2339 for (i = 0; i < tech->pass_count; ++i)
2340 {
2341 struct d3dx_pass *pass = &tech->passes[i];
2342
2343 if (!strcmp(pass->name, name))
2344 {
2345 TRACE("Returning pass %p\n", pass);
2346 return get_pass_handle(pass);
2347 }
2348 }
2349 }
2350
2351 WARN("Pass not found.\n");
2352
2353 return NULL;
2354 }
2355
d3dx_effect_GetFunction(ID3DXEffect * iface,UINT index)2356 static D3DXHANDLE WINAPI d3dx_effect_GetFunction(ID3DXEffect *iface, UINT index)
2357 {
2358 FIXME("iface %p, index %u stub.\n", iface, index);
2359
2360 return NULL;
2361 }
2362
d3dx_effect_GetFunctionByName(ID3DXEffect * iface,const char * name)2363 static D3DXHANDLE WINAPI d3dx_effect_GetFunctionByName(ID3DXEffect *iface, const char *name)
2364 {
2365 FIXME("iface %p, name %s stub.\n", iface, debugstr_a(name));
2366
2367 return NULL;
2368 }
2369
d3dx_effect_GetAnnotation(ID3DXEffect * iface,D3DXHANDLE object,UINT index)2370 static D3DXHANDLE WINAPI d3dx_effect_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
2371 {
2372 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2373 struct d3dx_parameter *annotations = NULL;
2374 unsigned int annotation_count;
2375
2376 TRACE("iface %p, object %p, index %u.\n", iface, object, index);
2377
2378 annotation_count = get_annotation_from_object(effect, object, &annotations);
2379
2380 if (index < annotation_count)
2381 {
2382 TRACE("Returning parameter %p\n", &annotations[index]);
2383 return get_parameter_handle(&annotations[index]);
2384 }
2385
2386 WARN("Annotation not found.\n");
2387
2388 return NULL;
2389 }
2390
d3dx_effect_GetAnnotationByName(ID3DXEffect * iface,D3DXHANDLE object,const char * name)2391 static D3DXHANDLE WINAPI d3dx_effect_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object,
2392 const char *name)
2393 {
2394 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2395 struct d3dx_parameter *annotation = NULL;
2396 struct d3dx_parameter *annotations = NULL;
2397 unsigned int annotation_count;
2398
2399 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
2400
2401 if (!name)
2402 {
2403 WARN("Invalid argument specified\n");
2404 return NULL;
2405 }
2406
2407 annotation_count = get_annotation_from_object(effect, object, &annotations);
2408
2409 annotation = get_annotation_by_name(effect, annotation_count, annotations, name);
2410 if (annotation)
2411 {
2412 TRACE("Returning parameter %p\n", annotation);
2413 return get_parameter_handle(annotation);
2414 }
2415
2416 WARN("Annotation not found.\n");
2417
2418 return NULL;
2419 }
2420
d3dx_effect_SetValue(ID3DXEffect * iface,D3DXHANDLE parameter,const void * data,UINT bytes)2421 static HRESULT WINAPI d3dx_effect_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter,
2422 const void *data, UINT bytes)
2423 {
2424 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2425 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2426
2427 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
2428
2429 if (!param)
2430 {
2431 WARN("Invalid parameter %p specified.\n", parameter);
2432 return D3DERR_INVALIDCALL;
2433 }
2434 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
2435 {
2436 WARN("Parameter is a sampler, returning E_FAIL.\n");
2437 return E_FAIL;
2438 }
2439
2440 if (data && param->bytes <= bytes)
2441 return set_value(param, data, bytes, param_get_data_and_dirtify(effect, param, param->bytes, TRUE));
2442
2443 WARN("Invalid argument specified.\n");
2444
2445 return D3DERR_INVALIDCALL;
2446 }
2447
d3dx_effect_GetValue(ID3DXEffect * iface,D3DXHANDLE parameter,void * data,UINT bytes)2448 static HRESULT WINAPI d3dx_effect_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, void *data, UINT bytes)
2449 {
2450 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2451 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2452
2453 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
2454
2455 if (!param)
2456 {
2457 WARN("Invalid parameter %p specified.\n", parameter);
2458 return D3DERR_INVALIDCALL;
2459 }
2460 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
2461 {
2462 WARN("Parameter is a sampler, returning E_FAIL.\n");
2463 return E_FAIL;
2464 }
2465
2466 if (data && param->bytes <= bytes)
2467 {
2468 TRACE("Type %s.\n", debug_d3dxparameter_type(param->type));
2469
2470 switch (param->type)
2471 {
2472 case D3DXPT_VOID:
2473 case D3DXPT_BOOL:
2474 case D3DXPT_INT:
2475 case D3DXPT_FLOAT:
2476 case D3DXPT_STRING:
2477 break;
2478
2479 case D3DXPT_VERTEXSHADER:
2480 case D3DXPT_PIXELSHADER:
2481 case D3DXPT_TEXTURE:
2482 case D3DXPT_TEXTURE1D:
2483 case D3DXPT_TEXTURE2D:
2484 case D3DXPT_TEXTURE3D:
2485 case D3DXPT_TEXTURECUBE:
2486 {
2487 unsigned int i;
2488
2489 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
2490 {
2491 IUnknown *unk = ((IUnknown **)param->data)[i];
2492 if (unk)
2493 IUnknown_AddRef(unk);
2494 }
2495 break;
2496 }
2497
2498 default:
2499 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
2500 break;
2501 }
2502
2503 TRACE("Copy %u bytes.\n", param->bytes);
2504 memcpy(data, param->data, param->bytes);
2505 return D3D_OK;
2506 }
2507
2508 WARN("Parameter not found.\n");
2509
2510 return D3DERR_INVALIDCALL;
2511 }
2512
d3dx_effect_SetBool(ID3DXEffect * iface,D3DXHANDLE parameter,BOOL b)2513 static HRESULT WINAPI d3dx_effect_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
2514 {
2515 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2516 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2517
2518 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
2519
2520 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
2521 {
2522 set_number(param_get_data_and_dirtify(effect, param, sizeof(int), TRUE),
2523 param->type, &b, D3DXPT_BOOL);
2524 return D3D_OK;
2525 }
2526
2527 WARN("Parameter not found.\n");
2528
2529 return D3DERR_INVALIDCALL;
2530 }
2531
d3dx_effect_GetBool(ID3DXEffect * iface,D3DXHANDLE parameter,BOOL * b)2532 static HRESULT WINAPI d3dx_effect_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
2533 {
2534 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2535 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2536
2537 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
2538
2539 if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
2540 {
2541 set_number(b, D3DXPT_BOOL, param->data, param->type);
2542 TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
2543 return D3D_OK;
2544 }
2545
2546 WARN("Parameter not found.\n");
2547
2548 return D3DERR_INVALIDCALL;
2549 }
2550
d3dx_effect_SetBoolArray(ID3DXEffect * iface,D3DXHANDLE parameter,const BOOL * b,UINT count)2551 static HRESULT WINAPI d3dx_effect_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, const BOOL *b, UINT count)
2552 {
2553 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2554 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2555 DWORD *data;
2556
2557 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
2558
2559 if (param)
2560 {
2561 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2562
2563 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2564
2565 switch (param->class)
2566 {
2567 case D3DXPC_SCALAR:
2568 case D3DXPC_VECTOR:
2569 case D3DXPC_MATRIX_ROWS:
2570 data = param_get_data_and_dirtify(effect, param, size * sizeof(int), TRUE);
2571 for (i = 0; i < size; ++i)
2572 {
2573 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
2574 set_number(data + i, param->type, &b[i], D3DXPT_INT);
2575 }
2576 return D3D_OK;
2577
2578 case D3DXPC_OBJECT:
2579 case D3DXPC_STRUCT:
2580 break;
2581
2582 default:
2583 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2584 break;
2585 }
2586 }
2587
2588 WARN("Parameter not found.\n");
2589
2590 return D3DERR_INVALIDCALL;
2591 }
2592
d3dx_effect_GetBoolArray(ID3DXEffect * iface,D3DXHANDLE parameter,BOOL * b,UINT count)2593 static HRESULT WINAPI d3dx_effect_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
2594 {
2595 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2596 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2597
2598 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
2599
2600 if (b && param && (param->class == D3DXPC_SCALAR
2601 || param->class == D3DXPC_VECTOR
2602 || param->class == D3DXPC_MATRIX_ROWS
2603 || param->class == D3DXPC_MATRIX_COLUMNS))
2604 {
2605 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2606
2607 for (i = 0; i < size; ++i)
2608 {
2609 set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
2610 }
2611 return D3D_OK;
2612 }
2613
2614 WARN("Parameter not found.\n");
2615
2616 return D3DERR_INVALIDCALL;
2617 }
2618
d3dx_effect_SetInt(ID3DXEffect * iface,D3DXHANDLE parameter,INT n)2619 static HRESULT WINAPI d3dx_effect_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
2620 {
2621 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2622 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2623
2624 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
2625
2626 if (param && !param->element_count)
2627 {
2628 if (param->rows == 1 && param->columns == 1)
2629 {
2630 DWORD value;
2631
2632 set_number(&value, param->type, &n, D3DXPT_INT);
2633 *(DWORD *)param_get_data_and_dirtify(effect, param, sizeof(int),
2634 value != *(DWORD *)param->data) = value;
2635 return D3D_OK;
2636 }
2637
2638 /* Split the value if parameter is a vector with dimension 3 or 4. */
2639 if (param->type == D3DXPT_FLOAT
2640 && ((param->class == D3DXPC_VECTOR && param->columns != 2)
2641 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
2642 {
2643 float *data;
2644
2645 TRACE("Vector fixup.\n");
2646
2647 data = param_get_data_and_dirtify(effect, param,
2648 min(4, param->rows * param->columns) * sizeof(float), TRUE);
2649
2650 data[0] = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2651 data[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2652 data[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
2653 if (param->rows * param->columns > 3)
2654 data[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2655
2656 return D3D_OK;
2657 }
2658 }
2659
2660 WARN("Parameter not found.\n");
2661
2662 return D3DERR_INVALIDCALL;
2663 }
2664
d3dx_effect_GetInt(ID3DXEffect * iface,D3DXHANDLE parameter,INT * n)2665 static HRESULT WINAPI d3dx_effect_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
2666 {
2667 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2668 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2669
2670 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
2671
2672 if (n && param && !param->element_count)
2673 {
2674 if (param->columns == 1 && param->rows == 1)
2675 {
2676 set_number(n, D3DXPT_INT, param->data, param->type);
2677 TRACE("Returning %d.\n", *n);
2678 return D3D_OK;
2679 }
2680
2681 if (param->type == D3DXPT_FLOAT &&
2682 ((param->class == D3DXPC_VECTOR && param->columns != 2)
2683 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
2684 {
2685 TRACE("Vector fixup.\n");
2686
2687 *n = min(max(0.0f, *((float *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI;
2688 *n += ((int)(min(max(0.0f, *((float *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
2689 *n += ((int)(min(max(0.0f, *((float *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
2690 if (param->columns * param->rows > 3)
2691 *n += ((int)(min(max(0.0f, *((float *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
2692
2693 TRACE("Returning %d.\n", *n);
2694 return D3D_OK;
2695 }
2696 }
2697
2698 WARN("Parameter not found.\n");
2699
2700 return D3DERR_INVALIDCALL;
2701 }
2702
d3dx_effect_SetIntArray(ID3DXEffect * iface,D3DXHANDLE parameter,const INT * n,UINT count)2703 static HRESULT WINAPI d3dx_effect_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, const INT *n, UINT count)
2704 {
2705 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2706 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2707 DWORD *data;
2708
2709 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
2710
2711 if (param)
2712 {
2713 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2714
2715 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2716
2717 switch (param->class)
2718 {
2719 case D3DXPC_SCALAR:
2720 case D3DXPC_VECTOR:
2721 case D3DXPC_MATRIX_ROWS:
2722 data = param_get_data_and_dirtify(effect, param, size * sizeof(int), TRUE);
2723 for (i = 0; i < size; ++i)
2724 set_number(data + i, param->type, &n[i], D3DXPT_INT);
2725 return D3D_OK;
2726
2727 case D3DXPC_OBJECT:
2728 case D3DXPC_STRUCT:
2729 break;
2730
2731 default:
2732 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2733 break;
2734 }
2735 }
2736
2737 WARN("Parameter not found.\n");
2738
2739 return D3DERR_INVALIDCALL;
2740 }
2741
d3dx_effect_GetIntArray(ID3DXEffect * iface,D3DXHANDLE parameter,INT * n,UINT count)2742 static HRESULT WINAPI d3dx_effect_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
2743 {
2744 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2745 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2746
2747 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
2748
2749 if (n && param && (param->class == D3DXPC_SCALAR
2750 || param->class == D3DXPC_VECTOR
2751 || param->class == D3DXPC_MATRIX_ROWS
2752 || param->class == D3DXPC_MATRIX_COLUMNS))
2753 {
2754 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2755
2756 for (i = 0; i < size; ++i)
2757 set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
2758 return D3D_OK;
2759 }
2760
2761 WARN("Parameter not found.\n");
2762
2763 return D3DERR_INVALIDCALL;
2764 }
2765
d3dx_effect_SetFloat(ID3DXEffect * iface,D3DXHANDLE parameter,float f)2766 static HRESULT WINAPI d3dx_effect_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
2767 {
2768 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2769 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2770
2771 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
2772
2773 if (param && !param->element_count && param->rows == 1 && param->columns == 1)
2774 {
2775 DWORD value;
2776
2777 set_number(&value, param->type, &f, D3DXPT_FLOAT);
2778 *(DWORD *)param_get_data_and_dirtify(effect, param, sizeof(float),
2779 value != *(DWORD *)param->data) = value;
2780 return D3D_OK;
2781 }
2782
2783 WARN("Parameter not found.\n");
2784
2785 return D3DERR_INVALIDCALL;
2786 }
2787
d3dx_effect_GetFloat(ID3DXEffect * iface,D3DXHANDLE parameter,float * f)2788 static HRESULT WINAPI d3dx_effect_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
2789 {
2790 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2791 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2792
2793 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
2794
2795 if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
2796 {
2797 set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
2798 TRACE("Returning %f.\n", *f);
2799 return D3D_OK;
2800 }
2801
2802 WARN("Parameter not found.\n");
2803
2804 return D3DERR_INVALIDCALL;
2805 }
2806
d3dx_effect_SetFloatArray(ID3DXEffect * iface,D3DXHANDLE parameter,const float * f,UINT count)2807 static HRESULT WINAPI d3dx_effect_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter,
2808 const float *f, UINT count)
2809 {
2810 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2811 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2812 DWORD *data;
2813
2814 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
2815
2816 if (param)
2817 {
2818 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2819
2820 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2821
2822 switch (param->class)
2823 {
2824 case D3DXPC_SCALAR:
2825 case D3DXPC_VECTOR:
2826 case D3DXPC_MATRIX_ROWS:
2827 data = param_get_data_and_dirtify(effect, param, size * sizeof(float), TRUE);
2828 for (i = 0; i < size; ++i)
2829 set_number(data + i, param->type, &f[i], D3DXPT_FLOAT);
2830 return D3D_OK;
2831
2832 case D3DXPC_OBJECT:
2833 case D3DXPC_STRUCT:
2834 break;
2835
2836 default:
2837 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2838 break;
2839 }
2840 }
2841
2842 WARN("Parameter not found.\n");
2843
2844 return D3DERR_INVALIDCALL;
2845 }
2846
d3dx_effect_GetFloatArray(ID3DXEffect * iface,D3DXHANDLE parameter,float * f,UINT count)2847 static HRESULT WINAPI d3dx_effect_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, float *f, UINT count)
2848 {
2849 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2850 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2851
2852 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
2853
2854 if (f && param && (param->class == D3DXPC_SCALAR
2855 || param->class == D3DXPC_VECTOR
2856 || param->class == D3DXPC_MATRIX_ROWS
2857 || param->class == D3DXPC_MATRIX_COLUMNS))
2858 {
2859 unsigned int i, size = min(count, param->bytes / sizeof(DWORD));
2860
2861 for (i = 0; i < size; ++i)
2862 set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
2863 return D3D_OK;
2864 }
2865
2866 WARN("Parameter not found.\n");
2867
2868 return D3DERR_INVALIDCALL;
2869 }
2870
d3dx_effect_SetVector(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXVECTOR4 * vector)2871 static HRESULT WINAPI d3dx_effect_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2872 {
2873 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2874 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2875
2876 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
2877
2878 if (param && !param->element_count)
2879 {
2880 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2881
2882 switch (param->class)
2883 {
2884 case D3DXPC_SCALAR:
2885 case D3DXPC_VECTOR:
2886 if (param->type == D3DXPT_INT && param->bytes == 4)
2887 {
2888 DWORD tmp;
2889
2890 TRACE("INT fixup.\n");
2891 tmp = max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI;
2892 tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2893 tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2894 tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2895
2896 *(int *)param_get_data_and_dirtify(effect, param, sizeof(int), TRUE) = tmp;
2897 return D3D_OK;
2898 }
2899 if (param->type == D3DXPT_FLOAT)
2900 {
2901 memcpy(param_get_data_and_dirtify(effect, param, param->columns * sizeof(float), TRUE),
2902 vector, param->columns * sizeof(float));
2903 return D3D_OK;
2904 }
2905
2906 set_vector(param, vector, param_get_data_and_dirtify(effect, param, param->columns * sizeof(float), TRUE));
2907 return D3D_OK;
2908
2909 case D3DXPC_MATRIX_ROWS:
2910 case D3DXPC_OBJECT:
2911 case D3DXPC_STRUCT:
2912 break;
2913
2914 default:
2915 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2916 break;
2917 }
2918 }
2919
2920 WARN("Parameter not found.\n");
2921
2922 return D3DERR_INVALIDCALL;
2923 }
2924
d3dx_effect_GetVector(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXVECTOR4 * vector)2925 static HRESULT WINAPI d3dx_effect_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2926 {
2927 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2928 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2929
2930 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
2931
2932 if (vector && param && !param->element_count)
2933 {
2934 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2935
2936 switch (param->class)
2937 {
2938 case D3DXPC_SCALAR:
2939 case D3DXPC_VECTOR:
2940 if (param->type == D3DXPT_INT && param->bytes == 4)
2941 {
2942 TRACE("INT fixup.\n");
2943 vector->x = (((*(int *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2944 vector->y = (((*(int *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2945 vector->z = ((*(int *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2946 vector->w = (((*(int *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2947 return D3D_OK;
2948 }
2949 get_vector(param, vector);
2950 return D3D_OK;
2951
2952 case D3DXPC_MATRIX_ROWS:
2953 case D3DXPC_OBJECT:
2954 case D3DXPC_STRUCT:
2955 break;
2956
2957 default:
2958 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
2959 break;
2960 }
2961 }
2962
2963 WARN("Parameter not found.\n");
2964
2965 return D3DERR_INVALIDCALL;
2966 }
2967
d3dx_effect_SetVectorArray(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXVECTOR4 * vector,UINT count)2968 static HRESULT WINAPI d3dx_effect_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter,
2969 const D3DXVECTOR4 *vector, UINT count)
2970 {
2971 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
2972 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
2973
2974 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
2975
2976 if (param && param->element_count && param->element_count >= count)
2977 {
2978 unsigned int i;
2979 BYTE *data;
2980
2981 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
2982
2983 switch (param->class)
2984 {
2985 case D3DXPC_VECTOR:
2986 data = param_get_data_and_dirtify(effect, param, count * param->columns * sizeof(float), TRUE);
2987
2988 if (param->type == D3DXPT_FLOAT)
2989 {
2990 if (param->columns == 4)
2991 {
2992 memcpy(data, vector, count * 4 * sizeof(float));
2993 }
2994 else
2995 {
2996 for (i = 0; i < count; ++i)
2997 memcpy((float *)data + param->columns * i, vector + i,
2998 param->columns * sizeof(float));
2999 }
3000 return D3D_OK;
3001 }
3002
3003 for (i = 0; i < count; ++i)
3004 set_vector(¶m->members[i], &vector[i], data + i * param->columns * sizeof(float));
3005
3006 return D3D_OK;
3007
3008 case D3DXPC_SCALAR:
3009 case D3DXPC_MATRIX_ROWS:
3010 case D3DXPC_OBJECT:
3011 case D3DXPC_STRUCT:
3012 break;
3013
3014 default:
3015 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3016 break;
3017 }
3018 }
3019
3020 WARN("Parameter not found.\n");
3021
3022 return D3DERR_INVALIDCALL;
3023 }
3024
d3dx_effect_GetVectorArray(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXVECTOR4 * vector,UINT count)3025 static HRESULT WINAPI d3dx_effect_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3026 D3DXVECTOR4 *vector, UINT count)
3027 {
3028 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3029 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3030
3031 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3032
3033 if (!count)
3034 return D3D_OK;
3035
3036 if (vector && param && count <= param->element_count)
3037 {
3038 unsigned int i;
3039
3040 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3041
3042 switch (param->class)
3043 {
3044 case D3DXPC_VECTOR:
3045 for (i = 0; i < count; ++i)
3046 get_vector(¶m->members[i], &vector[i]);
3047 return D3D_OK;
3048
3049 case D3DXPC_SCALAR:
3050 case D3DXPC_MATRIX_ROWS:
3051 case D3DXPC_OBJECT:
3052 case D3DXPC_STRUCT:
3053 break;
3054
3055 default:
3056 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3057 break;
3058 }
3059 }
3060
3061 WARN("Parameter not found.\n");
3062
3063 return D3DERR_INVALIDCALL;
3064 }
3065
d3dx_effect_SetMatrix(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix)3066 static HRESULT WINAPI d3dx_effect_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3067 {
3068 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3069 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3070
3071 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3072
3073 if (param && !param->element_count)
3074 {
3075 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3076
3077 switch (param->class)
3078 {
3079 case D3DXPC_MATRIX_ROWS:
3080 set_matrix(param, matrix, param_get_data_and_dirtify(effect, param,
3081 param->rows * param->columns * sizeof(float), TRUE));
3082 return D3D_OK;
3083
3084 case D3DXPC_SCALAR:
3085 case D3DXPC_VECTOR:
3086 case D3DXPC_OBJECT:
3087 case D3DXPC_STRUCT:
3088 break;
3089
3090 default:
3091 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3092 break;
3093 }
3094 }
3095
3096 WARN("Parameter not found.\n");
3097
3098 return D3DERR_INVALIDCALL;
3099 }
3100
d3dx_effect_GetMatrix(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix)3101 static HRESULT WINAPI d3dx_effect_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3102 {
3103 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3104 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3105
3106 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3107
3108 if (matrix && param && !param->element_count)
3109 {
3110 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3111
3112 switch (param->class)
3113 {
3114 case D3DXPC_MATRIX_ROWS:
3115 get_matrix(param, matrix, FALSE);
3116 return D3D_OK;
3117
3118 case D3DXPC_SCALAR:
3119 case D3DXPC_VECTOR:
3120 case D3DXPC_OBJECT:
3121 case D3DXPC_STRUCT:
3122 break;
3123
3124 default:
3125 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3126 break;
3127 }
3128 }
3129
3130 WARN("Parameter not found.\n");
3131
3132 return D3DERR_INVALIDCALL;
3133 }
3134
d3dx_effect_SetMatrixArray(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix,UINT count)3135 static HRESULT WINAPI d3dx_effect_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3136 const D3DXMATRIX *matrix, UINT count)
3137 {
3138 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3139 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3140
3141 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3142
3143 if (param && param->element_count >= count)
3144 {
3145 unsigned int i;
3146 BYTE *data;
3147
3148 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3149
3150 switch (param->class)
3151 {
3152 case D3DXPC_MATRIX_ROWS:
3153 data = param_get_data_and_dirtify(effect, param, count * param->rows
3154 * param->columns * sizeof(float), TRUE);
3155
3156 for (i = 0; i < count; ++i)
3157 set_matrix(¶m->members[i], &matrix[i],
3158 data + i * param->rows * param->columns * sizeof(float));
3159
3160 return D3D_OK;
3161
3162 case D3DXPC_SCALAR:
3163 case D3DXPC_VECTOR:
3164 case D3DXPC_OBJECT:
3165 case D3DXPC_STRUCT:
3166 break;
3167
3168 default:
3169 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3170 break;
3171 }
3172 }
3173
3174 WARN("Parameter not found.\n");
3175
3176 return D3DERR_INVALIDCALL;
3177 }
3178
d3dx_effect_GetMatrixArray(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix,UINT count)3179 static HRESULT WINAPI d3dx_effect_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3180 D3DXMATRIX *matrix, UINT count)
3181 {
3182 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3183 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3184
3185 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3186
3187 if (!count)
3188 return D3D_OK;
3189
3190 if (matrix && param && count <= param->element_count)
3191 {
3192 unsigned int i;
3193
3194 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3195
3196 switch (param->class)
3197 {
3198 case D3DXPC_MATRIX_ROWS:
3199 for (i = 0; i < count; ++i)
3200 get_matrix(¶m->members[i], &matrix[i], FALSE);
3201 return D3D_OK;
3202
3203 case D3DXPC_SCALAR:
3204 case D3DXPC_VECTOR:
3205 case D3DXPC_OBJECT:
3206 case D3DXPC_STRUCT:
3207 break;
3208
3209 default:
3210 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3211 break;
3212 }
3213 }
3214
3215 WARN("Parameter not found.\n");
3216
3217 return D3DERR_INVALIDCALL;
3218 }
3219
d3dx_effect_SetMatrixPointerArray(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXMATRIX ** matrix,UINT count)3220 static HRESULT WINAPI d3dx_effect_SetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3221 const D3DXMATRIX **matrix, UINT count)
3222 {
3223 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3224 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3225
3226 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3227
3228 if (param && count <= param->element_count)
3229 {
3230 unsigned int i;
3231 BYTE *data;
3232
3233 switch (param->class)
3234 {
3235 case D3DXPC_MATRIX_ROWS:
3236 data = param_get_data_and_dirtify(effect, param, count * param->rows
3237 * param->columns * sizeof(float), TRUE);
3238
3239 for (i = 0; i < count; ++i)
3240 set_matrix(¶m->members[i], matrix[i], data + i * param->rows
3241 * param->columns * sizeof(float));
3242
3243 return D3D_OK;
3244
3245 case D3DXPC_SCALAR:
3246 case D3DXPC_VECTOR:
3247 case D3DXPC_OBJECT:
3248 break;
3249
3250 default:
3251 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3252 break;
3253 }
3254 }
3255
3256 WARN("Parameter not found.\n");
3257
3258 return D3DERR_INVALIDCALL;
3259 }
3260
d3dx_effect_GetMatrixPointerArray(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXMATRIX ** matrix,UINT count)3261 static HRESULT WINAPI d3dx_effect_GetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3262 D3DXMATRIX **matrix, UINT count)
3263 {
3264 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3265 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3266
3267 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3268
3269 if (!count)
3270 return D3D_OK;
3271
3272 if (param && matrix && count <= param->element_count)
3273 {
3274 unsigned int i;
3275
3276 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3277
3278 switch (param->class)
3279 {
3280 case D3DXPC_MATRIX_ROWS:
3281 for (i = 0; i < count; ++i)
3282 get_matrix(¶m->members[i], matrix[i], FALSE);
3283 return D3D_OK;
3284
3285 case D3DXPC_SCALAR:
3286 case D3DXPC_VECTOR:
3287 case D3DXPC_OBJECT:
3288 break;
3289
3290 default:
3291 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3292 break;
3293 }
3294 }
3295
3296 WARN("Parameter not found.\n");
3297
3298 return D3DERR_INVALIDCALL;
3299 }
3300
d3dx_effect_SetMatrixTranspose(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix)3301 static HRESULT WINAPI d3dx_effect_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter,
3302 const D3DXMATRIX *matrix)
3303 {
3304 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3305 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3306
3307 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3308
3309 if (param && !param->element_count)
3310 {
3311 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3312
3313 switch (param->class)
3314 {
3315 case D3DXPC_MATRIX_ROWS:
3316 set_matrix_transpose(param, matrix, param_get_data_and_dirtify(effect, param,
3317 param->rows * param->columns * sizeof(float), TRUE));
3318 return D3D_OK;
3319
3320 case D3DXPC_SCALAR:
3321 case D3DXPC_VECTOR:
3322 case D3DXPC_OBJECT:
3323 case D3DXPC_STRUCT:
3324 break;
3325
3326 default:
3327 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3328 break;
3329 }
3330 }
3331
3332 WARN("Parameter not found.\n");
3333
3334 return D3DERR_INVALIDCALL;
3335 }
3336
d3dx_effect_GetMatrixTranspose(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix)3337 static HRESULT WINAPI d3dx_effect_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter,
3338 D3DXMATRIX *matrix)
3339 {
3340 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3341 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3342
3343 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3344
3345 if (matrix && param && !param->element_count)
3346 {
3347 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3348
3349 switch (param->class)
3350 {
3351 case D3DXPC_SCALAR:
3352 case D3DXPC_VECTOR:
3353 get_matrix(param, matrix, FALSE);
3354 return D3D_OK;
3355
3356 case D3DXPC_MATRIX_ROWS:
3357 get_matrix(param, matrix, TRUE);
3358 return D3D_OK;
3359
3360 case D3DXPC_OBJECT:
3361 case D3DXPC_STRUCT:
3362 break;
3363
3364 default:
3365 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3366 break;
3367 }
3368 }
3369
3370 WARN("Parameter not found.\n");
3371
3372 return D3DERR_INVALIDCALL;
3373 }
3374
d3dx_effect_SetMatrixTransposeArray(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix,UINT count)3375 static HRESULT WINAPI d3dx_effect_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3376 const D3DXMATRIX *matrix, UINT count)
3377 {
3378 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3379 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3380
3381 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3382
3383 if (param && param->element_count >= count)
3384 {
3385 unsigned int i;
3386 BYTE *data;
3387
3388 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3389
3390 switch (param->class)
3391 {
3392 case D3DXPC_MATRIX_ROWS:
3393 data = param_get_data_and_dirtify(effect, param, count * param->rows
3394 * param->columns * sizeof(float), TRUE);
3395
3396 for (i = 0; i < count; ++i)
3397 set_matrix_transpose(¶m->members[i], &matrix[i], data
3398 + i * param->rows * param->columns * sizeof(float));
3399
3400 return D3D_OK;
3401
3402 case D3DXPC_SCALAR:
3403 case D3DXPC_VECTOR:
3404 case D3DXPC_OBJECT:
3405 case D3DXPC_STRUCT:
3406 break;
3407
3408 default:
3409 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3410 break;
3411 }
3412 }
3413
3414 WARN("Parameter not found.\n");
3415
3416 return D3DERR_INVALIDCALL;
3417 }
3418
d3dx_effect_GetMatrixTransposeArray(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix,UINT count)3419 static HRESULT WINAPI d3dx_effect_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3420 D3DXMATRIX *matrix, UINT count)
3421 {
3422 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3423 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3424
3425 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3426
3427 if (!count)
3428 return D3D_OK;
3429
3430 if (matrix && param && count <= param->element_count)
3431 {
3432 unsigned int i;
3433
3434 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3435
3436 switch (param->class)
3437 {
3438 case D3DXPC_MATRIX_ROWS:
3439 for (i = 0; i < count; ++i)
3440 get_matrix(¶m->members[i], &matrix[i], TRUE);
3441 return D3D_OK;
3442
3443 case D3DXPC_SCALAR:
3444 case D3DXPC_VECTOR:
3445 case D3DXPC_OBJECT:
3446 case D3DXPC_STRUCT:
3447 break;
3448
3449 default:
3450 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3451 break;
3452 }
3453 }
3454
3455 WARN("Parameter not found.\n");
3456
3457 return D3DERR_INVALIDCALL;
3458 }
3459
d3dx_effect_SetMatrixTransposePointerArray(ID3DXEffect * iface,D3DXHANDLE parameter,const D3DXMATRIX ** matrix,UINT count)3460 static HRESULT WINAPI d3dx_effect_SetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3461 const D3DXMATRIX **matrix, UINT count)
3462 {
3463 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3464 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3465
3466 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3467
3468 if (param && count <= param->element_count)
3469 {
3470 unsigned int i;
3471 BYTE *data;
3472
3473 switch (param->class)
3474 {
3475 case D3DXPC_MATRIX_ROWS:
3476 data = param_get_data_and_dirtify(effect, param, count * param->rows
3477 * param->columns * sizeof(float), TRUE);
3478
3479 for (i = 0; i < count; ++i)
3480 set_matrix_transpose(¶m->members[i], matrix[i], data
3481 + i * param->rows * param->columns * sizeof(float));
3482
3483 return D3D_OK;
3484
3485 case D3DXPC_SCALAR:
3486 case D3DXPC_VECTOR:
3487 case D3DXPC_OBJECT:
3488 break;
3489
3490 default:
3491 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3492 break;
3493 }
3494 }
3495
3496 WARN("Parameter not found.\n");
3497
3498 return D3DERR_INVALIDCALL;
3499 }
3500
d3dx_effect_GetMatrixTransposePointerArray(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXMATRIX ** matrix,UINT count)3501 static HRESULT WINAPI d3dx_effect_GetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter,
3502 D3DXMATRIX **matrix, UINT count)
3503 {
3504 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3505 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3506
3507 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3508
3509 if (!count)
3510 return D3D_OK;
3511
3512 if (matrix && param && count <= param->element_count)
3513 {
3514 unsigned int i;
3515
3516 TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
3517
3518 switch (param->class)
3519 {
3520 case D3DXPC_MATRIX_ROWS:
3521 for (i = 0; i < count; ++i)
3522 get_matrix(¶m->members[i], matrix[i], TRUE);
3523 return D3D_OK;
3524
3525 case D3DXPC_SCALAR:
3526 case D3DXPC_VECTOR:
3527 case D3DXPC_OBJECT:
3528 break;
3529
3530 default:
3531 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param->class));
3532 break;
3533 }
3534 }
3535
3536 WARN("Parameter not found.\n");
3537
3538 return D3DERR_INVALIDCALL;
3539 }
3540
d3dx_effect_SetString(ID3DXEffect * iface,D3DXHANDLE parameter,const char * string)3541 static HRESULT WINAPI d3dx_effect_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char *string)
3542 {
3543 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3544 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3545
3546 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
3547
3548 if (param && param->type == D3DXPT_STRING)
3549 return set_string(param_get_data_and_dirtify(effect, param, sizeof(void *), TRUE), string);
3550
3551 WARN("Parameter not found.\n");
3552
3553 return D3DERR_INVALIDCALL;
3554 }
3555
d3dx_effect_GetString(ID3DXEffect * iface,D3DXHANDLE parameter,const char ** string)3556 static HRESULT WINAPI d3dx_effect_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, const char **string)
3557 {
3558 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3559 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3560
3561 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string);
3562
3563 if (string && param && !param->element_count && param->type == D3DXPT_STRING)
3564 {
3565 *string = *(const char **)param->data;
3566 TRACE("Returning %s.\n", debugstr_a(*string));
3567 return D3D_OK;
3568 }
3569
3570 WARN("Parameter not found.\n");
3571
3572 return D3DERR_INVALIDCALL;
3573 }
3574
d3dx_effect_SetTexture(ID3DXEffect * iface,D3DXHANDLE parameter,IDirect3DBaseTexture9 * texture)3575 static HRESULT WINAPI d3dx_effect_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter,
3576 IDirect3DBaseTexture9 *texture)
3577 {
3578 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3579 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3580
3581 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3582
3583 if (param && !param->element_count
3584 && (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
3585 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
3586 || param->type == D3DXPT_TEXTURECUBE))
3587 {
3588 IDirect3DBaseTexture9 **data = param_get_data_and_dirtify(effect, param,
3589 sizeof(void *), texture != *(IDirect3DBaseTexture9 **)param->data);
3590 IDirect3DBaseTexture9 *old_texture = *data;
3591
3592 *data = texture;
3593
3594 if (texture == old_texture)
3595 return D3D_OK;
3596
3597 if (texture)
3598 IDirect3DBaseTexture9_AddRef(texture);
3599 if (old_texture)
3600 IDirect3DBaseTexture9_Release(old_texture);
3601
3602 return D3D_OK;
3603 }
3604
3605 WARN("Parameter not found.\n");
3606
3607 return D3DERR_INVALIDCALL;
3608 }
3609
d3dx_effect_GetTexture(ID3DXEffect * iface,D3DXHANDLE parameter,IDirect3DBaseTexture9 ** texture)3610 static HRESULT WINAPI d3dx_effect_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter,
3611 IDirect3DBaseTexture9 **texture)
3612 {
3613 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3614 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3615
3616 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture);
3617
3618 if (texture && param && !param->element_count
3619 && (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
3620 || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
3621 || param->type == D3DXPT_TEXTURECUBE))
3622 {
3623 *texture = *(IDirect3DBaseTexture9 **)param->data;
3624 if (*texture)
3625 IDirect3DBaseTexture9_AddRef(*texture);
3626 TRACE("Returning %p.\n", *texture);
3627 return D3D_OK;
3628 }
3629
3630 WARN("Parameter not found.\n");
3631
3632 return D3DERR_INVALIDCALL;
3633 }
3634
d3dx_effect_GetPixelShader(ID3DXEffect * iface,D3DXHANDLE parameter,IDirect3DPixelShader9 ** shader)3635 static HRESULT WINAPI d3dx_effect_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter,
3636 IDirect3DPixelShader9 **shader)
3637 {
3638 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3639 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3640
3641 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3642
3643 if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
3644 {
3645 if ((*shader = *(IDirect3DPixelShader9 **)param->data))
3646 IDirect3DPixelShader9_AddRef(*shader);
3647 TRACE("Returning %p.\n", *shader);
3648 return D3D_OK;
3649 }
3650
3651 WARN("Parameter not found.\n");
3652
3653 return D3DERR_INVALIDCALL;
3654 }
3655
d3dx_effect_GetVertexShader(ID3DXEffect * iface,D3DXHANDLE parameter,IDirect3DVertexShader9 ** shader)3656 static HRESULT WINAPI d3dx_effect_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter,
3657 IDirect3DVertexShader9 **shader)
3658 {
3659 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3660 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3661
3662 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader);
3663
3664 if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
3665 {
3666 if ((*shader = *(IDirect3DVertexShader9 **)param->data))
3667 IDirect3DVertexShader9_AddRef(*shader);
3668 TRACE("Returning %p.\n", *shader);
3669 return D3D_OK;
3670 }
3671
3672 WARN("Parameter not found.\n");
3673
3674 return D3DERR_INVALIDCALL;
3675 }
3676
d3dx_effect_SetArrayRange(ID3DXEffect * iface,D3DXHANDLE parameter,UINT start,UINT end)3677 static HRESULT WINAPI d3dx_effect_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3678 {
3679 FIXME("iface %p, parameter %p, start %u, end %u stub.\n", iface, parameter, start, end);
3680
3681 return E_NOTIMPL;
3682 }
3683
3684 /*** ID3DXEffect methods ***/
d3dx_effect_GetPool(ID3DXEffect * iface,ID3DXEffectPool ** pool)3685 static HRESULT WINAPI d3dx_effect_GetPool(ID3DXEffect *iface, ID3DXEffectPool **pool)
3686 {
3687 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3688
3689 TRACE("iface %p, pool %p.\n", effect, pool);
3690
3691 if (!pool)
3692 {
3693 WARN("Invalid argument supplied.\n");
3694 return D3DERR_INVALIDCALL;
3695 }
3696
3697 *pool = NULL;
3698 if (effect->pool)
3699 {
3700 *pool = &effect->pool->ID3DXEffectPool_iface;
3701 (*pool)->lpVtbl->AddRef(*pool);
3702 }
3703
3704 TRACE("Returning pool %p.\n", *pool);
3705
3706 return S_OK;
3707 }
3708
d3dx_effect_SetTechnique(ID3DXEffect * iface,D3DXHANDLE technique)3709 static HRESULT WINAPI d3dx_effect_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3710 {
3711 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3712 struct d3dx_technique *tech = get_valid_technique(effect, technique);
3713
3714 TRACE("iface %p, technique %p\n", iface, technique);
3715
3716 if (tech)
3717 {
3718 effect->active_technique = tech;
3719 TRACE("Technique %p\n", tech);
3720 return D3D_OK;
3721 }
3722
3723 WARN("Technique not found.\n");
3724
3725 return D3DERR_INVALIDCALL;
3726 }
3727
d3dx_effect_GetCurrentTechnique(ID3DXEffect * iface)3728 static D3DXHANDLE WINAPI d3dx_effect_GetCurrentTechnique(ID3DXEffect *iface)
3729 {
3730 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
3731
3732 TRACE("iface %p\n", This);
3733
3734 return get_technique_handle(This->active_technique);
3735 }
3736
d3dx_effect_ValidateTechnique(ID3DXEffect * iface,D3DXHANDLE technique)3737 static HRESULT WINAPI d3dx_effect_ValidateTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3738 {
3739 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3740 struct d3dx_technique *tech = get_valid_technique(effect, technique);
3741 HRESULT ret = D3D_OK;
3742 unsigned int i, j;
3743
3744 FIXME("iface %p, technique %p semi-stub.\n", iface, technique);
3745
3746 if (!tech)
3747 {
3748 ret = D3DERR_INVALIDCALL;
3749 goto done;
3750 }
3751 for (i = 0; i < tech->pass_count; ++i)
3752 {
3753 struct d3dx_pass *pass = &tech->passes[i];
3754
3755 for (j = 0; j < pass->state_count; ++j)
3756 {
3757 struct d3dx_state *state = &pass->states[j];
3758
3759 if (state_table[state->operation].class == SC_VERTEXSHADER
3760 || state_table[state->operation].class == SC_PIXELSHADER)
3761 {
3762 struct d3dx_parameter *param;
3763 void *param_value;
3764 BOOL param_dirty;
3765 HRESULT hr;
3766
3767 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[j], ¶m_value, ¶m,
3768 FALSE, ¶m_dirty)))
3769 return hr;
3770
3771 if (param->object_id && effect->objects[param->object_id].creation_failed)
3772 {
3773 ret = E_FAIL;
3774 goto done;
3775 }
3776 }
3777 }
3778 }
3779 done:
3780 TRACE("Returning %#x.\n", ret);
3781 return ret;
3782 }
3783
d3dx_effect_FindNextValidTechnique(ID3DXEffect * iface,D3DXHANDLE technique,D3DXHANDLE * next_technique)3784 static HRESULT WINAPI d3dx_effect_FindNextValidTechnique(ID3DXEffect *iface, D3DXHANDLE technique,
3785 D3DXHANDLE *next_technique)
3786 {
3787 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3788 struct d3dx_technique *prev_tech, *tech;
3789 unsigned int i;
3790
3791 TRACE("iface %p, technique %p, next_technique %p.\n", iface, technique, next_technique);
3792
3793 if (technique)
3794 {
3795 if (!(prev_tech = get_valid_technique(effect, technique)))
3796 return D3DERR_INVALIDCALL;
3797
3798 for (i = 0; i < effect->technique_count; ++i)
3799 {
3800 tech = &effect->techniques[i];
3801 if (tech == prev_tech)
3802 {
3803 ++i;
3804 break;
3805 }
3806 }
3807 }
3808 else
3809 {
3810 i = 0;
3811 }
3812
3813 for (; i < effect->technique_count; ++i)
3814 {
3815 tech = &effect->techniques[i];
3816 if (SUCCEEDED(d3dx_effect_ValidateTechnique(iface, get_technique_handle(tech))))
3817 {
3818 *next_technique = get_technique_handle(tech);
3819 return D3D_OK;
3820 }
3821 }
3822
3823 *next_technique = get_technique_handle(&effect->techniques[0]);
3824 return S_FALSE;
3825 }
3826
3827 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
3828 void *data);
3829
walk_param_eval_dep(struct d3dx_param_eval * param_eval,walk_parameter_dep_func param_func,void * data)3830 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func,
3831 void *data)
3832 {
3833 struct d3dx_parameter **params;
3834 unsigned int i, param_count;
3835
3836 if (!param_eval)
3837 return FALSE;
3838
3839 params = param_eval->shader_inputs.inputs_param;
3840 param_count = param_eval->shader_inputs.input_count;
3841 for (i = 0; i < param_count; ++i)
3842 {
3843 if (walk_parameter_dep(params[i], param_func, data))
3844 return TRUE;
3845 }
3846
3847 params = param_eval->pres.inputs.inputs_param;
3848 param_count = param_eval->pres.inputs.input_count;
3849 for (i = 0; i < param_count; ++i)
3850 {
3851 if (walk_parameter_dep(params[i], param_func, data))
3852 return TRUE;
3853 }
3854 return FALSE;
3855 }
3856
walk_state_dep(struct d3dx_state * state,walk_parameter_dep_func param_func,void * data)3857 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func,
3858 void *data)
3859 {
3860 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type))
3861 {
3862 if (walk_parameter_dep(&state->parameter, param_func, data))
3863 return TRUE;
3864 }
3865 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER)
3866 {
3867 if (walk_parameter_dep(state->referenced_param, param_func, data))
3868 return TRUE;
3869 }
3870 return walk_param_eval_dep(state->parameter.param_eval, param_func, data);
3871 }
3872
walk_parameter_dep(struct d3dx_parameter * param,walk_parameter_dep_func param_func,void * data)3873 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func,
3874 void *data)
3875 {
3876 unsigned int i;
3877 unsigned int member_count;
3878
3879 param = ¶m->top_level_param->param;
3880 if (param_func(data, param))
3881 return TRUE;
3882
3883 if (walk_param_eval_dep(param->param_eval, param_func, data))
3884 return TRUE;
3885
3886 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
3887 {
3888 struct d3dx_sampler *sampler;
3889 unsigned int sampler_idx;
3890 unsigned int samplers_count = max(param->element_count, 1);
3891
3892 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx)
3893 {
3894 sampler = param->element_count ? param->members[sampler_idx].data : param->data;
3895 for (i = 0; i < sampler->state_count; ++i)
3896 {
3897 if (walk_state_dep(&sampler->states[i], param_func, data))
3898 return TRUE;
3899 }
3900 }
3901 return FALSE;
3902 }
3903
3904 member_count = param->element_count ? param->element_count : param->member_count;
3905 for (i = 0; i < member_count; ++i)
3906 {
3907 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data))
3908 return TRUE;
3909 }
3910
3911 return FALSE;
3912 }
3913
is_parameter_used(struct d3dx_parameter * param,struct d3dx_technique * tech)3914 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech)
3915 {
3916 unsigned int i, j;
3917 struct d3dx_pass *pass;
3918
3919 if (!tech || !param)
3920 return FALSE;
3921
3922 for (i = 0; i < tech->pass_count; ++i)
3923 {
3924 pass = &tech->passes[i];
3925 for (j = 0; j < pass->state_count; ++j)
3926 {
3927 if (walk_state_dep(&pass->states[j], is_same_parameter, param))
3928 return TRUE;
3929 }
3930 }
3931 return FALSE;
3932 }
3933
d3dx_effect_IsParameterUsed(ID3DXEffect * iface,D3DXHANDLE parameter,D3DXHANDLE technique)3934 static BOOL WINAPI d3dx_effect_IsParameterUsed(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXHANDLE technique)
3935 {
3936 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3937 struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
3938 struct d3dx_technique *tech = get_valid_technique(effect, technique);
3939 BOOL ret;
3940
3941 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique);
3942 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech);
3943
3944 ret = is_parameter_used(param, tech);
3945 TRACE("Returning %#x.\n", ret);
3946 return ret;
3947 }
3948
d3dx_effect_Begin(ID3DXEffect * iface,UINT * passes,DWORD flags)3949 static HRESULT WINAPI d3dx_effect_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
3950 {
3951 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
3952 struct d3dx_technique *technique = effect->active_technique;
3953
3954 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags);
3955
3956 if (technique)
3957 {
3958 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE))
3959 WARN("Invalid flags (%#x) specified.\n", flags);
3960
3961 if (flags & D3DXFX_DONOTSAVESTATE)
3962 {
3963 TRACE("State capturing disabled.\n");
3964 }
3965 else
3966 {
3967 HRESULT hr;
3968 unsigned int i;
3969
3970 if (!technique->saved_state)
3971 {
3972 ID3DXEffectStateManager *manager;
3973
3974 manager = effect->manager;
3975 effect->manager = NULL;
3976 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
3977 ERR("BeginStateBlock failed, hr %#x.\n", hr);
3978 for (i = 0; i < technique->pass_count; i++)
3979 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE);
3980 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
3981 ERR("EndStateBlock failed, hr %#x.\n", hr);
3982 effect->manager = manager;
3983 }
3984 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
3985 ERR("StateBlock Capture failed, hr %#x.\n", hr);
3986 }
3987
3988 if (passes)
3989 *passes = technique->pass_count;
3990 effect->started = TRUE;
3991 effect->begin_flags = flags;
3992
3993 return D3D_OK;
3994 }
3995
3996 WARN("Invalid argument supplied.\n");
3997
3998 return D3DERR_INVALIDCALL;
3999 }
4000
d3dx_effect_BeginPass(ID3DXEffect * iface,UINT pass)4001 static HRESULT WINAPI d3dx_effect_BeginPass(ID3DXEffect *iface, UINT pass)
4002 {
4003 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4004 struct d3dx_technique *technique = effect->active_technique;
4005
4006 TRACE("iface %p, pass %u\n", effect, pass);
4007
4008 if (technique && pass < technique->pass_count && !effect->active_pass)
4009 {
4010 HRESULT hr;
4011
4012 memset(effect->current_light, 0, sizeof(effect->current_light));
4013 memset(&effect->current_material, 0, sizeof(effect->current_material));
4014
4015 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE)))
4016 effect->active_pass = &technique->passes[pass];
4017 return hr;
4018 }
4019
4020 WARN("Invalid argument supplied.\n");
4021
4022 return D3DERR_INVALIDCALL;
4023 }
4024
d3dx_effect_CommitChanges(ID3DXEffect * iface)4025 static HRESULT WINAPI d3dx_effect_CommitChanges(ID3DXEffect *iface)
4026 {
4027 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4028
4029 TRACE("iface %p.\n", iface);
4030
4031 if (!effect->active_pass)
4032 {
4033 WARN("Called without an active pass.\n");
4034 return D3D_OK;
4035 }
4036 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE);
4037 }
4038
d3dx_effect_EndPass(ID3DXEffect * iface)4039 static HRESULT WINAPI d3dx_effect_EndPass(ID3DXEffect *iface)
4040 {
4041 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4042
4043 TRACE("iface %p\n", This);
4044
4045 if (This->active_pass)
4046 {
4047 This->active_pass = NULL;
4048 return D3D_OK;
4049 }
4050
4051 WARN("Invalid call.\n");
4052
4053 return D3DERR_INVALIDCALL;
4054 }
4055
d3dx_effect_End(ID3DXEffect * iface)4056 static HRESULT WINAPI d3dx_effect_End(ID3DXEffect *iface)
4057 {
4058 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4059 struct d3dx_technique *technique = effect->active_technique;
4060
4061 TRACE("iface %p.\n", iface);
4062
4063 if (!effect->started)
4064 return D3D_OK;
4065
4066 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE)
4067 {
4068 TRACE("State restoring disabled.\n");
4069 }
4070 else
4071 {
4072 HRESULT hr;
4073
4074 if (technique && technique->saved_state)
4075 {
4076 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
4077 ERR("State block apply failed, hr %#x.\n", hr);
4078 }
4079 else
4080 ERR("No saved state.\n");
4081 }
4082
4083 effect->started = FALSE;
4084
4085 return D3D_OK;
4086 }
4087
d3dx_effect_GetDevice(ID3DXEffect * iface,struct IDirect3DDevice9 ** device)4088 static HRESULT WINAPI d3dx_effect_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device)
4089 {
4090 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4091
4092 TRACE("iface %p, device %p\n", This, device);
4093
4094 if (!device)
4095 {
4096 WARN("Invalid argument supplied.\n");
4097 return D3DERR_INVALIDCALL;
4098 }
4099
4100 IDirect3DDevice9_AddRef(This->device);
4101
4102 *device = This->device;
4103
4104 TRACE("Returning device %p\n", *device);
4105
4106 return S_OK;
4107 }
4108
param_on_lost_device(void * data,struct d3dx_parameter * param)4109 static BOOL param_on_lost_device(void *data, struct d3dx_parameter *param)
4110 {
4111 struct IDirect3DVolumeTexture9 *volume_texture;
4112 struct IDirect3DCubeTexture9 *cube_texture;
4113 struct IDirect3DTexture9 *texture;
4114 D3DSURFACE_DESC surface_desc;
4115 D3DVOLUME_DESC volume_desc;
4116
4117 if (param->class == D3DXPC_OBJECT && !param->element_count)
4118 {
4119 switch (param->type)
4120 {
4121 case D3DXPT_TEXTURE:
4122 case D3DXPT_TEXTURE1D:
4123 case D3DXPT_TEXTURE2D:
4124 texture = *(IDirect3DTexture9 **)param->data;
4125 if (!texture)
4126 return FALSE;
4127 IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
4128 if (surface_desc.Pool != D3DPOOL_DEFAULT)
4129 return FALSE;
4130 break;
4131 case D3DXPT_TEXTURE3D:
4132 volume_texture = *(IDirect3DVolumeTexture9 **)param->data;
4133 if (!volume_texture)
4134 return FALSE;
4135 IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
4136 if (volume_desc.Pool != D3DPOOL_DEFAULT)
4137 return FALSE;
4138 break;
4139 case D3DXPT_TEXTURECUBE:
4140 cube_texture = *(IDirect3DCubeTexture9 **)param->data;
4141 if (!cube_texture)
4142 return FALSE;
4143 IDirect3DTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
4144 if (surface_desc.Pool != D3DPOOL_DEFAULT)
4145 return FALSE;
4146 break;
4147 default:
4148 return FALSE;
4149 }
4150 IUnknown_Release(*(IUnknown **)param->data);
4151 *(IUnknown **)param->data = NULL;
4152 }
4153 return FALSE;
4154 }
4155
d3dx_effect_OnLostDevice(ID3DXEffect * iface)4156 static HRESULT WINAPI d3dx_effect_OnLostDevice(ID3DXEffect *iface)
4157 {
4158 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4159 unsigned int i;
4160
4161 TRACE("iface %p.\n", iface);
4162
4163 for (i = 0; i < effect->parameter_count; ++i)
4164 walk_parameter_tree(&effect->parameters[i].param, param_on_lost_device, NULL);
4165
4166 return D3D_OK;
4167 }
4168
d3dx_effect_OnResetDevice(ID3DXEffect * iface)4169 static HRESULT WINAPI d3dx_effect_OnResetDevice(ID3DXEffect *iface)
4170 {
4171 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4172
4173 FIXME("(%p)->(): stub\n", This);
4174
4175 return E_NOTIMPL;
4176 }
4177
d3dx_effect_SetStateManager(ID3DXEffect * iface,ID3DXEffectStateManager * manager)4178 static HRESULT WINAPI d3dx_effect_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager)
4179 {
4180 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4181
4182 TRACE("iface %p, manager %p\n", This, manager);
4183
4184 if (manager) IUnknown_AddRef(manager);
4185 if (This->manager) IUnknown_Release(This->manager);
4186
4187 This->manager = manager;
4188
4189 return D3D_OK;
4190 }
4191
d3dx_effect_GetStateManager(ID3DXEffect * iface,ID3DXEffectStateManager ** manager)4192 static HRESULT WINAPI d3dx_effect_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager)
4193 {
4194 struct d3dx_effect *This = impl_from_ID3DXEffect(iface);
4195
4196 TRACE("iface %p, manager %p\n", This, manager);
4197
4198 if (!manager)
4199 {
4200 WARN("Invalid argument supplied.\n");
4201 return D3DERR_INVALIDCALL;
4202 }
4203
4204 if (This->manager) IUnknown_AddRef(This->manager);
4205 *manager = This->manager;
4206
4207 return D3D_OK;
4208 }
4209
d3dx_effect_BeginParameterBlock(ID3DXEffect * iface)4210 static HRESULT WINAPI d3dx_effect_BeginParameterBlock(ID3DXEffect *iface)
4211 {
4212 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4213
4214 TRACE("iface %p.\n", iface);
4215
4216 if (effect->current_parameter_block)
4217 {
4218 WARN("Parameter block is already started.\n");
4219 return D3DERR_INVALIDCALL;
4220 }
4221
4222 effect->current_parameter_block = heap_alloc_zero(sizeof(*effect->current_parameter_block));
4223 memcpy(effect->current_parameter_block->magic_string, parameter_block_magic_string,
4224 sizeof(parameter_block_magic_string));
4225 effect->current_parameter_block->effect = effect;
4226
4227 return D3D_OK;
4228 }
4229
d3dx_effect_EndParameterBlock(ID3DXEffect * iface)4230 static D3DXHANDLE WINAPI d3dx_effect_EndParameterBlock(ID3DXEffect *iface)
4231 {
4232 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4233 struct d3dx_parameter_block *ret;
4234
4235 TRACE("iface %p.\n", iface);
4236
4237 if (!effect->current_parameter_block)
4238 {
4239 WARN("No active parameter block.\n");
4240 return NULL;
4241 }
4242 ret = effect->current_parameter_block;
4243
4244 ret->buffer = heap_realloc(ret->buffer, ret->offset);
4245 ret->size = ret->offset;
4246
4247 effect->current_parameter_block = NULL;
4248 list_add_tail(&effect->parameter_block_list, &ret->entry);
4249 return (D3DXHANDLE)ret;
4250 }
4251
d3dx_effect_ApplyParameterBlock(ID3DXEffect * iface,D3DXHANDLE parameter_block)4252 static HRESULT WINAPI d3dx_effect_ApplyParameterBlock(ID3DXEffect *iface, D3DXHANDLE parameter_block)
4253 {
4254 struct d3dx_parameter_block *block = get_valid_parameter_block(parameter_block);
4255 struct d3dx_recorded_parameter *record;
4256
4257 TRACE("iface %p, parameter_block %p.\n", iface, parameter_block);
4258
4259 if (!block || !block->offset)
4260 return D3DERR_INVALIDCALL;
4261
4262 record = (struct d3dx_recorded_parameter *)block->buffer;
4263 while ((BYTE *)record < block->buffer + block->offset)
4264 {
4265 set_value(record->param, record + 1, record->bytes,
4266 param_get_data_and_dirtify(block->effect, record->param, record->bytes, TRUE));
4267 record = (struct d3dx_recorded_parameter *)((BYTE *)record + get_recorded_parameter_size(record));
4268 }
4269 assert((BYTE *)record == block->buffer + block->offset);
4270 return D3D_OK;
4271 }
4272
4273 #if D3DX_SDK_VERSION >= 26
d3dx_effect_DeleteParameterBlock(ID3DXEffect * iface,D3DXHANDLE parameter_block)4274 static HRESULT WINAPI d3dx_effect_DeleteParameterBlock(ID3DXEffect *iface, D3DXHANDLE parameter_block)
4275 {
4276 struct d3dx_parameter_block *block = get_valid_parameter_block(parameter_block);
4277 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4278 struct d3dx_parameter_block *b;
4279
4280 TRACE("iface %p, parameter_block %p.\n", iface, parameter_block);
4281
4282 if (!block)
4283 return D3DERR_INVALIDCALL;
4284
4285 LIST_FOR_EACH_ENTRY(b, &effect->parameter_block_list, struct d3dx_parameter_block, entry)
4286 {
4287 if (b == block)
4288 {
4289 list_remove(&b->entry);
4290 free_parameter_block(b);
4291 return D3D_OK;
4292 }
4293 }
4294
4295 WARN("Block is not found in issued block list, not freeing memory.\n");
4296 return D3DERR_INVALIDCALL;
4297 }
4298 #endif
4299
d3dx_effect_CloneEffect(ID3DXEffect * iface,IDirect3DDevice9 * device,ID3DXEffect ** new_effect)4300 static HRESULT WINAPI d3dx_effect_CloneEffect(ID3DXEffect *iface, IDirect3DDevice9 *device,
4301 ID3DXEffect **new_effect)
4302 {
4303 struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
4304
4305 FIXME("iface %p, device %p, new_effect %p stub.\n", effect, device, new_effect);
4306
4307 if (!new_effect)
4308 return D3DERR_INVALIDCALL;
4309
4310 if (effect->flags & D3DXFX_NOT_CLONEABLE)
4311 return E_FAIL;
4312
4313 if (!device)
4314 return D3DERR_INVALIDCALL;
4315
4316 iface->lpVtbl->AddRef(iface);
4317 *new_effect = iface;
4318 return S_OK;
4319 }
4320
4321 #if D3DX_SDK_VERSION >= 27
d3dx_effect_SetRawValue(ID3DXEffect * iface,D3DXHANDLE parameter,const void * data,UINT byte_offset,UINT bytes)4322 static HRESULT WINAPI d3dx_effect_SetRawValue(ID3DXEffect *iface, D3DXHANDLE parameter, const void *data,
4323 UINT byte_offset, UINT bytes)
4324 {
4325 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4326 iface, parameter, data, byte_offset, bytes);
4327
4328 return E_NOTIMPL;
4329 }
4330 #endif
4331
4332 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
4333 {
4334 /*** IUnknown methods ***/
4335 d3dx_effect_QueryInterface,
4336 d3dx_effect_AddRef,
4337 d3dx_effect_Release,
4338 /*** ID3DXBaseEffect methods ***/
4339 d3dx_effect_GetDesc,
4340 d3dx_effect_GetParameterDesc,
4341 d3dx_effect_GetTechniqueDesc,
4342 d3dx_effect_GetPassDesc,
4343 d3dx_effect_GetFunctionDesc,
4344 d3dx_effect_GetParameter,
4345 d3dx_effect_GetParameterByName,
4346 d3dx_effect_GetParameterBySemantic,
4347 d3dx_effect_GetParameterElement,
4348 d3dx_effect_GetTechnique,
4349 d3dx_effect_GetTechniqueByName,
4350 d3dx_effect_GetPass,
4351 d3dx_effect_GetPassByName,
4352 d3dx_effect_GetFunction,
4353 d3dx_effect_GetFunctionByName,
4354 d3dx_effect_GetAnnotation,
4355 d3dx_effect_GetAnnotationByName,
4356 d3dx_effect_SetValue,
4357 d3dx_effect_GetValue,
4358 d3dx_effect_SetBool,
4359 d3dx_effect_GetBool,
4360 d3dx_effect_SetBoolArray,
4361 d3dx_effect_GetBoolArray,
4362 d3dx_effect_SetInt,
4363 d3dx_effect_GetInt,
4364 d3dx_effect_SetIntArray,
4365 d3dx_effect_GetIntArray,
4366 d3dx_effect_SetFloat,
4367 d3dx_effect_GetFloat,
4368 d3dx_effect_SetFloatArray,
4369 d3dx_effect_GetFloatArray,
4370 d3dx_effect_SetVector,
4371 d3dx_effect_GetVector,
4372 d3dx_effect_SetVectorArray,
4373 d3dx_effect_GetVectorArray,
4374 d3dx_effect_SetMatrix,
4375 d3dx_effect_GetMatrix,
4376 d3dx_effect_SetMatrixArray,
4377 d3dx_effect_GetMatrixArray,
4378 d3dx_effect_SetMatrixPointerArray,
4379 d3dx_effect_GetMatrixPointerArray,
4380 d3dx_effect_SetMatrixTranspose,
4381 d3dx_effect_GetMatrixTranspose,
4382 d3dx_effect_SetMatrixTransposeArray,
4383 d3dx_effect_GetMatrixTransposeArray,
4384 d3dx_effect_SetMatrixTransposePointerArray,
4385 d3dx_effect_GetMatrixTransposePointerArray,
4386 d3dx_effect_SetString,
4387 d3dx_effect_GetString,
4388 d3dx_effect_SetTexture,
4389 d3dx_effect_GetTexture,
4390 d3dx_effect_GetPixelShader,
4391 d3dx_effect_GetVertexShader,
4392 d3dx_effect_SetArrayRange,
4393 /*** ID3DXEffect methods ***/
4394 d3dx_effect_GetPool,
4395 d3dx_effect_SetTechnique,
4396 d3dx_effect_GetCurrentTechnique,
4397 d3dx_effect_ValidateTechnique,
4398 d3dx_effect_FindNextValidTechnique,
4399 d3dx_effect_IsParameterUsed,
4400 d3dx_effect_Begin,
4401 d3dx_effect_BeginPass,
4402 d3dx_effect_CommitChanges,
4403 d3dx_effect_EndPass,
4404 d3dx_effect_End,
4405 d3dx_effect_GetDevice,
4406 d3dx_effect_OnLostDevice,
4407 d3dx_effect_OnResetDevice,
4408 d3dx_effect_SetStateManager,
4409 d3dx_effect_GetStateManager,
4410 d3dx_effect_BeginParameterBlock,
4411 d3dx_effect_EndParameterBlock,
4412 d3dx_effect_ApplyParameterBlock,
4413 #if D3DX_SDK_VERSION >= 26
4414 d3dx_effect_DeleteParameterBlock,
4415 #endif
4416 d3dx_effect_CloneEffect,
4417 #if D3DX_SDK_VERSION >= 27
4418 d3dx_effect_SetRawValue
4419 #endif
4420 };
4421
impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler * iface)4422 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
4423 {
4424 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
4425 }
4426
4427 /*** IUnknown methods ***/
ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler * iface,REFIID riid,void ** object)4428 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
4429 {
4430 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
4431
4432 if (IsEqualGUID(riid, &IID_IUnknown)
4433 || IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
4434 {
4435 iface->lpVtbl->AddRef(iface);
4436 *object = iface;
4437 return S_OK;
4438 }
4439
4440 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
4441
4442 *object = NULL;
4443 return E_NOINTERFACE;
4444 }
4445
ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler * iface)4446 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
4447 {
4448 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4449 ULONG refcount = InterlockedIncrement(&compiler->ref);
4450
4451 TRACE("%p increasing refcount to %u.\n", iface, refcount);
4452
4453 return refcount;
4454 }
4455
ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler * iface)4456 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
4457 {
4458 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface);
4459 ULONG refcount = InterlockedDecrement(&compiler->ref);
4460
4461 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
4462
4463 if (!refcount)
4464 {
4465 heap_free(compiler);
4466 }
4467
4468 return refcount;
4469 }
4470
4471 /*** ID3DXBaseEffect methods ***/
ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler * iface,D3DXEFFECT_DESC * desc)4472 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
4473 {
4474 FIXME("iface %p, desc %p stub!\n", iface, desc);
4475
4476 return E_NOTIMPL;
4477 }
4478
ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXPARAMETER_DESC * desc)4479 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface,
4480 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
4481 {
4482 FIXME("iface %p, parameter %p, desc %p stub!\n", iface, parameter, desc);
4483
4484 return E_NOTIMPL;
4485 }
4486
ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler * iface,D3DXHANDLE technique,D3DXTECHNIQUE_DESC * desc)4487 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface,
4488 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
4489 {
4490 FIXME("iface %p, technique %p, desc %p stub!\n", iface, technique, desc);
4491
4492 return E_NOTIMPL;
4493 }
4494
ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler * iface,D3DXHANDLE pass,D3DXPASS_DESC * desc)4495 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface,
4496 D3DXHANDLE pass, D3DXPASS_DESC *desc)
4497 {
4498 FIXME("iface %p, pass %p, desc %p stub!\n", iface, pass, desc);
4499
4500 return E_NOTIMPL;
4501 }
4502
ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler * iface,D3DXHANDLE shader,D3DXFUNCTION_DESC * desc)4503 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface,
4504 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
4505 {
4506 FIXME("iface %p, shader %p, desc %p stub!\n", iface, shader, desc);
4507
4508 return E_NOTIMPL;
4509 }
4510
ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,UINT index)4511 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface,
4512 D3DXHANDLE parameter, UINT index)
4513 {
4514 FIXME("iface %p, parameter %p, index %u stub!\n", iface, parameter, index);
4515
4516 return NULL;
4517 }
4518
ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const char * name)4519 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface,
4520 D3DXHANDLE parameter, const char *name)
4521 {
4522 FIXME("iface %p, parameter %p, name %s stub!\n", iface, parameter, debugstr_a(name));
4523
4524 return NULL;
4525 }
4526
ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const char * semantic)4527 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface,
4528 D3DXHANDLE parameter, const char *semantic)
4529 {
4530 FIXME("iface %p, parameter %p, semantic %s stub!\n", iface, parameter, debugstr_a(semantic));
4531
4532 return NULL;
4533 }
4534
ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,UINT index)4535 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface,
4536 D3DXHANDLE parameter, UINT index)
4537 {
4538 FIXME("iface %p, parameter %p, index %u stub!\n", iface, parameter, index);
4539
4540 return NULL;
4541 }
4542
ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler * iface,UINT index)4543 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
4544 {
4545 FIXME("iface %p, index %u stub!\n", iface, index);
4546
4547 return NULL;
4548 }
4549
ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler * iface,const char * name)4550 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name)
4551 {
4552 FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name));
4553
4554 return NULL;
4555 }
4556
ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler * iface,D3DXHANDLE technique,UINT index)4557 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
4558 {
4559 FIXME("iface %p, technique %p, index %u stub!\n", iface, technique, index);
4560
4561 return NULL;
4562 }
4563
ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler * iface,D3DXHANDLE technique,const char * name)4564 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface,
4565 D3DXHANDLE technique, const char *name)
4566 {
4567 FIXME("iface %p, technique %p, name %s stub!\n", iface, technique, debugstr_a(name));
4568
4569 return NULL;
4570 }
4571
ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler * iface,UINT index)4572 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
4573 {
4574 FIXME("iface %p, index %u stub!\n", iface, index);
4575
4576 return NULL;
4577 }
4578
ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler * iface,const char * name)4579 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name)
4580 {
4581 FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name));
4582
4583 return NULL;
4584 }
4585
ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler * iface,D3DXHANDLE object,UINT index)4586 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface,
4587 D3DXHANDLE object, UINT index)
4588 {
4589 FIXME("iface %p, object %p, index %u stub!\n", iface, object, index);
4590
4591 return NULL;
4592 }
4593
ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler * iface,D3DXHANDLE object,const char * name)4594 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface,
4595 D3DXHANDLE object, const char *name)
4596 {
4597 FIXME("iface %p, object %p, name %s stub!\n", iface, object, debugstr_a(name));
4598
4599 return NULL;
4600 }
4601
ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const void * data,UINT bytes)4602 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface,
4603 D3DXHANDLE parameter, const void *data, UINT bytes)
4604 {
4605 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface, parameter, data, bytes);
4606
4607 return E_NOTIMPL;
4608 }
4609
ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,void * data,UINT bytes)4610 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface,
4611 D3DXHANDLE parameter, void *data, UINT bytes)
4612 {
4613 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface, parameter, data, bytes);
4614
4615 return E_NOTIMPL;
4616 }
4617
ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,BOOL b)4618 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
4619 {
4620 FIXME("iface %p, parameter %p, b %#x stub!\n", iface, parameter, b);
4621
4622 return E_NOTIMPL;
4623 }
4624
ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,BOOL * b)4625 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
4626 {
4627 FIXME("iface %p, parameter %p, b %p stub!\n", iface, parameter, b);
4628
4629 return E_NOTIMPL;
4630 }
4631
ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const BOOL * b,UINT count)4632 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface,
4633 D3DXHANDLE parameter, const BOOL *b, UINT count)
4634 {
4635 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface, parameter, b, count);
4636
4637 return E_NOTIMPL;
4638 }
4639
ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,BOOL * b,UINT count)4640 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface,
4641 D3DXHANDLE parameter, BOOL *b, UINT count)
4642 {
4643 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface, parameter, b, count);
4644
4645 return E_NOTIMPL;
4646 }
4647
ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,INT n)4648 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4649 {
4650 FIXME("iface %p, parameter %p, n %d stub!\n", iface, parameter, n);
4651
4652 return E_NOTIMPL;
4653 }
4654
ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,INT * n)4655 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4656 {
4657 FIXME("iface %p, parameter %p, n %p stub!\n", iface, parameter, n);
4658
4659 return E_NOTIMPL;
4660 }
4661
ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const INT * n,UINT count)4662 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface,
4663 D3DXHANDLE parameter, const INT *n, UINT count)
4664 {
4665 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface, parameter, n, count);
4666
4667 return E_NOTIMPL;
4668 }
4669
ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,INT * n,UINT count)4670 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface,
4671 D3DXHANDLE parameter, INT *n, UINT count)
4672 {
4673 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface, parameter, n, count);
4674
4675 return E_NOTIMPL;
4676 }
4677
ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,float f)4678 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f)
4679 {
4680 FIXME("iface %p, parameter %p, f %.8e stub!\n", iface, parameter, f);
4681
4682 return E_NOTIMPL;
4683 }
4684
ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,float * f)4685 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f)
4686 {
4687 FIXME("iface %p, parameter %p, f %p stub!\n", iface, parameter, f);
4688
4689 return E_NOTIMPL;
4690 }
4691
ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const float * f,UINT count)4692 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface,
4693 D3DXHANDLE parameter, const float *f, UINT count)
4694 {
4695 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface, parameter, f, count);
4696
4697 return E_NOTIMPL;
4698 }
4699
ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,float * f,UINT count)4700 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface,
4701 D3DXHANDLE parameter, float *f, UINT count)
4702 {
4703 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface, parameter, f, count);
4704
4705 return E_NOTIMPL;
4706 }
4707
ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXVECTOR4 * vector)4708 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface,
4709 D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
4710 {
4711 FIXME("iface %p, parameter %p, vector %p stub!\n", iface, parameter, vector);
4712
4713 return E_NOTIMPL;
4714 }
4715
ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXVECTOR4 * vector)4716 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface,
4717 D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4718 {
4719 FIXME("iface %p, parameter %p, vector %p stub!\n", iface, parameter, vector);
4720
4721 return E_NOTIMPL;
4722 }
4723
ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXVECTOR4 * vector,UINT count)4724 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface,
4725 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
4726 {
4727 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface, parameter, vector, count);
4728
4729 return E_NOTIMPL;
4730 }
4731
ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXVECTOR4 * vector,UINT count)4732 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface,
4733 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4734 {
4735 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface, parameter, vector, count);
4736
4737 return E_NOTIMPL;
4738 }
4739
ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix)4740 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface,
4741 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4742 {
4743 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4744
4745 return E_NOTIMPL;
4746 }
4747
ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix)4748 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface,
4749 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4750 {
4751 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4752
4753 return E_NOTIMPL;
4754 }
4755
ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix,UINT count)4756 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface,
4757 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4758 {
4759 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4760
4761 return E_NOTIMPL;
4762 }
4763
ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix,UINT count)4764 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface,
4765 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4766 {
4767 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4768
4769 return E_NOTIMPL;
4770 }
4771
ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXMATRIX ** matrix,UINT count)4772 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface,
4773 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4774 {
4775 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4776
4777 return E_NOTIMPL;
4778 }
4779
ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXMATRIX ** matrix,UINT count)4780 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface,
4781 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4782 {
4783 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4784
4785 return E_NOTIMPL;
4786 }
4787
ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix)4788 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface,
4789 D3DXHANDLE parameter, const D3DXMATRIX *matrix)
4790 {
4791 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4792
4793 return E_NOTIMPL;
4794 }
4795
ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix)4796 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface,
4797 D3DXHANDLE parameter, D3DXMATRIX *matrix)
4798 {
4799 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface, parameter, matrix);
4800
4801 return E_NOTIMPL;
4802 }
4803
ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXMATRIX * matrix,UINT count)4804 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4805 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
4806 {
4807 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4808
4809 return E_NOTIMPL;
4810 }
4811
ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXMATRIX * matrix,UINT count)4812 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface,
4813 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4814 {
4815 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4816
4817 return E_NOTIMPL;
4818 }
4819
ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const D3DXMATRIX ** matrix,UINT count)4820 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4821 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
4822 {
4823 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4824
4825 return E_NOTIMPL;
4826 }
4827
ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,D3DXMATRIX ** matrix,UINT count)4828 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface,
4829 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4830 {
4831 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface, parameter, matrix, count);
4832
4833 return E_NOTIMPL;
4834 }
4835
ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const char * string)4836 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface,
4837 D3DXHANDLE parameter, const char *string)
4838 {
4839 FIXME("iface %p, parameter %p, string %s stub!\n", iface, parameter, debugstr_a(string));
4840
4841 return E_NOTIMPL;
4842 }
4843
ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,const char ** string)4844 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface,
4845 D3DXHANDLE parameter, const char **string)
4846 {
4847 FIXME("iface %p, parameter %p, string %p stub!\n", iface, parameter, string);
4848
4849 return E_NOTIMPL;
4850 }
4851
ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler * iface,D3DXHANDLE parameter,struct IDirect3DBaseTexture9 * texture)4852 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface,
4853 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
4854 {
4855 FIXME("iface %p, parameter %p, texture %p stub!\n", iface, parameter, texture);
4856
4857 return E_NOTIMPL;
4858 }
4859
ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler * iface,D3DXHANDLE parameter,struct IDirect3DBaseTexture9 ** texture)4860 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface,
4861 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
4862 {
4863 FIXME("iface %p, parameter %p, texture %p stub!\n", iface, parameter, texture);
4864
4865 return E_NOTIMPL;
4866 }
4867
ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,struct IDirect3DPixelShader9 ** shader)4868 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface,
4869 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
4870 {
4871 FIXME("iface %p, parameter %p, shader %p stub!\n", iface, parameter, shader);
4872
4873 return E_NOTIMPL;
4874 }
4875
ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler * iface,D3DXHANDLE parameter,struct IDirect3DVertexShader9 ** shader)4876 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface,
4877 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
4878 {
4879 FIXME("iface %p, parameter %p, shader %p stub!\n", iface, parameter, shader);
4880
4881 return E_NOTIMPL;
4882 }
4883
ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,UINT start,UINT end)4884 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface,
4885 D3DXHANDLE parameter, UINT start, UINT end)
4886 {
4887 FIXME("iface %p, parameter %p, start %u, end %u stub!\n", iface, parameter, start, end);
4888
4889 return E_NOTIMPL;
4890 }
4891
4892 /*** ID3DXEffectCompiler methods ***/
ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,BOOL literal)4893 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
4894 {
4895 FIXME("iface %p, parameter %p, literal %#x stub!\n", iface, parameter, literal);
4896
4897 return E_NOTIMPL;
4898 }
4899
ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler * iface,D3DXHANDLE parameter,BOOL * literal)4900 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
4901 {
4902 FIXME("iface %p, parameter %p, literal %p stub!\n", iface, parameter, literal);
4903
4904 return E_NOTIMPL;
4905 }
4906
ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler * iface,DWORD flags,ID3DXBuffer ** effect,ID3DXBuffer ** error_msgs)4907 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
4908 ID3DXBuffer **effect, ID3DXBuffer **error_msgs)
4909 {
4910 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub!\n", iface, flags, effect, error_msgs);
4911
4912 return E_NOTIMPL;
4913 }
4914
ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler * iface,D3DXHANDLE function,const char * target,DWORD flags,ID3DXBuffer ** shader,ID3DXBuffer ** error_msgs,ID3DXConstantTable ** constant_table)4915 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
4916 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs,
4917 ID3DXConstantTable **constant_table)
4918 {
4919 FIXME("iface %p, function %p, target %s, flags %#x, shader %p, error_msgs %p, constant_table %p stub!\n",
4920 iface, function, debugstr_a(target), flags, shader, error_msgs, constant_table);
4921
4922 return E_NOTIMPL;
4923 }
4924
4925 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
4926 {
4927 /*** IUnknown methods ***/
4928 ID3DXEffectCompilerImpl_QueryInterface,
4929 ID3DXEffectCompilerImpl_AddRef,
4930 ID3DXEffectCompilerImpl_Release,
4931 /*** ID3DXBaseEffect methods ***/
4932 ID3DXEffectCompilerImpl_GetDesc,
4933 ID3DXEffectCompilerImpl_GetParameterDesc,
4934 ID3DXEffectCompilerImpl_GetTechniqueDesc,
4935 ID3DXEffectCompilerImpl_GetPassDesc,
4936 ID3DXEffectCompilerImpl_GetFunctionDesc,
4937 ID3DXEffectCompilerImpl_GetParameter,
4938 ID3DXEffectCompilerImpl_GetParameterByName,
4939 ID3DXEffectCompilerImpl_GetParameterBySemantic,
4940 ID3DXEffectCompilerImpl_GetParameterElement,
4941 ID3DXEffectCompilerImpl_GetTechnique,
4942 ID3DXEffectCompilerImpl_GetTechniqueByName,
4943 ID3DXEffectCompilerImpl_GetPass,
4944 ID3DXEffectCompilerImpl_GetPassByName,
4945 ID3DXEffectCompilerImpl_GetFunction,
4946 ID3DXEffectCompilerImpl_GetFunctionByName,
4947 ID3DXEffectCompilerImpl_GetAnnotation,
4948 ID3DXEffectCompilerImpl_GetAnnotationByName,
4949 ID3DXEffectCompilerImpl_SetValue,
4950 ID3DXEffectCompilerImpl_GetValue,
4951 ID3DXEffectCompilerImpl_SetBool,
4952 ID3DXEffectCompilerImpl_GetBool,
4953 ID3DXEffectCompilerImpl_SetBoolArray,
4954 ID3DXEffectCompilerImpl_GetBoolArray,
4955 ID3DXEffectCompilerImpl_SetInt,
4956 ID3DXEffectCompilerImpl_GetInt,
4957 ID3DXEffectCompilerImpl_SetIntArray,
4958 ID3DXEffectCompilerImpl_GetIntArray,
4959 ID3DXEffectCompilerImpl_SetFloat,
4960 ID3DXEffectCompilerImpl_GetFloat,
4961 ID3DXEffectCompilerImpl_SetFloatArray,
4962 ID3DXEffectCompilerImpl_GetFloatArray,
4963 ID3DXEffectCompilerImpl_SetVector,
4964 ID3DXEffectCompilerImpl_GetVector,
4965 ID3DXEffectCompilerImpl_SetVectorArray,
4966 ID3DXEffectCompilerImpl_GetVectorArray,
4967 ID3DXEffectCompilerImpl_SetMatrix,
4968 ID3DXEffectCompilerImpl_GetMatrix,
4969 ID3DXEffectCompilerImpl_SetMatrixArray,
4970 ID3DXEffectCompilerImpl_GetMatrixArray,
4971 ID3DXEffectCompilerImpl_SetMatrixPointerArray,
4972 ID3DXEffectCompilerImpl_GetMatrixPointerArray,
4973 ID3DXEffectCompilerImpl_SetMatrixTranspose,
4974 ID3DXEffectCompilerImpl_GetMatrixTranspose,
4975 ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
4976 ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
4977 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
4978 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
4979 ID3DXEffectCompilerImpl_SetString,
4980 ID3DXEffectCompilerImpl_GetString,
4981 ID3DXEffectCompilerImpl_SetTexture,
4982 ID3DXEffectCompilerImpl_GetTexture,
4983 ID3DXEffectCompilerImpl_GetPixelShader,
4984 ID3DXEffectCompilerImpl_GetVertexShader,
4985 ID3DXEffectCompilerImpl_SetArrayRange,
4986 /*** ID3DXEffectCompiler methods ***/
4987 ID3DXEffectCompilerImpl_SetLiteral,
4988 ID3DXEffectCompilerImpl_GetLiteral,
4989 ID3DXEffectCompilerImpl_CompileEffect,
4990 ID3DXEffectCompilerImpl_CompileShader,
4991 };
4992
d3dx_parse_sampler(struct d3dx_effect * effect,struct d3dx_sampler * sampler,const char * data,const char ** ptr,struct d3dx_object * objects)4993 static HRESULT d3dx_parse_sampler(struct d3dx_effect *effect, struct d3dx_sampler *sampler,
4994 const char *data, const char **ptr, struct d3dx_object *objects)
4995 {
4996 HRESULT hr;
4997 UINT i;
4998
4999 read_dword(ptr, &sampler->state_count);
5000 TRACE("Count: %u\n", sampler->state_count);
5001
5002 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count);
5003 if (!sampler->states)
5004 {
5005 ERR("Out of memory\n");
5006 return E_OUTOFMEMORY;
5007 }
5008
5009 for (i = 0; i < sampler->state_count; ++i)
5010 {
5011 hr = d3dx_parse_state(effect, &sampler->states[i], data, ptr, objects);
5012 if (hr != D3D_OK)
5013 {
5014 WARN("Failed to parse state %u\n", i);
5015 goto err_out;
5016 }
5017 }
5018
5019 return D3D_OK;
5020
5021 err_out:
5022
5023 for (i = 0; i < sampler->state_count; ++i)
5024 {
5025 free_state(&sampler->states[i]);
5026 }
5027 HeapFree(GetProcessHeap(), 0, sampler->states);
5028 sampler->states = NULL;
5029
5030 return hr;
5031 }
5032
d3dx_parse_value(struct d3dx_effect * effect,struct d3dx_parameter * param,void * value,const char * data,const char ** ptr,struct d3dx_object * objects)5033 static HRESULT d3dx_parse_value(struct d3dx_effect *effect, struct d3dx_parameter *param,
5034 void *value, const char *data, const char **ptr, struct d3dx_object *objects)
5035 {
5036 unsigned int i;
5037 HRESULT hr;
5038 UINT old_size = 0;
5039
5040 if (param->element_count)
5041 {
5042 param->data = value;
5043
5044 for (i = 0; i < param->element_count; ++i)
5045 {
5046 struct d3dx_parameter *member = ¶m->members[i];
5047
5048 hr = d3dx_parse_value(effect, member, value ? (char *)value + old_size : NULL, data, ptr, objects);
5049 if (hr != D3D_OK)
5050 {
5051 WARN("Failed to parse value %u\n", i);
5052 return hr;
5053 }
5054
5055 old_size += member->bytes;
5056 }
5057
5058 return D3D_OK;
5059 }
5060
5061 switch(param->class)
5062 {
5063 case D3DXPC_SCALAR:
5064 case D3DXPC_VECTOR:
5065 case D3DXPC_MATRIX_ROWS:
5066 case D3DXPC_MATRIX_COLUMNS:
5067 param->data = value;
5068 break;
5069
5070 case D3DXPC_STRUCT:
5071 param->data = value;
5072
5073 for (i = 0; i < param->member_count; ++i)
5074 {
5075 struct d3dx_parameter *member = ¶m->members[i];
5076
5077 hr = d3dx_parse_value(effect, member, (char *)value + old_size, data, ptr, objects);
5078 if (hr != D3D_OK)
5079 {
5080 WARN("Failed to parse value %u\n", i);
5081 return hr;
5082 }
5083
5084 old_size += member->bytes;
5085 }
5086 break;
5087
5088 case D3DXPC_OBJECT:
5089 switch (param->type)
5090 {
5091 case D3DXPT_STRING:
5092 case D3DXPT_TEXTURE:
5093 case D3DXPT_TEXTURE1D:
5094 case D3DXPT_TEXTURE2D:
5095 case D3DXPT_TEXTURE3D:
5096 case D3DXPT_TEXTURECUBE:
5097 case D3DXPT_PIXELSHADER:
5098 case D3DXPT_VERTEXSHADER:
5099 read_dword(ptr, ¶m->object_id);
5100 TRACE("Id: %u\n", param->object_id);
5101 objects[param->object_id].param = param;
5102 param->data = value;
5103 break;
5104
5105 case D3DXPT_SAMPLER:
5106 case D3DXPT_SAMPLER1D:
5107 case D3DXPT_SAMPLER2D:
5108 case D3DXPT_SAMPLER3D:
5109 case D3DXPT_SAMPLERCUBE:
5110 {
5111 struct d3dx_sampler *sampler;
5112
5113 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
5114 if (!sampler)
5115 return E_OUTOFMEMORY;
5116
5117 hr = d3dx_parse_sampler(effect, sampler, data, ptr, objects);
5118 if (hr != D3D_OK)
5119 {
5120 HeapFree(GetProcessHeap(), 0, sampler);
5121 WARN("Failed to parse sampler\n");
5122 return hr;
5123 }
5124
5125 param->data = sampler;
5126 break;
5127 }
5128
5129 default:
5130 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5131 break;
5132 }
5133 break;
5134
5135 default:
5136 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5137 break;
5138 }
5139
5140 return D3D_OK;
5141 }
5142
d3dx_parse_init_value(struct d3dx_effect * effect,struct d3dx_parameter * param,const char * data,const char * ptr,struct d3dx_object * objects)5143 static HRESULT d3dx_parse_init_value(struct d3dx_effect *effect, struct d3dx_parameter *param,
5144 const char *data, const char *ptr, struct d3dx_object *objects)
5145 {
5146 UINT size = param->bytes;
5147 HRESULT hr;
5148 void *value = NULL;
5149
5150 TRACE("param size: %u\n", size);
5151
5152 if (size)
5153 {
5154 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5155 if (!value)
5156 {
5157 ERR("Failed to allocate data memory.\n");
5158 return E_OUTOFMEMORY;
5159 }
5160
5161 switch(param->class)
5162 {
5163 case D3DXPC_OBJECT:
5164 break;
5165
5166 case D3DXPC_SCALAR:
5167 case D3DXPC_VECTOR:
5168 case D3DXPC_MATRIX_ROWS:
5169 case D3DXPC_MATRIX_COLUMNS:
5170 case D3DXPC_STRUCT:
5171 TRACE("Data: %s.\n", debugstr_an(ptr, size));
5172 memcpy(value, ptr, size);
5173 break;
5174
5175 default:
5176 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5177 break;
5178 }
5179 }
5180
5181 hr = d3dx_parse_value(effect, param, value, data, &ptr, objects);
5182 if (hr != D3D_OK)
5183 {
5184 WARN("Failed to parse value\n");
5185 HeapFree(GetProcessHeap(), 0, value);
5186 return hr;
5187 }
5188
5189 return D3D_OK;
5190 }
5191
d3dx9_parse_name(char ** name,const char * ptr)5192 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
5193 {
5194 DWORD size;
5195
5196 read_dword(&ptr, &size);
5197 TRACE("Name size: %#x\n", size);
5198
5199 if (!size)
5200 {
5201 return D3D_OK;
5202 }
5203
5204 *name = HeapAlloc(GetProcessHeap(), 0, size);
5205 if (!*name)
5206 {
5207 ERR("Failed to allocate name memory.\n");
5208 return E_OUTOFMEMORY;
5209 }
5210
5211 TRACE("Name: %s.\n", debugstr_an(ptr, size));
5212 memcpy(*name, ptr, size);
5213
5214 return D3D_OK;
5215 }
5216
d3dx9_copy_data(struct d3dx_effect * effect,unsigned int object_id,const char ** ptr)5217 static HRESULT d3dx9_copy_data(struct d3dx_effect *effect, unsigned int object_id, const char **ptr)
5218 {
5219 struct d3dx_object *object = &effect->objects[object_id];
5220
5221 if (object->size || object->data)
5222 {
5223 if (object_id)
5224 FIXME("Overwriting object id %u!\n", object_id);
5225 else
5226 TRACE("Overwriting object id 0.\n");
5227
5228 HeapFree(GetProcessHeap(), 0, object->data);
5229 object->data = NULL;
5230 }
5231
5232 read_dword(ptr, &object->size);
5233 TRACE("Data size: %#x.\n", object->size);
5234
5235 if (!object->size)
5236 return D3D_OK;
5237
5238 object->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5239 if (!object->data)
5240 {
5241 ERR("Failed to allocate object memory.\n");
5242 return E_OUTOFMEMORY;
5243 }
5244
5245 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size));
5246 memcpy(object->data, *ptr, object->size);
5247
5248 *ptr += ((object->size + 3) & ~3);
5249
5250 return D3D_OK;
5251 }
5252
param_set_magic_number(struct d3dx_parameter * param)5253 static void param_set_magic_number(struct d3dx_parameter *param)
5254 {
5255 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string));
5256 }
5257
param_rb_compare(const void * key,const struct wine_rb_entry * entry)5258 static int param_rb_compare(const void *key, const struct wine_rb_entry *entry)
5259 {
5260 const char *name = key;
5261 struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry);
5262
5263 return strcmp(name, param->full_name);
5264 }
5265
add_param_to_tree(struct d3dx_effect * effect,struct d3dx_parameter * param,struct d3dx_parameter * parent,char separator,unsigned int element)5266 static void add_param_to_tree(struct d3dx_effect *effect, struct d3dx_parameter *param,
5267 struct d3dx_parameter *parent, char separator, unsigned int element)
5268 {
5269 const char *parent_name = parent ? parent->full_name : NULL;
5270 unsigned int i;
5271
5272 TRACE("Adding parameter %p (%s - parent %p, element %u) to the rbtree.\n",
5273 param, debugstr_a(param->name), parent, element);
5274
5275 if (parent_name)
5276 {
5277 unsigned int parent_name_len = strlen(parent_name);
5278 unsigned int name_len = strlen(param->name);
5279 unsigned int part_str_len;
5280 unsigned int len;
5281 char part_str[16];
5282
5283 if (separator == '[')
5284 {
5285 sprintf(part_str, "[%u]", element);
5286 part_str_len = strlen(part_str);
5287 name_len = 0;
5288 }
5289 else
5290 {
5291 part_str[0] = separator;
5292 part_str[1] = 0;
5293 part_str_len = 1;
5294 }
5295 len = parent_name_len + part_str_len + name_len + 1;
5296
5297 if (!(param->full_name = heap_alloc(len)))
5298 {
5299 ERR("Out of memory.\n");
5300 return;
5301 }
5302
5303 memcpy(param->full_name, parent_name, parent_name_len);
5304 memcpy(param->full_name + parent_name_len, part_str, part_str_len);
5305 memcpy(param->full_name + parent_name_len + part_str_len, param->name, name_len);
5306 param->full_name[len - 1] = 0;
5307 }
5308 else
5309 {
5310 unsigned int len = strlen(param->name) + 1;
5311
5312 if (!(param->full_name = heap_alloc(len)))
5313 {
5314 ERR("Out of memory.\n");
5315 return;
5316 }
5317
5318 memcpy(param->full_name, param->name, len);
5319 }
5320 TRACE("Full name is %s.\n", param->full_name);
5321 wine_rb_put(&effect->param_tree, param->full_name, ¶m->rb_entry);
5322
5323 if (is_top_level_parameter(param))
5324 for (i = 0; i < param->top_level_param->annotation_count; ++i)
5325 add_param_to_tree(effect, ¶m->top_level_param->annotations[i], param, '@', 0);
5326
5327 if (param->element_count)
5328 for (i = 0; i < param->element_count; ++i)
5329 add_param_to_tree(effect, ¶m->members[i], param, '[', i);
5330 else
5331 for (i = 0; i < param->member_count; ++i)
5332 add_param_to_tree(effect, ¶m->members[i], param, '.', 0);
5333 }
5334
d3dx_parse_effect_typedef(struct d3dx_effect * effect,struct d3dx_parameter * param,const char * data,const char ** ptr,struct d3dx_parameter * parent,UINT flags)5335 static HRESULT d3dx_parse_effect_typedef(struct d3dx_effect *effect, struct d3dx_parameter *param,
5336 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags)
5337 {
5338 DWORD offset;
5339 HRESULT hr;
5340 UINT i;
5341
5342 param->flags = flags;
5343
5344 if (!parent)
5345 {
5346 read_dword(ptr, (DWORD *)¶m->type);
5347 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
5348
5349 read_dword(ptr, (DWORD *)¶m->class);
5350 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
5351
5352 read_dword(ptr, &offset);
5353 TRACE("Type name offset: %#x\n", offset);
5354 hr = d3dx9_parse_name(¶m->name, data + offset);
5355 if (hr != D3D_OK)
5356 {
5357 WARN("Failed to parse name\n");
5358 goto err_out;
5359 }
5360
5361 read_dword(ptr, &offset);
5362 TRACE("Type semantic offset: %#x\n", offset);
5363 hr = d3dx9_parse_name(¶m->semantic, data + offset);
5364 if (hr != D3D_OK)
5365 {
5366 WARN("Failed to parse semantic\n");
5367 goto err_out;
5368 }
5369
5370 read_dword(ptr, ¶m->element_count);
5371 TRACE("Elements: %u\n", param->element_count);
5372
5373 switch (param->class)
5374 {
5375 case D3DXPC_VECTOR:
5376 read_dword(ptr, ¶m->columns);
5377 TRACE("Columns: %u\n", param->columns);
5378
5379 read_dword(ptr, ¶m->rows);
5380 TRACE("Rows: %u\n", param->rows);
5381
5382 /* sizeof(DWORD) * rows * columns */
5383 param->bytes = 4 * param->rows * param->columns;
5384 break;
5385
5386 case D3DXPC_SCALAR:
5387 case D3DXPC_MATRIX_ROWS:
5388 case D3DXPC_MATRIX_COLUMNS:
5389 read_dword(ptr, ¶m->rows);
5390 TRACE("Rows: %u\n", param->rows);
5391
5392 read_dword(ptr, ¶m->columns);
5393 TRACE("Columns: %u\n", param->columns);
5394
5395 /* sizeof(DWORD) * rows * columns */
5396 param->bytes = 4 * param->rows * param->columns;
5397 break;
5398
5399 case D3DXPC_STRUCT:
5400 read_dword(ptr, ¶m->member_count);
5401 TRACE("Members: %u\n", param->member_count);
5402 break;
5403
5404 case D3DXPC_OBJECT:
5405 switch (param->type)
5406 {
5407 case D3DXPT_STRING:
5408 case D3DXPT_PIXELSHADER:
5409 case D3DXPT_VERTEXSHADER:
5410 case D3DXPT_TEXTURE:
5411 case D3DXPT_TEXTURE1D:
5412 case D3DXPT_TEXTURE2D:
5413 case D3DXPT_TEXTURE3D:
5414 case D3DXPT_TEXTURECUBE:
5415 param->bytes = sizeof(void *);
5416 break;
5417
5418 case D3DXPT_SAMPLER:
5419 case D3DXPT_SAMPLER1D:
5420 case D3DXPT_SAMPLER2D:
5421 case D3DXPT_SAMPLER3D:
5422 case D3DXPT_SAMPLERCUBE:
5423 param->bytes = 0;
5424 break;
5425
5426 default:
5427 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5428 break;
5429 }
5430 break;
5431
5432 default:
5433 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
5434 break;
5435 }
5436 }
5437 else
5438 {
5439 /* elements */
5440 param->type = parent->type;
5441 param->class = parent->class;
5442 param->name = parent->name;
5443 param->semantic = parent->semantic;
5444 param->element_count = 0;
5445 param->member_count = parent->member_count;
5446 param->bytes = parent->bytes;
5447 param->rows = parent->rows;
5448 param->columns = parent->columns;
5449 }
5450
5451 if (param->element_count)
5452 {
5453 unsigned int param_bytes = 0;
5454 const char *save_ptr = *ptr;
5455
5456 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count);
5457 if (!param->members)
5458 {
5459 ERR("Out of memory\n");
5460 hr = E_OUTOFMEMORY;
5461 goto err_out;
5462 }
5463
5464 for (i = 0; i < param->element_count; ++i)
5465 {
5466 *ptr = save_ptr;
5467
5468 param_set_magic_number(¶m->members[i]);
5469 hr = d3dx_parse_effect_typedef(effect, ¶m->members[i], data, ptr, param, flags);
5470 if (hr != D3D_OK)
5471 {
5472 WARN("Failed to parse member %u\n", i);
5473 goto err_out;
5474 }
5475
5476 param_bytes += param->members[i].bytes;
5477 }
5478
5479 param->bytes = param_bytes;
5480 }
5481 else if (param->member_count)
5482 {
5483 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count);
5484 if (!param->members)
5485 {
5486 ERR("Out of memory\n");
5487 hr = E_OUTOFMEMORY;
5488 goto err_out;
5489 }
5490
5491 for (i = 0; i < param->member_count; ++i)
5492 {
5493 param_set_magic_number(¶m->members[i]);
5494 hr = d3dx_parse_effect_typedef(effect, ¶m->members[i], data, ptr, NULL, flags);
5495 if (hr != D3D_OK)
5496 {
5497 WARN("Failed to parse member %u\n", i);
5498 goto err_out;
5499 }
5500
5501 param->bytes += param->members[i].bytes;
5502 }
5503 }
5504 return D3D_OK;
5505
5506 err_out:
5507
5508 if (param->members)
5509 {
5510 unsigned int count = param->element_count ? param->element_count : param->member_count;
5511
5512 for (i = 0; i < count; ++i)
5513 free_parameter(¶m->members[i], param->element_count != 0, TRUE);
5514 HeapFree(GetProcessHeap(), 0, param->members);
5515 param->members = NULL;
5516 }
5517
5518 if (!parent)
5519 {
5520 HeapFree(GetProcessHeap(), 0, param->name);
5521 HeapFree(GetProcessHeap(), 0, param->semantic);
5522 }
5523 param->name = NULL;
5524 param->semantic = NULL;
5525
5526 return hr;
5527 }
5528
d3dx_parse_effect_annotation(struct d3dx_effect * effect,struct d3dx_parameter * anno,const char * data,const char ** ptr,struct d3dx_object * objects)5529 static HRESULT d3dx_parse_effect_annotation(struct d3dx_effect *effect, struct d3dx_parameter *anno,
5530 const char *data, const char **ptr, struct d3dx_object *objects)
5531 {
5532 DWORD offset;
5533 const char *ptr2;
5534 HRESULT hr;
5535
5536 anno->flags = D3DX_PARAMETER_ANNOTATION;
5537
5538 read_dword(ptr, &offset);
5539 TRACE("Typedef offset: %#x\n", offset);
5540 ptr2 = data + offset;
5541 hr = d3dx_parse_effect_typedef(effect, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
5542 if (hr != D3D_OK)
5543 {
5544 WARN("Failed to parse type definition\n");
5545 return hr;
5546 }
5547
5548 read_dword(ptr, &offset);
5549 TRACE("Value offset: %#x\n", offset);
5550 hr = d3dx_parse_init_value(effect, anno, data, data + offset, objects);
5551 if (hr != D3D_OK)
5552 {
5553 WARN("Failed to parse value\n");
5554 return hr;
5555 }
5556
5557 return D3D_OK;
5558 }
5559
d3dx_parse_state(struct d3dx_effect * effect,struct d3dx_state * state,const char * data,const char ** ptr,struct d3dx_object * objects)5560 static HRESULT d3dx_parse_state(struct d3dx_effect *effect, struct d3dx_state *state,
5561 const char *data, const char **ptr, struct d3dx_object *objects)
5562 {
5563 struct d3dx_parameter *param = &state->parameter;
5564 enum STATE_CLASS state_class;
5565 const char *ptr2;
5566 void *new_data;
5567 DWORD offset;
5568 HRESULT hr;
5569
5570 state->type = ST_CONSTANT;
5571
5572 read_dword(ptr, &state->operation);
5573 if (state->operation >= ARRAY_SIZE(state_table))
5574 {
5575 WARN("Unknown state operation %u.\n", state->operation);
5576 return D3DERR_INVALIDCALL;
5577 }
5578
5579 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5580
5581 read_dword(ptr, &state->index);
5582 TRACE("Index: %#x\n", state->index);
5583
5584 read_dword(ptr, &offset);
5585 TRACE("Typedef offset: %#x\n", offset);
5586 ptr2 = data + offset;
5587 hr = d3dx_parse_effect_typedef(effect, param, data, &ptr2, NULL, 0);
5588 if (hr != D3D_OK)
5589 {
5590 WARN("Failed to parse type definition\n");
5591 goto err_out;
5592 }
5593
5594 read_dword(ptr, &offset);
5595 TRACE("Value offset: %#x\n", offset);
5596 hr = d3dx_parse_init_value(effect, param, data, data + offset, objects);
5597 if (hr != D3D_OK)
5598 {
5599 WARN("Failed to parse value\n");
5600 goto err_out;
5601 }
5602
5603 if (((state_class = state_table[state->operation].class) == SC_VERTEXSHADER
5604 || state_class == SC_PIXELSHADER || state_class == SC_TEXTURE)
5605 && param->bytes < sizeof(void *))
5606 {
5607 if (param->type != D3DXPT_INT || *(unsigned int *)param->data)
5608 {
5609 FIXME("Unexpected parameter for object, param->type %#x, param->class %#x, *param->data %#x.\n",
5610 param->type, param->class, *(unsigned int *)param->data);
5611 hr = D3DXERR_INVALIDDATA;
5612 goto err_out;
5613 }
5614
5615 new_data = heap_realloc(param->data, sizeof(void *));
5616 if (!new_data)
5617 {
5618 ERR("Out of memory.\n");
5619 hr = E_OUTOFMEMORY;
5620 goto err_out;
5621 }
5622 memset(new_data, 0, sizeof(void *));
5623 param->data = new_data;
5624 param->bytes = sizeof(void *);
5625 }
5626
5627 return D3D_OK;
5628
5629 err_out:
5630
5631 free_parameter(param, FALSE, FALSE);
5632
5633 return hr;
5634 }
5635
d3dx_parse_effect_parameter(struct d3dx_effect * effect,struct d3dx_top_level_parameter * param,const char * data,const char ** ptr,struct d3dx_object * objects)5636 static HRESULT d3dx_parse_effect_parameter(struct d3dx_effect *effect, struct d3dx_top_level_parameter *param,
5637 const char *data, const char **ptr, struct d3dx_object *objects)
5638 {
5639 DWORD offset;
5640 HRESULT hr;
5641 unsigned int i;
5642 const char *ptr2;
5643
5644 read_dword(ptr, &offset);
5645 TRACE("Typedef offset: %#x.\n", offset);
5646 ptr2 = data + offset;
5647
5648 read_dword(ptr, &offset);
5649 TRACE("Value offset: %#x.\n", offset);
5650
5651 read_dword(ptr, ¶m->param.flags);
5652 TRACE("Flags: %#x.\n", param->param.flags);
5653
5654 read_dword(ptr, ¶m->annotation_count);
5655 TRACE("Annotation count: %u.\n", param->annotation_count);
5656
5657 hr = d3dx_parse_effect_typedef(effect, ¶m->param, data, &ptr2, NULL, param->param.flags);
5658 if (hr != D3D_OK)
5659 {
5660 WARN("Failed to parse type definition.\n");
5661 return hr;
5662 }
5663
5664 hr = d3dx_parse_init_value(effect, ¶m->param, data, data + offset, objects);
5665 if (hr != D3D_OK)
5666 {
5667 WARN("Failed to parse value.\n");
5668 return hr;
5669 }
5670
5671 if (param->annotation_count)
5672 {
5673 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5674 sizeof(*param->annotations) * param->annotation_count);
5675 if (!param->annotations)
5676 {
5677 ERR("Out of memory.\n");
5678 hr = E_OUTOFMEMORY;
5679 goto err_out;
5680 }
5681
5682 for (i = 0; i < param->annotation_count; ++i)
5683 {
5684 param_set_magic_number(¶m->annotations[i]);
5685 hr = d3dx_parse_effect_annotation(effect, ¶m->annotations[i], data, ptr, objects);
5686 if (hr != D3D_OK)
5687 {
5688 WARN("Failed to parse annotation.\n");
5689 goto err_out;
5690 }
5691 }
5692 }
5693
5694 return D3D_OK;
5695
5696 err_out:
5697
5698 if (param->annotations)
5699 {
5700 for (i = 0; i < param->annotation_count; ++i)
5701 free_parameter(¶m->annotations[i], FALSE, FALSE);
5702 HeapFree(GetProcessHeap(), 0, param->annotations);
5703 param->annotations = NULL;
5704 }
5705
5706 return hr;
5707 }
5708
d3dx_parse_effect_pass(struct d3dx_effect * effect,struct d3dx_pass * pass,const char * data,const char ** ptr,struct d3dx_object * objects)5709 static HRESULT d3dx_parse_effect_pass(struct d3dx_effect *effect, struct d3dx_pass *pass,
5710 const char *data, const char **ptr, struct d3dx_object *objects)
5711 {
5712 DWORD offset;
5713 HRESULT hr;
5714 unsigned int i;
5715 struct d3dx_state *states = NULL;
5716 char *name = NULL;
5717
5718 read_dword(ptr, &offset);
5719 TRACE("Pass name offset: %#x\n", offset);
5720 hr = d3dx9_parse_name(&name, data + offset);
5721 if (hr != D3D_OK)
5722 {
5723 WARN("Failed to parse name\n");
5724 goto err_out;
5725 }
5726
5727 read_dword(ptr, &pass->annotation_count);
5728 TRACE("Annotation count: %u\n", pass->annotation_count);
5729
5730 read_dword(ptr, &pass->state_count);
5731 TRACE("State count: %u\n", pass->state_count);
5732
5733 if (pass->annotation_count)
5734 {
5735 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5736 sizeof(*pass->annotations) * pass->annotation_count);
5737 if (!pass->annotations)
5738 {
5739 ERR("Out of memory\n");
5740 hr = E_OUTOFMEMORY;
5741 goto err_out;
5742 }
5743
5744 for (i = 0; i < pass->annotation_count; ++i)
5745 {
5746 param_set_magic_number(&pass->annotations[i]);
5747 hr = d3dx_parse_effect_annotation(effect, &pass->annotations[i], data, ptr, objects);
5748 if (hr != D3D_OK)
5749 {
5750 WARN("Failed to parse annotation %u\n", i);
5751 goto err_out;
5752 }
5753 }
5754 }
5755
5756 if (pass->state_count)
5757 {
5758 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5759 if (!states)
5760 {
5761 ERR("Out of memory\n");
5762 hr = E_OUTOFMEMORY;
5763 goto err_out;
5764 }
5765
5766 for (i = 0; i < pass->state_count; ++i)
5767 {
5768 hr = d3dx_parse_state(effect, &states[i], data, ptr, objects);
5769 if (hr != D3D_OK)
5770 {
5771 WARN("Failed to parse annotation %u\n", i);
5772 goto err_out;
5773 }
5774 }
5775 }
5776
5777 pass->name = name;
5778 pass->states = states;
5779
5780 return D3D_OK;
5781
5782 err_out:
5783
5784 if (pass->annotations)
5785 {
5786 for (i = 0; i < pass->annotation_count; ++i)
5787 free_parameter(&pass->annotations[i], FALSE, FALSE);
5788 HeapFree(GetProcessHeap(), 0, pass->annotations);
5789 pass->annotations = NULL;
5790 }
5791
5792 if (states)
5793 {
5794 for (i = 0; i < pass->state_count; ++i)
5795 {
5796 free_state(&states[i]);
5797 }
5798 HeapFree(GetProcessHeap(), 0, states);
5799 }
5800
5801 HeapFree(GetProcessHeap(), 0, name);
5802
5803 return hr;
5804 }
5805
d3dx_parse_effect_technique(struct d3dx_effect * effect,struct d3dx_technique * technique,const char * data,const char ** ptr,struct d3dx_object * objects)5806 static HRESULT d3dx_parse_effect_technique(struct d3dx_effect *effect, struct d3dx_technique *technique,
5807 const char *data, const char **ptr, struct d3dx_object *objects)
5808 {
5809 DWORD offset;
5810 HRESULT hr;
5811 unsigned int i;
5812 char *name = NULL;
5813
5814 read_dword(ptr, &offset);
5815 TRACE("Technique name offset: %#x\n", offset);
5816 hr = d3dx9_parse_name(&name, data + offset);
5817 if (hr != D3D_OK)
5818 {
5819 WARN("Failed to parse name\n");
5820 goto err_out;
5821 }
5822
5823 read_dword(ptr, &technique->annotation_count);
5824 TRACE("Annotation count: %u\n", technique->annotation_count);
5825
5826 read_dword(ptr, &technique->pass_count);
5827 TRACE("Pass count: %u\n", technique->pass_count);
5828
5829 if (technique->annotation_count)
5830 {
5831 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5832 sizeof(*technique->annotations) * technique->annotation_count);
5833 if (!technique->annotations)
5834 {
5835 ERR("Out of memory\n");
5836 hr = E_OUTOFMEMORY;
5837 goto err_out;
5838 }
5839
5840 for (i = 0; i < technique->annotation_count; ++i)
5841 {
5842 param_set_magic_number(&technique->annotations[i]);
5843 hr = d3dx_parse_effect_annotation(effect, &technique->annotations[i], data, ptr, objects);
5844 if (hr != D3D_OK)
5845 {
5846 WARN("Failed to parse annotation %u\n", i);
5847 goto err_out;
5848 }
5849 }
5850 }
5851
5852 if (technique->pass_count)
5853 {
5854 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
5855 sizeof(*technique->passes) * technique->pass_count);
5856 if (!technique->passes)
5857 {
5858 ERR("Out of memory\n");
5859 hr = E_OUTOFMEMORY;
5860 goto err_out;
5861 }
5862
5863 for (i = 0; i < technique->pass_count; ++i)
5864 {
5865 hr = d3dx_parse_effect_pass(effect, &technique->passes[i], data, ptr, objects);
5866 if (hr != D3D_OK)
5867 {
5868 WARN("Failed to parse pass %u\n", i);
5869 goto err_out;
5870 }
5871 }
5872 }
5873
5874 technique->name = name;
5875
5876 return D3D_OK;
5877
5878 err_out:
5879
5880 if (technique->passes)
5881 {
5882 for (i = 0; i < technique->pass_count; ++i)
5883 free_pass(&technique->passes[i]);
5884 HeapFree(GetProcessHeap(), 0, technique->passes);
5885 technique->passes = NULL;
5886 }
5887
5888 if (technique->annotations)
5889 {
5890 for (i = 0; i < technique->annotation_count; ++i)
5891 free_parameter(&technique->annotations[i], FALSE, FALSE);
5892 HeapFree(GetProcessHeap(), 0, technique->annotations);
5893 technique->annotations = NULL;
5894 }
5895
5896 HeapFree(GetProcessHeap(), 0, name);
5897
5898 return hr;
5899 }
5900
d3dx9_create_object(struct d3dx_effect * effect,struct d3dx_object * object)5901 static HRESULT d3dx9_create_object(struct d3dx_effect *effect, struct d3dx_object *object)
5902 {
5903 struct d3dx_parameter *param = object->param;
5904 IDirect3DDevice9 *device = effect->device;
5905 HRESULT hr;
5906
5907 if (*(char **)param->data)
5908 ERR("Parameter data already allocated.\n");
5909
5910 switch (param->type)
5911 {
5912 case D3DXPT_STRING:
5913 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size);
5914 if (!*(char **)param->data)
5915 {
5916 ERR("Out of memory.\n");
5917 return E_OUTOFMEMORY;
5918 }
5919 memcpy(*(char **)param->data, object->data, object->size);
5920 break;
5921 case D3DXPT_VERTEXSHADER:
5922 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data,
5923 (IDirect3DVertexShader9 **)param->data)))
5924 {
5925 WARN("Failed to create vertex shader.\n");
5926 object->creation_failed = TRUE;
5927 }
5928 break;
5929 case D3DXPT_PIXELSHADER:
5930 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data,
5931 (IDirect3DPixelShader9 **)param->data)))
5932 {
5933 WARN("Failed to create pixel shader.\n");
5934 object->creation_failed = TRUE;
5935 }
5936 break;
5937 default:
5938 break;
5939 }
5940 return D3D_OK;
5941 }
5942
d3dx_parse_array_selector(struct d3dx_effect * effect,struct d3dx_state * state,const char ** skip_constants,unsigned int skip_constants_count)5943 static HRESULT d3dx_parse_array_selector(struct d3dx_effect *effect, struct d3dx_state *state,
5944 const char **skip_constants, unsigned int skip_constants_count)
5945 {
5946 DWORD string_size;
5947 struct d3dx_parameter *param = &state->parameter;
5948 struct d3dx_object *object = &effect->objects[param->object_id];
5949 char *ptr = object->data;
5950 HRESULT ret;
5951
5952 TRACE("Parsing array entry selection state for parameter %p.\n", param);
5953
5954 string_size = *(DWORD *)ptr;
5955 state->referenced_param = get_parameter_by_name(effect, NULL, ptr + 4);
5956 if (state->referenced_param)
5957 {
5958 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name));
5959 }
5960 else
5961 {
5962 FIXME("Referenced parameter %s not found.\n", ptr + 4);
5963 return D3DXERR_INVALIDDATA;
5964 }
5965 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
5966
5967 if (string_size % sizeof(DWORD))
5968 FIXME("Unaligned string_size %u.\n", string_size);
5969 if (FAILED(ret = d3dx_create_param_eval(effect, (DWORD *)(ptr + string_size) + 1,
5970 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, ¶m->param_eval,
5971 get_version_counter_ptr(effect), NULL, 0)))
5972 return ret;
5973 ret = D3D_OK;
5974 param = state->referenced_param;
5975 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
5976 {
5977 unsigned int i;
5978
5979 for (i = 0; i < param->element_count; i++)
5980 {
5981 if (param->members[i].type != param->type)
5982 {
5983 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
5984 return D3DXERR_INVALIDDATA;
5985 }
5986 if (!param->members[i].param_eval)
5987 {
5988 TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
5989 object = &effect->objects[param->members[i].object_id];
5990 if (FAILED(ret = d3dx_create_param_eval(effect, object->data, object->size, param->type,
5991 ¶m->members[i].param_eval, get_version_counter_ptr(effect),
5992 skip_constants, skip_constants_count)))
5993 break;
5994 }
5995 }
5996 }
5997 return ret;
5998 }
5999
d3dx_parse_resource(struct d3dx_effect * effect,const char * data,const char ** ptr,const char ** skip_constants,unsigned int skip_constants_count)6000 static HRESULT d3dx_parse_resource(struct d3dx_effect *effect, const char *data, const char **ptr,
6001 const char **skip_constants, unsigned int skip_constants_count)
6002 {
6003 DWORD technique_index;
6004 DWORD index, state_index, usage, element_index;
6005 struct d3dx_state *state;
6006 struct d3dx_parameter *param;
6007 struct d3dx_object *object;
6008 HRESULT hr = E_FAIL;
6009
6010 read_dword(ptr, &technique_index);
6011 TRACE("technique_index: %u\n", technique_index);
6012
6013 read_dword(ptr, &index);
6014 TRACE("index: %u\n", index);
6015
6016 read_dword(ptr, &element_index);
6017 TRACE("element_index: %u\n", element_index);
6018
6019 read_dword(ptr, &state_index);
6020 TRACE("state_index: %u\n", state_index);
6021
6022 read_dword(ptr, &usage);
6023 TRACE("usage: %u\n", usage);
6024
6025 if (technique_index == 0xffffffff)
6026 {
6027 struct d3dx_parameter *parameter;
6028 struct d3dx_sampler *sampler;
6029
6030 if (index >= effect->parameter_count)
6031 {
6032 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, effect->parameter_count);
6033 return E_FAIL;
6034 }
6035
6036 parameter = &effect->parameters[index].param;
6037 if (element_index != 0xffffffff)
6038 {
6039 if (element_index >= parameter->element_count && parameter->element_count != 0)
6040 {
6041 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
6042 return E_FAIL;
6043 }
6044
6045 if (parameter->element_count)
6046 parameter = ¶meter->members[element_index];
6047 }
6048
6049 sampler = parameter->data;
6050 if (state_index >= sampler->state_count)
6051 {
6052 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
6053 return E_FAIL;
6054 }
6055
6056 state = &sampler->states[state_index];
6057 }
6058 else
6059 {
6060 struct d3dx_technique *technique;
6061 struct d3dx_pass *pass;
6062
6063 if (technique_index >= effect->technique_count)
6064 {
6065 FIXME("Index out of bounds: technique_index %u >= technique_count %u.\n", technique_index,
6066 effect->technique_count);
6067 return E_FAIL;
6068 }
6069
6070 technique = &effect->techniques[technique_index];
6071 if (index >= technique->pass_count)
6072 {
6073 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
6074 return E_FAIL;
6075 }
6076
6077 pass = &technique->passes[index];
6078 if (state_index >= pass->state_count)
6079 {
6080 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
6081 return E_FAIL;
6082 }
6083
6084 state = &pass->states[state_index];
6085 }
6086
6087 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name);
6088 param = &state->parameter;
6089 TRACE("Using object id %u.\n", param->object_id);
6090 object = &effect->objects[param->object_id];
6091
6092 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class),
6093 debug_d3dxparameter_type(param->type));
6094 switch (usage)
6095 {
6096 case 0:
6097 switch (param->type)
6098 {
6099 case D3DXPT_VERTEXSHADER:
6100 case D3DXPT_PIXELSHADER:
6101 state->type = ST_CONSTANT;
6102 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6103 return hr;
6104
6105 if (object->data)
6106 {
6107 if (FAILED(hr = d3dx9_create_object(effect, object)))
6108 return hr;
6109 if (FAILED(hr = d3dx_create_param_eval(effect, object->data, object->size, param->type,
6110 ¶m->param_eval, get_version_counter_ptr(effect),
6111 skip_constants, skip_constants_count)))
6112 return hr;
6113 }
6114 break;
6115
6116 case D3DXPT_BOOL:
6117 case D3DXPT_INT:
6118 case D3DXPT_FLOAT:
6119 case D3DXPT_STRING:
6120 state->type = ST_FXLC;
6121 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6122 return hr;
6123 if (FAILED(hr = d3dx_create_param_eval(effect, object->data, object->size, param->type,
6124 ¶m->param_eval, get_version_counter_ptr(effect), NULL, 0)))
6125 return hr;
6126 break;
6127
6128 default:
6129 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
6130 break;
6131 }
6132 break;
6133
6134 case 1:
6135 state->type = ST_PARAMETER;
6136 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6137 return hr;
6138
6139 TRACE("Looking for parameter %s.\n", debugstr_a(object->data));
6140 state->referenced_param = get_parameter_by_name(effect, NULL, object->data);
6141 if (state->referenced_param)
6142 {
6143 struct d3dx_parameter *refpar = state->referenced_param;
6144
6145 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
6146 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
6147 {
6148 struct d3dx_object *refobj = &effect->objects[refpar->object_id];
6149
6150 if (!refpar->param_eval)
6151 {
6152 if (FAILED(hr = d3dx_create_param_eval(effect, refobj->data, refobj->size,
6153 refpar->type, &refpar->param_eval, get_version_counter_ptr(effect),
6154 skip_constants, skip_constants_count)))
6155 return hr;
6156 }
6157 }
6158 }
6159 else
6160 {
6161 FIXME("Referenced parameter %s not found.\n", (char *)object->data);
6162 return D3DXERR_INVALIDDATA;
6163 }
6164 break;
6165
6166 case 2:
6167 state->type = ST_ARRAY_SELECTOR;
6168 if (FAILED(hr = d3dx9_copy_data(effect, param->object_id, ptr)))
6169 return hr;
6170 hr = d3dx_parse_array_selector(effect, state, skip_constants, skip_constants_count);
6171 break;
6172
6173 default:
6174 FIXME("Unknown usage %x\n", usage);
6175 break;
6176 }
6177
6178 return hr;
6179 }
6180
param_set_top_level_param(void * top_level_param,struct d3dx_parameter * param)6181 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param)
6182 {
6183 param->top_level_param = top_level_param;
6184 return FALSE;
6185 }
6186
d3dx_parse_effect(struct d3dx_effect * effect,const char * data,UINT data_size,DWORD start,const char ** skip_constants,unsigned int skip_constants_count)6187 static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, UINT data_size,
6188 DWORD start, const char **skip_constants, unsigned int skip_constants_count)
6189 {
6190 const char *ptr = data + start;
6191 UINT stringcount, resourcecount;
6192 HRESULT hr;
6193 UINT i;
6194
6195 read_dword(&ptr, &effect->parameter_count);
6196 TRACE("Parameter count: %u.\n", effect->parameter_count);
6197
6198 read_dword(&ptr, &effect->technique_count);
6199 TRACE("Technique count: %u.\n", effect->technique_count);
6200
6201 skip_dword_unknown(&ptr, 1);
6202
6203 read_dword(&ptr, &effect->object_count);
6204 TRACE("Object count: %u.\n", effect->object_count);
6205
6206 effect->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
6207 sizeof(*effect->objects) * effect->object_count);
6208 if (!effect->objects)
6209 {
6210 ERR("Out of memory.\n");
6211 hr = E_OUTOFMEMORY;
6212 goto err_out;
6213 }
6214
6215 wine_rb_init(&effect->param_tree, param_rb_compare);
6216 if (effect->parameter_count)
6217 {
6218 effect->parameters = heap_alloc_zero(sizeof(*effect->parameters) * effect->parameter_count);
6219 if (!effect->parameters)
6220 {
6221 ERR("Out of memory.\n");
6222 hr = E_OUTOFMEMORY;
6223 goto err_out;
6224 }
6225
6226 for (i = 0; i < effect->parameter_count; ++i)
6227 {
6228 param_set_magic_number(&effect->parameters[i].param);
6229 hr = d3dx_parse_effect_parameter(effect, &effect->parameters[i], data, &ptr, effect->objects);
6230 if (hr != D3D_OK)
6231 {
6232 WARN("Failed to parse parameter %u.\n", i);
6233 goto err_out;
6234 }
6235 walk_parameter_tree(&effect->parameters[i].param, param_set_top_level_param, &effect->parameters[i]);
6236 add_param_to_tree(effect, &effect->parameters[i].param, NULL, 0, 0);
6237 }
6238 }
6239
6240 if (effect->technique_count)
6241 {
6242 effect->techniques = heap_alloc_zero(sizeof(*effect->techniques) * effect->technique_count);
6243 if (!effect->techniques)
6244 {
6245 ERR("Out of memory.\n");
6246 hr = E_OUTOFMEMORY;
6247 goto err_out;
6248 }
6249
6250 for (i = 0; i < effect->technique_count; ++i)
6251 {
6252 TRACE("Parsing technique %u.\n", i);
6253 hr = d3dx_parse_effect_technique(effect, &effect->techniques[i], data, &ptr, effect->objects);
6254 if (hr != D3D_OK)
6255 {
6256 WARN("Failed to parse technique %u.\n", i);
6257 goto err_out;
6258 }
6259 }
6260 }
6261
6262 read_dword(&ptr, &stringcount);
6263 TRACE("String count: %u.\n", stringcount);
6264
6265 read_dword(&ptr, &resourcecount);
6266 TRACE("Resource count: %u.\n", resourcecount);
6267
6268 for (i = 0; i < stringcount; ++i)
6269 {
6270 DWORD id;
6271
6272 read_dword(&ptr, &id);
6273 TRACE("id: %u.\n", id);
6274
6275 if (FAILED(hr = d3dx9_copy_data(effect, id, &ptr)))
6276 goto err_out;
6277
6278 if (effect->objects[id].data)
6279 {
6280 if (FAILED(hr = d3dx9_create_object(effect, &effect->objects[id])))
6281 goto err_out;
6282 }
6283 }
6284
6285 for (i = 0; i < resourcecount; ++i)
6286 {
6287 TRACE("parse resource %u.\n", i);
6288
6289 hr = d3dx_parse_resource(effect, data, &ptr, skip_constants, skip_constants_count);
6290 if (hr != D3D_OK)
6291 {
6292 WARN("Failed to parse resource %u.\n", i);
6293 goto err_out;
6294 }
6295 }
6296
6297 for (i = 0; i < effect->parameter_count; ++i)
6298 {
6299 if (FAILED(hr = d3dx_pool_sync_shared_parameter(effect->pool, &effect->parameters[i])))
6300 goto err_out;
6301 effect->parameters[i].version_counter = get_version_counter_ptr(effect);
6302 set_dirty(&effect->parameters[i].param);
6303 }
6304 return D3D_OK;
6305
6306 err_out:
6307
6308 if (effect->techniques)
6309 {
6310 for (i = 0; i < effect->technique_count; ++i)
6311 free_technique(&effect->techniques[i]);
6312 heap_free(effect->techniques);
6313 effect->techniques = NULL;
6314 }
6315
6316 if (effect->parameters)
6317 {
6318 for (i = 0; i < effect->parameter_count; ++i)
6319 {
6320 free_top_level_parameter(&effect->parameters[i]);
6321 }
6322 heap_free(effect->parameters);
6323 effect->parameters = NULL;
6324 }
6325
6326 if (effect->objects)
6327 {
6328 for (i = 0; i < effect->object_count; ++i)
6329 {
6330 free_object(&effect->objects[i]);
6331 }
6332 HeapFree(GetProcessHeap(), 0, effect->objects);
6333 effect->objects = NULL;
6334 }
6335
6336 return hr;
6337 }
6338
6339 #define INITIAL_CONST_NAMES_SIZE 4
6340
next_valid_constant_name(char ** string)6341 static char *next_valid_constant_name(char **string)
6342 {
6343 char *ret = *string;
6344 char *next;
6345
6346 while (*ret && !isalpha(*ret) && *ret != '_')
6347 ++ret;
6348 if (!*ret)
6349 return NULL;
6350
6351 next = ret + 1;
6352 while (isalpha(*next) || isdigit(*next) || *next == '_')
6353 ++next;
6354 if (*next)
6355 *next++ = 0;
6356 *string = next;
6357 return ret;
6358 }
6359
parse_skip_constants_string(char * skip_constants_string,unsigned int * names_count)6360 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count)
6361 {
6362 const char **names, **new_alloc;
6363 const char *name;
6364 char *s;
6365 unsigned int size = INITIAL_CONST_NAMES_SIZE;
6366
6367 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size);
6368 if (!names)
6369 return NULL;
6370
6371 *names_count = 0;
6372 s = skip_constants_string;
6373 while ((name = next_valid_constant_name(&s)))
6374 {
6375 if (*names_count == size)
6376 {
6377 size *= 2;
6378 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size);
6379 if (!new_alloc)
6380 {
6381 HeapFree(GetProcessHeap(), 0, names);
6382 return NULL;
6383 }
6384 names = new_alloc;
6385 }
6386 names[(*names_count)++] = name;
6387 }
6388 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names));
6389 if (!new_alloc)
6390 return names;
6391 return new_alloc;
6392 }
6393
d3dx9_effect_init(struct d3dx_effect * effect,struct IDirect3DDevice9 * device,const char * data,SIZE_T data_size,const D3D_SHADER_MACRO * defines,ID3DInclude * include,UINT eflags,ID3DBlob ** errors,struct ID3DXEffectPool * pool,const char * skip_constants_string)6394 static HRESULT d3dx9_effect_init(struct d3dx_effect *effect, struct IDirect3DDevice9 *device,
6395 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6396 UINT eflags, ID3DBlob **errors, struct ID3DXEffectPool *pool, const char *skip_constants_string)
6397 {
6398 #if D3DX_SDK_VERSION <= 36
6399 UINT compile_flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
6400 #else
6401 UINT compile_flags = 0;
6402 #endif
6403 ID3DBlob *bytecode = NULL, *temp_errors = NULL;
6404 unsigned int skip_constants_count = 0;
6405 char *skip_constants_buffer = NULL;
6406 const char **skip_constants = NULL;
6407 const char *ptr = data;
6408 DWORD tag, offset;
6409 unsigned int i, j;
6410 HRESULT hr;
6411
6412 TRACE("effect %p, device %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, errors %p, "
6413 "pool %p, skip_constants %s.\n",
6414 effect, device, data, data_size, defines, include, eflags, errors, pool,
6415 debugstr_a(skip_constants_string));
6416
6417 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
6418 effect->ref = 1;
6419
6420 if (pool)
6421 {
6422 effect->pool = unsafe_impl_from_ID3DXEffectPool(pool);
6423 pool->lpVtbl->AddRef(pool);
6424 }
6425
6426 IDirect3DDevice9_AddRef(device);
6427 effect->device = device;
6428
6429 effect->flags = eflags;
6430
6431 list_init(&effect->parameter_block_list);
6432
6433 read_dword(&ptr, &tag);
6434 TRACE("Tag: %x\n", tag);
6435
6436 if (tag != d3dx9_effect_version(9, 1))
6437 {
6438 TRACE("HLSL ASCII effect, trying to compile it.\n");
6439 hr = D3DCompile(data, data_size, NULL, defines, include,
6440 NULL, "fx_2_0", compile_flags, eflags, &bytecode, &temp_errors);
6441 if (FAILED(hr))
6442 {
6443 WARN("Failed to compile ASCII effect.\n");
6444 if (bytecode)
6445 ID3D10Blob_Release(bytecode);
6446 if (temp_errors)
6447 {
6448 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors);
6449 const char *string_ptr;
6450
6451 while (*error_string)
6452 {
6453 string_ptr = error_string;
6454 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r'
6455 && string_ptr - error_string < 80)
6456 ++string_ptr;
6457 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string));
6458 error_string = string_ptr;
6459 while (*error_string == '\n' || *error_string == '\r')
6460 ++error_string;
6461 }
6462 }
6463 if (errors)
6464 *errors = temp_errors;
6465 else if (temp_errors)
6466 ID3D10Blob_Release(temp_errors);
6467 return hr;
6468 }
6469 if (!bytecode)
6470 {
6471 FIXME("No output from effect compilation.\n");
6472 return D3DERR_INVALIDCALL;
6473 }
6474 if (errors)
6475 *errors = temp_errors;
6476 else if (temp_errors)
6477 ID3D10Blob_Release(temp_errors);
6478
6479 ptr = ID3D10Blob_GetBufferPointer(bytecode);
6480 read_dword(&ptr, &tag);
6481 TRACE("Tag: %x\n", tag);
6482 }
6483
6484 if (skip_constants_string)
6485 {
6486 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0,
6487 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1));
6488 if (!skip_constants_buffer)
6489 {
6490 if (bytecode)
6491 ID3D10Blob_Release(bytecode);
6492 return E_OUTOFMEMORY;
6493 }
6494 strcpy(skip_constants_buffer, skip_constants_string);
6495
6496 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count)))
6497 {
6498 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6499 if (bytecode)
6500 ID3D10Blob_Release(bytecode);
6501 return E_OUTOFMEMORY;
6502 }
6503 }
6504 read_dword(&ptr, &offset);
6505 TRACE("Offset: %x\n", offset);
6506
6507 hr = d3dx_parse_effect(effect, ptr, data_size, offset, skip_constants, skip_constants_count);
6508 if (bytecode)
6509 ID3D10Blob_Release(bytecode);
6510 if (hr != D3D_OK)
6511 {
6512 FIXME("Failed to parse effect.\n");
6513 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6514 HeapFree(GetProcessHeap(), 0, skip_constants);
6515 return hr;
6516 }
6517
6518 for (i = 0; i < skip_constants_count; ++i)
6519 {
6520 struct d3dx_parameter *param;
6521 param = get_parameter_by_name(effect, NULL, skip_constants[i]);
6522 if (param)
6523 {
6524 for (j = 0; j < effect->technique_count; ++j)
6525 {
6526 if (is_parameter_used(param, &effect->techniques[j]))
6527 {
6528 WARN("skip_constants parameter %s is used in technique %u.\n",
6529 debugstr_a(skip_constants[i]), j);
6530 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6531 HeapFree(GetProcessHeap(), 0, skip_constants);
6532 return D3DERR_INVALIDCALL;
6533 }
6534 }
6535 }
6536 else
6537 {
6538 TRACE("skip_constants parameter %s not found.\n",
6539 debugstr_a(skip_constants[i]));
6540 }
6541 }
6542
6543 HeapFree(GetProcessHeap(), 0, skip_constants_buffer);
6544 HeapFree(GetProcessHeap(), 0, skip_constants);
6545
6546 /* initialize defaults - check because of unsupported ascii effects */
6547 if (effect->techniques)
6548 {
6549 effect->active_technique = &effect->techniques[0];
6550 effect->active_pass = NULL;
6551 }
6552
6553 return D3D_OK;
6554 }
6555
D3DXCreateEffectEx(struct IDirect3DDevice9 * device,const void * srcdata,UINT srcdatalen,const D3DXMACRO * defines,struct ID3DXInclude * include,const char * skip_constants,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilation_errors)6556 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6557 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags,
6558 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6559 {
6560 struct d3dx_effect *object;
6561 HRESULT hr;
6562
6563 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p,"
6564 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n",
6565 device, srcdata, srcdatalen, defines, include,
6566 skip_constants, flags, pool, effect, compilation_errors);
6567
6568 if (compilation_errors)
6569 *compilation_errors = NULL;
6570
6571 if (!device || !srcdata)
6572 return D3DERR_INVALIDCALL;
6573
6574 if (!srcdatalen)
6575 return E_FAIL;
6576
6577 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6578 if (!effect)
6579 return D3D_OK;
6580
6581 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6582 if (!object)
6583 return E_OUTOFMEMORY;
6584
6585 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6586 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants);
6587 if (FAILED(hr))
6588 {
6589 WARN("Failed to create effect object, hr %#x.\n", hr);
6590 d3dx_effect_cleanup(object);
6591 return hr;
6592 }
6593
6594 *effect = &object->ID3DXEffect_iface;
6595
6596 TRACE("Created ID3DXEffect %p\n", object);
6597
6598 return D3D_OK;
6599 }
6600
D3DXCreateEffect(struct IDirect3DDevice9 * device,const void * srcdata,UINT srcdatalen,const D3DXMACRO * defines,struct ID3DXInclude * include,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilation_errors)6601 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen,
6602 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6603 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors)
6604 {
6605 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
6606 include, flags, pool, effect, compilation_errors);
6607
6608 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
6609 }
6610
d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl * compiler,const char * data,SIZE_T data_size,const D3D_SHADER_MACRO * defines,ID3DInclude * include,UINT eflags,ID3DBlob ** error_messages)6611 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler,
6612 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include,
6613 UINT eflags, ID3DBlob **error_messages)
6614 {
6615 TRACE("compiler %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, error_messages %p.\n",
6616 compiler, data, data_size, defines, include, eflags, error_messages);
6617
6618 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
6619 compiler->ref = 1;
6620
6621 FIXME("ID3DXEffectCompiler implementation is only a stub.\n");
6622
6623 return D3D_OK;
6624 }
6625
D3DXCreateEffectCompiler(const char * srcdata,UINT srcdatalen,const D3DXMACRO * defines,ID3DXInclude * include,DWORD flags,ID3DXEffectCompiler ** compiler,ID3DXBuffer ** parse_errors)6626 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines,
6627 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors)
6628 {
6629 struct ID3DXEffectCompilerImpl *object;
6630 HRESULT hr;
6631
6632 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
6633 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
6634
6635 if (!srcdata || !compiler)
6636 {
6637 WARN("Invalid arguments supplied\n");
6638 return D3DERR_INVALIDCALL;
6639 }
6640
6641 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6642 if (!object)
6643 return E_OUTOFMEMORY;
6644
6645 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines,
6646 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors);
6647 if (FAILED(hr))
6648 {
6649 WARN("Failed to initialize effect compiler\n");
6650 HeapFree(GetProcessHeap(), 0, object);
6651 return hr;
6652 }
6653
6654 *compiler = &object->ID3DXEffectCompiler_iface;
6655
6656 TRACE("Created ID3DXEffectCompiler %p\n", object);
6657
6658 return D3D_OK;
6659 }
6660
6661 /*** IUnknown methods ***/
d3dx_effect_pool_QueryInterface(ID3DXEffectPool * iface,REFIID riid,void ** object)6662 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
6663 {
6664 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
6665
6666 if (IsEqualGUID(riid, &IID_IUnknown) ||
6667 IsEqualGUID(riid, &IID_ID3DXEffectPool))
6668 {
6669 iface->lpVtbl->AddRef(iface);
6670 *object = iface;
6671 return S_OK;
6672 }
6673
6674 WARN("Interface %s not found\n", debugstr_guid(riid));
6675
6676 return E_NOINTERFACE;
6677 }
6678
d3dx_effect_pool_AddRef(ID3DXEffectPool * iface)6679 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface)
6680 {
6681 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6682 ULONG refcount = InterlockedIncrement(&pool->refcount);
6683
6684 TRACE("%p increasing refcount to %u.\n", pool, refcount);
6685
6686 return refcount;
6687 }
6688
free_effect_pool(struct d3dx_effect_pool * pool)6689 static void free_effect_pool(struct d3dx_effect_pool *pool)
6690 {
6691 unsigned int i;
6692
6693 for (i = 0; i < pool->size; ++i)
6694 {
6695 if (pool->shared_data[i].count)
6696 {
6697 unsigned int j;
6698
6699 WARN("Releasing pool with referenced parameters.\n");
6700
6701 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE);
6702 pool->shared_data[i].parameters[0]->shared_data = NULL;
6703
6704 for (j = 1; j < pool->shared_data[i].count; ++j)
6705 {
6706 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL);
6707 pool->shared_data[i].parameters[j]->shared_data = NULL;
6708 }
6709 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters);
6710 }
6711 }
6712 HeapFree(GetProcessHeap(), 0, pool->shared_data);
6713 HeapFree(GetProcessHeap(), 0, pool);
6714 }
6715
d3dx_effect_pool_Release(ID3DXEffectPool * iface)6716 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface)
6717 {
6718 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface);
6719 ULONG refcount = InterlockedDecrement(&pool->refcount);
6720
6721 TRACE("%p decreasing refcount to %u.\n", pool, refcount);
6722
6723 if (!refcount)
6724 free_effect_pool(pool);
6725
6726 return refcount;
6727 }
6728
6729 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
6730 {
6731 /*** IUnknown methods ***/
6732 d3dx_effect_pool_QueryInterface,
6733 d3dx_effect_pool_AddRef,
6734 d3dx_effect_pool_Release
6735 };
6736
unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool * iface)6737 static inline struct d3dx_effect_pool *unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
6738 {
6739 if (!iface)
6740 return NULL;
6741
6742 assert(iface->lpVtbl == &ID3DXEffectPool_Vtbl);
6743 return impl_from_ID3DXEffectPool(iface);
6744 }
6745
D3DXCreateEffectPool(ID3DXEffectPool ** pool)6746 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool)
6747 {
6748 struct d3dx_effect_pool *object;
6749
6750 TRACE("pool %p.\n", pool);
6751
6752 if (!pool)
6753 return D3DERR_INVALIDCALL;
6754
6755 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
6756 if (!object)
6757 return E_OUTOFMEMORY;
6758
6759 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
6760 object->refcount = 1;
6761
6762 *pool = &object->ID3DXEffectPool_iface;
6763
6764 return S_OK;
6765 }
6766
D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 * device,const WCHAR * srcfile,const D3DXMACRO * defines,struct ID3DXInclude * include,const char * skipconstants,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6767 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6768 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6769 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6770 {
6771 struct d3dx_include_from_file include_from_file;
6772 const void *buffer;
6773 unsigned int size;
6774 char *filename_a;
6775 HRESULT ret;
6776
6777 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6778 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6779 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants),
6780 flags, pool, effect, compilationerrors);
6781
6782 if (!device || !srcfile)
6783 return D3DERR_INVALIDCALL;
6784
6785 if (!include)
6786 {
6787 include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
6788 include = &include_from_file.ID3DXInclude_iface;
6789 }
6790
6791 size = WideCharToMultiByte(CP_ACP, 0, srcfile, -1, NULL, 0, NULL, NULL);
6792 filename_a = heap_alloc(size);
6793 if (!filename_a)
6794 return E_OUTOFMEMORY;
6795 WideCharToMultiByte(CP_ACP, 0, srcfile, -1, filename_a, size, NULL, NULL);
6796
6797 EnterCriticalSection(&from_file_mutex);
6798 ret = ID3DXInclude_Open(include, D3DXINC_LOCAL, filename_a, NULL, &buffer, &size);
6799 if (FAILED(ret))
6800 {
6801 LeaveCriticalSection(&from_file_mutex);
6802 heap_free(filename_a);
6803 return D3DXERR_INVALIDDATA;
6804 }
6805
6806 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool,
6807 effect, compilationerrors);
6808
6809 ID3DXInclude_Close(include, buffer);
6810 LeaveCriticalSection(&from_file_mutex);
6811 heap_free(filename_a);
6812 return ret;
6813 }
6814
D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 * device,const char * srcfile,const D3DXMACRO * defines,struct ID3DXInclude * include,const char * skipconstants,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6815 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
6816 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
6817 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6818 {
6819 WCHAR *srcfileW;
6820 HRESULT ret;
6821 DWORD len;
6822
6823 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6824 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6825 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants),
6826 flags, pool, effect, compilationerrors);
6827
6828 if (!srcfile)
6829 return D3DERR_INVALIDCALL;
6830
6831 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6832 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6833 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6834
6835 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6836 HeapFree(GetProcessHeap(), 0, srcfileW);
6837
6838 return ret;
6839 }
6840
D3DXCreateEffectFromFileW(struct IDirect3DDevice9 * device,const WCHAR * srcfile,const D3DXMACRO * defines,struct ID3DXInclude * include,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6841 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
6842 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6843 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6844 {
6845 TRACE("(void): relay\n");
6846 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6847 }
6848
D3DXCreateEffectFromFileA(struct IDirect3DDevice9 * device,const char * srcfile,const D3DXMACRO * defines,struct ID3DXInclude * include,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6849 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile,
6850 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool,
6851 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6852 {
6853 TRACE("(void): relay\n");
6854 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6855 }
6856
D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 * device,HMODULE srcmodule,const WCHAR * srcresource,const D3DXMACRO * defines,struct ID3DXInclude * include,const char * skipconstants,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6857 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6858 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6859 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6860 {
6861 HRSRC resinfo;
6862 void *buffer;
6863 DWORD size;
6864
6865 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6866 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6867 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants),
6868 flags, pool, effect, compilationerrors);
6869
6870 if (!device)
6871 return D3DERR_INVALIDCALL;
6872
6873 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
6874 return D3DXERR_INVALIDDATA;
6875
6876 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6877 return D3DXERR_INVALIDDATA;
6878
6879 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6880 skipconstants, flags, pool, effect, compilationerrors);
6881 }
6882
D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 * device,HMODULE srcmodule,const char * srcresource,const D3DXMACRO * defines,struct ID3DXInclude * include,const char * skipconstants,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6883 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6884 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants,
6885 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6886 {
6887 HRSRC resinfo;
6888 void *buffer;
6889 DWORD size;
6890
6891 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
6892 "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
6893 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants),
6894 flags, pool, effect, compilationerrors);
6895
6896 if (!device)
6897 return D3DERR_INVALIDCALL;
6898
6899 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6900 return D3DXERR_INVALIDDATA;
6901
6902 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6903 return D3DXERR_INVALIDDATA;
6904
6905 return D3DXCreateEffectEx(device, buffer, size, defines, include,
6906 skipconstants, flags, pool, effect, compilationerrors);
6907 }
6908
D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 * device,HMODULE srcmodule,const WCHAR * srcresource,const D3DXMACRO * defines,struct ID3DXInclude * include,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6909 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6910 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6911 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6912 {
6913 TRACE("(void): relay\n");
6914 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6915 }
6916
D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 * device,HMODULE srcmodule,const char * srcresource,const D3DXMACRO * defines,struct ID3DXInclude * include,DWORD flags,struct ID3DXEffectPool * pool,struct ID3DXEffect ** effect,struct ID3DXBuffer ** compilationerrors)6917 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
6918 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags,
6919 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
6920 {
6921 TRACE("(void): relay\n");
6922 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6923 }
6924
D3DXCreateEffectCompilerFromFileW(const WCHAR * srcfile,const D3DXMACRO * defines,ID3DXInclude * include,DWORD flags,ID3DXEffectCompiler ** effectcompiler,ID3DXBuffer ** parseerrors)6925 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines,
6926 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6927 {
6928 void *buffer;
6929 HRESULT ret;
6930 DWORD size;
6931
6932 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6933 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors);
6934
6935 if (!srcfile)
6936 return D3DERR_INVALIDCALL;
6937
6938 ret = map_view_of_file(srcfile, &buffer, &size);
6939
6940 if (FAILED(ret))
6941 return D3DXERR_INVALIDDATA;
6942
6943 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6944 UnmapViewOfFile(buffer);
6945
6946 return ret;
6947 }
6948
D3DXCreateEffectCompilerFromFileA(const char * srcfile,const D3DXMACRO * defines,ID3DXInclude * include,DWORD flags,ID3DXEffectCompiler ** effectcompiler,ID3DXBuffer ** parseerrors)6949 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines,
6950 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6951 {
6952 WCHAR *srcfileW;
6953 HRESULT ret;
6954 DWORD len;
6955
6956 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6957 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors);
6958
6959 if (!srcfile)
6960 return D3DERR_INVALIDCALL;
6961
6962 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6963 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6964 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6965
6966 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
6967 HeapFree(GetProcessHeap(), 0, srcfileW);
6968
6969 return ret;
6970 }
6971
D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule,const char * srcresource,const D3DXMACRO * defines,ID3DXInclude * include,DWORD flags,ID3DXEffectCompiler ** effectcompiler,ID3DXBuffer ** parseerrors)6972 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource,
6973 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
6974 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6975 {
6976 HRSRC resinfo;
6977 void *buffer;
6978 DWORD size;
6979
6980 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
6981 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors);
6982
6983 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA)))
6984 return D3DXERR_INVALIDDATA;
6985
6986 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
6987 return D3DXERR_INVALIDDATA;
6988
6989 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6990 }
6991
D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule,const WCHAR * srcresource,const D3DXMACRO * defines,ID3DXInclude * include,DWORD flags,ID3DXEffectCompiler ** effectcompiler,ID3DXBuffer ** parseerrors)6992 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource,
6993 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags,
6994 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors)
6995 {
6996 HRSRC resinfo;
6997 void *buffer;
6998 DWORD size;
6999
7000 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n",
7001 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors);
7002
7003 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA)))
7004 return D3DXERR_INVALIDDATA;
7005
7006 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
7007 return D3DXERR_INVALIDDATA;
7008
7009 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
7010 }
7011
D3DXDisassembleEffect(ID3DXEffect * effect,BOOL enable_color_code,ID3DXBuffer ** disassembly)7012 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly)
7013 {
7014 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly);
7015
7016 return D3DXERR_INVALIDDATA;
7017 }
7018