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