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