2 * Copyright 2010 Christian Costa
3 * Copyright 2011 Rico Schüller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "d3dx9_private.h"
25 #include "d3dcompiler.h"
27 #include "wine/list.h"
29 /* Constants for special INT/FLOAT conversation */
30 #define INT_FLOAT_MULTI 255.0f
31 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
33 static const char parameter_magic_string
[4] = {'@', '!', '#', '\xFF'};
34 static const char parameter_block_magic_string
[4] = {'@', '!', '#', '\xFE'};
36 #define PARAMETER_FLAG_SHARED 1
38 #define INITIAL_POOL_SIZE 16
39 #define INITIAL_PARAM_BLOCK_SIZE 1024
41 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
88 enum SHADER_CONSTANT_TYPE
110 struct d3dx_parameter
*param
;
111 BOOL creation_failed
;
116 unsigned int operation
;
118 enum STATE_TYPE type
;
119 struct d3dx_parameter parameter
;
120 struct d3dx_parameter
*referenced_param
;
126 struct d3dx_state
*states
;
132 unsigned int state_count
;
133 unsigned int annotation_count
;
135 struct d3dx_state
*states
;
136 struct d3dx_parameter
*annotations
;
138 ULONG64 update_version
;
141 struct d3dx_technique
144 unsigned int pass_count
;
145 unsigned int annotation_count
;
147 struct d3dx_parameter
*annotations
;
148 struct d3dx_pass
*passes
;
150 struct IDirect3DStateBlock9
*saved_state
;
153 struct d3dx_parameter_block
155 char magic_string
[ARRAY_SIZE(parameter_block_magic_string
)];
156 struct d3dx_effect
*effect
;
163 struct d3dx_recorded_parameter
165 struct d3dx_parameter
*param
;
171 ID3DXEffect ID3DXEffect_iface
;
174 unsigned int technique_count
;
175 unsigned int object_count
;
176 struct d3dx_technique
*techniques
;
177 struct d3dx_object
*objects
;
180 struct d3dx_parameters_store params
;
182 struct ID3DXEffectStateManager
*manager
;
183 struct IDirect3DDevice9
*device
;
184 struct d3dx_effect_pool
*pool
;
185 struct d3dx_technique
*active_technique
;
186 struct d3dx_pass
*active_pass
;
189 ULONG64 version_counter
;
191 D3DLIGHT9 current_light
[8];
192 unsigned int light_updated
;
193 D3DMATERIAL9 current_material
;
194 BOOL material_updated
;
196 struct list parameter_block_list
;
197 struct d3dx_parameter_block
*current_parameter_block
;
201 char *skip_constants_string
;
204 #define INITIAL_SHARED_DATA_SIZE 4
206 struct d3dx_effect_pool
208 ID3DXEffectPool ID3DXEffectPool_iface
;
211 struct d3dx_shared_data
*shared_data
;
214 ULONG64 version_counter
;
217 struct ID3DXEffectCompilerImpl
219 ID3DXEffectCompiler ID3DXEffectCompiler_iface
;
223 static HRESULT
d3dx9_effect_init_from_binary(struct d3dx_effect
*effect
,
224 struct IDirect3DDevice9
*device
, const char *data
, SIZE_T data_size
,
225 unsigned int flags
, struct ID3DXEffectPool
*pool
, const char *skip_constants_string
);
226 static HRESULT
d3dx_parse_state(struct d3dx_effect
*effect
, struct d3dx_state
*state
,
227 const char *data
, const char **ptr
, struct d3dx_object
*objects
);
228 static void free_parameter(struct d3dx_parameter
*param
, BOOL element
, BOOL child
);
230 typedef BOOL (*walk_parameter_dep_func
)(void *data
, struct d3dx_parameter
*param
);
234 enum STATE_CLASS
class;
241 {SC_RENDERSTATE
, D3DRS_ZENABLE
, "D3DRS_ZENABLE"}, /* 0x0 */
242 {SC_RENDERSTATE
, D3DRS_FILLMODE
, "D3DRS_FILLMODE"},
243 {SC_RENDERSTATE
, D3DRS_SHADEMODE
, "D3DRS_SHADEMODE"},
244 {SC_RENDERSTATE
, D3DRS_ZWRITEENABLE
, "D3DRS_ZWRITEENABLE"},
245 {SC_RENDERSTATE
, D3DRS_ALPHATESTENABLE
, "D3DRS_ALPHATESTENABLE"},
246 {SC_RENDERSTATE
, D3DRS_LASTPIXEL
, "D3DRS_LASTPIXEL"},
247 {SC_RENDERSTATE
, D3DRS_SRCBLEND
, "D3DRS_SRCBLEND"},
248 {SC_RENDERSTATE
, D3DRS_DESTBLEND
, "D3DRS_DESTBLEND"},
249 {SC_RENDERSTATE
, D3DRS_CULLMODE
, "D3DRS_CULLMODE"},
250 {SC_RENDERSTATE
, D3DRS_ZFUNC
, "D3DRS_ZFUNC"},
251 {SC_RENDERSTATE
, D3DRS_ALPHAREF
, "D3DRS_ALPHAREF"},
252 {SC_RENDERSTATE
, D3DRS_ALPHAFUNC
, "D3DRS_ALPHAFUNC"},
253 {SC_RENDERSTATE
, D3DRS_DITHERENABLE
, "D3DRS_DITHERENABLE"},
254 {SC_RENDERSTATE
, D3DRS_ALPHABLENDENABLE
, "D3DRS_ALPHABLENDENABLE"},
255 {SC_RENDERSTATE
, D3DRS_FOGENABLE
, "D3DRS_FOGENABLE"},
256 {SC_RENDERSTATE
, D3DRS_SPECULARENABLE
, "D3DRS_SPECULARENABLE"},
257 {SC_RENDERSTATE
, D3DRS_FOGCOLOR
, "D3DRS_FOGCOLOR"}, /* 0x10 */
258 {SC_RENDERSTATE
, D3DRS_FOGTABLEMODE
, "D3DRS_FOGTABLEMODE"},
259 {SC_RENDERSTATE
, D3DRS_FOGSTART
, "D3DRS_FOGSTART"},
260 {SC_RENDERSTATE
, D3DRS_FOGEND
, "D3DRS_FOGEND"},
261 {SC_RENDERSTATE
, D3DRS_FOGDENSITY
, "D3DRS_FOGDENSITY"},
262 {SC_RENDERSTATE
, D3DRS_RANGEFOGENABLE
, "D3DRS_RANGEFOGENABLE"},
263 {SC_RENDERSTATE
, D3DRS_STENCILENABLE
, "D3DRS_STENCILENABLE"},
264 {SC_RENDERSTATE
, D3DRS_STENCILFAIL
, "D3DRS_STENCILFAIL"},
265 {SC_RENDERSTATE
, D3DRS_STENCILZFAIL
, "D3DRS_STENCILZFAIL"},
266 {SC_RENDERSTATE
, D3DRS_STENCILPASS
, "D3DRS_STENCILPASS"},
267 {SC_RENDERSTATE
, D3DRS_STENCILFUNC
, "D3DRS_STENCILFUNC"},
268 {SC_RENDERSTATE
, D3DRS_STENCILREF
, "D3DRS_STENCILREF"},
269 {SC_RENDERSTATE
, D3DRS_STENCILMASK
, "D3DRS_STENCILMASK"},
270 {SC_RENDERSTATE
, D3DRS_STENCILWRITEMASK
, "D3DRS_STENCILWRITEMASK"},
271 {SC_RENDERSTATE
, D3DRS_TEXTUREFACTOR
, "D3DRS_TEXTUREFACTOR"},
272 {SC_RENDERSTATE
, D3DRS_WRAP0
, "D3DRS_WRAP0"},
273 {SC_RENDERSTATE
, D3DRS_WRAP1
, "D3DRS_WRAP1"}, /* 0x20 */
274 {SC_RENDERSTATE
, D3DRS_WRAP2
, "D3DRS_WRAP2"},
275 {SC_RENDERSTATE
, D3DRS_WRAP3
, "D3DRS_WRAP3"},
276 {SC_RENDERSTATE
, D3DRS_WRAP4
, "D3DRS_WRAP4"},
277 {SC_RENDERSTATE
, D3DRS_WRAP5
, "D3DRS_WRAP5"},
278 {SC_RENDERSTATE
, D3DRS_WRAP6
, "D3DRS_WRAP6"},
279 {SC_RENDERSTATE
, D3DRS_WRAP7
, "D3DRS_WRAP7"},
280 {SC_RENDERSTATE
, D3DRS_WRAP8
, "D3DRS_WRAP8"},
281 {SC_RENDERSTATE
, D3DRS_WRAP9
, "D3DRS_WRAP9"},
282 {SC_RENDERSTATE
, D3DRS_WRAP10
, "D3DRS_WRAP10"},
283 {SC_RENDERSTATE
, D3DRS_WRAP11
, "D3DRS_WRAP11"},
284 {SC_RENDERSTATE
, D3DRS_WRAP12
, "D3DRS_WRAP12"},
285 {SC_RENDERSTATE
, D3DRS_WRAP13
, "D3DRS_WRAP13"},
286 {SC_RENDERSTATE
, D3DRS_WRAP14
, "D3DRS_WRAP14"},
287 {SC_RENDERSTATE
, D3DRS_WRAP15
, "D3DRS_WRAP15"},
288 {SC_RENDERSTATE
, D3DRS_CLIPPING
, "D3DRS_CLIPPING"},
289 {SC_RENDERSTATE
, D3DRS_LIGHTING
, "D3DRS_LIGHTING"}, /* 0x30 */
290 {SC_RENDERSTATE
, D3DRS_AMBIENT
, "D3DRS_AMBIENT"},
291 {SC_RENDERSTATE
, D3DRS_FOGVERTEXMODE
, "D3DRS_FOGVERTEXMODE"},
292 {SC_RENDERSTATE
, D3DRS_COLORVERTEX
, "D3DRS_COLORVERTEX"},
293 {SC_RENDERSTATE
, D3DRS_LOCALVIEWER
, "D3DRS_LOCALVIEWER"},
294 {SC_RENDERSTATE
, D3DRS_NORMALIZENORMALS
, "D3DRS_NORMALIZENORMALS"},
295 {SC_RENDERSTATE
, D3DRS_DIFFUSEMATERIALSOURCE
, "D3DRS_DIFFUSEMATERIALSOURCE"},
296 {SC_RENDERSTATE
, D3DRS_SPECULARMATERIALSOURCE
, "D3DRS_SPECULARMATERIALSOURCE"},
297 {SC_RENDERSTATE
, D3DRS_AMBIENTMATERIALSOURCE
, "D3DRS_AMBIENTMATERIALSOURCE"},
298 {SC_RENDERSTATE
, D3DRS_EMISSIVEMATERIALSOURCE
, "D3DRS_EMISSIVEMATERIALSOURCE"},
299 {SC_RENDERSTATE
, D3DRS_VERTEXBLEND
, "D3DRS_VERTEXBLEND"},
300 {SC_RENDERSTATE
, D3DRS_CLIPPLANEENABLE
, "D3DRS_CLIPPLANEENABLE"},
301 {SC_RENDERSTATE
, D3DRS_POINTSIZE
, "D3DRS_POINTSIZE"},
302 {SC_RENDERSTATE
, D3DRS_POINTSIZE_MIN
, "D3DRS_POINTSIZE_MIN"},
303 {SC_RENDERSTATE
, D3DRS_POINTSIZE_MAX
, "D3DRS_POINTSIZE_MAX"},
304 {SC_RENDERSTATE
, D3DRS_POINTSPRITEENABLE
, "D3DRS_POINTSPRITEENABLE"},
305 {SC_RENDERSTATE
, D3DRS_POINTSCALEENABLE
, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
306 {SC_RENDERSTATE
, D3DRS_POINTSCALE_A
, "D3DRS_POINTSCALE_A"},
307 {SC_RENDERSTATE
, D3DRS_POINTSCALE_B
, "D3DRS_POINTSCALE_B"},
308 {SC_RENDERSTATE
, D3DRS_POINTSCALE_C
, "D3DRS_POINTSCALE_C"},
309 {SC_RENDERSTATE
, D3DRS_MULTISAMPLEANTIALIAS
, "D3DRS_MULTISAMPLEANTIALIAS"},
310 {SC_RENDERSTATE
, D3DRS_MULTISAMPLEMASK
, "D3DRS_MULTISAMPLEMASK"},
311 {SC_RENDERSTATE
, D3DRS_PATCHEDGESTYLE
, "D3DRS_PATCHEDGESTYLE"},
312 {SC_RENDERSTATE
, D3DRS_DEBUGMONITORTOKEN
, "D3DRS_DEBUGMONITORTOKEN"},
313 {SC_RENDERSTATE
, D3DRS_INDEXEDVERTEXBLENDENABLE
, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
314 {SC_RENDERSTATE
, D3DRS_COLORWRITEENABLE
, "D3DRS_COLORWRITEENABLE"},
315 {SC_RENDERSTATE
, D3DRS_TWEENFACTOR
, "D3DRS_TWEENFACTOR"},
316 {SC_RENDERSTATE
, D3DRS_BLENDOP
, "D3DRS_BLENDOP"},
317 {SC_RENDERSTATE
, D3DRS_POSITIONDEGREE
, "D3DRS_POSITIONDEGREE"},
318 {SC_RENDERSTATE
, D3DRS_NORMALDEGREE
, "D3DRS_NORMALDEGREE"},
319 {SC_RENDERSTATE
, D3DRS_SCISSORTESTENABLE
, "D3DRS_SCISSORTESTENABLE"},
320 {SC_RENDERSTATE
, D3DRS_SLOPESCALEDEPTHBIAS
, "D3DRS_SLOPESCALEDEPTHBIAS"},
321 {SC_RENDERSTATE
, D3DRS_ANTIALIASEDLINEENABLE
, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
322 {SC_RENDERSTATE
, D3DRS_MINTESSELLATIONLEVEL
, "D3DRS_MINTESSELLATIONLEVEL"},
323 {SC_RENDERSTATE
, D3DRS_MAXTESSELLATIONLEVEL
, "D3DRS_MAXTESSELLATIONLEVEL"},
324 {SC_RENDERSTATE
, D3DRS_ADAPTIVETESS_X
, "D3DRS_ADAPTIVETESS_X"},
325 {SC_RENDERSTATE
, D3DRS_ADAPTIVETESS_Y
, "D3DRS_ADAPTIVETESS_Y"},
326 {SC_RENDERSTATE
, D3DRS_ADAPTIVETESS_Z
, "D3DRS_ADAPTIVETESS_Z"},
327 {SC_RENDERSTATE
, D3DRS_ADAPTIVETESS_W
, "D3DRS_ADAPTIVETESS_W"},
328 {SC_RENDERSTATE
, D3DRS_ENABLEADAPTIVETESSELLATION
, "D3DRS_ENABLEADAPTIVETESSELLATION"},
329 {SC_RENDERSTATE
, D3DRS_TWOSIDEDSTENCILMODE
, "D3DRS_TWOSIDEDSTENCILMODE"},
330 {SC_RENDERSTATE
, D3DRS_CCW_STENCILFAIL
, "D3DRS_CCW_STENCILFAIL"},
331 {SC_RENDERSTATE
, D3DRS_CCW_STENCILZFAIL
, "D3DRS_CCW_STENCILZFAIL"},
332 {SC_RENDERSTATE
, D3DRS_CCW_STENCILPASS
, "D3DRS_CCW_STENCILPASS"},
333 {SC_RENDERSTATE
, D3DRS_CCW_STENCILFUNC
, "D3DRS_CCW_STENCILFUNC"},
334 {SC_RENDERSTATE
, D3DRS_COLORWRITEENABLE1
, "D3DRS_COLORWRITEENABLE1"},
335 {SC_RENDERSTATE
, D3DRS_COLORWRITEENABLE2
, "D3DRS_COLORWRITEENABLE2"},
336 {SC_RENDERSTATE
, D3DRS_COLORWRITEENABLE3
, "D3DRS_COLORWRITEENABLE3"},
337 {SC_RENDERSTATE
, D3DRS_BLENDFACTOR
, "D3DRS_BLENDFACTOR"}, /* 0x60 */
338 {SC_RENDERSTATE
, D3DRS_SRGBWRITEENABLE
, "D3DRS_SRGBWRITEENABLE"},
339 {SC_RENDERSTATE
, D3DRS_DEPTHBIAS
, "D3DRS_DEPTHBIAS"},
340 {SC_RENDERSTATE
, D3DRS_SEPARATEALPHABLENDENABLE
, "D3DRS_SEPARATEALPHABLENDENABLE"},
341 {SC_RENDERSTATE
, D3DRS_SRCBLENDALPHA
, "D3DRS_SRCBLENDALPHA"},
342 {SC_RENDERSTATE
, D3DRS_DESTBLENDALPHA
, "D3DRS_DESTBLENDALPHA"},
343 {SC_RENDERSTATE
, D3DRS_BLENDOPALPHA
, "D3DRS_BLENDOPALPHA"},
345 {SC_TEXTURESTAGE
, D3DTSS_COLOROP
, "D3DTSS_COLOROP"},
346 {SC_TEXTURESTAGE
, D3DTSS_COLORARG0
, "D3DTSS_COLORARG0"},
347 {SC_TEXTURESTAGE
, D3DTSS_COLORARG1
, "D3DTSS_COLORARG1"},
348 {SC_TEXTURESTAGE
, D3DTSS_COLORARG2
, "D3DTSS_COLORARG2"},
349 {SC_TEXTURESTAGE
, D3DTSS_ALPHAOP
, "D3DTSS_ALPHAOP"},
350 {SC_TEXTURESTAGE
, D3DTSS_ALPHAARG0
, "D3DTSS_ALPHAARG0"},
351 {SC_TEXTURESTAGE
, D3DTSS_ALPHAARG1
, "D3DTSS_ALPHAARG1"},
352 {SC_TEXTURESTAGE
, D3DTSS_ALPHAARG2
, "D3DTSS_ALPHAARG2"},
353 {SC_TEXTURESTAGE
, D3DTSS_RESULTARG
, "D3DTSS_RESULTARG"},
354 {SC_TEXTURESTAGE
, D3DTSS_BUMPENVMAT00
, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
355 {SC_TEXTURESTAGE
, D3DTSS_BUMPENVMAT01
, "D3DTSS_BUMPENVMAT01"},
356 {SC_TEXTURESTAGE
, D3DTSS_BUMPENVMAT10
, "D3DTSS_BUMPENVMAT10"},
357 {SC_TEXTURESTAGE
, D3DTSS_BUMPENVMAT11
, "D3DTSS_BUMPENVMAT11"},
358 {SC_TEXTURESTAGE
, D3DTSS_TEXCOORDINDEX
, "D3DTSS_TEXCOORDINDEX"},
359 {SC_TEXTURESTAGE
, D3DTSS_BUMPENVLSCALE
, "D3DTSS_BUMPENVLSCALE"},
360 {SC_TEXTURESTAGE
, D3DTSS_BUMPENVLOFFSET
, "D3DTSS_BUMPENVLOFFSET"},
361 {SC_TEXTURESTAGE
, D3DTSS_TEXTURETRANSFORMFLAGS
, "D3DTSS_TEXTURETRANSFORMFLAGS"},
362 {SC_TEXTURESTAGE
, D3DTSS_CONSTANT
, "D3DTSS_CONSTANT"},
364 {SC_NPATCHMODE
, 0, "NPatchMode"},
368 {SC_TRANSFORM
, D3DTS_PROJECTION
, "D3DTS_PROJECTION"},
369 {SC_TRANSFORM
, D3DTS_VIEW
, "D3DTS_VIEW"},
370 {SC_TRANSFORM
, D3DTS_WORLD
, "D3DTS_WORLD"},
371 {SC_TRANSFORM
, D3DTS_TEXTURE0
, "D3DTS_TEXTURE0"},
373 {SC_MATERIAL
, MT_DIFFUSE
, "MaterialDiffuse"},
374 {SC_MATERIAL
, MT_AMBIENT
, "MaterialAmbient"}, /* 0x80 */
375 {SC_MATERIAL
, MT_SPECULAR
, "MaterialSpecular"},
376 {SC_MATERIAL
, MT_EMISSIVE
, "MaterialEmissive"},
377 {SC_MATERIAL
, MT_POWER
, "MaterialPower"},
379 {SC_LIGHT
, LT_TYPE
, "LightType"},
380 {SC_LIGHT
, LT_DIFFUSE
, "LightDiffuse"},
381 {SC_LIGHT
, LT_SPECULAR
, "LightSpecular"},
382 {SC_LIGHT
, LT_AMBIENT
, "LightAmbient"},
383 {SC_LIGHT
, LT_POSITION
, "LightPosition"},
384 {SC_LIGHT
, LT_DIRECTION
, "LightDirection"},
385 {SC_LIGHT
, LT_RANGE
, "LightRange"},
386 {SC_LIGHT
, LT_FALLOFF
, "LightFallOff"},
387 {SC_LIGHT
, LT_ATTENUATION0
, "LightAttenuation0"},
388 {SC_LIGHT
, LT_ATTENUATION1
, "LightAttenuation1"},
389 {SC_LIGHT
, LT_ATTENUATION2
, "LightAttenuation2"},
390 {SC_LIGHT
, LT_THETA
, "LightTheta"},
391 {SC_LIGHT
, LT_PHI
, "LightPhi"}, /* 0x90 */
393 {SC_LIGHTENABLE
, 0, "LightEnable"},
395 {SC_VERTEXSHADER
, 0, "Vertexshader"},
397 {SC_PIXELSHADER
, 0, "Pixelshader"},
398 /* Shader constants */
399 {SC_SHADERCONST
, SCT_VSFLOAT
, "VertexShaderConstantF"},
400 {SC_SHADERCONST
, SCT_VSBOOL
, "VertexShaderConstantB"},
401 {SC_SHADERCONST
, SCT_VSINT
, "VertexShaderConstantI"},
402 {SC_SHADERCONST
, SCT_VSFLOAT
, "VertexShaderConstant"},
403 {SC_SHADERCONST
, SCT_VSFLOAT
, "VertexShaderConstant1"},
404 {SC_SHADERCONST
, SCT_VSFLOAT
, "VertexShaderConstant2"},
405 {SC_SHADERCONST
, SCT_VSFLOAT
, "VertexShaderConstant3"},
406 {SC_SHADERCONST
, SCT_VSFLOAT
, "VertexShaderConstant4"},
407 {SC_SHADERCONST
, SCT_PSFLOAT
, "PixelShaderConstantF"},
408 {SC_SHADERCONST
, SCT_PSBOOL
, "PixelShaderConstantB"},
409 {SC_SHADERCONST
, SCT_PSINT
, "PixelShaderConstantI"},
410 {SC_SHADERCONST
, SCT_PSFLOAT
, "PixelShaderConstant"},
411 {SC_SHADERCONST
, SCT_PSFLOAT
, "PixelShaderConstant1"}, /* 0xa0 */
412 {SC_SHADERCONST
, SCT_PSFLOAT
, "PixelShaderConstant2"},
413 {SC_SHADERCONST
, SCT_PSFLOAT
, "PixelShaderConstant3"},
414 {SC_SHADERCONST
, SCT_PSFLOAT
, "PixelShaderConstant4"},
416 {SC_TEXTURE
, 0, "Texture"},
418 {SC_SAMPLERSTATE
, D3DSAMP_ADDRESSU
, "AddressU"},
419 {SC_SAMPLERSTATE
, D3DSAMP_ADDRESSV
, "AddressV"},
420 {SC_SAMPLERSTATE
, D3DSAMP_ADDRESSW
, "AddressW"},
421 {SC_SAMPLERSTATE
, D3DSAMP_BORDERCOLOR
, "BorderColor"},
422 {SC_SAMPLERSTATE
, D3DSAMP_MAGFILTER
, "MagFilter"},
423 {SC_SAMPLERSTATE
, D3DSAMP_MINFILTER
, "MinFilter"},
424 {SC_SAMPLERSTATE
, D3DSAMP_MIPFILTER
, "MipFilter"},
425 {SC_SAMPLERSTATE
, D3DSAMP_MIPMAPLODBIAS
, "MipMapLodBias"},
426 {SC_SAMPLERSTATE
, D3DSAMP_MAXMIPLEVEL
, "MaxMipLevel"},
427 {SC_SAMPLERSTATE
, D3DSAMP_MAXANISOTROPY
, "MaxAnisotropy"},
428 {SC_SAMPLERSTATE
, D3DSAMP_SRGBTEXTURE
, "SRGBTexture"},
429 {SC_SAMPLERSTATE
, D3DSAMP_ELEMENTINDEX
, "ElementIndex"}, /* 0xb0 */
430 {SC_SAMPLERSTATE
, D3DSAMP_DMAPOFFSET
, "DMAPOffset"},
432 {SC_SETSAMPLER
, 0, "Sampler"},
435 static inline uint32_t read_u32(const char **ptr
)
439 memcpy(&u
, *ptr
, sizeof(u
));
444 static void skip_u32_unknown(const char **ptr
, unsigned int count
)
449 WARN("Skipping %u unknown DWORDs:\n", count
);
450 for (i
= 0; i
< count
; ++i
)
453 WARN("\t0x%08x\n", u
);
457 static inline D3DXHANDLE
get_parameter_handle(struct d3dx_parameter
*parameter
)
459 return (D3DXHANDLE
)parameter
;
462 static inline D3DXHANDLE
get_technique_handle(struct d3dx_technique
*technique
)
464 return (D3DXHANDLE
)technique
;
467 static inline D3DXHANDLE
get_pass_handle(struct d3dx_pass
*pass
)
469 return (D3DXHANDLE
)pass
;
472 static struct d3dx_technique
*get_technique_by_name(struct d3dx_effect
*effect
, const char *name
)
476 if (!name
) return NULL
;
478 for (i
= 0; i
< effect
->technique_count
; ++i
)
480 if (!strcmp(effect
->techniques
[i
].name
, name
))
481 return &effect
->techniques
[i
];
487 static struct d3dx_technique
*get_valid_technique(struct d3dx_effect
*effect
, D3DXHANDLE technique
)
491 for (i
= 0; i
< effect
->technique_count
; ++i
)
493 if (get_technique_handle(&effect
->techniques
[i
]) == technique
)
494 return &effect
->techniques
[i
];
497 return get_technique_by_name(effect
, technique
);
500 static struct d3dx_pass
*get_valid_pass(struct d3dx_effect
*effect
, D3DXHANDLE pass
)
504 for (i
= 0; i
< effect
->technique_count
; ++i
)
506 struct d3dx_technique
*technique
= &effect
->techniques
[i
];
508 for (k
= 0; k
< technique
->pass_count
; ++k
)
510 if (get_pass_handle(&technique
->passes
[k
]) == pass
)
511 return &technique
->passes
[k
];
518 static struct d3dx_parameter
*get_valid_parameter(struct d3dx_effect
*effect
, D3DXHANDLE parameter
)
520 struct d3dx_parameter
*handle_param
= (struct d3dx_parameter
*)parameter
;
522 if (handle_param
&& !strncmp(handle_param
->magic_string
, parameter_magic_string
,
523 sizeof(parameter_magic_string
)))
526 return effect
->flags
& D3DXFX_LARGEADDRESSAWARE
? NULL
: get_parameter_by_name(&effect
->params
, NULL
, parameter
);
529 static struct d3dx_parameter_block
*get_valid_parameter_block(D3DXHANDLE handle
)
531 struct d3dx_parameter_block
*block
= (struct d3dx_parameter_block
*)handle
;
533 return block
&& !strncmp(block
->magic_string
, parameter_block_magic_string
,
534 sizeof(parameter_block_magic_string
)) ? block
: NULL
;
537 static void free_state(struct d3dx_state
*state
)
539 free_parameter(&state
->parameter
, FALSE
, FALSE
);
542 static void free_object(struct d3dx_object
*object
)
547 static void free_sampler(struct d3dx_sampler
*sampler
)
551 for (i
= 0; i
< sampler
->state_count
; ++i
)
553 free_state(&sampler
->states
[i
]);
555 free(sampler
->states
);
558 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter
*param
);
560 static void free_parameter_object_data(struct d3dx_parameter
*param
, const void *data
, unsigned int bytes
)
562 unsigned int i
, count
;
564 if (param
->class != D3DXPC_OBJECT
)
567 count
= min(param
->element_count
? param
->element_count
: 1, bytes
/ sizeof(void *));
569 for (i
= 0; i
< count
; ++i
)
574 free(((char **)data
)[i
]);
578 case D3DXPT_TEXTURE1D
:
579 case D3DXPT_TEXTURE2D
:
580 case D3DXPT_TEXTURE3D
:
581 case D3DXPT_TEXTURECUBE
:
582 case D3DXPT_PIXELSHADER
:
583 case D3DXPT_VERTEXSHADER
:
584 if (*(IUnknown
**)data
)
585 IUnknown_Release(((IUnknown
**)data
)[i
]);
589 case D3DXPT_SAMPLER1D
:
590 case D3DXPT_SAMPLER2D
:
591 case D3DXPT_SAMPLER3D
:
592 case D3DXPT_SAMPLERCUBE
:
594 free_sampler((struct d3dx_sampler
*)data
);
598 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param
->type
));
604 static void free_parameter_data(struct d3dx_parameter
*param
, BOOL child
)
609 if (!param
->element_count
)
610 free_parameter_object_data(param
, param
->data
, param
->bytes
);
612 if (!child
|| is_param_type_sampler(param
->type
))
616 static void free_parameter(struct d3dx_parameter
*param
, BOOL element
, BOOL child
)
620 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param
, param
->name
,
621 debug_d3dxparameter_type(param
->type
), element
, child
);
623 if (param
->param_eval
)
624 d3dx_free_param_eval(param
->param_eval
);
628 unsigned int count
= param
->element_count
? param
->element_count
: param
->member_count
;
630 for (i
= 0; i
< count
; ++i
)
631 free_parameter(¶m
->members
[i
], param
->element_count
!= 0, TRUE
);
632 free(param
->members
);
635 free(param
->full_name
);
636 free_parameter_data(param
, child
);
638 /* only the parent has to release name and semantic */
642 free(param
->semantic
);
646 static void free_top_level_parameter(struct d3dx_top_level_parameter
*param
)
648 if (param
->annotations
)
652 for (i
= 0; i
< param
->annotation_count
; ++i
)
653 free_parameter(¶m
->annotations
[i
], FALSE
, FALSE
);
654 free(param
->annotations
);
656 d3dx_pool_release_shared_parameter(param
);
657 free_parameter(¶m
->param
, FALSE
, FALSE
);
660 static void free_pass(struct d3dx_pass
*pass
)
664 TRACE("Free pass %p\n", pass
);
669 if (pass
->annotations
)
671 for (i
= 0; i
< pass
->annotation_count
; ++i
)
672 free_parameter(&pass
->annotations
[i
], FALSE
, FALSE
);
673 free(pass
->annotations
);
674 pass
->annotations
= NULL
;
679 for (i
= 0; i
< pass
->state_count
; ++i
)
680 free_state(&pass
->states
[i
]);
689 static void free_technique(struct d3dx_technique
*technique
)
693 TRACE("Free technique %p\n", technique
);
698 if (technique
->saved_state
)
700 IDirect3DStateBlock9_Release(technique
->saved_state
);
701 technique
->saved_state
= NULL
;
704 if (technique
->annotations
)
706 for (i
= 0; i
< technique
->annotation_count
; ++i
)
707 free_parameter(&technique
->annotations
[i
], FALSE
, FALSE
);
708 free(technique
->annotations
);
709 technique
->annotations
= NULL
;
712 if (technique
->passes
)
714 for (i
= 0; i
< technique
->pass_count
; ++i
)
715 free_pass(&technique
->passes
[i
]);
716 free(technique
->passes
);
717 technique
->passes
= NULL
;
720 free(technique
->name
);
721 technique
->name
= NULL
;
724 static unsigned int get_recorded_parameter_size(const struct d3dx_recorded_parameter
*record
)
726 return sizeof(*record
) + record
->bytes
;
729 static void free_parameter_block(struct d3dx_parameter_block
*block
)
731 struct d3dx_recorded_parameter
*record
;
736 record
= (struct d3dx_recorded_parameter
*)block
->buffer
;
737 while ((BYTE
*)record
< block
->buffer
+ block
->offset
)
739 free_parameter_object_data(record
->param
, record
+ 1, record
->bytes
);
740 record
= (struct d3dx_recorded_parameter
*)((BYTE
*)record
+ get_recorded_parameter_size(record
));
742 assert((BYTE
*)record
== block
->buffer
+ block
->offset
);
748 static int param_rb_compare(const void *key
, const struct wine_rb_entry
*entry
)
750 const char *name
= key
;
751 struct d3dx_parameter
*param
= WINE_RB_ENTRY_VALUE(entry
, struct d3dx_parameter
, rb_entry
);
753 return strcmp(name
, param
->full_name
);
756 HRESULT
d3dx_init_parameters_store(struct d3dx_parameters_store
*store
, unsigned int count
)
758 store
->count
= count
;
759 wine_rb_init(&store
->tree
, param_rb_compare
);
761 if (store
->count
&& !(store
->parameters
= calloc(store
->count
, sizeof(*store
->parameters
))))
762 return E_OUTOFMEMORY
;
767 void d3dx_parameters_store_cleanup(struct d3dx_parameters_store
*store
)
771 free(store
->full_name_tmp
);
773 if (store
->parameters
)
775 for (i
= 0; i
< store
->count
; ++i
)
776 free_top_level_parameter(&store
->parameters
[i
]);
777 free(store
->parameters
);
778 store
->parameters
= NULL
;
782 static void d3dx_effect_cleanup(struct d3dx_effect
*effect
)
784 struct d3dx_parameter_block
*block
, *cursor
;
785 ID3DXEffectPool
*pool
;
788 TRACE("effect %p.\n", effect
);
790 free_parameter_block(effect
->current_parameter_block
);
791 LIST_FOR_EACH_ENTRY_SAFE(block
, cursor
, &effect
->parameter_block_list
, struct d3dx_parameter_block
, entry
)
793 list_remove(&block
->entry
);
794 free_parameter_block(block
);
797 d3dx_parameters_store_cleanup(&effect
->params
);
799 if (effect
->techniques
)
801 for (i
= 0; i
< effect
->technique_count
; ++i
)
802 free_technique(&effect
->techniques
[i
]);
803 free(effect
->techniques
);
808 for (i
= 0; i
< effect
->object_count
; ++i
)
809 free_object(&effect
->objects
[i
]);
810 free(effect
->objects
);
815 pool
= &effect
->pool
->ID3DXEffectPool_iface
;
816 pool
->lpVtbl
->Release(pool
);
820 IUnknown_Release(effect
->manager
);
822 IDirect3DDevice9_Release(effect
->device
);
826 static void get_vector(struct d3dx_parameter
*param
, D3DXVECTOR4
*vector
)
830 for (i
= 0; i
< 4; ++i
)
832 if (i
< param
->columns
)
833 set_number((FLOAT
*)vector
+ i
, D3DXPT_FLOAT
, (DWORD
*)param
->data
+ i
, param
->type
);
835 ((FLOAT
*)vector
)[i
] = 0.0f
;
839 static void set_vector(struct d3dx_parameter
*param
, const D3DXVECTOR4
*vector
, void *dst_data
)
843 for (i
= 0; i
< param
->columns
; ++i
)
844 set_number((FLOAT
*)dst_data
+ i
, param
->type
, (FLOAT
*)vector
+ i
, D3DXPT_FLOAT
);
847 static void get_matrix(struct d3dx_parameter
*param
, D3DXMATRIX
*matrix
, BOOL transpose
)
851 for (i
= 0; i
< 4; ++i
)
853 for (k
= 0; k
< 4; ++k
)
855 FLOAT
*tmp
= transpose
? (FLOAT
*)&matrix
->m
[k
][i
] : (FLOAT
*)&matrix
->m
[i
][k
];
857 if ((i
< param
->rows
) && (k
< param
->columns
))
858 set_number(tmp
, D3DXPT_FLOAT
, (DWORD
*)param
->data
+ i
* param
->columns
+ k
, param
->type
);
865 static void set_matrix(struct d3dx_parameter
*param
, const D3DXMATRIX
*matrix
, void *dst_data
)
869 if (param
->type
== D3DXPT_FLOAT
)
871 if (param
->columns
== 4)
873 memcpy(dst_data
, matrix
->m
, param
->rows
* 4 * sizeof(float));
877 for (i
= 0; i
< param
->rows
; ++i
)
878 memcpy((float *)dst_data
+ i
* param
->columns
, matrix
->m
+ i
, param
->columns
* sizeof(float));
883 for (i
= 0; i
< param
->rows
; ++i
)
885 for (k
= 0; k
< param
->columns
; ++k
)
886 set_number((FLOAT
*)dst_data
+ i
* param
->columns
+ k
, param
->type
,
887 &matrix
->m
[i
][k
], D3DXPT_FLOAT
);
891 static void set_matrix_transpose(struct d3dx_parameter
*param
, const D3DXMATRIX
*matrix
, void *dst_data
)
895 for (i
= 0; i
< param
->rows
; ++i
)
897 for (k
= 0; k
< param
->columns
; ++k
)
899 set_number((FLOAT
*)dst_data
+ i
* param
->columns
+ k
, param
->type
,
900 &matrix
->m
[k
][i
], D3DXPT_FLOAT
);
905 static HRESULT
set_string(char **param_data
, const char *string
)
908 *param_data
= strdup(string
);
911 ERR("Out of memory.\n");
912 return E_OUTOFMEMORY
;
917 static HRESULT
set_value(struct d3dx_parameter
*param
, const void *data
, unsigned int bytes
,
920 unsigned int i
, count
;
922 bytes
= min(bytes
, param
->bytes
);
923 count
= min(param
->element_count
? param
->element_count
: 1, bytes
/ sizeof(void *));
928 case D3DXPT_TEXTURE1D
:
929 case D3DXPT_TEXTURE2D
:
930 case D3DXPT_TEXTURE3D
:
931 case D3DXPT_TEXTURECUBE
:
932 for (i
= 0; i
< count
; ++i
)
934 IUnknown
*old_texture
= ((IUnknown
**)dst_data
)[i
];
935 IUnknown
*new_texture
= ((IUnknown
**)data
)[i
];
937 if (new_texture
== old_texture
)
941 IUnknown_AddRef(new_texture
);
943 IUnknown_Release(old_texture
);
950 TRACE("Copy %u bytes.\n", bytes
);
951 memcpy(dst_data
, data
, bytes
);
958 for (i
= 0; i
< count
; ++i
)
959 if (FAILED(hr
= set_string(&((char **)dst_data
)[i
], ((const char **)data
)[i
])))
965 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param
->type
));
972 static struct d3dx_parameter
*get_parameter_element_by_name(struct d3dx_parameters_store
*store
,
973 struct d3dx_parameter
*parameter
, const char *name
)
976 struct d3dx_parameter
*temp_parameter
;
979 TRACE("parameter %p, name %s\n", parameter
, debugstr_a(name
));
981 if (!name
|| !*name
) return NULL
;
983 element
= atoi(name
);
984 part
= strchr(name
, ']') + 1;
986 /* check for empty [] && element range */
987 if ((part
- name
) > 1 && parameter
->element_count
> element
)
989 temp_parameter
= ¶meter
->members
[element
];
994 return get_parameter_by_name(store
, temp_parameter
, part
);
997 TRACE("Returning parameter %p\n", temp_parameter
);
998 return temp_parameter
;
1001 FIXME("Unhandled case \"%c\"\n", *--part
);
1006 TRACE("Parameter not found\n");
1010 static struct d3dx_parameter
*get_annotation_by_name(struct d3dx_effect
*effect
, unsigned int count
,
1011 struct d3dx_parameter
*annotations
, const char *name
)
1014 struct d3dx_parameter
*temp_parameter
;
1017 TRACE("count %u, annotations %p, name %s\n", count
, annotations
, debugstr_a(name
));
1019 if (!name
|| !*name
) return NULL
;
1021 length
= strcspn( name
, "[.@" );
1022 part
= name
+ length
;
1024 for (i
= 0; i
< count
; ++i
)
1026 temp_parameter
= &annotations
[i
];
1028 if (!strcmp(temp_parameter
->name
, name
))
1030 TRACE("Returning annotation %p\n", temp_parameter
);
1031 return temp_parameter
;
1033 else if (strlen(temp_parameter
->name
) == length
&& !strncmp(temp_parameter
->name
, name
, length
))
1038 return get_parameter_by_name(&effect
->params
, temp_parameter
, part
);
1041 return get_parameter_element_by_name(&effect
->params
, temp_parameter
, part
);
1044 FIXME("Unhandled case \"%c\"\n", *--part
);
1050 TRACE("Annotation not found\n");
1054 struct d3dx_parameter
*get_parameter_by_name(struct d3dx_parameters_store
*store
,
1055 struct d3dx_parameter
*parameter
, const char *name
)
1057 struct d3dx_parameter
*temp_parameter
;
1058 unsigned int name_len
, param_name_len
;
1059 unsigned int i
, count
, length
;
1060 struct wine_rb_entry
*entry
;
1061 unsigned int full_name_size
;
1065 TRACE("store %p, parameter %p, name %s.\n", store
, parameter
, debugstr_a(name
));
1067 if (!name
|| !*name
) return NULL
;
1071 if ((entry
= wine_rb_get(&store
->tree
, name
)))
1072 return WINE_RB_ENTRY_VALUE(entry
, struct d3dx_parameter
, rb_entry
);
1076 if (parameter
->full_name
)
1078 name_len
= strlen(name
);
1079 param_name_len
= strlen(parameter
->full_name
);
1080 full_name_size
= name_len
+ param_name_len
+ 2;
1081 if (store
->full_name_tmp_size
< full_name_size
)
1083 if (!(full_name
= realloc(store
->full_name_tmp
, full_name_size
)))
1085 ERR("Out of memory.\n");
1088 store
->full_name_tmp
= full_name
;
1089 store
->full_name_tmp_size
= full_name_size
;
1093 full_name
= store
->full_name_tmp
;
1095 memcpy(full_name
, parameter
->full_name
, param_name_len
);
1096 full_name
[param_name_len
] = '.';
1097 memcpy(full_name
+ param_name_len
+ 1, name
, name_len
);
1098 full_name
[param_name_len
+ 1 + name_len
] = 0;
1100 if ((entry
= wine_rb_get(&store
->tree
, full_name
)))
1101 return WINE_RB_ENTRY_VALUE(entry
, struct d3dx_parameter
, rb_entry
);
1105 /* Pass / technique annotations are not stored in the parameters tree,
1106 * do a linear search. */
1107 count
= parameter
->member_count
;
1109 length
= strcspn( name
, "[." );
1110 part
= name
+ length
;
1112 for (i
= 0; i
< count
; i
++)
1114 temp_parameter
= ¶meter
->members
[i
];
1116 if (!strcmp(temp_parameter
->name
, name
))
1118 TRACE("Returning parameter %p\n", temp_parameter
);
1119 return temp_parameter
;
1121 else if (strlen(temp_parameter
->name
) == length
&& !strncmp(temp_parameter
->name
, name
, length
))
1126 return get_parameter_by_name(store
, temp_parameter
, part
);
1129 return get_parameter_element_by_name(store
, temp_parameter
, part
);
1132 FIXME("Unhandled case \"%c\"\n", *--part
);
1138 TRACE("Parameter not found\n");
1142 static inline DWORD
d3dx9_effect_version(DWORD major
, DWORD minor
)
1144 return (0xfeff0000 | ((major
) << 8) | (minor
));
1147 static HRESULT
d3dx9_get_param_value_ptr(struct d3dx_pass
*pass
, struct d3dx_state
*state
,
1148 void **param_value
, struct d3dx_parameter
**out_param
,
1149 BOOL update_all
, BOOL
*param_dirty
)
1151 struct d3dx_parameter
*param
= &state
->parameter
;
1153 *param_value
= NULL
;
1155 *param_dirty
= FALSE
;
1157 switch (state
->type
)
1160 param
= state
->referenced_param
;
1161 *param_dirty
= is_param_dirty(param
, pass
->update_version
);
1165 *param_value
= param
->data
;
1167 case ST_ARRAY_SELECTOR
:
1169 unsigned int array_idx
;
1170 static const struct d3dx_parameter array_idx_param
=
1171 {"", NULL
, NULL
, NULL
, NULL
, D3DXPC_SCALAR
, D3DXPT_INT
, 1, 1, 0, 0, 0, sizeof(array_idx
)};
1173 struct d3dx_parameter
*ref_param
, *selected_param
;
1175 if (!param
->param_eval
)
1177 FIXME("Preshader structure is null.\n");
1178 return D3DERR_INVALIDCALL
;
1180 /* We override with the update_version of the pass because we want
1181 * to force index recomputation and check for out of bounds. */
1182 if (is_param_eval_input_dirty(param
->param_eval
, pass
->update_version
))
1184 if (FAILED(hr
= d3dx_evaluate_parameter(param
->param_eval
, &array_idx_param
, &array_idx
)))
1189 array_idx
= state
->index
;
1191 ref_param
= state
->referenced_param
;
1192 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx
, state
->index
,
1193 ref_param
->element_count
);
1194 /* According to the tests, native d3dx handles the case of array index evaluated to -1
1195 * in a specific way, always selecting first array element and not returning error. */
1196 if (array_idx
== ~0u)
1198 WARN("Array index is -1, setting to 0.\n");
1202 if (array_idx
>= ref_param
->element_count
)
1204 WARN("Computed array index %u is larger than array size %u.\n",
1205 array_idx
, ref_param
->element_count
);
1208 selected_param
= &ref_param
->members
[array_idx
];
1209 *param_dirty
= state
->index
!= array_idx
|| is_param_dirty(selected_param
, pass
->update_version
);
1210 state
->index
= array_idx
;
1212 *param_value
= selected_param
->data
;
1213 *out_param
= selected_param
;
1217 if (param
->param_eval
)
1220 *param_value
= param
->data
;
1221 /* We check with the update_version of the pass because the
1222 * same preshader might be used by both the vertex and the
1223 * pixel shader (that can happen e.g. for sampler states). */
1224 if (update_all
|| is_param_eval_input_dirty(param
->param_eval
, pass
->update_version
))
1226 *param_dirty
= TRUE
;
1227 return d3dx_evaluate_parameter(param
->param_eval
, param
, *param_value
);
1234 FIXME("No preshader for FXLC parameter.\n");
1235 return D3DERR_INVALIDCALL
;
1241 static unsigned int get_annotation_from_object(struct d3dx_effect
*effect
, D3DXHANDLE object
,
1242 struct d3dx_parameter
**annotations
)
1244 struct d3dx_parameter
*param
= get_valid_parameter(effect
, object
);
1245 struct d3dx_pass
*pass
= get_valid_pass(effect
, object
);
1246 struct d3dx_technique
*technique
= get_valid_technique(effect
, object
);
1250 *annotations
= pass
->annotations
;
1251 return pass
->annotation_count
;
1255 *annotations
= technique
->annotations
;
1256 return technique
->annotation_count
;
1260 if (is_top_level_parameter(param
))
1262 struct d3dx_top_level_parameter
*top_param
1263 = top_level_parameter_from_parameter(param
);
1265 *annotations
= top_param
->annotations
;
1266 return top_param
->annotation_count
;
1270 *annotations
= NULL
;
1276 FIXME("Functions are not handled, yet!\n");
1281 static BOOL
walk_parameter_tree(struct d3dx_parameter
*param
, walk_parameter_dep_func param_func
,
1285 unsigned int member_count
;
1287 if (param_func(data
, param
))
1290 member_count
= param
->element_count
? param
->element_count
: param
->member_count
;
1291 for (i
= 0; i
< member_count
; ++i
)
1293 if (walk_parameter_tree(¶m
->members
[i
], param_func
, data
))
1299 static ULONG64
*get_version_counter_ptr(struct d3dx_effect
*effect
)
1301 return effect
->pool
? &effect
->pool
->version_counter
: &effect
->version_counter
;
1304 static ULONG64
next_effect_update_version(struct d3dx_effect
*effect
)
1306 return next_update_version(get_version_counter_ptr(effect
));
1309 static void *record_parameter(struct d3dx_effect
*effect
, struct d3dx_parameter
*param
, unsigned int bytes
)
1311 struct d3dx_parameter_block
*block
= effect
->current_parameter_block
;
1312 struct d3dx_recorded_parameter new_record
, *record
;
1313 unsigned int new_size
, alloc_size
;
1315 new_record
.param
= param
;
1316 new_record
.bytes
= bytes
;
1317 new_size
= block
->offset
+ get_recorded_parameter_size(&new_record
);
1319 if (new_size
> block
->size
)
1323 alloc_size
= max(block
->size
* 2, max(new_size
, INITIAL_PARAM_BLOCK_SIZE
));
1324 new_alloc
= realloc(block
->buffer
, alloc_size
);
1327 ERR("Out of memory.\n");
1330 /* Data update functions may want to free some references upon setting value. */
1331 memset(new_alloc
+ block
->size
, 0, alloc_size
- block
->size
);
1333 block
->size
= alloc_size
;
1334 block
->buffer
= new_alloc
;
1336 record
= (struct d3dx_recorded_parameter
*)(block
->buffer
+ block
->offset
);
1337 *record
= new_record
;
1338 block
->offset
= new_size
;
1342 static void set_dirty(struct d3dx_parameter
*param
)
1344 struct d3dx_top_level_parameter
*top_param
= param
->top_level_param
;
1345 struct d3dx_shared_data
*shared_data
;
1346 ULONG64 new_update_version
;
1348 /* This is true for annotations. */
1352 new_update_version
= next_update_version(top_param
->version_counter
);
1353 if ((shared_data
= top_param
->shared_data
))
1354 shared_data
->update_version
= new_update_version
;
1356 top_param
->update_version
= new_update_version
;
1359 static void *param_get_data_and_dirtify(struct d3dx_effect
*effect
, struct d3dx_parameter
*param
,
1360 unsigned int bytes
, BOOL value_changed
)
1362 assert(bytes
<= param
->bytes
);
1364 if (value_changed
&& !effect
->current_parameter_block
)
1367 return effect
->current_parameter_block
? record_parameter(effect
, param
, bytes
) : param
->data
;
1370 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op
, D3DLIGHT9
*light
, void *value
)
1374 unsigned int offset
;
1379 {FIELD_OFFSET(D3DLIGHT9
, Type
), "LC_TYPE"},
1380 {FIELD_OFFSET(D3DLIGHT9
, Diffuse
), "LT_DIFFUSE"},
1381 {FIELD_OFFSET(D3DLIGHT9
, Specular
), "LT_SPECULAR"},
1382 {FIELD_OFFSET(D3DLIGHT9
, Ambient
), "LT_AMBIENT"},
1383 {FIELD_OFFSET(D3DLIGHT9
, Position
), "LT_POSITION"},
1384 {FIELD_OFFSET(D3DLIGHT9
, Direction
), "LT_DIRECTION"},
1385 {FIELD_OFFSET(D3DLIGHT9
, Range
), "LT_RANGE"},
1386 {FIELD_OFFSET(D3DLIGHT9
, Falloff
), "LT_FALLOFF"},
1387 {FIELD_OFFSET(D3DLIGHT9
, Attenuation0
), "LT_ATTENUATION0"},
1388 {FIELD_OFFSET(D3DLIGHT9
, Attenuation1
), "LT_ATTENUATION1"},
1389 {FIELD_OFFSET(D3DLIGHT9
, Attenuation2
), "LT_ATTENUATION2"},
1390 {FIELD_OFFSET(D3DLIGHT9
, Theta
), "LT_THETA"},
1391 {FIELD_OFFSET(D3DLIGHT9
, Phi
), "LT_PHI"}
1396 TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE
*)value
);
1397 light
->Type
= *(D3DLIGHTTYPE
*)value
;
1403 D3DCOLORVALUE c
= *(D3DCOLORVALUE
*)value
;
1405 TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl
[op
].name
, c
.r
, c
.g
, c
.b
, c
.a
);
1406 *(D3DCOLORVALUE
*)((BYTE
*)light
+ light_tbl
[op
].offset
) = c
;
1412 D3DVECTOR v
= *(D3DVECTOR
*)value
;
1414 TRACE("%s (%.8e %.8e %.8e).\n", light_tbl
[op
].name
, v
.x
, v
.y
, v
.z
);
1415 *(D3DVECTOR
*)((BYTE
*)light
+ light_tbl
[op
].offset
) = v
;
1420 case LT_ATTENUATION0
:
1421 case LT_ATTENUATION1
:
1422 case LT_ATTENUATION2
:
1426 float v
= *(float *)value
;
1427 TRACE("%s %.8e.\n", light_tbl
[op
].name
, v
);
1428 *(float *)((BYTE
*)light
+ light_tbl
[op
].offset
) = v
;
1432 WARN("Unknown light parameter %u.\n", op
);
1437 static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op
, D3DMATERIAL9
*material
, void *value
)
1441 unsigned int offset
;
1446 {FIELD_OFFSET(D3DMATERIAL9
, Diffuse
), "MT_DIFFUSE"},
1447 {FIELD_OFFSET(D3DMATERIAL9
, Ambient
), "MT_AMBIENT"},
1448 {FIELD_OFFSET(D3DMATERIAL9
, Specular
), "MT_SPECULAR"},
1449 {FIELD_OFFSET(D3DMATERIAL9
, Emissive
), "MT_EMISSIVE"},
1450 {FIELD_OFFSET(D3DMATERIAL9
, Power
), "MT_POWER"}
1457 float v
= *(float *)value
;
1459 TRACE("%s %.8e.\n", material_tbl
[op
].name
, v
);
1460 material
->Power
= v
;
1468 D3DCOLORVALUE c
= *(D3DCOLORVALUE
*)value
;
1470 TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl
[op
].name
, c
.r
, c
.g
, c
.b
, c
.a
);
1471 *(D3DCOLORVALUE
*)((BYTE
*)material
+ material_tbl
[op
].offset
) = c
;
1475 WARN("Unknown material parameter %u.\n", op
);
1480 static HRESULT
d3dx_set_shader_const_state(struct d3dx_effect
*effect
, enum SHADER_CONSTANT_TYPE op
, UINT index
,
1481 struct d3dx_parameter
*param
, void *value_ptr
)
1485 D3DXPARAMETER_TYPE type
;
1491 {D3DXPT_FLOAT
, sizeof(float) * 4, "SCT_VSFLOAT"},
1492 {D3DXPT_BOOL
, sizeof(BOOL
), "SCT_VSBOOL"},
1493 {D3DXPT_INT
, sizeof(int) * 4, "SCT_VSINT"},
1494 {D3DXPT_FLOAT
, sizeof(float) * 4, "SCT_PSFLOAT"},
1495 {D3DXPT_BOOL
, sizeof(BOOL
), "SCT_PSBOOL"},
1496 {D3DXPT_INT
, sizeof(int) * 4, "SCT_PSINT"},
1499 BOOL is_heap_buffer
= FALSE
;
1500 unsigned int element_count
;
1501 void *buffer
= value_ptr
;
1505 assert(op
< ARRAY_SIZE(const_tbl
));
1506 element_count
= param
->bytes
/ const_tbl
[op
].elem_size
;
1507 TRACE("%s, index %u, element_count %u.\n", const_tbl
[op
].name
, index
, element_count
);
1508 if (param
->type
!= const_tbl
[op
].type
)
1510 FIXME("Unexpected param type %u.\n", param
->type
);
1511 return D3DERR_INVALIDCALL
;
1514 if (param
->bytes
% const_tbl
[op
].elem_size
|| element_count
> 1)
1516 unsigned int param_data_size
;
1518 TRACE("Parameter size %u, rows %u, cols %u.\n", param
->bytes
, param
->rows
, param
->columns
);
1520 if (param
->bytes
% const_tbl
[op
].elem_size
)
1522 if (element_count
> 1)
1524 WARN("Setting %u elements.\n", element_count
);
1525 buffer
= calloc(element_count
, const_tbl
[op
].elem_size
);
1528 ERR("Out of memory.\n");
1529 return E_OUTOFMEMORY
;
1531 is_heap_buffer
= TRUE
;
1535 assert(const_tbl
[op
].elem_size
<= sizeof(value
));
1538 param_data_size
= min(param
->bytes
, const_tbl
[op
].elem_size
);
1539 memcpy(buffer
, value_ptr
, param_data_size
);
1545 ret
= SET_D3D_STATE(effect
, SetVertexShaderConstantF
, index
, (const float *)buffer
, element_count
);
1548 ret
= SET_D3D_STATE(effect
, SetVertexShaderConstantB
, index
, (const BOOL
*)buffer
, element_count
);
1551 ret
= SET_D3D_STATE(effect
, SetVertexShaderConstantI
, index
, (const int *)buffer
, element_count
);
1554 ret
= SET_D3D_STATE(effect
, SetPixelShaderConstantF
, index
, (const float *)buffer
, element_count
);
1557 ret
= SET_D3D_STATE(effect
, SetPixelShaderConstantB
, index
, (const BOOL
*)buffer
, element_count
);
1560 ret
= SET_D3D_STATE(effect
, SetPixelShaderConstantI
, index
, (const int *)buffer
, element_count
);
1563 ret
= D3DERR_INVALIDCALL
;
1573 static HRESULT
d3dx9_apply_state(struct d3dx_effect
*effect
, struct d3dx_pass
*pass
,
1574 struct d3dx_state
*state
, unsigned int parent_index
, BOOL update_all
);
1576 static HRESULT
d3dx_set_shader_constants(struct d3dx_effect
*effect
, struct d3dx_pass
*pass
,
1577 struct d3dx_parameter
*param
, BOOL vs
, BOOL update_all
)
1580 struct d3dx_parameter
**params
;
1581 D3DXCONSTANT_DESC
*cdesc
;
1582 unsigned int parameters_count
;
1585 if (!param
->param_eval
)
1587 FIXME("param_eval structure is null.\n");
1588 return D3DERR_INVALIDCALL
;
1590 if (FAILED(hr
= d3dx_param_eval_set_shader_constants(effect
->manager
, effect
->device
,
1591 param
->param_eval
, update_all
)))
1593 params
= param
->param_eval
->shader_inputs
.inputs_param
;
1594 cdesc
= param
->param_eval
->shader_inputs
.inputs
;
1595 parameters_count
= param
->param_eval
->shader_inputs
.input_count
;
1597 for (i
= 0; i
< parameters_count
; ++i
)
1599 if (params
[i
] && params
[i
]->class == D3DXPC_OBJECT
&& is_param_type_sampler(params
[i
]->type
))
1601 struct d3dx_sampler
*sampler
;
1602 unsigned int sampler_idx
;
1604 for (sampler_idx
= 0; sampler_idx
< cdesc
[i
].RegisterCount
; ++sampler_idx
)
1606 sampler
= params
[i
]->element_count
? params
[i
]->members
[sampler_idx
].data
: params
[i
]->data
;
1607 TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params
[i
]->name
),
1608 cdesc
[i
].RegisterIndex
, sampler
->state_count
);
1609 for (j
= 0; j
< sampler
->state_count
; ++j
)
1611 if (FAILED(hr
= d3dx9_apply_state(effect
, pass
, &sampler
->states
[j
],
1612 cdesc
[i
].RegisterIndex
+ sampler_idx
+ (vs
? D3DVERTEXTEXTURESAMPLER0
: 0),
1622 static HRESULT
d3dx9_apply_state(struct d3dx_effect
*effect
, struct d3dx_pass
*pass
,
1623 struct d3dx_state
*state
, unsigned int parent_index
, BOOL update_all
)
1625 struct d3dx_parameter
*param
;
1630 TRACE("operation %u, index %u, type %u.\n", state
->operation
, state
->index
, state
->type
);
1632 if (FAILED(hr
= d3dx9_get_param_value_ptr(pass
, state
, ¶m_value
, ¶m
,
1633 update_all
, ¶m_dirty
)))
1635 if (!update_all
&& hr
== E_FAIL
)
1637 /* Native d3dx9 returns D3D_OK from CommitChanges() involving
1638 * out of bounds array access and does not touch the affected
1640 WARN("Returning D3D_OK on out of bounds array access.\n");
1646 if (!(update_all
|| param_dirty
1647 || state_table
[state
->operation
].class == SC_VERTEXSHADER
1648 || state_table
[state
->operation
].class == SC_PIXELSHADER
1649 || state_table
[state
->operation
].class == SC_SETSAMPLER
))
1652 switch (state_table
[state
->operation
].class)
1654 case SC_RENDERSTATE
:
1655 TRACE("%s, operation %u, value %lu.\n", state_table
[state
->operation
].name
,
1656 state_table
[state
->operation
].op
, *(DWORD
*)param_value
);
1657 return SET_D3D_STATE(effect
, SetRenderState
, state_table
[state
->operation
].op
, *(DWORD
*)param_value
);
1659 TRACE("%s, value %#lx.\n", state_table
[state
->operation
].name
, *(DWORD
*)param_value
);
1660 return SET_D3D_STATE(effect
, SetFVF
, *(DWORD
*)param_value
);
1665 unit
= parent_index
== ~0u ? state
->index
: parent_index
;
1666 TRACE("%s, unit %u, value %p.\n", state_table
[state
->operation
].name
, unit
,
1667 *(IDirect3DBaseTexture9
**)param_value
);
1668 return SET_D3D_STATE(effect
, SetTexture
, unit
, *(IDirect3DBaseTexture9
**)param_value
);
1670 case SC_TEXTURESTAGE
:
1671 TRACE("%s, stage %u, value %lu.\n", state_table
[state
->operation
].name
, state
->index
, *(DWORD
*)param_value
);
1672 return SET_D3D_STATE(effect
, SetTextureStageState
, state
->index
,
1673 state_table
[state
->operation
].op
, *(DWORD
*)param_value
);
1676 struct d3dx_sampler
*sampler
;
1680 sampler
= (struct d3dx_sampler
*)param_value
;
1681 TRACE("%s, sampler %u, applying %u states.\n", state_table
[state
->operation
].name
, state
->index
,
1682 sampler
->state_count
);
1684 for (i
= 0; i
< sampler
->state_count
; i
++)
1686 if (FAILED(hr
= d3dx9_apply_state(effect
, pass
, &sampler
->states
[i
], state
->index
, update_all
)))
1691 case SC_SAMPLERSTATE
:
1695 sampler
= parent_index
== ~0u ? state
->index
: parent_index
;
1696 TRACE("%s, sampler %u, value %lu.\n", state_table
[state
->operation
].name
, sampler
, *(DWORD
*)param_value
);
1697 return SET_D3D_STATE(effect
, SetSamplerState
, sampler
, state_table
[state
->operation
].op
,
1698 *(DWORD
*)param_value
);
1700 case SC_VERTEXSHADER
:
1701 TRACE("%s, shader %p.\n", state_table
[state
->operation
].name
, *(IDirect3DVertexShader9
**)param_value
);
1702 if ((update_all
|| param_dirty
)
1703 && FAILED(hr
= SET_D3D_STATE(effect
, SetVertexShader
,
1704 *(IDirect3DVertexShader9
**)param_value
)))
1705 ERR("Could not set vertex shader, hr %#lx.\n", hr
);
1706 else if (*(IDirect3DVertexShader9
**)param_value
)
1707 hr
= d3dx_set_shader_constants(effect
, pass
, param
, TRUE
, update_all
|| param_dirty
);
1709 case SC_PIXELSHADER
:
1710 TRACE("%s, shader %p.\n", state_table
[state
->operation
].name
, *(IDirect3DPixelShader9
**)param_value
);
1711 if ((update_all
|| param_dirty
)
1712 && FAILED(hr
= SET_D3D_STATE(effect
, SetPixelShader
,
1713 *(IDirect3DPixelShader9
**)param_value
)))
1714 ERR("Could not set pixel shader, hr %#lx.\n", hr
);
1715 else if (*(IDirect3DPixelShader9
**)param_value
)
1716 hr
= d3dx_set_shader_constants(effect
, pass
, param
, FALSE
, update_all
|| param_dirty
);
1719 TRACE("%s, state %u.\n", state_table
[state
->operation
].name
, state
->index
);
1720 return SET_D3D_STATE(effect
, SetTransform
, state_table
[state
->operation
].op
+ state
->index
,
1721 (D3DMATRIX
*)param_value
);
1722 case SC_LIGHTENABLE
:
1723 TRACE("%s, index %u, value %u.\n", state_table
[state
->operation
].name
, state
->index
, *(BOOL
*)param_value
);
1724 return SET_D3D_STATE(effect
, LightEnable
, state
->index
, *(BOOL
*)param_value
);
1727 TRACE("%s, index %u, op %u.\n", state_table
[state
->operation
].name
, state
->index
,
1728 state_table
[state
->operation
].op
);
1729 d3dx9_set_light_parameter(state_table
[state
->operation
].op
,
1730 &effect
->current_light
[state
->index
], param_value
);
1731 effect
->light_updated
|= 1u << state
->index
;
1736 TRACE("%s, index %u, op %u.\n", state_table
[state
->operation
].name
, state
->index
,
1737 state_table
[state
->operation
].op
);
1738 d3dx9_set_material_parameter(state_table
[state
->operation
].op
,
1739 &effect
->current_material
, param_value
);
1740 effect
->material_updated
= TRUE
;
1744 TRACE("%s, nsegments %f.\n", state_table
[state
->operation
].name
, *(float *)param_value
);
1745 return SET_D3D_STATE(effect
, SetNPatchMode
, *(float *)param_value
);
1746 case SC_SHADERCONST
:
1747 TRACE("%s, index %u, op %u.\n", state_table
[state
->operation
].name
, state
->index
,
1748 state_table
[state
->operation
].op
);
1749 return d3dx_set_shader_const_state(effect
, state_table
[state
->operation
].op
, state
->index
,
1750 param
, param_value
);
1752 FIXME("%s not handled.\n", state_table
[state
->operation
].name
);
1758 static HRESULT
d3dx9_apply_pass_states(struct d3dx_effect
*effect
, struct d3dx_pass
*pass
, BOOL update_all
)
1763 ULONG64 new_update_version
= next_effect_update_version(effect
);
1765 TRACE("effect %p, pass %p, state_count %u.\n", effect
, pass
, pass
->state_count
);
1768 for (i
= 0; i
< pass
->state_count
; ++i
)
1770 if (FAILED(hr
= d3dx9_apply_state(effect
, pass
, &pass
->states
[i
], ~0u, update_all
)))
1772 WARN("Error applying state, hr %#lx.\n", hr
);
1777 if (effect
->light_updated
)
1779 for (i
= 0; i
< ARRAY_SIZE(effect
->current_light
); ++i
)
1781 if ((effect
->light_updated
& (1u << i
))
1782 && FAILED(hr
= SET_D3D_STATE(effect
, SetLight
, i
, &effect
->current_light
[i
])))
1784 WARN("Error setting light, hr %#lx.\n", hr
);
1788 effect
->light_updated
= 0;
1791 if (effect
->material_updated
1792 && FAILED(hr
= SET_D3D_STATE(effect
, SetMaterial
, &effect
->current_material
)))
1794 WARN("Error setting material, hr %#lx.\n", hr
);
1797 effect
->material_updated
= FALSE
;
1799 pass
->update_version
= new_update_version
;
1803 static void param_set_data_pointer(struct d3dx_parameter
*param
, unsigned char *data
, BOOL child
, BOOL free_data
)
1805 unsigned char *member_data
= data
;
1806 unsigned int i
, count
;
1808 count
= param
->element_count
? param
->element_count
: param
->member_count
;
1809 for (i
= 0; i
< count
; ++i
)
1811 param_set_data_pointer(¶m
->members
[i
], member_data
, TRUE
, free_data
);
1813 member_data
+= param
->members
[i
].bytes
;
1816 free_parameter_data(param
, child
);
1820 static BOOL
is_same_parameter(void *param1_
, struct d3dx_parameter
*param2
)
1822 struct d3dx_parameter
*param1
= (struct d3dx_parameter
*)param1_
;
1824 unsigned int i
, member_count
;
1826 matches
= !strcmp(param1
->name
, param2
->name
) && param1
->class == param2
->class
1827 && param1
->type
== param2
->type
&& param1
->rows
== param2
->rows
1828 && param1
->columns
== param2
->columns
&& param1
->element_count
== param2
->element_count
1829 && param1
->member_count
== param2
->member_count
;
1831 member_count
= param1
->element_count
? param1
->element_count
: param1
->member_count
;
1833 if (!matches
|| !member_count
)
1836 for (i
= 0; i
< member_count
; ++i
)
1838 if (!is_same_parameter(¶m1
->members
[i
], ¶m2
->members
[i
]))
1844 static HRESULT
d3dx_pool_sync_shared_parameter(struct d3dx_effect_pool
*pool
, struct d3dx_top_level_parameter
*param
)
1846 unsigned int i
, free_entry_index
;
1847 unsigned int new_size
, new_count
;
1849 if (!(param
->param
.flags
& PARAMETER_FLAG_SHARED
) || !pool
|| is_param_type_sampler(param
->param
.type
))
1852 free_entry_index
= pool
->size
;
1853 for (i
= 0; i
< pool
->size
; ++i
)
1855 if (!pool
->shared_data
[i
].count
)
1856 free_entry_index
= i
;
1857 else if (is_same_parameter(¶m
->param
, &pool
->shared_data
[i
].parameters
[0]->param
))
1860 if (i
== pool
->size
)
1862 i
= free_entry_index
;
1863 if (i
== pool
->size
)
1865 struct d3dx_shared_data
*new_alloc
;
1869 new_size
= INITIAL_POOL_SIZE
;
1870 new_alloc
= calloc(new_size
, sizeof(*pool
->shared_data
));
1876 new_size
= pool
->size
* 2;
1877 new_alloc
= _recalloc(pool
->shared_data
, new_size
, sizeof(*pool
->shared_data
));
1880 if (new_alloc
!= pool
->shared_data
)
1884 for (j
= 0; j
< pool
->size
; ++j
)
1885 for (k
= 0; k
< new_alloc
[j
].count
; ++k
)
1886 new_alloc
[j
].parameters
[k
]->shared_data
= &new_alloc
[j
];
1889 pool
->shared_data
= new_alloc
;
1890 pool
->size
= new_size
;
1892 pool
->shared_data
[i
].data
= param
->param
.data
;
1896 param_set_data_pointer(¶m
->param
, pool
->shared_data
[i
].data
, FALSE
, TRUE
);
1898 new_count
= ++pool
->shared_data
[i
].count
;
1899 if (new_count
>= pool
->shared_data
[i
].size
)
1901 struct d3dx_top_level_parameter
**new_alloc
;
1903 new_size
= pool
->shared_data
[i
].size
? pool
->shared_data
[i
].size
* 2 : INITIAL_SHARED_DATA_SIZE
;
1904 new_alloc
= _recalloc(pool
->shared_data
[i
].parameters
, new_size
, sizeof(*pool
->shared_data
[i
].parameters
));
1907 pool
->shared_data
[i
].parameters
= new_alloc
;
1908 pool
->shared_data
[i
].size
= new_size
;
1911 param
->shared_data
= &pool
->shared_data
[i
];
1912 pool
->shared_data
[i
].parameters
[new_count
- 1] = param
;
1914 TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param
->param
.name
), i
,
1920 ERR("Out of memory.\n");
1921 return E_OUTOFMEMORY
;
1924 static BOOL
param_zero_data_func(void *dummy
, struct d3dx_parameter
*param
)
1930 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter
*param
)
1932 unsigned int new_count
;
1934 if (!(param
->param
.flags
& PARAMETER_FLAG_SHARED
) || !param
->shared_data
)
1936 new_count
= --param
->shared_data
->count
;
1938 TRACE("param %p, param->shared_data %p, new_count %d.\n", param
, param
->shared_data
, new_count
);
1944 for (i
= 0; i
< new_count
; ++i
)
1946 if (param
->shared_data
->parameters
[i
] == param
)
1948 memmove(¶m
->shared_data
->parameters
[i
],
1949 ¶m
->shared_data
->parameters
[i
+ 1],
1950 sizeof(param
->shared_data
->parameters
[i
]) * (new_count
- i
));
1954 walk_parameter_tree(¶m
->param
, param_zero_data_func
, NULL
);
1958 free(param
->shared_data
->parameters
);
1959 /* Zeroing table size is required as the entry in pool parameters table can be reused. */
1960 param
->shared_data
->size
= 0;
1961 param
->shared_data
= NULL
;
1965 static inline struct d3dx_effect_pool
*impl_from_ID3DXEffectPool(ID3DXEffectPool
*iface
)
1967 return CONTAINING_RECORD(iface
, struct d3dx_effect_pool
, ID3DXEffectPool_iface
);
1970 static inline struct d3dx_effect_pool
*unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool
*iface
);
1972 static inline struct d3dx_effect
*impl_from_ID3DXEffect(ID3DXEffect
*iface
)
1974 return CONTAINING_RECORD(iface
, struct d3dx_effect
, ID3DXEffect_iface
);
1977 /*** IUnknown methods ***/
1978 static HRESULT WINAPI
d3dx_effect_QueryInterface(ID3DXEffect
*iface
, REFIID riid
, void **object
)
1980 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), object
);
1982 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
1983 IsEqualGUID(riid
, &IID_ID3DXEffect
))
1985 iface
->lpVtbl
->AddRef(iface
);
1990 ERR("Interface %s not found\n", debugstr_guid(riid
));
1992 return E_NOINTERFACE
;
1995 static ULONG WINAPI
d3dx_effect_AddRef(ID3DXEffect
*iface
)
1997 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
1998 ULONG refcount
= InterlockedIncrement(&effect
->ref
);
2000 TRACE("%p increasing refcount to %lu.\n", effect
, refcount
);
2005 static ULONG WINAPI
d3dx_effect_Release(ID3DXEffect
*iface
)
2007 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2008 ULONG refcount
= InterlockedDecrement(&effect
->ref
);
2010 TRACE("%p decreasing refcount to %lu.\n", effect
, refcount
);
2013 d3dx_effect_cleanup(effect
);
2018 /*** ID3DXBaseEffect methods ***/
2019 static HRESULT WINAPI
d3dx_effect_GetDesc(ID3DXEffect
*iface
, D3DXEFFECT_DESC
*desc
)
2021 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2023 FIXME("iface %p, desc %p partial stub.\n", iface
, desc
);
2027 WARN("Invalid argument specified.\n");
2028 return D3DERR_INVALIDCALL
;
2031 /* TODO: add creator and function count. */
2032 desc
->Creator
= NULL
;
2033 desc
->Functions
= 0;
2034 desc
->Parameters
= effect
->params
.count
;
2035 desc
->Techniques
= effect
->technique_count
;
2040 static HRESULT WINAPI
d3dx_effect_GetParameterDesc(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
2041 D3DXPARAMETER_DESC
*desc
)
2043 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2044 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2046 TRACE("iface %p, parameter %p, desc %p.\n", iface
, parameter
, desc
);
2048 if (!desc
|| !param
)
2050 WARN("Invalid argument specified.\n");
2051 return D3DERR_INVALIDCALL
;
2054 desc
->Name
= param
->name
;
2055 desc
->Semantic
= param
->semantic
;
2056 desc
->Class
= param
->class;
2057 desc
->Type
= param
->type
;
2058 desc
->Rows
= param
->rows
;
2059 desc
->Columns
= param
->columns
;
2060 desc
->Elements
= param
->element_count
;
2061 desc
->Annotations
= is_top_level_parameter(param
)
2062 ? top_level_parameter_from_parameter(param
)->annotation_count
: 0;
2063 desc
->StructMembers
= param
->member_count
;
2064 desc
->Flags
= param
->flags
;
2065 desc
->Bytes
= param
->bytes
;
2070 static HRESULT WINAPI
d3dx_effect_GetTechniqueDesc(ID3DXEffect
*iface
, D3DXHANDLE technique
,
2071 D3DXTECHNIQUE_DESC
*desc
)
2073 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2074 struct d3dx_technique
*tech
= technique
? get_valid_technique(effect
, technique
) : &effect
->techniques
[0];
2076 TRACE("iface %p, technique %p, desc %p.\n", iface
, technique
, desc
);
2080 WARN("Invalid argument specified.\n");
2081 return D3DERR_INVALIDCALL
;
2084 desc
->Name
= tech
->name
;
2085 desc
->Passes
= tech
->pass_count
;
2086 desc
->Annotations
= tech
->annotation_count
;
2091 static HRESULT WINAPI
d3dx_effect_GetPassDesc(ID3DXEffect
*iface
, D3DXHANDLE pass_handle
, D3DXPASS_DESC
*desc
)
2093 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2094 struct d3dx_pass
*pass
= get_valid_pass(effect
, pass_handle
);
2097 TRACE("iface %p, pass %p, desc %p.\n", iface
, pass
, desc
);
2101 WARN("Invalid argument specified.\n");
2102 return D3DERR_INVALIDCALL
;
2105 desc
->Name
= pass
->name
;
2106 desc
->Annotations
= pass
->annotation_count
;
2108 desc
->pVertexShaderFunction
= NULL
;
2109 desc
->pPixelShaderFunction
= NULL
;
2111 if (effect
->flags
& D3DXFX_NOT_CLONEABLE
)
2114 for (i
= 0; i
< pass
->state_count
; ++i
)
2116 struct d3dx_state
*state
= &pass
->states
[i
];
2118 if (state_table
[state
->operation
].class == SC_VERTEXSHADER
2119 || state_table
[state
->operation
].class == SC_PIXELSHADER
)
2121 struct d3dx_parameter
*param
;
2127 if (FAILED(hr
= d3dx9_get_param_value_ptr(pass
, &pass
->states
[i
], ¶m_value
, ¶m
,
2128 FALSE
, ¶m_dirty
)))
2131 data
= param
->object_id
? effect
->objects
[param
->object_id
].data
: NULL
;
2132 if (state_table
[state
->operation
].class == SC_VERTEXSHADER
)
2133 desc
->pVertexShaderFunction
= data
;
2135 desc
->pPixelShaderFunction
= data
;
2142 static HRESULT WINAPI
d3dx_effect_GetFunctionDesc(ID3DXEffect
*iface
, D3DXHANDLE shader
,
2143 D3DXFUNCTION_DESC
*desc
)
2145 FIXME("iface %p, shader %p, desc %p stub.\n", iface
, shader
, desc
);
2150 static D3DXHANDLE WINAPI
d3dx_effect_GetParameter(ID3DXEffect
*iface
, D3DXHANDLE parameter
, UINT index
)
2152 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2153 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2155 TRACE("iface %p, parameter %p, index %u.\n", iface
, parameter
, index
);
2159 if (index
< effect
->params
.count
)
2161 TRACE("Returning parameter %p.\n", &effect
->params
.parameters
[index
]);
2162 return get_parameter_handle(&effect
->params
.parameters
[index
].param
);
2167 if (param
&& !param
->element_count
&& index
< param
->member_count
)
2169 TRACE("Returning parameter %p.\n", ¶m
->members
[index
]);
2170 return get_parameter_handle(¶m
->members
[index
]);
2174 WARN("Parameter not found.\n");
2179 static D3DXHANDLE WINAPI
d3dx_effect_GetParameterByName(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
2182 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2183 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2186 TRACE("iface %p, parameter %p, name %s.\n", iface
, parameter
, debugstr_a(name
));
2190 handle
= get_parameter_handle(param
);
2191 TRACE("Returning parameter %p.\n", handle
);
2195 handle
= get_parameter_handle(get_parameter_by_name(&effect
->params
, param
, name
));
2196 TRACE("Returning parameter %p.\n", handle
);
2201 static D3DXHANDLE WINAPI
d3dx_effect_GetParameterBySemantic(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
2202 const char *semantic
)
2204 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2205 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2206 struct d3dx_parameter
*temp_param
;
2209 TRACE("iface %p, parameter %p, semantic %s.\n", iface
, parameter
, debugstr_a(semantic
));
2213 for (i
= 0; i
< effect
->params
.count
; ++i
)
2215 temp_param
= &effect
->params
.parameters
[i
].param
;
2217 if (!temp_param
->semantic
)
2221 TRACE("Returning parameter %p\n", temp_param
);
2222 return get_parameter_handle(temp_param
);
2227 if (!stricmp(temp_param
->semantic
, semantic
))
2229 TRACE("Returning parameter %p\n", temp_param
);
2230 return get_parameter_handle(temp_param
);
2236 for (i
= 0; i
< param
->member_count
; ++i
)
2238 temp_param
= ¶m
->members
[i
];
2240 if (!temp_param
->semantic
)
2244 TRACE("Returning parameter %p\n", temp_param
);
2245 return get_parameter_handle(temp_param
);
2250 if (!stricmp(temp_param
->semantic
, semantic
))
2252 TRACE("Returning parameter %p\n", temp_param
);
2253 return get_parameter_handle(temp_param
);
2258 WARN("Parameter not found.\n");
2263 static D3DXHANDLE WINAPI
d3dx_effect_GetParameterElement(ID3DXEffect
*iface
, D3DXHANDLE parameter
, UINT index
)
2265 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2266 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2268 TRACE("iface %p, parameter %p, index %u.\n", iface
, parameter
, index
);
2272 if (index
< effect
->params
.count
)
2274 TRACE("Returning parameter %p.\n", &effect
->params
.parameters
[index
]);
2275 return get_parameter_handle(&effect
->params
.parameters
[index
].param
);
2280 if (index
< param
->element_count
)
2282 TRACE("Returning parameter %p.\n", ¶m
->members
[index
]);
2283 return get_parameter_handle(¶m
->members
[index
]);
2287 WARN("Parameter not found.\n");
2292 static D3DXHANDLE WINAPI
d3dx_effect_GetTechnique(ID3DXEffect
*iface
, UINT index
)
2294 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2296 TRACE("iface %p, index %u.\n", iface
, index
);
2298 if (index
>= effect
->technique_count
)
2300 WARN("Invalid argument specified.\n");
2304 TRACE("Returning technique %p.\n", &effect
->techniques
[index
]);
2306 return get_technique_handle(&effect
->techniques
[index
]);
2309 static D3DXHANDLE WINAPI
d3dx_effect_GetTechniqueByName(ID3DXEffect
*iface
, const char *name
)
2311 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2312 struct d3dx_technique
*tech
= get_technique_by_name(effect
, name
);
2314 TRACE("iface %p, name %s.\n", iface
, debugstr_a(name
));
2318 D3DXHANDLE t
= get_technique_handle(tech
);
2319 TRACE("Returning technique %p\n", t
);
2323 WARN("Technique not found.\n");
2328 static D3DXHANDLE WINAPI
d3dx_effect_GetPass(ID3DXEffect
*iface
, D3DXHANDLE technique
, UINT index
)
2330 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2331 struct d3dx_technique
*tech
= get_valid_technique(effect
, technique
);
2333 TRACE("iface %p, technique %p, index %u.\n", iface
, technique
, index
);
2335 if (tech
&& index
< tech
->pass_count
)
2337 TRACE("Returning pass %p\n", &tech
->passes
[index
]);
2338 return get_pass_handle(&tech
->passes
[index
]);
2341 WARN("Pass not found.\n");
2346 static D3DXHANDLE WINAPI
d3dx_effect_GetPassByName(ID3DXEffect
*iface
, D3DXHANDLE technique
, const char *name
)
2348 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2349 struct d3dx_technique
*tech
= get_valid_technique(effect
, technique
);
2351 TRACE("iface %p, technique %p, name %s.\n", iface
, technique
, debugstr_a(name
));
2357 for (i
= 0; i
< tech
->pass_count
; ++i
)
2359 struct d3dx_pass
*pass
= &tech
->passes
[i
];
2361 if (!strcmp(pass
->name
, name
))
2363 TRACE("Returning pass %p\n", pass
);
2364 return get_pass_handle(pass
);
2369 WARN("Pass not found.\n");
2374 static D3DXHANDLE WINAPI
d3dx_effect_GetFunction(ID3DXEffect
*iface
, UINT index
)
2376 FIXME("iface %p, index %u stub.\n", iface
, index
);
2381 static D3DXHANDLE WINAPI
d3dx_effect_GetFunctionByName(ID3DXEffect
*iface
, const char *name
)
2383 FIXME("iface %p, name %s stub.\n", iface
, debugstr_a(name
));
2388 static D3DXHANDLE WINAPI
d3dx_effect_GetAnnotation(ID3DXEffect
*iface
, D3DXHANDLE object
, UINT index
)
2390 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2391 struct d3dx_parameter
*annotations
= NULL
;
2392 unsigned int annotation_count
;
2394 TRACE("iface %p, object %p, index %u.\n", iface
, object
, index
);
2396 annotation_count
= get_annotation_from_object(effect
, object
, &annotations
);
2398 if (index
< annotation_count
)
2400 TRACE("Returning parameter %p\n", &annotations
[index
]);
2401 return get_parameter_handle(&annotations
[index
]);
2404 WARN("Annotation not found.\n");
2409 static D3DXHANDLE WINAPI
d3dx_effect_GetAnnotationByName(ID3DXEffect
*iface
, D3DXHANDLE object
,
2412 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2413 struct d3dx_parameter
*annotation
= NULL
;
2414 struct d3dx_parameter
*annotations
= NULL
;
2415 unsigned int annotation_count
;
2417 TRACE("iface %p, object %p, name %s.\n", iface
, object
, debugstr_a(name
));
2421 WARN("Invalid argument specified\n");
2425 annotation_count
= get_annotation_from_object(effect
, object
, &annotations
);
2427 annotation
= get_annotation_by_name(effect
, annotation_count
, annotations
, name
);
2430 TRACE("Returning parameter %p\n", annotation
);
2431 return get_parameter_handle(annotation
);
2434 WARN("Annotation not found.\n");
2439 static HRESULT WINAPI
d3dx_effect_SetValue(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
2440 const void *data
, UINT bytes
)
2442 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2443 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2445 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface
, parameter
, data
, bytes
);
2449 WARN("Invalid parameter %p specified.\n", parameter
);
2450 return D3DERR_INVALIDCALL
;
2452 if (param
->class == D3DXPC_OBJECT
&& is_param_type_sampler(param
->type
))
2454 WARN("Parameter is a sampler, returning E_FAIL.\n");
2458 if (data
&& param
->bytes
<= bytes
)
2459 return set_value(param
, data
, bytes
, param_get_data_and_dirtify(effect
, param
, param
->bytes
, TRUE
));
2461 WARN("Invalid argument specified.\n");
2463 return D3DERR_INVALIDCALL
;
2466 static HRESULT WINAPI
d3dx_effect_GetValue(ID3DXEffect
*iface
, D3DXHANDLE parameter
, void *data
, UINT bytes
)
2468 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2469 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2471 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface
, parameter
, data
, bytes
);
2475 WARN("Invalid parameter %p specified.\n", parameter
);
2476 return D3DERR_INVALIDCALL
;
2478 if (param
->class == D3DXPC_OBJECT
&& is_param_type_sampler(param
->type
))
2480 WARN("Parameter is a sampler, returning E_FAIL.\n");
2484 if (data
&& param
->bytes
<= bytes
)
2486 TRACE("Type %s.\n", debug_d3dxparameter_type(param
->type
));
2488 switch (param
->type
)
2497 case D3DXPT_VERTEXSHADER
:
2498 case D3DXPT_PIXELSHADER
:
2499 case D3DXPT_TEXTURE
:
2500 case D3DXPT_TEXTURE1D
:
2501 case D3DXPT_TEXTURE2D
:
2502 case D3DXPT_TEXTURE3D
:
2503 case D3DXPT_TEXTURECUBE
:
2507 for (i
= 0; i
< (param
->element_count
? param
->element_count
: 1); ++i
)
2509 IUnknown
*unk
= ((IUnknown
**)param
->data
)[i
];
2511 IUnknown_AddRef(unk
);
2517 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param
->type
));
2521 TRACE("Copy %u bytes.\n", param
->bytes
);
2522 memcpy(data
, param
->data
, param
->bytes
);
2526 WARN("Parameter not found.\n");
2528 return D3DERR_INVALIDCALL
;
2531 static HRESULT WINAPI
d3dx_effect_SetBool(ID3DXEffect
*iface
, D3DXHANDLE parameter
, BOOL b
)
2533 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2534 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2536 TRACE("iface %p, parameter %p, b %#x.\n", iface
, parameter
, b
);
2538 if (param
&& !param
->element_count
&& param
->rows
== 1 && param
->columns
== 1)
2540 set_number(param_get_data_and_dirtify(effect
, param
, sizeof(int), TRUE
),
2541 param
->type
, &b
, D3DXPT_BOOL
);
2545 WARN("Parameter not found.\n");
2547 return D3DERR_INVALIDCALL
;
2550 static HRESULT WINAPI
d3dx_effect_GetBool(ID3DXEffect
*iface
, D3DXHANDLE parameter
, BOOL
*b
)
2552 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2553 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2555 TRACE("iface %p, parameter %p, b %p.\n", iface
, parameter
, b
);
2557 if (b
&& param
&& !param
->element_count
&& param
->rows
== 1 && param
->columns
== 1)
2559 set_number(b
, D3DXPT_BOOL
, param
->data
, param
->type
);
2560 TRACE("Returning %s\n", *b
? "TRUE" : "FALSE");
2564 WARN("Parameter not found.\n");
2566 return D3DERR_INVALIDCALL
;
2569 static HRESULT WINAPI
d3dx_effect_SetBoolArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const BOOL
*b
, UINT count
)
2571 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2572 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2575 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface
, parameter
, b
, count
);
2579 unsigned int i
, size
= min(count
, param
->bytes
/ sizeof(DWORD
));
2581 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
2583 switch (param
->class)
2587 case D3DXPC_MATRIX_ROWS
:
2588 data
= param_get_data_and_dirtify(effect
, param
, size
* sizeof(int), TRUE
);
2589 for (i
= 0; i
< size
; ++i
)
2591 /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
2592 set_number(data
+ i
, param
->type
, &b
[i
], D3DXPT_INT
);
2601 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
2606 WARN("Parameter not found.\n");
2608 return D3DERR_INVALIDCALL
;
2611 static HRESULT WINAPI
d3dx_effect_GetBoolArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
, BOOL
*b
, UINT count
)
2613 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2614 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2616 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface
, parameter
, b
, count
);
2618 if (b
&& param
&& (param
->class == D3DXPC_SCALAR
2619 || param
->class == D3DXPC_VECTOR
2620 || param
->class == D3DXPC_MATRIX_ROWS
2621 || param
->class == D3DXPC_MATRIX_COLUMNS
))
2623 unsigned int i
, size
= min(count
, param
->bytes
/ sizeof(DWORD
));
2625 for (i
= 0; i
< size
; ++i
)
2627 set_number(&b
[i
], D3DXPT_BOOL
, (DWORD
*)param
->data
+ i
, param
->type
);
2632 WARN("Parameter not found.\n");
2634 return D3DERR_INVALIDCALL
;
2637 static HRESULT WINAPI
d3dx_effect_SetInt(ID3DXEffect
*iface
, D3DXHANDLE parameter
, INT n
)
2639 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2640 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2642 TRACE("iface %p, parameter %p, n %d.\n", iface
, parameter
, n
);
2644 if (param
&& !param
->element_count
)
2646 if (param
->rows
== 1 && param
->columns
== 1)
2650 set_number(&value
, param
->type
, &n
, D3DXPT_INT
);
2651 *(DWORD
*)param_get_data_and_dirtify(effect
, param
, sizeof(int),
2652 value
!= *(DWORD
*)param
->data
) = value
;
2656 /* Split the value if parameter is a vector with dimension 3 or 4. */
2657 if (param
->type
== D3DXPT_FLOAT
2658 && ((param
->class == D3DXPC_VECTOR
&& param
->columns
!= 2)
2659 || (param
->class == D3DXPC_MATRIX_ROWS
&& param
->rows
!= 2 && param
->columns
== 1)))
2663 TRACE("Vector fixup.\n");
2665 data
= param_get_data_and_dirtify(effect
, param
,
2666 min(4, param
->rows
* param
->columns
) * sizeof(float), TRUE
);
2668 data
[0] = ((n
& 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE
;
2669 data
[1] = ((n
& 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE
;
2670 data
[2] = (n
& 0xff) * INT_FLOAT_MULTI_INVERSE
;
2671 if (param
->rows
* param
->columns
> 3)
2672 data
[3] = ((n
& 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE
;
2678 WARN("Parameter not found.\n");
2680 return D3DERR_INVALIDCALL
;
2683 static HRESULT WINAPI
d3dx_effect_GetInt(ID3DXEffect
*iface
, D3DXHANDLE parameter
, INT
*n
)
2685 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2686 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2688 TRACE("iface %p, parameter %p, n %p.\n", iface
, parameter
, n
);
2690 if (n
&& param
&& !param
->element_count
)
2692 if (param
->columns
== 1 && param
->rows
== 1)
2694 set_number(n
, D3DXPT_INT
, param
->data
, param
->type
);
2695 TRACE("Returning %d.\n", *n
);
2699 if (param
->type
== D3DXPT_FLOAT
&&
2700 ((param
->class == D3DXPC_VECTOR
&& param
->columns
!= 2)
2701 || (param
->class == D3DXPC_MATRIX_ROWS
&& param
->rows
!= 2 && param
->columns
== 1)))
2703 TRACE("Vector fixup.\n");
2705 *n
= min(max(0.0f
, *((float *)param
->data
+ 2)), 1.0f
) * INT_FLOAT_MULTI
;
2706 *n
+= ((int)(min(max(0.0f
, *((float *)param
->data
+ 1)), 1.0f
) * INT_FLOAT_MULTI
)) << 8;
2707 *n
+= ((int)(min(max(0.0f
, *((float *)param
->data
+ 0)), 1.0f
) * INT_FLOAT_MULTI
)) << 16;
2708 if (param
->columns
* param
->rows
> 3)
2709 *n
+= ((int)(min(max(0.0f
, *((float *)param
->data
+ 3)), 1.0f
) * INT_FLOAT_MULTI
)) << 24;
2711 TRACE("Returning %d.\n", *n
);
2716 WARN("Parameter not found.\n");
2718 return D3DERR_INVALIDCALL
;
2721 static HRESULT WINAPI
d3dx_effect_SetIntArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const INT
*n
, UINT count
)
2723 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2724 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2727 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface
, parameter
, n
, count
);
2731 unsigned int i
, size
= min(count
, param
->bytes
/ sizeof(DWORD
));
2733 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
2735 switch (param
->class)
2739 case D3DXPC_MATRIX_ROWS
:
2740 data
= param_get_data_and_dirtify(effect
, param
, size
* sizeof(int), TRUE
);
2741 for (i
= 0; i
< size
; ++i
)
2742 set_number(data
+ i
, param
->type
, &n
[i
], D3DXPT_INT
);
2750 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
2755 WARN("Parameter not found.\n");
2757 return D3DERR_INVALIDCALL
;
2760 static HRESULT WINAPI
d3dx_effect_GetIntArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
, INT
*n
, UINT count
)
2762 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2763 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2765 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface
, parameter
, n
, count
);
2767 if (n
&& param
&& (param
->class == D3DXPC_SCALAR
2768 || param
->class == D3DXPC_VECTOR
2769 || param
->class == D3DXPC_MATRIX_ROWS
2770 || param
->class == D3DXPC_MATRIX_COLUMNS
))
2772 unsigned int i
, size
= min(count
, param
->bytes
/ sizeof(DWORD
));
2774 for (i
= 0; i
< size
; ++i
)
2775 set_number(&n
[i
], D3DXPT_INT
, (DWORD
*)param
->data
+ i
, param
->type
);
2779 WARN("Parameter not found.\n");
2781 return D3DERR_INVALIDCALL
;
2784 static HRESULT WINAPI
d3dx_effect_SetFloat(ID3DXEffect
*iface
, D3DXHANDLE parameter
, float f
)
2786 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2787 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2789 TRACE("iface %p, parameter %p, f %.8e.\n", iface
, parameter
, f
);
2791 if (param
&& !param
->element_count
&& param
->rows
== 1 && param
->columns
== 1)
2795 set_number(&value
, param
->type
, &f
, D3DXPT_FLOAT
);
2796 *(DWORD
*)param_get_data_and_dirtify(effect
, param
, sizeof(float),
2797 value
!= *(DWORD
*)param
->data
) = value
;
2801 WARN("Parameter not found.\n");
2803 return D3DERR_INVALIDCALL
;
2806 static HRESULT WINAPI
d3dx_effect_GetFloat(ID3DXEffect
*iface
, D3DXHANDLE parameter
, float *f
)
2808 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2809 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2811 TRACE("iface %p, parameter %p, f %p.\n", iface
, parameter
, f
);
2813 if (f
&& param
&& !param
->element_count
&& param
->columns
== 1 && param
->rows
== 1)
2815 set_number(f
, D3DXPT_FLOAT
, (DWORD
*)param
->data
, param
->type
);
2816 TRACE("Returning %f.\n", *f
);
2820 WARN("Parameter not found.\n");
2822 return D3DERR_INVALIDCALL
;
2825 static HRESULT WINAPI
d3dx_effect_SetFloatArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
2826 const float *f
, UINT count
)
2828 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2829 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2832 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface
, parameter
, f
, count
);
2836 unsigned int i
, size
= min(count
, param
->bytes
/ sizeof(DWORD
));
2838 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
2840 switch (param
->class)
2844 case D3DXPC_MATRIX_ROWS
:
2845 data
= param_get_data_and_dirtify(effect
, param
, size
* sizeof(float), TRUE
);
2846 for (i
= 0; i
< size
; ++i
)
2847 set_number(data
+ i
, param
->type
, &f
[i
], D3DXPT_FLOAT
);
2855 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
2860 WARN("Parameter not found.\n");
2862 return D3DERR_INVALIDCALL
;
2865 static HRESULT WINAPI
d3dx_effect_GetFloatArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
, float *f
, UINT count
)
2867 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2868 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2870 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface
, parameter
, f
, count
);
2872 if (f
&& param
&& (param
->class == D3DXPC_SCALAR
2873 || param
->class == D3DXPC_VECTOR
2874 || param
->class == D3DXPC_MATRIX_ROWS
2875 || param
->class == D3DXPC_MATRIX_COLUMNS
))
2877 unsigned int i
, size
= min(count
, param
->bytes
/ sizeof(DWORD
));
2879 for (i
= 0; i
< size
; ++i
)
2880 set_number(&f
[i
], D3DXPT_FLOAT
, (DWORD
*)param
->data
+ i
, param
->type
);
2884 WARN("Parameter not found.\n");
2886 return D3DERR_INVALIDCALL
;
2889 static HRESULT WINAPI
d3dx_effect_SetVector(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const D3DXVECTOR4
*vector
)
2891 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2892 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2894 TRACE("iface %p, parameter %p, vector %p.\n", iface
, parameter
, vector
);
2896 if (param
&& !param
->element_count
)
2898 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
2900 switch (param
->class)
2904 if (param
->type
== D3DXPT_INT
&& param
->bytes
== 4)
2908 TRACE("INT fixup.\n");
2909 tmp
= max(min(vector
->z
, 1.0f
), 0.0f
) * INT_FLOAT_MULTI
;
2910 tmp
+= ((DWORD
)(max(min(vector
->y
, 1.0f
), 0.0f
) * INT_FLOAT_MULTI
)) << 8;
2911 tmp
+= ((DWORD
)(max(min(vector
->x
, 1.0f
), 0.0f
) * INT_FLOAT_MULTI
)) << 16;
2912 tmp
+= ((DWORD
)(max(min(vector
->w
, 1.0f
), 0.0f
) * INT_FLOAT_MULTI
)) << 24;
2914 *(int *)param_get_data_and_dirtify(effect
, param
, sizeof(int), TRUE
) = tmp
;
2917 if (param
->type
== D3DXPT_FLOAT
)
2919 memcpy(param_get_data_and_dirtify(effect
, param
, param
->columns
* sizeof(float), TRUE
),
2920 vector
, param
->columns
* sizeof(float));
2924 set_vector(param
, vector
, param_get_data_and_dirtify(effect
, param
, param
->columns
* sizeof(float), TRUE
));
2927 case D3DXPC_MATRIX_ROWS
:
2933 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
2938 WARN("Parameter not found.\n");
2940 return D3DERR_INVALIDCALL
;
2943 static HRESULT WINAPI
d3dx_effect_GetVector(ID3DXEffect
*iface
, D3DXHANDLE parameter
, D3DXVECTOR4
*vector
)
2945 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2946 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2948 TRACE("iface %p, parameter %p, vector %p.\n", iface
, parameter
, vector
);
2950 if (vector
&& param
&& !param
->element_count
)
2952 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
2954 switch (param
->class)
2958 if (param
->type
== D3DXPT_INT
&& param
->bytes
== 4)
2960 TRACE("INT fixup.\n");
2961 vector
->x
= (((*(int *)param
->data
) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE
;
2962 vector
->y
= (((*(int *)param
->data
) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE
;
2963 vector
->z
= ((*(int *)param
->data
) & 0xff) * INT_FLOAT_MULTI_INVERSE
;
2964 vector
->w
= (((*(int *)param
->data
) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE
;
2967 get_vector(param
, vector
);
2970 case D3DXPC_MATRIX_ROWS
:
2976 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
2981 WARN("Parameter not found.\n");
2983 return D3DERR_INVALIDCALL
;
2986 static HRESULT WINAPI
d3dx_effect_SetVectorArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
2987 const D3DXVECTOR4
*vector
, UINT count
)
2989 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
2990 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
2992 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface
, parameter
, vector
, count
);
2994 if (param
&& param
->element_count
&& param
->element_count
>= count
)
2999 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3001 switch (param
->class)
3004 data
= param_get_data_and_dirtify(effect
, param
, count
* param
->columns
* sizeof(float), TRUE
);
3006 if (param
->type
== D3DXPT_FLOAT
)
3008 if (param
->columns
== 4)
3010 memcpy(data
, vector
, count
* 4 * sizeof(float));
3014 for (i
= 0; i
< count
; ++i
)
3015 memcpy((float *)data
+ param
->columns
* i
, vector
+ i
,
3016 param
->columns
* sizeof(float));
3021 for (i
= 0; i
< count
; ++i
)
3022 set_vector(¶m
->members
[i
], &vector
[i
], data
+ i
* param
->columns
* sizeof(float));
3027 case D3DXPC_MATRIX_ROWS
:
3033 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3038 WARN("Parameter not found.\n");
3040 return D3DERR_INVALIDCALL
;
3043 static HRESULT WINAPI
d3dx_effect_GetVectorArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3044 D3DXVECTOR4
*vector
, UINT count
)
3046 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3047 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3049 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface
, parameter
, vector
, count
);
3054 if (vector
&& param
&& count
<= param
->element_count
)
3058 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3060 switch (param
->class)
3063 for (i
= 0; i
< count
; ++i
)
3064 get_vector(¶m
->members
[i
], &vector
[i
]);
3068 case D3DXPC_MATRIX_ROWS
:
3074 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3079 WARN("Parameter not found.\n");
3081 return D3DERR_INVALIDCALL
;
3084 static HRESULT WINAPI
d3dx_effect_SetMatrix(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const D3DXMATRIX
*matrix
)
3086 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3087 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3089 TRACE("iface %p, parameter %p, matrix %p.\n", iface
, parameter
, matrix
);
3091 if (param
&& !param
->element_count
)
3093 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3095 switch (param
->class)
3097 case D3DXPC_MATRIX_ROWS
:
3098 set_matrix(param
, matrix
, param_get_data_and_dirtify(effect
, param
,
3099 param
->rows
* param
->columns
* sizeof(float), TRUE
));
3109 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3114 WARN("Parameter not found.\n");
3116 return D3DERR_INVALIDCALL
;
3119 static HRESULT WINAPI
d3dx_effect_GetMatrix(ID3DXEffect
*iface
, D3DXHANDLE parameter
, D3DXMATRIX
*matrix
)
3121 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3122 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3124 TRACE("iface %p, parameter %p, matrix %p.\n", iface
, parameter
, matrix
);
3126 if (matrix
&& param
&& !param
->element_count
)
3128 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3130 switch (param
->class)
3132 case D3DXPC_MATRIX_ROWS
:
3133 get_matrix(param
, matrix
, FALSE
);
3143 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3148 WARN("Parameter not found.\n");
3150 return D3DERR_INVALIDCALL
;
3153 static HRESULT WINAPI
d3dx_effect_SetMatrixArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3154 const D3DXMATRIX
*matrix
, UINT count
)
3156 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3157 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3159 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3161 if (param
&& param
->element_count
>= count
)
3166 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3168 switch (param
->class)
3170 case D3DXPC_MATRIX_ROWS
:
3171 data
= param_get_data_and_dirtify(effect
, param
, count
* param
->rows
3172 * param
->columns
* sizeof(float), TRUE
);
3174 for (i
= 0; i
< count
; ++i
)
3175 set_matrix(¶m
->members
[i
], &matrix
[i
],
3176 data
+ i
* param
->rows
* param
->columns
* sizeof(float));
3187 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3192 WARN("Parameter not found.\n");
3194 return D3DERR_INVALIDCALL
;
3197 static HRESULT WINAPI
d3dx_effect_GetMatrixArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3198 D3DXMATRIX
*matrix
, UINT count
)
3200 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3201 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3203 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3208 if (matrix
&& param
&& count
<= param
->element_count
)
3212 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3214 switch (param
->class)
3216 case D3DXPC_MATRIX_ROWS
:
3217 for (i
= 0; i
< count
; ++i
)
3218 get_matrix(¶m
->members
[i
], &matrix
[i
], FALSE
);
3228 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3233 WARN("Parameter not found.\n");
3235 return D3DERR_INVALIDCALL
;
3238 static HRESULT WINAPI
d3dx_effect_SetMatrixPointerArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3239 const D3DXMATRIX
**matrix
, UINT count
)
3241 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3242 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3244 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3246 if (param
&& count
<= param
->element_count
)
3251 switch (param
->class)
3253 case D3DXPC_MATRIX_ROWS
:
3254 data
= param_get_data_and_dirtify(effect
, param
, count
* param
->rows
3255 * param
->columns
* sizeof(float), TRUE
);
3257 for (i
= 0; i
< count
; ++i
)
3258 set_matrix(¶m
->members
[i
], matrix
[i
], data
+ i
* param
->rows
3259 * param
->columns
* sizeof(float));
3269 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3274 WARN("Parameter not found.\n");
3276 return D3DERR_INVALIDCALL
;
3279 static HRESULT WINAPI
d3dx_effect_GetMatrixPointerArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3280 D3DXMATRIX
**matrix
, UINT count
)
3282 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3283 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3285 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3290 if (param
&& matrix
&& count
<= param
->element_count
)
3294 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3296 switch (param
->class)
3298 case D3DXPC_MATRIX_ROWS
:
3299 for (i
= 0; i
< count
; ++i
)
3300 get_matrix(¶m
->members
[i
], matrix
[i
], FALSE
);
3309 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3314 WARN("Parameter not found.\n");
3316 return D3DERR_INVALIDCALL
;
3319 static HRESULT WINAPI
d3dx_effect_SetMatrixTranspose(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3320 const D3DXMATRIX
*matrix
)
3322 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3323 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3325 TRACE("iface %p, parameter %p, matrix %p.\n", iface
, parameter
, matrix
);
3327 if (param
&& !param
->element_count
)
3329 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3331 switch (param
->class)
3333 case D3DXPC_MATRIX_ROWS
:
3334 set_matrix_transpose(param
, matrix
, param_get_data_and_dirtify(effect
, param
,
3335 param
->rows
* param
->columns
* sizeof(float), TRUE
));
3345 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3350 WARN("Parameter not found.\n");
3352 return D3DERR_INVALIDCALL
;
3355 static HRESULT WINAPI
d3dx_effect_GetMatrixTranspose(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3358 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3359 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3361 TRACE("iface %p, parameter %p, matrix %p.\n", iface
, parameter
, matrix
);
3363 if (matrix
&& param
&& !param
->element_count
)
3365 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3367 switch (param
->class)
3371 get_matrix(param
, matrix
, FALSE
);
3374 case D3DXPC_MATRIX_ROWS
:
3375 get_matrix(param
, matrix
, TRUE
);
3383 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3388 WARN("Parameter not found.\n");
3390 return D3DERR_INVALIDCALL
;
3393 static HRESULT WINAPI
d3dx_effect_SetMatrixTransposeArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3394 const D3DXMATRIX
*matrix
, UINT count
)
3396 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3397 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3399 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3401 if (param
&& param
->element_count
>= count
)
3406 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3408 switch (param
->class)
3410 case D3DXPC_MATRIX_ROWS
:
3411 data
= param_get_data_and_dirtify(effect
, param
, count
* param
->rows
3412 * param
->columns
* sizeof(float), TRUE
);
3414 for (i
= 0; i
< count
; ++i
)
3415 set_matrix_transpose(¶m
->members
[i
], &matrix
[i
], data
3416 + i
* param
->rows
* param
->columns
* sizeof(float));
3427 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3432 WARN("Parameter not found.\n");
3434 return D3DERR_INVALIDCALL
;
3437 static HRESULT WINAPI
d3dx_effect_GetMatrixTransposeArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3438 D3DXMATRIX
*matrix
, UINT count
)
3440 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3441 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3443 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3448 if (matrix
&& param
&& count
<= param
->element_count
)
3452 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3454 switch (param
->class)
3456 case D3DXPC_MATRIX_ROWS
:
3457 for (i
= 0; i
< count
; ++i
)
3458 get_matrix(¶m
->members
[i
], &matrix
[i
], TRUE
);
3468 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3473 WARN("Parameter not found.\n");
3475 return D3DERR_INVALIDCALL
;
3478 static HRESULT WINAPI
d3dx_effect_SetMatrixTransposePointerArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3479 const D3DXMATRIX
**matrix
, UINT count
)
3481 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3482 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3484 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3486 if (param
&& count
<= param
->element_count
)
3491 switch (param
->class)
3493 case D3DXPC_MATRIX_ROWS
:
3494 data
= param_get_data_and_dirtify(effect
, param
, count
* param
->rows
3495 * param
->columns
* sizeof(float), TRUE
);
3497 for (i
= 0; i
< count
; ++i
)
3498 set_matrix_transpose(¶m
->members
[i
], matrix
[i
], data
3499 + i
* param
->rows
* param
->columns
* sizeof(float));
3509 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3514 WARN("Parameter not found.\n");
3516 return D3DERR_INVALIDCALL
;
3519 static HRESULT WINAPI
d3dx_effect_GetMatrixTransposePointerArray(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3520 D3DXMATRIX
**matrix
, UINT count
)
3522 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3523 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3525 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface
, parameter
, matrix
, count
);
3530 if (matrix
&& param
&& count
<= param
->element_count
)
3534 TRACE("Class %s.\n", debug_d3dxparameter_class(param
->class));
3536 switch (param
->class)
3538 case D3DXPC_MATRIX_ROWS
:
3539 for (i
= 0; i
< count
; ++i
)
3540 get_matrix(¶m
->members
[i
], matrix
[i
], TRUE
);
3549 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
3554 WARN("Parameter not found.\n");
3556 return D3DERR_INVALIDCALL
;
3559 static HRESULT WINAPI
d3dx_effect_SetString(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const char *string
)
3561 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3562 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3564 TRACE("iface %p, parameter %p, string %s.\n", iface
, parameter
, debugstr_a(string
));
3566 if (param
&& param
->type
== D3DXPT_STRING
)
3567 return set_string(param_get_data_and_dirtify(effect
, param
, sizeof(void *), TRUE
), string
);
3569 WARN("Parameter not found.\n");
3571 return D3DERR_INVALIDCALL
;
3574 static HRESULT WINAPI
d3dx_effect_GetString(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const char **string
)
3576 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3577 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3579 TRACE("iface %p, parameter %p, string %p.\n", iface
, parameter
, string
);
3581 if (string
&& param
&& !param
->element_count
&& param
->type
== D3DXPT_STRING
)
3583 *string
= *(const char **)param
->data
;
3584 TRACE("Returning %s.\n", debugstr_a(*string
));
3588 WARN("Parameter not found.\n");
3590 return D3DERR_INVALIDCALL
;
3593 static HRESULT WINAPI
d3dx_effect_SetTexture(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3594 IDirect3DBaseTexture9
*texture
)
3596 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3597 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3599 TRACE("iface %p, parameter %p, texture %p.\n", iface
, parameter
, texture
);
3601 if (param
&& !param
->element_count
3602 && (param
->type
== D3DXPT_TEXTURE
|| param
->type
== D3DXPT_TEXTURE1D
3603 || param
->type
== D3DXPT_TEXTURE2D
|| param
->type
== D3DXPT_TEXTURE3D
3604 || param
->type
== D3DXPT_TEXTURECUBE
))
3606 IDirect3DBaseTexture9
**data
= param_get_data_and_dirtify(effect
, param
,
3607 sizeof(void *), texture
!= *(IDirect3DBaseTexture9
**)param
->data
);
3608 IDirect3DBaseTexture9
*old_texture
= *data
;
3612 if (texture
== old_texture
)
3616 IDirect3DBaseTexture9_AddRef(texture
);
3618 IDirect3DBaseTexture9_Release(old_texture
);
3623 WARN("Parameter not found.\n");
3625 return D3DERR_INVALIDCALL
;
3628 static HRESULT WINAPI
d3dx_effect_GetTexture(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3629 IDirect3DBaseTexture9
**texture
)
3631 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3632 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3634 TRACE("iface %p, parameter %p, texture %p.\n", iface
, parameter
, texture
);
3636 if (texture
&& param
&& !param
->element_count
3637 && (param
->type
== D3DXPT_TEXTURE
|| param
->type
== D3DXPT_TEXTURE1D
3638 || param
->type
== D3DXPT_TEXTURE2D
|| param
->type
== D3DXPT_TEXTURE3D
3639 || param
->type
== D3DXPT_TEXTURECUBE
))
3641 *texture
= *(IDirect3DBaseTexture9
**)param
->data
;
3643 IDirect3DBaseTexture9_AddRef(*texture
);
3644 TRACE("Returning %p.\n", *texture
);
3648 WARN("Parameter not found.\n");
3650 return D3DERR_INVALIDCALL
;
3653 static HRESULT WINAPI
d3dx_effect_GetPixelShader(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3654 IDirect3DPixelShader9
**shader
)
3656 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3657 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3659 TRACE("iface %p, parameter %p, shader %p.\n", iface
, parameter
, shader
);
3661 if (shader
&& param
&& !param
->element_count
&& param
->type
== D3DXPT_PIXELSHADER
)
3663 if ((*shader
= *(IDirect3DPixelShader9
**)param
->data
))
3664 IDirect3DPixelShader9_AddRef(*shader
);
3665 TRACE("Returning %p.\n", *shader
);
3669 WARN("Parameter not found.\n");
3671 return D3DERR_INVALIDCALL
;
3674 static HRESULT WINAPI
d3dx_effect_GetVertexShader(ID3DXEffect
*iface
, D3DXHANDLE parameter
,
3675 IDirect3DVertexShader9
**shader
)
3677 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3678 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3680 TRACE("iface %p, parameter %p, shader %p.\n", iface
, parameter
, shader
);
3682 if (shader
&& param
&& !param
->element_count
&& param
->type
== D3DXPT_VERTEXSHADER
)
3684 if ((*shader
= *(IDirect3DVertexShader9
**)param
->data
))
3685 IDirect3DVertexShader9_AddRef(*shader
);
3686 TRACE("Returning %p.\n", *shader
);
3690 WARN("Parameter not found.\n");
3692 return D3DERR_INVALIDCALL
;
3695 static HRESULT WINAPI
d3dx_effect_SetArrayRange(ID3DXEffect
*iface
, D3DXHANDLE parameter
, UINT start
, UINT end
)
3697 FIXME("iface %p, parameter %p, start %u, end %u stub.\n", iface
, parameter
, start
, end
);
3702 /*** ID3DXEffect methods ***/
3703 static HRESULT WINAPI
d3dx_effect_GetPool(ID3DXEffect
*iface
, ID3DXEffectPool
**pool
)
3705 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3707 TRACE("iface %p, pool %p.\n", effect
, pool
);
3711 WARN("Invalid argument supplied.\n");
3712 return D3DERR_INVALIDCALL
;
3718 *pool
= &effect
->pool
->ID3DXEffectPool_iface
;
3719 (*pool
)->lpVtbl
->AddRef(*pool
);
3722 TRACE("Returning pool %p.\n", *pool
);
3727 static HRESULT WINAPI
d3dx_effect_SetTechnique(ID3DXEffect
*iface
, D3DXHANDLE technique
)
3729 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3730 struct d3dx_technique
*tech
= get_valid_technique(effect
, technique
);
3732 TRACE("iface %p, technique %p\n", iface
, technique
);
3736 effect
->active_technique
= tech
;
3737 TRACE("Technique %p\n", tech
);
3741 WARN("Technique not found.\n");
3743 return D3DERR_INVALIDCALL
;
3746 static D3DXHANDLE WINAPI
d3dx_effect_GetCurrentTechnique(ID3DXEffect
*iface
)
3748 struct d3dx_effect
*This
= impl_from_ID3DXEffect(iface
);
3750 TRACE("iface %p\n", This
);
3752 return get_technique_handle(This
->active_technique
);
3755 static HRESULT WINAPI
d3dx_effect_ValidateTechnique(ID3DXEffect
*iface
, D3DXHANDLE technique
)
3757 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3758 struct d3dx_technique
*tech
= get_valid_technique(effect
, technique
);
3759 HRESULT ret
= D3D_OK
;
3762 FIXME("iface %p, technique %p semi-stub.\n", iface
, technique
);
3766 ret
= D3DERR_INVALIDCALL
;
3769 for (i
= 0; i
< tech
->pass_count
; ++i
)
3771 struct d3dx_pass
*pass
= &tech
->passes
[i
];
3773 for (j
= 0; j
< pass
->state_count
; ++j
)
3775 struct d3dx_state
*state
= &pass
->states
[j
];
3777 if (state_table
[state
->operation
].class == SC_VERTEXSHADER
3778 || state_table
[state
->operation
].class == SC_PIXELSHADER
)
3780 struct d3dx_parameter
*param
;
3785 if (FAILED(hr
= d3dx9_get_param_value_ptr(pass
, &pass
->states
[j
], ¶m_value
, ¶m
,
3786 FALSE
, ¶m_dirty
)))
3789 if (param
->object_id
&& effect
->objects
[param
->object_id
].creation_failed
)
3798 TRACE("Returning %#lx.\n", ret
);
3802 static HRESULT WINAPI
d3dx_effect_FindNextValidTechnique(ID3DXEffect
*iface
, D3DXHANDLE technique
,
3803 D3DXHANDLE
*next_technique
)
3805 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3806 struct d3dx_technique
*prev_tech
, *tech
;
3809 TRACE("iface %p, technique %p, next_technique %p.\n", iface
, technique
, next_technique
);
3813 if (!(prev_tech
= get_valid_technique(effect
, technique
)))
3814 return D3DERR_INVALIDCALL
;
3816 for (i
= 0; i
< effect
->technique_count
; ++i
)
3818 tech
= &effect
->techniques
[i
];
3819 if (tech
== prev_tech
)
3831 for (; i
< effect
->technique_count
; ++i
)
3833 tech
= &effect
->techniques
[i
];
3834 if (SUCCEEDED(d3dx_effect_ValidateTechnique(iface
, get_technique_handle(tech
))))
3836 *next_technique
= get_technique_handle(tech
);
3841 *next_technique
= NULL
;
3845 static BOOL
walk_parameter_dep(struct d3dx_parameter
*param
, walk_parameter_dep_func param_func
,
3848 static BOOL
walk_param_eval_dep(struct d3dx_param_eval
*param_eval
, walk_parameter_dep_func param_func
,
3851 struct d3dx_parameter
**params
;
3852 unsigned int i
, param_count
;
3857 params
= param_eval
->shader_inputs
.inputs_param
;
3858 param_count
= param_eval
->shader_inputs
.input_count
;
3859 for (i
= 0; i
< param_count
; ++i
)
3861 if (walk_parameter_dep(params
[i
], param_func
, data
))
3865 params
= param_eval
->pres
.inputs
.inputs_param
;
3866 param_count
= param_eval
->pres
.inputs
.input_count
;
3867 for (i
= 0; i
< param_count
; ++i
)
3869 if (walk_parameter_dep(params
[i
], param_func
, data
))
3875 static BOOL
walk_state_dep(struct d3dx_state
*state
, walk_parameter_dep_func param_func
,
3878 if (state
->type
== ST_CONSTANT
&& is_param_type_sampler(state
->parameter
.type
))
3880 if (walk_parameter_dep(&state
->parameter
, param_func
, data
))
3883 else if (state
->type
== ST_ARRAY_SELECTOR
|| state
->type
== ST_PARAMETER
)
3885 if (walk_parameter_dep(state
->referenced_param
, param_func
, data
))
3888 return walk_param_eval_dep(state
->parameter
.param_eval
, param_func
, data
);
3891 static BOOL
walk_parameter_dep(struct d3dx_parameter
*param
, walk_parameter_dep_func param_func
,
3895 unsigned int member_count
;
3897 param
= ¶m
->top_level_param
->param
;
3898 if (param_func(data
, param
))
3901 if (walk_param_eval_dep(param
->param_eval
, param_func
, data
))
3904 if (param
->class == D3DXPC_OBJECT
&& is_param_type_sampler(param
->type
))
3906 struct d3dx_sampler
*sampler
;
3907 unsigned int sampler_idx
;
3908 unsigned int samplers_count
= max(param
->element_count
, 1);
3910 for (sampler_idx
= 0; sampler_idx
< samplers_count
; ++sampler_idx
)
3912 sampler
= param
->element_count
? param
->members
[sampler_idx
].data
: param
->data
;
3913 for (i
= 0; i
< sampler
->state_count
; ++i
)
3915 if (walk_state_dep(&sampler
->states
[i
], param_func
, data
))
3922 member_count
= param
->element_count
? param
->element_count
: param
->member_count
;
3923 for (i
= 0; i
< member_count
; ++i
)
3925 if (walk_param_eval_dep(param
->members
[i
].param_eval
, param_func
, data
))
3932 static BOOL
is_parameter_used(struct d3dx_parameter
*param
, struct d3dx_technique
*tech
)
3935 struct d3dx_pass
*pass
;
3937 if (!tech
|| !param
)
3940 for (i
= 0; i
< tech
->pass_count
; ++i
)
3942 pass
= &tech
->passes
[i
];
3943 for (j
= 0; j
< pass
->state_count
; ++j
)
3945 if (walk_state_dep(&pass
->states
[j
], is_same_parameter
, param
))
3952 static BOOL WINAPI
d3dx_effect_IsParameterUsed(ID3DXEffect
*iface
, D3DXHANDLE parameter
, D3DXHANDLE technique
)
3954 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3955 struct d3dx_parameter
*param
= get_valid_parameter(effect
, parameter
);
3956 struct d3dx_technique
*tech
= get_valid_technique(effect
, technique
);
3959 TRACE("iface %p, parameter %p, technique %p.\n", iface
, parameter
, technique
);
3960 TRACE("param %p, name %s, tech %p.\n", param
, param
? debugstr_a(param
->name
) : "", tech
);
3962 ret
= is_parameter_used(param
, tech
);
3963 TRACE("Returning %#x.\n", ret
);
3967 static HRESULT WINAPI
d3dx_effect_Begin(ID3DXEffect
*iface
, UINT
*passes
, DWORD flags
)
3969 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
3970 struct d3dx_technique
*technique
= effect
->active_technique
;
3972 TRACE("iface %p, passes %p, flags %#lx.\n", iface
, passes
, flags
);
3976 if (flags
& ~(D3DXFX_DONOTSAVESTATE
| D3DXFX_DONOTSAVESAMPLERSTATE
| D3DXFX_DONOTSAVESHADERSTATE
))
3977 WARN("Invalid flags %#lx specified.\n", flags
);
3979 if (flags
& D3DXFX_DONOTSAVESTATE
)
3981 TRACE("State capturing disabled.\n");
3988 if (!technique
->saved_state
)
3990 ID3DXEffectStateManager
*manager
;
3992 manager
= effect
->manager
;
3993 effect
->manager
= NULL
;
3994 if (FAILED(hr
= IDirect3DDevice9_BeginStateBlock(effect
->device
)))
3995 ERR("BeginStateBlock failed, hr %#lx.\n", hr
);
3996 for (i
= 0; i
< technique
->pass_count
; i
++)
3997 d3dx9_apply_pass_states(effect
, &technique
->passes
[i
], TRUE
);
3998 if (FAILED(hr
= IDirect3DDevice9_EndStateBlock(effect
->device
, &technique
->saved_state
)))
3999 ERR("EndStateBlock failed, hr %#lx.\n", hr
);
4000 effect
->manager
= manager
;
4002 if (FAILED(hr
= IDirect3DStateBlock9_Capture(technique
->saved_state
)))
4003 ERR("StateBlock Capture failed, hr %#lx.\n", hr
);
4007 *passes
= technique
->pass_count
;
4008 effect
->started
= TRUE
;
4009 effect
->begin_flags
= flags
;
4014 WARN("Invalid argument supplied.\n");
4016 return D3DERR_INVALIDCALL
;
4019 static HRESULT WINAPI
d3dx_effect_BeginPass(ID3DXEffect
*iface
, UINT pass
)
4021 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4022 struct d3dx_technique
*technique
= effect
->active_technique
;
4024 TRACE("iface %p, pass %u\n", effect
, pass
);
4026 if (!effect
->started
)
4028 WARN("Effect is not started, returning D3DERR_INVALIDCALL.\n");
4029 return D3DERR_INVALIDCALL
;
4032 if (technique
&& pass
< technique
->pass_count
&& !effect
->active_pass
)
4036 memset(effect
->current_light
, 0, sizeof(effect
->current_light
));
4037 memset(&effect
->current_material
, 0, sizeof(effect
->current_material
));
4039 if (SUCCEEDED(hr
= d3dx9_apply_pass_states(effect
, &technique
->passes
[pass
], TRUE
)))
4040 effect
->active_pass
= &technique
->passes
[pass
];
4044 WARN("Invalid argument supplied.\n");
4046 return D3DERR_INVALIDCALL
;
4049 static HRESULT WINAPI
d3dx_effect_CommitChanges(ID3DXEffect
*iface
)
4051 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4053 TRACE("iface %p.\n", iface
);
4055 if (!effect
->active_pass
)
4057 WARN("Called without an active pass.\n");
4060 return d3dx9_apply_pass_states(effect
, effect
->active_pass
, FALSE
);
4063 static HRESULT WINAPI
d3dx_effect_EndPass(ID3DXEffect
*iface
)
4065 struct d3dx_effect
*This
= impl_from_ID3DXEffect(iface
);
4067 TRACE("iface %p\n", This
);
4069 if (This
->active_pass
)
4071 This
->active_pass
= NULL
;
4075 WARN("Invalid call.\n");
4077 return D3DERR_INVALIDCALL
;
4080 static HRESULT WINAPI
d3dx_effect_End(ID3DXEffect
*iface
)
4082 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4083 struct d3dx_technique
*technique
= effect
->active_technique
;
4085 TRACE("iface %p.\n", iface
);
4087 if (!effect
->started
)
4090 if (effect
->begin_flags
& D3DXFX_DONOTSAVESTATE
)
4092 TRACE("State restoring disabled.\n");
4098 if (technique
&& technique
->saved_state
)
4100 if (FAILED(hr
= IDirect3DStateBlock9_Apply(technique
->saved_state
)))
4101 ERR("State block apply failed, hr %#lx.\n", hr
);
4104 ERR("No saved state.\n");
4107 effect
->started
= FALSE
;
4112 static HRESULT WINAPI
d3dx_effect_GetDevice(ID3DXEffect
*iface
, struct IDirect3DDevice9
**device
)
4114 struct d3dx_effect
*This
= impl_from_ID3DXEffect(iface
);
4116 TRACE("iface %p, device %p\n", This
, device
);
4120 WARN("Invalid argument supplied.\n");
4121 return D3DERR_INVALIDCALL
;
4124 IDirect3DDevice9_AddRef(This
->device
);
4126 *device
= This
->device
;
4128 TRACE("Returning device %p\n", *device
);
4133 static BOOL
param_on_lost_device(void *data
, struct d3dx_parameter
*param
)
4135 struct IDirect3DVolumeTexture9
*volume_texture
;
4136 struct IDirect3DCubeTexture9
*cube_texture
;
4137 struct IDirect3DTexture9
*texture
;
4138 D3DSURFACE_DESC surface_desc
;
4139 D3DVOLUME_DESC volume_desc
;
4141 if (param
->class == D3DXPC_OBJECT
&& !param
->element_count
)
4143 switch (param
->type
)
4145 case D3DXPT_TEXTURE
:
4146 case D3DXPT_TEXTURE1D
:
4147 case D3DXPT_TEXTURE2D
:
4148 texture
= *(IDirect3DTexture9
**)param
->data
;
4151 IDirect3DTexture9_GetLevelDesc(texture
, 0, &surface_desc
);
4152 if (surface_desc
.Pool
!= D3DPOOL_DEFAULT
)
4155 case D3DXPT_TEXTURE3D
:
4156 volume_texture
= *(IDirect3DVolumeTexture9
**)param
->data
;
4157 if (!volume_texture
)
4159 IDirect3DVolumeTexture9_GetLevelDesc(volume_texture
, 0, &volume_desc
);
4160 if (volume_desc
.Pool
!= D3DPOOL_DEFAULT
)
4163 case D3DXPT_TEXTURECUBE
:
4164 cube_texture
= *(IDirect3DCubeTexture9
**)param
->data
;
4167 IDirect3DTexture9_GetLevelDesc(cube_texture
, 0, &surface_desc
);
4168 if (surface_desc
.Pool
!= D3DPOOL_DEFAULT
)
4174 IUnknown_Release(*(IUnknown
**)param
->data
);
4175 *(IUnknown
**)param
->data
= NULL
;
4180 static HRESULT WINAPI
d3dx_effect_OnLostDevice(ID3DXEffect
*iface
)
4182 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4185 TRACE("iface %p.\n", iface
);
4187 for (i
= 0; i
< effect
->params
.count
; ++i
)
4188 walk_parameter_tree(&effect
->params
.parameters
[i
].param
, param_on_lost_device
, NULL
);
4193 static HRESULT WINAPI
d3dx_effect_OnResetDevice(ID3DXEffect
*iface
)
4195 struct d3dx_effect
*This
= impl_from_ID3DXEffect(iface
);
4197 FIXME("(%p)->(): stub\n", This
);
4202 static HRESULT WINAPI
d3dx_effect_SetStateManager(ID3DXEffect
*iface
, ID3DXEffectStateManager
*manager
)
4204 struct d3dx_effect
*This
= impl_from_ID3DXEffect(iface
);
4206 TRACE("iface %p, manager %p\n", This
, manager
);
4208 if (manager
) IUnknown_AddRef(manager
);
4209 if (This
->manager
) IUnknown_Release(This
->manager
);
4211 This
->manager
= manager
;
4216 static HRESULT WINAPI
d3dx_effect_GetStateManager(ID3DXEffect
*iface
, ID3DXEffectStateManager
**manager
)
4218 struct d3dx_effect
*This
= impl_from_ID3DXEffect(iface
);
4220 TRACE("iface %p, manager %p\n", This
, manager
);
4224 WARN("Invalid argument supplied.\n");
4225 return D3DERR_INVALIDCALL
;
4228 if (This
->manager
) IUnknown_AddRef(This
->manager
);
4229 *manager
= This
->manager
;
4234 static HRESULT WINAPI
d3dx_effect_BeginParameterBlock(ID3DXEffect
*iface
)
4236 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4238 TRACE("iface %p.\n", iface
);
4240 if (effect
->current_parameter_block
)
4242 WARN("Parameter block is already started.\n");
4243 return D3DERR_INVALIDCALL
;
4246 effect
->current_parameter_block
= calloc(1, sizeof(*effect
->current_parameter_block
));
4247 memcpy(effect
->current_parameter_block
->magic_string
, parameter_block_magic_string
,
4248 sizeof(parameter_block_magic_string
));
4249 effect
->current_parameter_block
->effect
= effect
;
4254 static D3DXHANDLE WINAPI
d3dx_effect_EndParameterBlock(ID3DXEffect
*iface
)
4256 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4257 struct d3dx_parameter_block
*ret
;
4260 TRACE("iface %p.\n", iface
);
4262 if (!effect
->current_parameter_block
)
4264 WARN("No active parameter block.\n");
4267 ret
= effect
->current_parameter_block
;
4269 new_buffer
= realloc(ret
->buffer
, ret
->offset
);
4271 ret
->buffer
= new_buffer
;
4272 ret
->size
= ret
->offset
;
4274 effect
->current_parameter_block
= NULL
;
4275 list_add_tail(&effect
->parameter_block_list
, &ret
->entry
);
4276 return (D3DXHANDLE
)ret
;
4279 static HRESULT WINAPI
d3dx_effect_ApplyParameterBlock(ID3DXEffect
*iface
, D3DXHANDLE parameter_block
)
4281 struct d3dx_parameter_block
*block
= get_valid_parameter_block(parameter_block
);
4282 struct d3dx_recorded_parameter
*record
;
4284 TRACE("iface %p, parameter_block %p.\n", iface
, parameter_block
);
4286 if (!block
|| !block
->offset
)
4287 return D3DERR_INVALIDCALL
;
4289 record
= (struct d3dx_recorded_parameter
*)block
->buffer
;
4290 while ((BYTE
*)record
< block
->buffer
+ block
->offset
)
4292 set_value(record
->param
, record
+ 1, record
->bytes
,
4293 param_get_data_and_dirtify(block
->effect
, record
->param
, record
->bytes
, TRUE
));
4294 record
= (struct d3dx_recorded_parameter
*)((BYTE
*)record
+ get_recorded_parameter_size(record
));
4296 assert((BYTE
*)record
== block
->buffer
+ block
->offset
);
4300 #if D3DX_SDK_VERSION >= 26
4301 static HRESULT WINAPI
d3dx_effect_DeleteParameterBlock(ID3DXEffect
*iface
, D3DXHANDLE parameter_block
)
4303 struct d3dx_parameter_block
*block
= get_valid_parameter_block(parameter_block
);
4304 struct d3dx_effect
*effect
= impl_from_ID3DXEffect(iface
);
4305 struct d3dx_parameter_block
*b
;
4307 TRACE("iface %p, parameter_block %p.\n", iface
, parameter_block
);
4310 return D3DERR_INVALIDCALL
;
4312 LIST_FOR_EACH_ENTRY(b
, &effect
->parameter_block_list
, struct d3dx_parameter_block
, entry
)
4316 list_remove(&b
->entry
);
4317 free_parameter_block(b
);
4322 WARN("Block is not found in issued block list, not freeing memory.\n");
4323 return D3DERR_INVALIDCALL
;
4327 static bool copy_parameter(struct d3dx_effect
*dst_effect
, const struct d3dx_effect
*src_effect
,
4328 struct d3dx_parameter
*dst
, const struct d3dx_parameter
*src
)
4332 if ((src
->flags
& PARAMETER_FLAG_SHARED
) && dst_effect
->pool
)
4341 memcpy(dst
->data
, src
->data
, src
->bytes
);
4345 free(*(char **)dst
->data
);
4346 if (!(*(char **)dst
->data
= strdup(*(char **)src
->data
)))
4350 case D3DXPT_TEXTURE
:
4351 case D3DXPT_TEXTURE1D
:
4352 case D3DXPT_TEXTURE2D
:
4353 case D3DXPT_TEXTURE3D
:
4354 case D3DXPT_TEXTURECUBE
:
4355 case D3DXPT_PIXELSHADER
:
4356 case D3DXPT_VERTEXSHADER
:
4357 iface
= *(IUnknown
**)src
->data
;
4358 if (src_effect
->device
== dst_effect
->device
&& iface
)
4360 if (*(IUnknown
**)dst
->data
)
4361 IUnknown_Release(*(IUnknown
**)dst
->data
);
4362 IUnknown_AddRef(iface
);
4363 *(IUnknown
**)dst
->data
= iface
;
4367 case D3DXPT_SAMPLER
:
4368 case D3DXPT_SAMPLER1D
:
4369 case D3DXPT_SAMPLER2D
:
4370 case D3DXPT_SAMPLER3D
:
4371 case D3DXPT_SAMPLERCUBE
:
4372 /* Nothing to do; these parameters are not mutable and cannot be
4373 * retrieved using API calls. */
4377 FIXME("Unhandled parameter type %#x.\n", src
->type
);
4383 static HRESULT WINAPI
d3dx_effect_CloneEffect(ID3DXEffect
*iface
, IDirect3DDevice9
*device
, ID3DXEffect
**out
)
4385 struct d3dx_effect
*src
= impl_from_ID3DXEffect(iface
);
4386 struct d3dx_effect
*dst
;
4387 unsigned int i
, j
, k
;
4390 TRACE("iface %p, device %p, out %p.\n", iface
, device
, out
);
4393 return D3DERR_INVALIDCALL
;
4395 if (src
->flags
& D3DXFX_NOT_CLONEABLE
)
4399 return D3DERR_INVALIDCALL
;
4401 if (!(dst
= calloc(1, sizeof(*dst
))))
4402 return E_OUTOFMEMORY
;
4404 if (FAILED(hr
= d3dx9_effect_init_from_binary(dst
, device
, src
->source
, src
->source_size
,
4405 src
->flags
, &src
->pool
->ID3DXEffectPool_iface
, src
->skip_constants_string
)))
4411 for (i
= 0; i
< src
->params
.count
; ++i
)
4413 const struct d3dx_top_level_parameter
*src_param
= &src
->params
.parameters
[i
];
4414 struct d3dx_top_level_parameter
*dst_param
= &dst
->params
.parameters
[i
];
4416 copy_parameter(dst
, src
, &dst_param
->param
, &src_param
->param
);
4417 for (j
= 0; j
< src_param
->annotation_count
; ++j
)
4418 copy_parameter(dst
, src
, &dst_param
->annotations
[j
], &src_param
->annotations
[j
]);
4421 for (i
= 0; i
< src
->technique_count
; ++i
)
4423 const struct d3dx_technique
*src_technique
= &src
->techniques
[i
];
4424 struct d3dx_technique
*dst_technique
= &dst
->techniques
[i
];
4426 for (j
= 0; j
< src_technique
->annotation_count
; ++j
)
4427 copy_parameter(dst
, src
, &dst_technique
->annotations
[j
], &src_technique
->annotations
[j
]);
4429 for (j
= 0; j
< src_technique
->pass_count
; ++j
)
4431 const struct d3dx_pass
*src_pass
= &src_technique
->passes
[j
];
4432 struct d3dx_pass
*dst_pass
= &dst_technique
->passes
[j
];
4434 for (k
= 0; k
< src_pass
->annotation_count
; ++k
)
4435 copy_parameter(dst
, src
, &dst_pass
->annotations
[k
], &src_pass
->annotations
[k
]);
4439 *out
= &dst
->ID3DXEffect_iface
;
4440 TRACE("Created effect %p.\n", dst
);
4444 #if D3DX_SDK_VERSION >= 27
4445 static HRESULT WINAPI
d3dx_effect_SetRawValue(ID3DXEffect
*iface
, D3DXHANDLE parameter
, const void *data
,
4446 UINT byte_offset
, UINT bytes
)
4448 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
4449 iface
, parameter
, data
, byte_offset
, bytes
);
4455 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl
=
4457 /*** IUnknown methods ***/
4458 d3dx_effect_QueryInterface
,
4460 d3dx_effect_Release
,
4461 /*** ID3DXBaseEffect methods ***/
4462 d3dx_effect_GetDesc
,
4463 d3dx_effect_GetParameterDesc
,
4464 d3dx_effect_GetTechniqueDesc
,
4465 d3dx_effect_GetPassDesc
,
4466 d3dx_effect_GetFunctionDesc
,
4467 d3dx_effect_GetParameter
,
4468 d3dx_effect_GetParameterByName
,
4469 d3dx_effect_GetParameterBySemantic
,
4470 d3dx_effect_GetParameterElement
,
4471 d3dx_effect_GetTechnique
,
4472 d3dx_effect_GetTechniqueByName
,
4473 d3dx_effect_GetPass
,
4474 d3dx_effect_GetPassByName
,
4475 d3dx_effect_GetFunction
,
4476 d3dx_effect_GetFunctionByName
,
4477 d3dx_effect_GetAnnotation
,
4478 d3dx_effect_GetAnnotationByName
,
4479 d3dx_effect_SetValue
,
4480 d3dx_effect_GetValue
,
4481 d3dx_effect_SetBool
,
4482 d3dx_effect_GetBool
,
4483 d3dx_effect_SetBoolArray
,
4484 d3dx_effect_GetBoolArray
,
4487 d3dx_effect_SetIntArray
,
4488 d3dx_effect_GetIntArray
,
4489 d3dx_effect_SetFloat
,
4490 d3dx_effect_GetFloat
,
4491 d3dx_effect_SetFloatArray
,
4492 d3dx_effect_GetFloatArray
,
4493 d3dx_effect_SetVector
,
4494 d3dx_effect_GetVector
,
4495 d3dx_effect_SetVectorArray
,
4496 d3dx_effect_GetVectorArray
,
4497 d3dx_effect_SetMatrix
,
4498 d3dx_effect_GetMatrix
,
4499 d3dx_effect_SetMatrixArray
,
4500 d3dx_effect_GetMatrixArray
,
4501 d3dx_effect_SetMatrixPointerArray
,
4502 d3dx_effect_GetMatrixPointerArray
,
4503 d3dx_effect_SetMatrixTranspose
,
4504 d3dx_effect_GetMatrixTranspose
,
4505 d3dx_effect_SetMatrixTransposeArray
,
4506 d3dx_effect_GetMatrixTransposeArray
,
4507 d3dx_effect_SetMatrixTransposePointerArray
,
4508 d3dx_effect_GetMatrixTransposePointerArray
,
4509 d3dx_effect_SetString
,
4510 d3dx_effect_GetString
,
4511 d3dx_effect_SetTexture
,
4512 d3dx_effect_GetTexture
,
4513 d3dx_effect_GetPixelShader
,
4514 d3dx_effect_GetVertexShader
,
4515 d3dx_effect_SetArrayRange
,
4516 /*** ID3DXEffect methods ***/
4517 d3dx_effect_GetPool
,
4518 d3dx_effect_SetTechnique
,
4519 d3dx_effect_GetCurrentTechnique
,
4520 d3dx_effect_ValidateTechnique
,
4521 d3dx_effect_FindNextValidTechnique
,
4522 d3dx_effect_IsParameterUsed
,
4524 d3dx_effect_BeginPass
,
4525 d3dx_effect_CommitChanges
,
4526 d3dx_effect_EndPass
,
4528 d3dx_effect_GetDevice
,
4529 d3dx_effect_OnLostDevice
,
4530 d3dx_effect_OnResetDevice
,
4531 d3dx_effect_SetStateManager
,
4532 d3dx_effect_GetStateManager
,
4533 d3dx_effect_BeginParameterBlock
,
4534 d3dx_effect_EndParameterBlock
,
4535 d3dx_effect_ApplyParameterBlock
,
4536 #if D3DX_SDK_VERSION >= 26
4537 d3dx_effect_DeleteParameterBlock
,
4539 d3dx_effect_CloneEffect
,
4540 #if D3DX_SDK_VERSION >= 27
4541 d3dx_effect_SetRawValue
4545 static inline struct ID3DXEffectCompilerImpl
*impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler
*iface
)
4547 return CONTAINING_RECORD(iface
, struct ID3DXEffectCompilerImpl
, ID3DXEffectCompiler_iface
);
4550 /*** IUnknown methods ***/
4551 static HRESULT WINAPI
ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler
*iface
, REFIID riid
, void **object
)
4553 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
4555 if (IsEqualGUID(riid
, &IID_IUnknown
)
4556 || IsEqualGUID(riid
, &IID_ID3DXEffectCompiler
))
4558 iface
->lpVtbl
->AddRef(iface
);
4563 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
4566 return E_NOINTERFACE
;
4569 static ULONG WINAPI
ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler
*iface
)
4571 struct ID3DXEffectCompilerImpl
*compiler
= impl_from_ID3DXEffectCompiler(iface
);
4572 ULONG refcount
= InterlockedIncrement(&compiler
->ref
);
4574 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
4579 static ULONG WINAPI
ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler
*iface
)
4581 struct ID3DXEffectCompilerImpl
*compiler
= impl_from_ID3DXEffectCompiler(iface
);
4582 ULONG refcount
= InterlockedDecrement(&compiler
->ref
);
4584 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
4594 /*** ID3DXBaseEffect methods ***/
4595 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler
*iface
, D3DXEFFECT_DESC
*desc
)
4597 FIXME("iface %p, desc %p stub!\n", iface
, desc
);
4602 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler
*iface
,
4603 D3DXHANDLE parameter
, D3DXPARAMETER_DESC
*desc
)
4605 FIXME("iface %p, parameter %p, desc %p stub!\n", iface
, parameter
, desc
);
4610 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler
*iface
,
4611 D3DXHANDLE technique
, D3DXTECHNIQUE_DESC
*desc
)
4613 FIXME("iface %p, technique %p, desc %p stub!\n", iface
, technique
, desc
);
4618 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler
*iface
,
4619 D3DXHANDLE pass
, D3DXPASS_DESC
*desc
)
4621 FIXME("iface %p, pass %p, desc %p stub!\n", iface
, pass
, desc
);
4626 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler
*iface
,
4627 D3DXHANDLE shader
, D3DXFUNCTION_DESC
*desc
)
4629 FIXME("iface %p, shader %p, desc %p stub!\n", iface
, shader
, desc
);
4634 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler
*iface
,
4635 D3DXHANDLE parameter
, UINT index
)
4637 FIXME("iface %p, parameter %p, index %u stub!\n", iface
, parameter
, index
);
4642 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler
*iface
,
4643 D3DXHANDLE parameter
, const char *name
)
4645 FIXME("iface %p, parameter %p, name %s stub!\n", iface
, parameter
, debugstr_a(name
));
4650 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler
*iface
,
4651 D3DXHANDLE parameter
, const char *semantic
)
4653 FIXME("iface %p, parameter %p, semantic %s stub!\n", iface
, parameter
, debugstr_a(semantic
));
4658 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler
*iface
,
4659 D3DXHANDLE parameter
, UINT index
)
4661 FIXME("iface %p, parameter %p, index %u stub!\n", iface
, parameter
, index
);
4666 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler
*iface
, UINT index
)
4668 FIXME("iface %p, index %u stub!\n", iface
, index
);
4673 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler
*iface
, const char *name
)
4675 FIXME("iface %p, name %s stub!\n", iface
, debugstr_a(name
));
4680 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler
*iface
, D3DXHANDLE technique
, UINT index
)
4682 FIXME("iface %p, technique %p, index %u stub!\n", iface
, technique
, index
);
4687 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler
*iface
,
4688 D3DXHANDLE technique
, const char *name
)
4690 FIXME("iface %p, technique %p, name %s stub!\n", iface
, technique
, debugstr_a(name
));
4695 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler
*iface
, UINT index
)
4697 FIXME("iface %p, index %u stub!\n", iface
, index
);
4702 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler
*iface
, const char *name
)
4704 FIXME("iface %p, name %s stub!\n", iface
, debugstr_a(name
));
4709 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler
*iface
,
4710 D3DXHANDLE object
, UINT index
)
4712 FIXME("iface %p, object %p, index %u stub!\n", iface
, object
, index
);
4717 static D3DXHANDLE WINAPI
ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler
*iface
,
4718 D3DXHANDLE object
, const char *name
)
4720 FIXME("iface %p, object %p, name %s stub!\n", iface
, object
, debugstr_a(name
));
4725 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler
*iface
,
4726 D3DXHANDLE parameter
, const void *data
, UINT bytes
)
4728 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface
, parameter
, data
, bytes
);
4733 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler
*iface
,
4734 D3DXHANDLE parameter
, void *data
, UINT bytes
)
4736 FIXME("iface %p, parameter %p, data %p, bytes %u stub!\n", iface
, parameter
, data
, bytes
);
4741 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, BOOL b
)
4743 FIXME("iface %p, parameter %p, b %#x stub!\n", iface
, parameter
, b
);
4748 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, BOOL
*b
)
4750 FIXME("iface %p, parameter %p, b %p stub!\n", iface
, parameter
, b
);
4755 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler
*iface
,
4756 D3DXHANDLE parameter
, const BOOL
*b
, UINT count
)
4758 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface
, parameter
, b
, count
);
4763 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler
*iface
,
4764 D3DXHANDLE parameter
, BOOL
*b
, UINT count
)
4766 FIXME("iface %p, parameter %p, b %p, count %u stub!\n", iface
, parameter
, b
, count
);
4771 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, INT n
)
4773 FIXME("iface %p, parameter %p, n %d stub!\n", iface
, parameter
, n
);
4778 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, INT
*n
)
4780 FIXME("iface %p, parameter %p, n %p stub!\n", iface
, parameter
, n
);
4785 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler
*iface
,
4786 D3DXHANDLE parameter
, const INT
*n
, UINT count
)
4788 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface
, parameter
, n
, count
);
4793 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler
*iface
,
4794 D3DXHANDLE parameter
, INT
*n
, UINT count
)
4796 FIXME("iface %p, parameter %p, n %p, count %u stub!\n", iface
, parameter
, n
, count
);
4801 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, float f
)
4803 FIXME("iface %p, parameter %p, f %.8e stub!\n", iface
, parameter
, f
);
4808 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, float *f
)
4810 FIXME("iface %p, parameter %p, f %p stub!\n", iface
, parameter
, f
);
4815 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler
*iface
,
4816 D3DXHANDLE parameter
, const float *f
, UINT count
)
4818 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface
, parameter
, f
, count
);
4823 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler
*iface
,
4824 D3DXHANDLE parameter
, float *f
, UINT count
)
4826 FIXME("iface %p, parameter %p, f %p, count %u stub!\n", iface
, parameter
, f
, count
);
4831 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler
*iface
,
4832 D3DXHANDLE parameter
, const D3DXVECTOR4
*vector
)
4834 FIXME("iface %p, parameter %p, vector %p stub!\n", iface
, parameter
, vector
);
4839 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler
*iface
,
4840 D3DXHANDLE parameter
, D3DXVECTOR4
*vector
)
4842 FIXME("iface %p, parameter %p, vector %p stub!\n", iface
, parameter
, vector
);
4847 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler
*iface
,
4848 D3DXHANDLE parameter
, const D3DXVECTOR4
*vector
, UINT count
)
4850 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface
, parameter
, vector
, count
);
4855 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler
*iface
,
4856 D3DXHANDLE parameter
, D3DXVECTOR4
*vector
, UINT count
)
4858 FIXME("iface %p, parameter %p, vector %p, count %u stub!\n", iface
, parameter
, vector
, count
);
4863 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler
*iface
,
4864 D3DXHANDLE parameter
, const D3DXMATRIX
*matrix
)
4866 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface
, parameter
, matrix
);
4871 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler
*iface
,
4872 D3DXHANDLE parameter
, D3DXMATRIX
*matrix
)
4874 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface
, parameter
, matrix
);
4879 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler
*iface
,
4880 D3DXHANDLE parameter
, const D3DXMATRIX
*matrix
, UINT count
)
4882 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4887 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler
*iface
,
4888 D3DXHANDLE parameter
, D3DXMATRIX
*matrix
, UINT count
)
4890 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4895 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler
*iface
,
4896 D3DXHANDLE parameter
, const D3DXMATRIX
**matrix
, UINT count
)
4898 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4903 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler
*iface
,
4904 D3DXHANDLE parameter
, D3DXMATRIX
**matrix
, UINT count
)
4906 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4911 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler
*iface
,
4912 D3DXHANDLE parameter
, const D3DXMATRIX
*matrix
)
4914 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface
, parameter
, matrix
);
4919 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler
*iface
,
4920 D3DXHANDLE parameter
, D3DXMATRIX
*matrix
)
4922 FIXME("iface %p, parameter %p, matrix %p stub!\n", iface
, parameter
, matrix
);
4927 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler
*iface
,
4928 D3DXHANDLE parameter
, const D3DXMATRIX
*matrix
, UINT count
)
4930 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4935 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler
*iface
,
4936 D3DXHANDLE parameter
, D3DXMATRIX
*matrix
, UINT count
)
4938 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4943 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler
*iface
,
4944 D3DXHANDLE parameter
, const D3DXMATRIX
**matrix
, UINT count
)
4946 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4951 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler
*iface
,
4952 D3DXHANDLE parameter
, D3DXMATRIX
**matrix
, UINT count
)
4954 FIXME("iface %p, parameter %p, matrix %p, count %u stub!\n", iface
, parameter
, matrix
, count
);
4959 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler
*iface
,
4960 D3DXHANDLE parameter
, const char *string
)
4962 FIXME("iface %p, parameter %p, string %s stub!\n", iface
, parameter
, debugstr_a(string
));
4967 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler
*iface
,
4968 D3DXHANDLE parameter
, const char **string
)
4970 FIXME("iface %p, parameter %p, string %p stub!\n", iface
, parameter
, string
);
4975 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler
*iface
,
4976 D3DXHANDLE parameter
, struct IDirect3DBaseTexture9
*texture
)
4978 FIXME("iface %p, parameter %p, texture %p stub!\n", iface
, parameter
, texture
);
4983 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler
*iface
,
4984 D3DXHANDLE parameter
, struct IDirect3DBaseTexture9
**texture
)
4986 FIXME("iface %p, parameter %p, texture %p stub!\n", iface
, parameter
, texture
);
4991 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler
*iface
,
4992 D3DXHANDLE parameter
, struct IDirect3DPixelShader9
**shader
)
4994 FIXME("iface %p, parameter %p, shader %p stub!\n", iface
, parameter
, shader
);
4999 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler
*iface
,
5000 D3DXHANDLE parameter
, struct IDirect3DVertexShader9
**shader
)
5002 FIXME("iface %p, parameter %p, shader %p stub!\n", iface
, parameter
, shader
);
5007 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler
*iface
,
5008 D3DXHANDLE parameter
, UINT start
, UINT end
)
5010 FIXME("iface %p, parameter %p, start %u, end %u stub!\n", iface
, parameter
, start
, end
);
5015 /*** ID3DXEffectCompiler methods ***/
5016 static HRESULT WINAPI
ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, BOOL literal
)
5018 FIXME("iface %p, parameter %p, literal %#x stub!\n", iface
, parameter
, literal
);
5023 static HRESULT WINAPI
ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler
*iface
, D3DXHANDLE parameter
, BOOL
*literal
)
5025 FIXME("iface %p, parameter %p, literal %p stub!\n", iface
, parameter
, literal
);
5030 static HRESULT WINAPI
ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler
*iface
, DWORD flags
,
5031 ID3DXBuffer
**effect
, ID3DXBuffer
**error_msgs
)
5033 FIXME("iface %p, flags %#lx, effect %p, error_msgs %p stub!\n", iface
, flags
, effect
, error_msgs
);
5038 static HRESULT WINAPI
ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler
*iface
, D3DXHANDLE function
,
5039 const char *target
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
,
5040 ID3DXConstantTable
**constant_table
)
5042 FIXME("iface %p, function %p, target %s, flags %#lx, shader %p, error_msgs %p, constant_table %p stub!\n",
5043 iface
, function
, debugstr_a(target
), flags
, shader
, error_msgs
, constant_table
);
5048 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl
=
5050 /*** IUnknown methods ***/
5051 ID3DXEffectCompilerImpl_QueryInterface
,
5052 ID3DXEffectCompilerImpl_AddRef
,
5053 ID3DXEffectCompilerImpl_Release
,
5054 /*** ID3DXBaseEffect methods ***/
5055 ID3DXEffectCompilerImpl_GetDesc
,
5056 ID3DXEffectCompilerImpl_GetParameterDesc
,
5057 ID3DXEffectCompilerImpl_GetTechniqueDesc
,
5058 ID3DXEffectCompilerImpl_GetPassDesc
,
5059 ID3DXEffectCompilerImpl_GetFunctionDesc
,
5060 ID3DXEffectCompilerImpl_GetParameter
,
5061 ID3DXEffectCompilerImpl_GetParameterByName
,
5062 ID3DXEffectCompilerImpl_GetParameterBySemantic
,
5063 ID3DXEffectCompilerImpl_GetParameterElement
,
5064 ID3DXEffectCompilerImpl_GetTechnique
,
5065 ID3DXEffectCompilerImpl_GetTechniqueByName
,
5066 ID3DXEffectCompilerImpl_GetPass
,
5067 ID3DXEffectCompilerImpl_GetPassByName
,
5068 ID3DXEffectCompilerImpl_GetFunction
,
5069 ID3DXEffectCompilerImpl_GetFunctionByName
,
5070 ID3DXEffectCompilerImpl_GetAnnotation
,
5071 ID3DXEffectCompilerImpl_GetAnnotationByName
,
5072 ID3DXEffectCompilerImpl_SetValue
,
5073 ID3DXEffectCompilerImpl_GetValue
,
5074 ID3DXEffectCompilerImpl_SetBool
,
5075 ID3DXEffectCompilerImpl_GetBool
,
5076 ID3DXEffectCompilerImpl_SetBoolArray
,
5077 ID3DXEffectCompilerImpl_GetBoolArray
,
5078 ID3DXEffectCompilerImpl_SetInt
,
5079 ID3DXEffectCompilerImpl_GetInt
,
5080 ID3DXEffectCompilerImpl_SetIntArray
,
5081 ID3DXEffectCompilerImpl_GetIntArray
,
5082 ID3DXEffectCompilerImpl_SetFloat
,
5083 ID3DXEffectCompilerImpl_GetFloat
,
5084 ID3DXEffectCompilerImpl_SetFloatArray
,
5085 ID3DXEffectCompilerImpl_GetFloatArray
,
5086 ID3DXEffectCompilerImpl_SetVector
,
5087 ID3DXEffectCompilerImpl_GetVector
,
5088 ID3DXEffectCompilerImpl_SetVectorArray
,
5089 ID3DXEffectCompilerImpl_GetVectorArray
,
5090 ID3DXEffectCompilerImpl_SetMatrix
,
5091 ID3DXEffectCompilerImpl_GetMatrix
,
5092 ID3DXEffectCompilerImpl_SetMatrixArray
,
5093 ID3DXEffectCompilerImpl_GetMatrixArray
,
5094 ID3DXEffectCompilerImpl_SetMatrixPointerArray
,
5095 ID3DXEffectCompilerImpl_GetMatrixPointerArray
,
5096 ID3DXEffectCompilerImpl_SetMatrixTranspose
,
5097 ID3DXEffectCompilerImpl_GetMatrixTranspose
,
5098 ID3DXEffectCompilerImpl_SetMatrixTransposeArray
,
5099 ID3DXEffectCompilerImpl_GetMatrixTransposeArray
,
5100 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray
,
5101 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray
,
5102 ID3DXEffectCompilerImpl_SetString
,
5103 ID3DXEffectCompilerImpl_GetString
,
5104 ID3DXEffectCompilerImpl_SetTexture
,
5105 ID3DXEffectCompilerImpl_GetTexture
,
5106 ID3DXEffectCompilerImpl_GetPixelShader
,
5107 ID3DXEffectCompilerImpl_GetVertexShader
,
5108 ID3DXEffectCompilerImpl_SetArrayRange
,
5109 /*** ID3DXEffectCompiler methods ***/
5110 ID3DXEffectCompilerImpl_SetLiteral
,
5111 ID3DXEffectCompilerImpl_GetLiteral
,
5112 ID3DXEffectCompilerImpl_CompileEffect
,
5113 ID3DXEffectCompilerImpl_CompileShader
,
5116 static HRESULT
d3dx_parse_sampler(struct d3dx_effect
*effect
, struct d3dx_sampler
*sampler
,
5117 const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5122 sampler
->state_count
= read_u32(ptr
);
5123 TRACE("Count: %u\n", sampler
->state_count
);
5125 sampler
->states
= calloc(sampler
->state_count
, sizeof(*sampler
->states
));
5126 if (!sampler
->states
)
5128 ERR("Out of memory\n");
5129 return E_OUTOFMEMORY
;
5132 for (i
= 0; i
< sampler
->state_count
; ++i
)
5134 hr
= d3dx_parse_state(effect
, &sampler
->states
[i
], data
, ptr
, objects
);
5137 WARN("Failed to parse state %u\n", i
);
5146 for (i
= 0; i
< sampler
->state_count
; ++i
)
5148 free_state(&sampler
->states
[i
]);
5150 free(sampler
->states
);
5151 sampler
->states
= NULL
;
5156 static HRESULT
d3dx_parse_value(struct d3dx_effect
*effect
, struct d3dx_parameter
*param
,
5157 void *value
, const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5163 if (param
->element_count
)
5165 param
->data
= value
;
5167 for (i
= 0; i
< param
->element_count
; ++i
)
5169 struct d3dx_parameter
*member
= ¶m
->members
[i
];
5171 hr
= d3dx_parse_value(effect
, member
, value
? (char *)value
+ old_size
: NULL
, data
, ptr
, objects
);
5174 WARN("Failed to parse value %u\n", i
);
5178 old_size
+= member
->bytes
;
5184 switch(param
->class)
5188 case D3DXPC_MATRIX_ROWS
:
5189 case D3DXPC_MATRIX_COLUMNS
:
5190 param
->data
= value
;
5194 param
->data
= value
;
5196 for (i
= 0; i
< param
->member_count
; ++i
)
5198 struct d3dx_parameter
*member
= ¶m
->members
[i
];
5200 hr
= d3dx_parse_value(effect
, member
, (char *)value
+ old_size
, data
, ptr
, objects
);
5203 WARN("Failed to parse value %u\n", i
);
5207 old_size
+= member
->bytes
;
5212 switch (param
->type
)
5215 case D3DXPT_TEXTURE
:
5216 case D3DXPT_TEXTURE1D
:
5217 case D3DXPT_TEXTURE2D
:
5218 case D3DXPT_TEXTURE3D
:
5219 case D3DXPT_TEXTURECUBE
:
5220 case D3DXPT_PIXELSHADER
:
5221 case D3DXPT_VERTEXSHADER
:
5222 param
->object_id
= read_u32(ptr
);
5223 TRACE("Id: %u\n", param
->object_id
);
5224 objects
[param
->object_id
].param
= param
;
5225 param
->data
= value
;
5228 case D3DXPT_SAMPLER
:
5229 case D3DXPT_SAMPLER1D
:
5230 case D3DXPT_SAMPLER2D
:
5231 case D3DXPT_SAMPLER3D
:
5232 case D3DXPT_SAMPLERCUBE
:
5234 struct d3dx_sampler
*sampler
;
5236 sampler
= calloc(1, sizeof(*sampler
));
5238 return E_OUTOFMEMORY
;
5240 hr
= d3dx_parse_sampler(effect
, sampler
, data
, ptr
, objects
);
5244 WARN("Failed to parse sampler\n");
5248 param
->data
= sampler
;
5253 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param
->type
));
5259 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param
->class));
5266 static HRESULT
d3dx_parse_init_value(struct d3dx_effect
*effect
, struct d3dx_parameter
*param
,
5267 const char *data
, const char *ptr
, struct d3dx_object
*objects
)
5269 UINT size
= param
->bytes
;
5273 TRACE("param size: %u\n", size
);
5277 value
= calloc(1, size
);
5280 ERR("Failed to allocate data memory.\n");
5281 return E_OUTOFMEMORY
;
5284 switch(param
->class)
5291 case D3DXPC_MATRIX_ROWS
:
5292 case D3DXPC_MATRIX_COLUMNS
:
5294 TRACE("Data: %s.\n", debugstr_an(ptr
, size
));
5295 memcpy(value
, ptr
, size
);
5299 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param
->class));
5304 hr
= d3dx_parse_value(effect
, param
, value
, data
, &ptr
, objects
);
5307 WARN("Failed to parse value\n");
5315 static HRESULT
d3dx9_parse_name(char **name
, const char *ptr
)
5319 size
= read_u32(&ptr
);
5320 TRACE("Name size: %#x.\n", size
);
5327 *name
= malloc(size
);
5330 ERR("Failed to allocate name memory.\n");
5331 return E_OUTOFMEMORY
;
5334 TRACE("Name: %s.\n", debugstr_an(ptr
, size
));
5335 memcpy(*name
, ptr
, size
);
5340 static HRESULT
d3dx9_copy_data(struct d3dx_effect
*effect
, unsigned int object_id
, const char **ptr
)
5342 struct d3dx_object
*object
= &effect
->objects
[object_id
];
5344 if (object
->size
|| object
->data
)
5347 FIXME("Overwriting object id %u!\n", object_id
);
5349 TRACE("Overwriting object id 0.\n");
5352 object
->data
= NULL
;
5355 object
->size
= read_u32(ptr
);
5356 TRACE("Data size: %#x.\n", object
->size
);
5361 object
->data
= malloc(object
->size
);
5364 ERR("Failed to allocate object memory.\n");
5365 return E_OUTOFMEMORY
;
5368 TRACE("Data: %s.\n", debugstr_an(*ptr
, object
->size
));
5369 memcpy(object
->data
, *ptr
, object
->size
);
5371 *ptr
+= ((object
->size
+ 3) & ~3);
5376 static void param_set_magic_number(struct d3dx_parameter
*param
)
5378 memcpy(param
->magic_string
, parameter_magic_string
, sizeof(parameter_magic_string
));
5381 static void add_param_to_tree(struct d3dx_effect
*effect
, struct d3dx_parameter
*param
,
5382 struct d3dx_parameter
*parent
, char separator
, unsigned int element
)
5384 const char *parent_name
= parent
? parent
->full_name
: NULL
;
5387 TRACE("Adding parameter %p (%s - parent %p, element %u) to the rbtree.\n",
5388 param
, debugstr_a(param
->name
), parent
, element
);
5392 unsigned int parent_name_len
= strlen(parent_name
);
5393 unsigned int name_len
= strlen(param
->name
);
5394 unsigned int part_str_len
;
5398 if (separator
== '[')
5400 sprintf(part_str
, "[%u]", element
);
5401 part_str_len
= strlen(part_str
);
5406 part_str
[0] = separator
;
5410 len
= parent_name_len
+ part_str_len
+ name_len
+ 1;
5412 if (!(param
->full_name
= malloc(len
)))
5414 ERR("Out of memory.\n");
5418 memcpy(param
->full_name
, parent_name
, parent_name_len
);
5419 memcpy(param
->full_name
+ parent_name_len
, part_str
, part_str_len
);
5420 memcpy(param
->full_name
+ parent_name_len
+ part_str_len
, param
->name
, name_len
);
5421 param
->full_name
[len
- 1] = 0;
5425 if (!(param
->full_name
= strdup(param
->name
)))
5427 ERR("Out of memory.\n");
5431 TRACE("Full name is %s.\n", param
->full_name
);
5432 wine_rb_put(&effect
->params
.tree
, param
->full_name
, ¶m
->rb_entry
);
5434 if (is_top_level_parameter(param
))
5435 for (i
= 0; i
< param
->top_level_param
->annotation_count
; ++i
)
5436 add_param_to_tree(effect
, ¶m
->top_level_param
->annotations
[i
], param
, '@', 0);
5438 if (param
->element_count
)
5439 for (i
= 0; i
< param
->element_count
; ++i
)
5440 add_param_to_tree(effect
, ¶m
->members
[i
], param
, '[', i
);
5442 for (i
= 0; i
< param
->member_count
; ++i
)
5443 add_param_to_tree(effect
, ¶m
->members
[i
], param
, '.', 0);
5446 static HRESULT
d3dx_parse_effect_typedef(struct d3dx_effect
*effect
, struct d3dx_parameter
*param
,
5447 const char *data
, const char **ptr
, struct d3dx_parameter
*parent
, UINT flags
)
5453 param
->flags
= flags
;
5457 param
->type
= read_u32(ptr
);
5458 TRACE("Type: %s.\n", debug_d3dxparameter_type(param
->type
));
5460 param
->class = read_u32(ptr
);
5461 TRACE("Class: %s.\n", debug_d3dxparameter_class(param
->class));
5463 offset
= read_u32(ptr
);
5464 TRACE("Type name offset: %#x.\n", offset
);
5465 hr
= d3dx9_parse_name(¶m
->name
, data
+ offset
);
5468 WARN("Failed to parse name\n");
5472 offset
= read_u32(ptr
);
5473 TRACE("Type semantic offset: %#x.\n", offset
);
5474 hr
= d3dx9_parse_name(¶m
->semantic
, data
+ offset
);
5477 WARN("Failed to parse semantic\n");
5481 param
->element_count
= read_u32(ptr
);
5482 TRACE("Elements: %u.\n", param
->element_count
);
5484 switch (param
->class)
5487 param
->columns
= read_u32(ptr
);
5488 TRACE("Columns: %u.\n", param
->columns
);
5490 param
->rows
= read_u32(ptr
);
5491 TRACE("Rows: %u.\n", param
->rows
);
5493 /* sizeof(DWORD) * rows * columns */
5494 param
->bytes
= 4 * param
->rows
* param
->columns
;
5498 case D3DXPC_MATRIX_ROWS
:
5499 case D3DXPC_MATRIX_COLUMNS
:
5500 param
->rows
= read_u32(ptr
);
5501 TRACE("Rows: %u.\n", param
->rows
);
5503 param
->columns
= read_u32(ptr
);
5504 TRACE("Columns: %u.\n", param
->columns
);
5506 /* sizeof(DWORD) * rows * columns */
5507 param
->bytes
= 4 * param
->rows
* param
->columns
;
5511 param
->member_count
= read_u32(ptr
);
5512 TRACE("Members: %u.\n", param
->member_count
);
5516 switch (param
->type
)
5519 case D3DXPT_PIXELSHADER
:
5520 case D3DXPT_VERTEXSHADER
:
5521 case D3DXPT_TEXTURE
:
5522 case D3DXPT_TEXTURE1D
:
5523 case D3DXPT_TEXTURE2D
:
5524 case D3DXPT_TEXTURE3D
:
5525 case D3DXPT_TEXTURECUBE
:
5526 param
->bytes
= sizeof(void *);
5529 case D3DXPT_SAMPLER
:
5530 case D3DXPT_SAMPLER1D
:
5531 case D3DXPT_SAMPLER2D
:
5532 case D3DXPT_SAMPLER3D
:
5533 case D3DXPT_SAMPLERCUBE
:
5538 FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param
->type
));
5544 FIXME("Unhandled class %s.\n", debug_d3dxparameter_class(param
->class));
5551 param
->type
= parent
->type
;
5552 param
->class = parent
->class;
5553 param
->name
= parent
->name
;
5554 param
->semantic
= parent
->semantic
;
5555 param
->element_count
= 0;
5556 param
->member_count
= parent
->member_count
;
5557 param
->bytes
= parent
->bytes
;
5558 param
->rows
= parent
->rows
;
5559 param
->columns
= parent
->columns
;
5562 if (param
->element_count
)
5564 unsigned int param_bytes
= 0;
5565 const char *save_ptr
= *ptr
;
5567 param
->members
= calloc(param
->element_count
, sizeof(*param
->members
));
5568 if (!param
->members
)
5570 ERR("Out of memory\n");
5575 for (i
= 0; i
< param
->element_count
; ++i
)
5579 param_set_magic_number(¶m
->members
[i
]);
5580 hr
= d3dx_parse_effect_typedef(effect
, ¶m
->members
[i
], data
, ptr
, param
, flags
);
5583 WARN("Failed to parse member %u\n", i
);
5587 param_bytes
+= param
->members
[i
].bytes
;
5590 param
->bytes
= param_bytes
;
5592 else if (param
->member_count
)
5594 param
->members
= calloc(param
->member_count
, sizeof(*param
->members
));
5595 if (!param
->members
)
5597 ERR("Out of memory\n");
5602 for (i
= 0; i
< param
->member_count
; ++i
)
5604 param_set_magic_number(¶m
->members
[i
]);
5605 hr
= d3dx_parse_effect_typedef(effect
, ¶m
->members
[i
], data
, ptr
, NULL
, flags
);
5608 WARN("Failed to parse member %u\n", i
);
5612 param
->bytes
+= param
->members
[i
].bytes
;
5621 unsigned int count
= param
->element_count
? param
->element_count
: param
->member_count
;
5623 for (i
= 0; i
< count
; ++i
)
5624 free_parameter(¶m
->members
[i
], param
->element_count
!= 0, TRUE
);
5625 free(param
->members
);
5626 param
->members
= NULL
;
5632 free(param
->semantic
);
5635 param
->semantic
= NULL
;
5640 static HRESULT
d3dx_parse_effect_annotation(struct d3dx_effect
*effect
, struct d3dx_parameter
*anno
,
5641 const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5647 anno
->flags
= D3DX_PARAMETER_ANNOTATION
;
5649 offset
= read_u32(ptr
);
5650 TRACE("Typedef offset: %#x.\n", offset
);
5651 ptr2
= data
+ offset
;
5652 hr
= d3dx_parse_effect_typedef(effect
, anno
, data
, &ptr2
, NULL
, D3DX_PARAMETER_ANNOTATION
);
5655 WARN("Failed to parse type definition.\n");
5659 offset
= read_u32(ptr
);
5660 TRACE("Value offset: %#x.\n", offset
);
5661 hr
= d3dx_parse_init_value(effect
, anno
, data
, data
+ offset
, objects
);
5664 WARN("Failed to parse value.\n");
5671 static HRESULT
d3dx_parse_state(struct d3dx_effect
*effect
, struct d3dx_state
*state
,
5672 const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5674 struct d3dx_parameter
*param
= &state
->parameter
;
5675 enum STATE_CLASS state_class
;
5681 state
->type
= ST_CONSTANT
;
5683 state
->operation
= read_u32(ptr
);
5684 if (state
->operation
>= ARRAY_SIZE(state_table
))
5686 WARN("Unknown state operation %u.\n", state
->operation
);
5687 return D3DERR_INVALIDCALL
;
5689 TRACE("Operation: %#x (%s).\n", state
->operation
, state_table
[state
->operation
].name
);
5691 state
->index
= read_u32(ptr
);
5692 TRACE("Index: %#x.\n", state
->index
);
5694 offset
= read_u32(ptr
);
5695 TRACE("Typedef offset: %#x.\n", offset
);
5696 ptr2
= data
+ offset
;
5697 hr
= d3dx_parse_effect_typedef(effect
, param
, data
, &ptr2
, NULL
, 0);
5700 WARN("Failed to parse type definition\n");
5704 offset
= read_u32(ptr
);
5705 TRACE("Value offset: %#x.\n", offset
);
5706 hr
= d3dx_parse_init_value(effect
, param
, data
, data
+ offset
, objects
);
5709 WARN("Failed to parse value\n");
5713 if (((state_class
= state_table
[state
->operation
].class) == SC_VERTEXSHADER
5714 || state_class
== SC_PIXELSHADER
|| state_class
== SC_TEXTURE
)
5715 && param
->bytes
< sizeof(void *))
5717 if (param
->type
!= D3DXPT_INT
|| *(unsigned int *)param
->data
)
5719 FIXME("Unexpected parameter for object, param->type %#x, param->class %#x, *param->data %#x.\n",
5720 param
->type
, param
->class, *(unsigned int *)param
->data
);
5721 hr
= D3DXERR_INVALIDDATA
;
5725 new_data
= realloc(param
->data
, sizeof(void *));
5728 ERR("Out of memory.\n");
5732 memset(new_data
, 0, sizeof(void *));
5733 param
->data
= new_data
;
5734 param
->bytes
= sizeof(void *);
5741 free_parameter(param
, FALSE
, FALSE
);
5746 static HRESULT
d3dx_parse_effect_parameter(struct d3dx_effect
*effect
, struct d3dx_top_level_parameter
*param
,
5747 const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5754 offset
= read_u32(ptr
);
5755 TRACE("Typedef offset: %#x.\n", offset
);
5756 ptr2
= data
+ offset
;
5758 offset
= read_u32(ptr
);
5759 TRACE("Value offset: %#x.\n", offset
);
5761 param
->param
.flags
= read_u32(ptr
);
5762 TRACE("Flags: %#x.\n", param
->param
.flags
);
5764 param
->annotation_count
= read_u32(ptr
);
5765 TRACE("Annotation count: %u.\n", param
->annotation_count
);
5767 hr
= d3dx_parse_effect_typedef(effect
, ¶m
->param
, data
, &ptr2
, NULL
, param
->param
.flags
);
5770 WARN("Failed to parse type definition.\n");
5774 hr
= d3dx_parse_init_value(effect
, ¶m
->param
, data
, data
+ offset
, objects
);
5777 WARN("Failed to parse value.\n");
5781 if (param
->annotation_count
)
5783 param
->annotations
= calloc(param
->annotation_count
, sizeof(*param
->annotations
));
5784 if (!param
->annotations
)
5786 ERR("Out of memory.\n");
5791 for (i
= 0; i
< param
->annotation_count
; ++i
)
5793 param_set_magic_number(¶m
->annotations
[i
]);
5794 hr
= d3dx_parse_effect_annotation(effect
, ¶m
->annotations
[i
], data
, ptr
, objects
);
5797 WARN("Failed to parse annotation.\n");
5807 if (param
->annotations
)
5809 for (i
= 0; i
< param
->annotation_count
; ++i
)
5810 free_parameter(¶m
->annotations
[i
], FALSE
, FALSE
);
5811 free(param
->annotations
);
5812 param
->annotations
= NULL
;
5818 static HRESULT
d3dx_parse_effect_pass(struct d3dx_effect
*effect
, struct d3dx_pass
*pass
,
5819 const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5821 struct d3dx_state
*states
= NULL
;
5827 offset
= read_u32(ptr
);
5828 TRACE("Pass name offset: %#x.\n", offset
);
5829 hr
= d3dx9_parse_name(&name
, data
+ offset
);
5832 WARN("Failed to parse name.\n");
5836 pass
->annotation_count
= read_u32(ptr
);
5837 TRACE("Annotation count: %u.\n", pass
->annotation_count
);
5839 pass
->state_count
= read_u32(ptr
);
5840 TRACE("State count: %u.\n", pass
->state_count
);
5842 if (pass
->annotation_count
)
5844 pass
->annotations
= calloc(pass
->annotation_count
, sizeof(*pass
->annotations
));
5845 if (!pass
->annotations
)
5847 ERR("Out of memory\n");
5852 for (i
= 0; i
< pass
->annotation_count
; ++i
)
5854 param_set_magic_number(&pass
->annotations
[i
]);
5855 hr
= d3dx_parse_effect_annotation(effect
, &pass
->annotations
[i
], data
, ptr
, objects
);
5858 WARN("Failed to parse annotation %u\n", i
);
5864 if (pass
->state_count
)
5866 states
= calloc(pass
->state_count
, sizeof(*states
));
5869 ERR("Out of memory\n");
5874 for (i
= 0; i
< pass
->state_count
; ++i
)
5876 hr
= d3dx_parse_state(effect
, &states
[i
], data
, ptr
, objects
);
5879 WARN("Failed to parse annotation %u\n", i
);
5886 pass
->states
= states
;
5892 if (pass
->annotations
)
5894 for (i
= 0; i
< pass
->annotation_count
; ++i
)
5895 free_parameter(&pass
->annotations
[i
], FALSE
, FALSE
);
5896 free(pass
->annotations
);
5897 pass
->annotations
= NULL
;
5902 for (i
= 0; i
< pass
->state_count
; ++i
)
5904 free_state(&states
[i
]);
5914 static HRESULT
d3dx_parse_effect_technique(struct d3dx_effect
*effect
, struct d3dx_technique
*technique
,
5915 const char *data
, const char **ptr
, struct d3dx_object
*objects
)
5922 offset
= read_u32(ptr
);
5923 TRACE("Technique name offset: %#x.\n", offset
);
5924 hr
= d3dx9_parse_name(&name
, data
+ offset
);
5927 WARN("Failed to parse name\n");
5931 technique
->annotation_count
= read_u32(ptr
);
5932 TRACE("Annotation count: %u.\n", technique
->annotation_count
);
5934 technique
->pass_count
= read_u32(ptr
);
5935 TRACE("Pass count: %u.\n", technique
->pass_count
);
5937 if (technique
->annotation_count
)
5939 technique
->annotations
= calloc(technique
->annotation_count
, sizeof(*technique
->annotations
));
5940 if (!technique
->annotations
)
5942 ERR("Out of memory\n");
5947 for (i
= 0; i
< technique
->annotation_count
; ++i
)
5949 param_set_magic_number(&technique
->annotations
[i
]);
5950 hr
= d3dx_parse_effect_annotation(effect
, &technique
->annotations
[i
], data
, ptr
, objects
);
5953 WARN("Failed to parse annotation %u\n", i
);
5959 if (technique
->pass_count
)
5961 technique
->passes
= calloc(technique
->pass_count
, sizeof(*technique
->passes
));
5962 if (!technique
->passes
)
5964 ERR("Out of memory\n");
5969 for (i
= 0; i
< technique
->pass_count
; ++i
)
5971 hr
= d3dx_parse_effect_pass(effect
, &technique
->passes
[i
], data
, ptr
, objects
);
5974 WARN("Failed to parse pass %u\n", i
);
5980 technique
->name
= name
;
5986 if (technique
->passes
)
5988 for (i
= 0; i
< technique
->pass_count
; ++i
)
5989 free_pass(&technique
->passes
[i
]);
5990 free(technique
->passes
);
5991 technique
->passes
= NULL
;
5994 if (technique
->annotations
)
5996 for (i
= 0; i
< technique
->annotation_count
; ++i
)
5997 free_parameter(&technique
->annotations
[i
], FALSE
, FALSE
);
5998 free(technique
->annotations
);
5999 technique
->annotations
= NULL
;
6007 static HRESULT
d3dx9_create_object(struct d3dx_effect
*effect
, struct d3dx_object
*object
)
6009 struct d3dx_parameter
*param
= object
->param
;
6010 IDirect3DDevice9
*device
= effect
->device
;
6013 if (*(char **)param
->data
)
6014 ERR("Parameter data already allocated.\n");
6016 switch (param
->type
)
6019 *(char **)param
->data
= malloc(object
->size
);
6020 if (!*(char **)param
->data
)
6022 ERR("Out of memory.\n");
6023 return E_OUTOFMEMORY
;
6025 memcpy(*(char **)param
->data
, object
->data
, object
->size
);
6027 case D3DXPT_VERTEXSHADER
:
6028 if (FAILED(hr
= IDirect3DDevice9_CreateVertexShader(device
, object
->data
,
6029 (IDirect3DVertexShader9
**)param
->data
)))
6031 WARN("Failed to create vertex shader.\n");
6032 object
->creation_failed
= TRUE
;
6035 case D3DXPT_PIXELSHADER
:
6036 if (FAILED(hr
= IDirect3DDevice9_CreatePixelShader(device
, object
->data
,
6037 (IDirect3DPixelShader9
**)param
->data
)))
6039 WARN("Failed to create pixel shader.\n");
6040 object
->creation_failed
= TRUE
;
6049 static HRESULT
d3dx_parse_array_selector(struct d3dx_effect
*effect
, struct d3dx_state
*state
,
6050 const char **skip_constants
, unsigned int skip_constants_count
)
6052 struct d3dx_parameter
*param
= &state
->parameter
;
6053 struct d3dx_object
*object
= &effect
->objects
[param
->object_id
];
6054 char *ptr
= object
->data
;
6055 uint32_t string_size
;
6058 TRACE("Parsing array entry selection state for parameter %p.\n", param
);
6060 string_size
= *(uint32_t *)ptr
;
6061 state
->referenced_param
= get_parameter_by_name(&effect
->params
, NULL
, ptr
+ 4);
6062 if (state
->referenced_param
)
6064 TRACE("Mapping to parameter %s.\n", debugstr_a(state
->referenced_param
->name
));
6068 FIXME("Referenced parameter %s not found.\n", ptr
+ 4);
6069 return D3DXERR_INVALIDDATA
;
6071 TRACE("Unknown u32: 0x%.8x.\n", *(uint32_t *)(ptr
+ string_size
));
6073 if (string_size
% sizeof(uint32_t))
6074 FIXME("Unaligned string_size %u.\n", string_size
);
6075 if (FAILED(ret
= d3dx_create_param_eval(&effect
->params
, (uint32_t *)(ptr
+ string_size
) + 1,
6076 object
->size
- (string_size
+ sizeof(uint32_t)), D3DXPT_INT
, ¶m
->param_eval
,
6077 get_version_counter_ptr(effect
), NULL
, 0)))
6080 param
= state
->referenced_param
;
6081 if (param
->type
== D3DXPT_VERTEXSHADER
|| param
->type
== D3DXPT_PIXELSHADER
)
6085 for (i
= 0; i
< param
->element_count
; i
++)
6087 if (param
->members
[i
].type
!= param
->type
)
6089 FIXME("Unexpected member parameter type %u, expected %u.\n", param
->members
[i
].type
, param
->type
);
6090 return D3DXERR_INVALIDDATA
;
6092 if (!param
->members
[i
].param_eval
)
6094 TRACE("Creating preshader for object %u.\n", param
->members
[i
].object_id
);
6095 object
= &effect
->objects
[param
->members
[i
].object_id
];
6096 if (FAILED(ret
= d3dx_create_param_eval(&effect
->params
, object
->data
, object
->size
, param
->type
,
6097 ¶m
->members
[i
].param_eval
, get_version_counter_ptr(effect
),
6098 skip_constants
, skip_constants_count
)))
6106 static HRESULT
d3dx_parse_resource(struct d3dx_effect
*effect
, const char *data
, const char **ptr
,
6107 const char **skip_constants
, unsigned int skip_constants_count
)
6109 unsigned int index
, state_index
, usage
, element_index
, technique_index
;
6110 struct d3dx_parameter
*param
;
6111 struct d3dx_object
*object
;
6112 struct d3dx_state
*state
;
6113 HRESULT hr
= E_FAIL
;
6115 technique_index
= read_u32(ptr
);
6116 TRACE("technique_index: %u.\n", technique_index
);
6118 index
= read_u32(ptr
);
6119 TRACE("index: %u.\n", index
);
6121 element_index
= read_u32(ptr
);
6122 TRACE("element_index: %u.\n", element_index
);
6124 state_index
= read_u32(ptr
);
6125 TRACE("state_index: %u.\n", state_index
);
6127 usage
= read_u32(ptr
);
6128 TRACE("usage: %u.\n", usage
);
6130 if (technique_index
== 0xffffffff)
6132 struct d3dx_parameter
*parameter
;
6133 struct d3dx_sampler
*sampler
;
6135 if (index
>= effect
->params
.count
)
6137 FIXME("Index out of bounds: index %u >= parameter count %u.\n", index
, effect
->params
.count
);
6141 parameter
= &effect
->params
.parameters
[index
].param
;
6142 if (element_index
!= 0xffffffff)
6144 if (element_index
>= parameter
->element_count
&& parameter
->element_count
!= 0)
6146 FIXME("Index out of bounds: element_index %u >= element_count %u.\n", element_index
, parameter
->element_count
);
6150 if (parameter
->element_count
)
6151 parameter
= ¶meter
->members
[element_index
];
6154 sampler
= parameter
->data
;
6155 if (state_index
>= sampler
->state_count
)
6157 FIXME("Index out of bounds: state_index %u >= state_count %u.\n", state_index
, sampler
->state_count
);
6161 state
= &sampler
->states
[state_index
];
6165 struct d3dx_technique
*technique
;
6166 struct d3dx_pass
*pass
;
6168 if (technique_index
>= effect
->technique_count
)
6170 FIXME("Index out of bounds: technique_index %u >= technique_count %u.\n", technique_index
,
6171 effect
->technique_count
);
6175 technique
= &effect
->techniques
[technique_index
];
6176 if (index
>= technique
->pass_count
)
6178 FIXME("Index out of bounds: index %u >= pass_count %u.\n", index
, technique
->pass_count
);
6182 pass
= &technique
->passes
[index
];
6183 if (state_index
>= pass
->state_count
)
6185 FIXME("Index out of bounds: state_index %u >= state_count %u.\n", state_index
, pass
->state_count
);
6189 state
= &pass
->states
[state_index
];
6192 TRACE("State operation %#x (%s).\n", state
->operation
, state_table
[state
->operation
].name
);
6193 param
= &state
->parameter
;
6194 TRACE("Using object id %u.\n", param
->object_id
);
6195 object
= &effect
->objects
[param
->object_id
];
6197 TRACE("Usage %u: class %s, type %s.\n", usage
, debug_d3dxparameter_class(param
->class),
6198 debug_d3dxparameter_type(param
->type
));
6202 switch (param
->type
)
6204 case D3DXPT_VERTEXSHADER
:
6205 case D3DXPT_PIXELSHADER
:
6206 state
->type
= ST_CONSTANT
;
6207 if (FAILED(hr
= d3dx9_copy_data(effect
, param
->object_id
, ptr
)))
6212 if (FAILED(hr
= d3dx9_create_object(effect
, object
)))
6214 if (FAILED(hr
= d3dx_create_param_eval(&effect
->params
, object
->data
, object
->size
, param
->type
,
6215 ¶m
->param_eval
, get_version_counter_ptr(effect
),
6216 skip_constants
, skip_constants_count
)))
6225 state
->type
= ST_FXLC
;
6226 if (FAILED(hr
= d3dx9_copy_data(effect
, param
->object_id
, ptr
)))
6228 if (FAILED(hr
= d3dx_create_param_eval(&effect
->params
, object
->data
, object
->size
, param
->type
,
6229 ¶m
->param_eval
, get_version_counter_ptr(effect
), NULL
, 0)))
6234 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param
->type
));
6240 state
->type
= ST_PARAMETER
;
6241 if (FAILED(hr
= d3dx9_copy_data(effect
, param
->object_id
, ptr
)))
6244 TRACE("Looking for parameter %s.\n", debugstr_a(object
->data
));
6245 state
->referenced_param
= get_parameter_by_name(&effect
->params
, NULL
, object
->data
);
6246 if (state
->referenced_param
)
6248 struct d3dx_parameter
*refpar
= state
->referenced_param
;
6250 TRACE("Mapping to parameter %p, having object id %u.\n", refpar
, refpar
->object_id
);
6251 if (refpar
->type
== D3DXPT_VERTEXSHADER
|| refpar
->type
== D3DXPT_PIXELSHADER
)
6253 struct d3dx_object
*refobj
= &effect
->objects
[refpar
->object_id
];
6255 if (!refpar
->param_eval
)
6257 if (FAILED(hr
= d3dx_create_param_eval(&effect
->params
, refobj
->data
, refobj
->size
,
6258 refpar
->type
, &refpar
->param_eval
, get_version_counter_ptr(effect
),
6259 skip_constants
, skip_constants_count
)))
6266 FIXME("Referenced parameter %s not found.\n", (char *)object
->data
);
6267 return D3DXERR_INVALIDDATA
;
6272 state
->type
= ST_ARRAY_SELECTOR
;
6273 if (FAILED(hr
= d3dx9_copy_data(effect
, param
->object_id
, ptr
)))
6275 hr
= d3dx_parse_array_selector(effect
, state
, skip_constants
, skip_constants_count
);
6279 FIXME("Unknown usage %u.\n", usage
);
6286 static BOOL
param_set_top_level_param(void *top_level_param
, struct d3dx_parameter
*param
)
6288 param
->top_level_param
= top_level_param
;
6292 static HRESULT
d3dx_parse_effect(struct d3dx_effect
*effect
, const char *data
, UINT data_size
,
6293 uint32_t start
, const char **skip_constants
, unsigned int skip_constants_count
)
6295 unsigned int string_count
, resource_count
, params_count
;
6296 const char *ptr
= data
+ start
;
6300 params_count
= read_u32(&ptr
);
6301 TRACE("Parameter count: %u.\n", params_count
);
6303 effect
->technique_count
= read_u32(&ptr
);
6304 TRACE("Technique count: %u.\n", effect
->technique_count
);
6306 skip_u32_unknown(&ptr
, 1);
6308 effect
->object_count
= read_u32(&ptr
);
6309 TRACE("Object count: %u.\n", effect
->object_count
);
6311 effect
->objects
= calloc(effect
->object_count
, sizeof(*effect
->objects
));
6312 if (!effect
->objects
)
6314 ERR("Out of memory.\n");
6319 if (FAILED(hr
= d3dx_init_parameters_store(&effect
->params
, params_count
)))
6325 for (i
= 0; i
< effect
->params
.count
; ++i
)
6327 param_set_magic_number(&effect
->params
.parameters
[i
].param
);
6328 hr
= d3dx_parse_effect_parameter(effect
, &effect
->params
.parameters
[i
], data
, &ptr
, effect
->objects
);
6331 WARN("Failed to parse parameter %u.\n", i
);
6334 walk_parameter_tree(&effect
->params
.parameters
[i
].param
, param_set_top_level_param
, &effect
->params
.parameters
[i
]);
6335 add_param_to_tree(effect
, &effect
->params
.parameters
[i
].param
, NULL
, 0, 0);
6338 if (effect
->technique_count
)
6340 effect
->techniques
= calloc(effect
->technique_count
, sizeof(*effect
->techniques
));
6341 if (!effect
->techniques
)
6343 ERR("Out of memory.\n");
6348 for (i
= 0; i
< effect
->technique_count
; ++i
)
6350 TRACE("Parsing technique %u.\n", i
);
6351 hr
= d3dx_parse_effect_technique(effect
, &effect
->techniques
[i
], data
, &ptr
, effect
->objects
);
6354 WARN("Failed to parse technique %u.\n", i
);
6360 string_count
= read_u32(&ptr
);
6361 TRACE("String count: %u.\n", string_count
);
6363 resource_count
= read_u32(&ptr
);
6364 TRACE("Resource count: %u.\n", resource_count
);
6366 for (i
= 0; i
< string_count
; ++i
)
6370 id
= read_u32(&ptr
);
6371 TRACE("id: %u.\n", id
);
6373 if (FAILED(hr
= d3dx9_copy_data(effect
, id
, &ptr
)))
6376 if (effect
->objects
[id
].data
)
6378 if (FAILED(hr
= d3dx9_create_object(effect
, &effect
->objects
[id
])))
6383 for (i
= 0; i
< resource_count
; ++i
)
6385 TRACE("parse resource %u.\n", i
);
6387 hr
= d3dx_parse_resource(effect
, data
, &ptr
, skip_constants
, skip_constants_count
);
6390 WARN("Failed to parse resource %u.\n", i
);
6395 for (i
= 0; i
< effect
->params
.count
; ++i
)
6397 if (FAILED(hr
= d3dx_pool_sync_shared_parameter(effect
->pool
, &effect
->params
.parameters
[i
])))
6399 effect
->params
.parameters
[i
].version_counter
= get_version_counter_ptr(effect
);
6400 set_dirty(&effect
->params
.parameters
[i
].param
);
6406 if (effect
->techniques
)
6408 for (i
= 0; i
< effect
->technique_count
; ++i
)
6409 free_technique(&effect
->techniques
[i
]);
6410 free(effect
->techniques
);
6411 effect
->techniques
= NULL
;
6414 d3dx_parameters_store_cleanup(&effect
->params
);
6416 if (effect
->objects
)
6418 for (i
= 0; i
< effect
->object_count
; ++i
)
6420 free_object(&effect
->objects
[i
]);
6422 free(effect
->objects
);
6423 effect
->objects
= NULL
;
6429 #define INITIAL_CONST_NAMES_SIZE 4
6431 static char *next_valid_constant_name(char **string
)
6433 char *ret
= *string
;
6436 while (*ret
&& !isalpha(*ret
) && *ret
!= '_')
6442 while (isalpha(*next
) || isdigit(*next
) || *next
== '_')
6450 static const char **parse_skip_constants_string(char *skip_constants_string
, unsigned int *names_count
)
6452 const char **names
, **new_alloc
;
6455 unsigned int size
= INITIAL_CONST_NAMES_SIZE
;
6457 names
= malloc(sizeof(*names
) * size
);
6462 s
= skip_constants_string
;
6463 while ((name
= next_valid_constant_name(&s
)))
6465 if (*names_count
== size
)
6468 new_alloc
= realloc(names
, sizeof(*names
) * size
);
6476 names
[(*names_count
)++] = name
;
6478 new_alloc
= realloc(names
, *names_count
* sizeof(*names
));
6484 static HRESULT
d3dx9_effect_init_from_binary(struct d3dx_effect
*effect
,
6485 struct IDirect3DDevice9
*device
, const char *data
, SIZE_T data_size
,
6486 unsigned int flags
, struct ID3DXEffectPool
*pool
, const char *skip_constants_string
)
6488 unsigned int skip_constants_count
= 0;
6489 char *skip_constants_buffer
= NULL
;
6490 const char **skip_constants
= NULL
;
6491 const char *ptr
= data
;
6492 uint32_t tag
, offset
;
6496 effect
->ID3DXEffect_iface
.lpVtbl
= &ID3DXEffect_Vtbl
;
6499 effect
->flags
= flags
;
6501 list_init(&effect
->parameter_block_list
);
6503 tag
= read_u32(&ptr
);
6504 TRACE("Tag: %#x.\n", tag
);
6506 if (!(flags
& D3DXFX_NOT_CLONEABLE
))
6508 if (!(effect
->source
= malloc(data_size
)))
6509 return E_OUTOFMEMORY
;
6510 memcpy(effect
->source
, data
, data_size
);
6511 effect
->source_size
= data_size
;
6516 effect
->pool
= unsafe_impl_from_ID3DXEffectPool(pool
);
6517 pool
->lpVtbl
->AddRef(pool
);
6520 IDirect3DDevice9_AddRef(device
);
6521 effect
->device
= device
;
6523 if (skip_constants_string
)
6525 if (!(flags
& D3DXFX_NOT_CLONEABLE
) && !(effect
->skip_constants_string
= strdup(skip_constants_string
)))
6531 if (!(skip_constants_buffer
= strdup(skip_constants_string
)))
6537 if (!(skip_constants
= parse_skip_constants_string(skip_constants_buffer
, &skip_constants_count
)))
6539 free(skip_constants_buffer
);
6544 offset
= read_u32(&ptr
);
6545 TRACE("Offset: %#x.\n", offset
);
6547 hr
= d3dx_parse_effect(effect
, ptr
, data_size
, offset
, skip_constants
, skip_constants_count
);
6550 FIXME("Failed to parse effect.\n");
6551 free(skip_constants_buffer
);
6552 free(skip_constants
);
6556 for (i
= 0; i
< skip_constants_count
; ++i
)
6558 struct d3dx_parameter
*param
;
6559 param
= get_parameter_by_name(&effect
->params
, NULL
, skip_constants
[i
]);
6562 for (j
= 0; j
< effect
->technique_count
; ++j
)
6564 if (is_parameter_used(param
, &effect
->techniques
[j
]))
6566 WARN("skip_constants parameter %s is used in technique %u.\n",
6567 debugstr_a(skip_constants
[i
]), j
);
6568 free(skip_constants_buffer
);
6569 free(skip_constants
);
6570 hr
= D3DERR_INVALIDCALL
;
6577 TRACE("skip_constants parameter %s not found.\n",
6578 debugstr_a(skip_constants
[i
]));
6582 free(skip_constants_buffer
);
6583 free(skip_constants
);
6585 /* initialize defaults - check because of unsupported ascii effects */
6586 if (effect
->techniques
)
6588 effect
->active_technique
= &effect
->techniques
[0];
6589 effect
->active_pass
= NULL
;
6595 if (effect
->techniques
)
6597 for (i
= 0; i
< effect
->technique_count
; ++i
)
6598 free_technique(&effect
->techniques
[i
]);
6599 free(effect
->techniques
);
6602 if (effect
->params
.parameters
)
6604 for (i
= 0; i
< effect
->params
.count
; ++i
)
6605 free_top_level_parameter(&effect
->params
.parameters
[i
]);
6606 free(effect
->params
.parameters
);
6609 if (effect
->objects
)
6611 for (i
= 0; i
< effect
->object_count
; ++i
)
6612 free_object(&effect
->objects
[i
]);
6613 free(effect
->objects
);
6616 IDirect3DDevice9_Release(effect
->device
);
6618 pool
->lpVtbl
->Release(pool
);
6619 free(effect
->source
);
6620 free(effect
->skip_constants_string
);
6624 static HRESULT
d3dx9_effect_init(struct d3dx_effect
*effect
, struct IDirect3DDevice9
*device
,
6625 const char *data
, SIZE_T data_size
, const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
,
6626 UINT flags
, ID3DBlob
**errors
, struct ID3DXEffectPool
*pool
, const char *skip_constants_string
)
6628 #if D3DX_SDK_VERSION <= 36
6629 UINT compile_flags
= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
6631 UINT compile_flags
= 0;
6633 ID3DBlob
*bytecode
= NULL
, *temp_errors
= NULL
;
6634 const char *ptr
= data
;
6638 TRACE("effect %p, device %p, data %p, data_size %Iu, defines %p, include %p, flags %#x, errors %p, "
6639 "pool %p, skip_constants %s.\n",
6640 effect
, device
, data
, data_size
, defines
, include
, flags
, errors
, pool
,
6641 debugstr_a(skip_constants_string
));
6643 tag
= read_u32(&ptr
);
6645 if (tag
== d3dx9_effect_version(9, 1))
6646 return d3dx9_effect_init_from_binary(effect
, device
, data
, data_size
, flags
, pool
, skip_constants_string
);
6648 TRACE("HLSL ASCII effect, trying to compile it.\n");
6649 compile_flags
|= flags
& ~(D3DXFX_NOT_CLONEABLE
| D3DXFX_LARGEADDRESSAWARE
);
6650 hr
= D3DCompile(data
, data_size
, NULL
, defines
, include
,
6651 NULL
, "fx_2_0", compile_flags
, 0, &bytecode
, &temp_errors
);
6654 WARN("Failed to compile ASCII effect.\n");
6656 ID3D10Blob_Release(bytecode
);
6659 const char *error_string
= ID3D10Blob_GetBufferPointer(temp_errors
);
6660 const char *string_ptr
;
6662 while (*error_string
)
6664 string_ptr
= error_string
;
6665 while (*string_ptr
&& *string_ptr
!= '\n' && *string_ptr
!= '\r'
6666 && string_ptr
- error_string
< 80)
6668 TRACE("%s\n", debugstr_an(error_string
, string_ptr
- error_string
));
6669 error_string
= string_ptr
;
6670 while (*error_string
== '\n' || *error_string
== '\r')
6675 *errors
= temp_errors
;
6676 else if (temp_errors
)
6677 ID3D10Blob_Release(temp_errors
);
6682 FIXME("No output from effect compilation.\n");
6683 return D3DERR_INVALIDCALL
;
6686 *errors
= temp_errors
;
6687 else if (temp_errors
)
6688 ID3D10Blob_Release(temp_errors
);
6690 hr
= d3dx9_effect_init_from_binary(effect
, device
, ID3D10Blob_GetBufferPointer(bytecode
),
6691 ID3D10Blob_GetBufferSize(bytecode
), flags
, pool
, skip_constants_string
);
6692 ID3D10Blob_Release(bytecode
);
6696 HRESULT WINAPI
D3DXCreateEffectEx(struct IDirect3DDevice9
*device
, const void *srcdata
, UINT srcdatalen
,
6697 const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, const char *skip_constants
, DWORD flags
,
6698 struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**compilation_errors
)
6700 struct d3dx_effect
*object
;
6703 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p, "
6704 "skip_constants %p, flags %#lx, pool %p, effect %p, compilation_errors %p.\n",
6705 device
, srcdata
, srcdatalen
, defines
, include
,
6706 skip_constants
, flags
, pool
, effect
, compilation_errors
);
6708 if (compilation_errors
)
6709 *compilation_errors
= NULL
;
6711 if (!device
|| !srcdata
)
6712 return D3DERR_INVALIDCALL
;
6717 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
6721 object
= calloc(1, sizeof(*object
));
6723 return E_OUTOFMEMORY
;
6725 hr
= d3dx9_effect_init(object
, device
, srcdata
, srcdatalen
, (const D3D_SHADER_MACRO
*)defines
,
6726 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)compilation_errors
, pool
, skip_constants
);
6729 WARN("Failed to create effect object, hr %#lx.\n", hr
);
6733 *effect
= &object
->ID3DXEffect_iface
;
6735 TRACE("Created ID3DXEffect %p\n", object
);
6740 HRESULT WINAPI
D3DXCreateEffect(struct IDirect3DDevice9
*device
, const void *data
, UINT data_size
,
6741 const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, DWORD flags
,
6742 struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
6744 TRACE("device %p, data %p, data_size %u, defines %p, include %p, flags %#lx, pool %p, "
6745 "effect %p, messages %p.\n", device
, data
, data_size
, defines
,
6746 include
, flags
, pool
, effect
, messages
);
6748 return D3DXCreateEffectEx(device
, data
, data_size
, defines
, include
, NULL
, flags
, pool
, effect
, messages
);
6751 static HRESULT
d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl
*compiler
,
6752 const char *data
, SIZE_T data_size
, const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
,
6753 UINT eflags
, ID3DBlob
**messages
)
6755 TRACE("compiler %p, data %p, data_size %Iu, defines %p, include %p, eflags %#x, messages %p.\n",
6756 compiler
, data
, data_size
, defines
, include
, eflags
, messages
);
6758 compiler
->ID3DXEffectCompiler_iface
.lpVtbl
= &ID3DXEffectCompiler_Vtbl
;
6761 FIXME("ID3DXEffectCompiler implementation is only a stub.\n");
6766 HRESULT WINAPI
D3DXCreateEffectCompiler(const char *data
, UINT data_size
, const D3DXMACRO
*defines
,
6767 ID3DXInclude
*include
, DWORD flags
, ID3DXEffectCompiler
**compiler
, ID3DXBuffer
**messages
)
6769 struct ID3DXEffectCompilerImpl
*object
;
6772 TRACE("data %p, data_size %u, defines %p, include %p, flags %#lx, compiler %p, messages %p.\n",
6773 data
, data_size
, defines
, include
, flags
, compiler
, messages
);
6775 if (!data
|| !compiler
)
6777 WARN("Invalid arguments supplied\n");
6778 return D3DERR_INVALIDCALL
;
6781 object
= calloc(1, sizeof(*object
));
6783 return E_OUTOFMEMORY
;
6785 hr
= d3dx9_effect_compiler_init(object
, data
, data_size
, (const D3D_SHADER_MACRO
*)defines
,
6786 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)messages
);
6789 WARN("Failed to initialize effect compiler\n");
6794 *compiler
= &object
->ID3DXEffectCompiler_iface
;
6796 TRACE("Created ID3DXEffectCompiler %p\n", object
);
6801 /*** IUnknown methods ***/
6802 static HRESULT WINAPI
d3dx_effect_pool_QueryInterface(ID3DXEffectPool
*iface
, REFIID riid
, void **object
)
6804 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
6806 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
6807 IsEqualGUID(riid
, &IID_ID3DXEffectPool
))
6809 iface
->lpVtbl
->AddRef(iface
);
6814 WARN("Interface %s not found\n", debugstr_guid(riid
));
6816 return E_NOINTERFACE
;
6819 static ULONG WINAPI
d3dx_effect_pool_AddRef(ID3DXEffectPool
*iface
)
6821 struct d3dx_effect_pool
*pool
= impl_from_ID3DXEffectPool(iface
);
6822 ULONG refcount
= InterlockedIncrement(&pool
->refcount
);
6824 TRACE("%p increasing refcount to %lu.\n", pool
, refcount
);
6829 static void free_effect_pool(struct d3dx_effect_pool
*pool
)
6833 for (i
= 0; i
< pool
->size
; ++i
)
6835 if (pool
->shared_data
[i
].count
)
6839 WARN("Releasing pool with referenced parameters.\n");
6841 param_set_data_pointer(&pool
->shared_data
[i
].parameters
[0]->param
, NULL
, FALSE
, TRUE
);
6842 pool
->shared_data
[i
].parameters
[0]->shared_data
= NULL
;
6844 for (j
= 1; j
< pool
->shared_data
[i
].count
; ++j
)
6846 walk_parameter_tree(&pool
->shared_data
[i
].parameters
[j
]->param
, param_zero_data_func
, NULL
);
6847 pool
->shared_data
[i
].parameters
[j
]->shared_data
= NULL
;
6849 free(pool
->shared_data
[i
].parameters
);
6852 free(pool
->shared_data
);
6856 static ULONG WINAPI
d3dx_effect_pool_Release(ID3DXEffectPool
*iface
)
6858 struct d3dx_effect_pool
*pool
= impl_from_ID3DXEffectPool(iface
);
6859 ULONG refcount
= InterlockedDecrement(&pool
->refcount
);
6861 TRACE("%p decreasing refcount to %lu.\n", pool
, refcount
);
6864 free_effect_pool(pool
);
6869 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl
=
6871 /*** IUnknown methods ***/
6872 d3dx_effect_pool_QueryInterface
,
6873 d3dx_effect_pool_AddRef
,
6874 d3dx_effect_pool_Release
6877 static inline struct d3dx_effect_pool
*unsafe_impl_from_ID3DXEffectPool(ID3DXEffectPool
*iface
)
6882 assert(iface
->lpVtbl
== &ID3DXEffectPool_Vtbl
);
6883 return impl_from_ID3DXEffectPool(iface
);
6886 HRESULT WINAPI
D3DXCreateEffectPool(ID3DXEffectPool
**pool
)
6888 struct d3dx_effect_pool
*object
;
6890 TRACE("pool %p.\n", pool
);
6893 return D3DERR_INVALIDCALL
;
6895 object
= calloc(1, sizeof(*object
));
6897 return E_OUTOFMEMORY
;
6899 object
->ID3DXEffectPool_iface
.lpVtbl
= &ID3DXEffectPool_Vtbl
;
6900 object
->refcount
= 1;
6902 *pool
= &object
->ID3DXEffectPool_iface
;
6907 HRESULT WINAPI
D3DXCreateEffectFromFileExW(struct IDirect3DDevice9
*device
, const WCHAR
*srcfile
,
6908 const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, const char *skipconstants
, DWORD flags
,
6909 struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
6911 struct d3dx_include_from_file include_from_file
;
6917 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6918 "flags %#lx, pool %p, effect %p, messages %p.\n",
6919 device
, debugstr_w(srcfile
), defines
, include
, debugstr_a(skipconstants
),
6920 flags
, pool
, effect
, messages
);
6922 if (!device
|| !srcfile
)
6923 return D3DERR_INVALIDCALL
;
6927 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
6928 include
= &include_from_file
.ID3DXInclude_iface
;
6931 size
= WideCharToMultiByte(CP_ACP
, 0, srcfile
, -1, NULL
, 0, NULL
, NULL
);
6932 filename_a
= malloc(size
);
6934 return E_OUTOFMEMORY
;
6935 WideCharToMultiByte(CP_ACP
, 0, srcfile
, -1, filename_a
, size
, NULL
, NULL
);
6937 EnterCriticalSection(&from_file_mutex
);
6938 ret
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &size
);
6941 LeaveCriticalSection(&from_file_mutex
);
6943 return D3DXERR_INVALIDDATA
;
6946 ret
= D3DXCreateEffectEx(device
, buffer
, size
, defines
, include
, skipconstants
, flags
, pool
,
6949 ID3DXInclude_Close(include
, buffer
);
6950 LeaveCriticalSection(&from_file_mutex
);
6955 HRESULT WINAPI
D3DXCreateEffectFromFileExA(struct IDirect3DDevice9
*device
, const char *srcfile
,
6956 const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, const char *skipconstants
, DWORD flags
,
6957 struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
6963 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
6964 "flags %#lx, pool %p, effect %p, messages %p.\n",
6965 device
, debugstr_a(srcfile
), defines
, include
, debugstr_a(skipconstants
),
6966 flags
, pool
, effect
, messages
);
6969 return D3DERR_INVALIDCALL
;
6971 len
= MultiByteToWideChar(CP_ACP
, 0, srcfile
, -1, NULL
, 0);
6972 srcfileW
= malloc(len
* sizeof(*srcfileW
));
6973 MultiByteToWideChar(CP_ACP
, 0, srcfile
, -1, srcfileW
, len
);
6975 ret
= D3DXCreateEffectFromFileExW(device
, srcfileW
, defines
, include
, skipconstants
, flags
, pool
, effect
, messages
);
6981 HRESULT WINAPI
D3DXCreateEffectFromFileW(struct IDirect3DDevice9
*device
, const WCHAR
*srcfile
,
6982 const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, DWORD flags
, struct ID3DXEffectPool
*pool
,
6983 struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
6985 TRACE("(void): relay\n");
6986 return D3DXCreateEffectFromFileExW(device
, srcfile
, defines
, include
, NULL
, flags
, pool
,
6990 HRESULT WINAPI
D3DXCreateEffectFromFileA(struct IDirect3DDevice9
*device
, const char *srcfile
,
6991 const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, DWORD flags
, struct ID3DXEffectPool
*pool
,
6992 struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
6994 TRACE("(void): relay\n");
6995 return D3DXCreateEffectFromFileExA(device
, srcfile
, defines
, include
, NULL
, flags
, pool
,
6999 HRESULT WINAPI
D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9
*device
, HMODULE srcmodule
,
7000 const WCHAR
*srcresource
, const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, const char *skipconstants
,
7001 DWORD flags
, struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
7007 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
7008 "flags %#lx, pool %p, effect %p, messages %p.\n",
7009 device
, srcmodule
, debugstr_w(srcresource
), defines
, include
, debugstr_a(skipconstants
),
7010 flags
, pool
, effect
, messages
);
7013 return D3DERR_INVALIDCALL
;
7015 if (!(resinfo
= FindResourceW(srcmodule
, srcresource
, (const WCHAR
*)RT_RCDATA
)))
7016 return D3DXERR_INVALIDDATA
;
7018 if (FAILED(load_resource_into_memory(srcmodule
, resinfo
, &buffer
, &size
)))
7019 return D3DXERR_INVALIDDATA
;
7021 return D3DXCreateEffectEx(device
, buffer
, size
, defines
, include
,
7022 skipconstants
, flags
, pool
, effect
, messages
);
7025 HRESULT WINAPI
D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9
*device
, HMODULE srcmodule
,
7026 const char *srcresource
, const D3DXMACRO
*defines
, struct ID3DXInclude
*include
,
7027 const char *skipconstants
, DWORD flags
, struct ID3DXEffectPool
*pool
,
7028 struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
7034 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, "
7035 "flags %#lx, pool %p, effect %p, messages %p.\n",
7036 device
, srcmodule
, debugstr_a(srcresource
), defines
, include
, debugstr_a(skipconstants
),
7037 flags
, pool
, effect
, messages
);
7040 return D3DERR_INVALIDCALL
;
7042 if (!(resinfo
= FindResourceA(srcmodule
, srcresource
, (const char *)RT_RCDATA
)))
7043 return D3DXERR_INVALIDDATA
;
7045 if (FAILED(load_resource_into_memory(srcmodule
, resinfo
, &buffer
, &size
)))
7046 return D3DXERR_INVALIDDATA
;
7048 return D3DXCreateEffectEx(device
, buffer
, size
, defines
, include
,
7049 skipconstants
, flags
, pool
, effect
, messages
);
7052 HRESULT WINAPI
D3DXCreateEffectFromResourceW(struct IDirect3DDevice9
*device
, HMODULE srcmodule
,
7053 const WCHAR
*srcresource
, const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, DWORD flags
,
7054 struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
7056 TRACE("(void): relay\n");
7057 return D3DXCreateEffectFromResourceExW(device
, srcmodule
, srcresource
, defines
, include
, NULL
,
7058 flags
, pool
, effect
, messages
);
7061 HRESULT WINAPI
D3DXCreateEffectFromResourceA(struct IDirect3DDevice9
*device
, HMODULE srcmodule
,
7062 const char *srcresource
, const D3DXMACRO
*defines
, struct ID3DXInclude
*include
, DWORD flags
,
7063 struct ID3DXEffectPool
*pool
, struct ID3DXEffect
**effect
, struct ID3DXBuffer
**messages
)
7065 TRACE("(void): relay\n");
7066 return D3DXCreateEffectFromResourceExA(device
, srcmodule
, srcresource
, defines
, include
, NULL
,
7067 flags
, pool
, effect
, messages
);
7070 HRESULT WINAPI
D3DXCreateEffectCompilerFromFileW(const WCHAR
*srcfile
, const D3DXMACRO
*defines
,
7071 ID3DXInclude
*include
, DWORD flags
, ID3DXEffectCompiler
**compiler
, ID3DXBuffer
**messages
)
7077 TRACE("srcfile %s, defines %p, include %p, flags %#lx, compiler %p, messages %p.\n",
7078 debugstr_w(srcfile
), defines
, include
, flags
, compiler
, messages
);
7081 return D3DERR_INVALIDCALL
;
7083 ret
= map_view_of_file(srcfile
, &buffer
, &size
);
7086 return D3DXERR_INVALIDDATA
;
7088 ret
= D3DXCreateEffectCompiler(buffer
, size
, defines
, include
, flags
, compiler
, messages
);
7089 UnmapViewOfFile(buffer
);
7094 HRESULT WINAPI
D3DXCreateEffectCompilerFromFileA(const char *srcfile
, const D3DXMACRO
*defines
,
7095 ID3DXInclude
*include
, DWORD flags
, ID3DXEffectCompiler
**compiler
, ID3DXBuffer
**messages
)
7101 TRACE("srcfile %s, defines %p, include %p, flags %#lx, compiler %p, messages %p.\n",
7102 debugstr_a(srcfile
), defines
, include
, flags
, compiler
, messages
);
7105 return D3DERR_INVALIDCALL
;
7107 len
= MultiByteToWideChar(CP_ACP
, 0, srcfile
, -1, NULL
, 0);
7108 srcfileW
= malloc(len
* sizeof(*srcfileW
));
7109 MultiByteToWideChar(CP_ACP
, 0, srcfile
, -1, srcfileW
, len
);
7111 ret
= D3DXCreateEffectCompilerFromFileW(srcfileW
, defines
, include
, flags
, compiler
, messages
);
7117 HRESULT WINAPI
D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule
, const char *srcresource
,
7118 const D3DXMACRO
*defines
, ID3DXInclude
*include
, DWORD flags
,
7119 ID3DXEffectCompiler
**compiler
, ID3DXBuffer
**messages
)
7125 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#lx, compiler %p, messages %p.\n",
7126 srcmodule
, debugstr_a(srcresource
), defines
, include
, flags
, compiler
, messages
);
7128 if (!(resinfo
= FindResourceA(srcmodule
, srcresource
, (const char *)RT_RCDATA
)))
7129 return D3DXERR_INVALIDDATA
;
7131 if (FAILED(load_resource_into_memory(srcmodule
, resinfo
, &buffer
, &size
)))
7132 return D3DXERR_INVALIDDATA
;
7134 return D3DXCreateEffectCompiler(buffer
, size
, defines
, include
, flags
, compiler
, messages
);
7137 HRESULT WINAPI
D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule
, const WCHAR
*srcresource
,
7138 const D3DXMACRO
*defines
, ID3DXInclude
*include
, DWORD flags
,
7139 ID3DXEffectCompiler
**compiler
, ID3DXBuffer
**messages
)
7145 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#lx, compiler %p, messages %p.\n",
7146 srcmodule
, debugstr_w(srcresource
), defines
, include
, flags
, compiler
, messages
);
7148 if (!(resinfo
= FindResourceW(srcmodule
, srcresource
, (const WCHAR
*)RT_RCDATA
)))
7149 return D3DXERR_INVALIDDATA
;
7151 if (FAILED(load_resource_into_memory(srcmodule
, resinfo
, &buffer
, &size
)))
7152 return D3DXERR_INVALIDDATA
;
7154 return D3DXCreateEffectCompiler(buffer
, size
, defines
, include
, flags
, compiler
, messages
);
7157 HRESULT WINAPI
D3DXDisassembleEffect(ID3DXEffect
*effect
, BOOL enable_color_code
, ID3DXBuffer
**disassembly
)
7159 FIXME("(%p, %u, %p): stub\n", effect
, enable_color_code
, disassembly
);
7161 return D3DXERR_INVALIDDATA
;