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