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