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