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