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