1 /* 2 * Copyright 2010 Christian Costa 3 * Copyright 2011 Rico Schüller 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "config.h" 21 #include "wine/port.h" 22 23 #include "d3dx9_private.h" 24 #include "d3dcompiler.h" 25 26 /* Constants for special INT/FLOAT conversation */ 27 #define INT_FLOAT_MULTI 255.0f 28 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI) 29 30 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'}; 31 32 #define PARAMETER_FLAG_SHARED 1 33 34 #define INITIAL_POOL_SIZE 16 35 36 WINE_DEFAULT_DEBUG_CHANNEL(d3dx); 37 38 enum STATE_CLASS 39 { 40 SC_LIGHTENABLE, 41 SC_FVF, 42 SC_LIGHT, 43 SC_MATERIAL, 44 SC_NPATCHMODE, 45 SC_PIXELSHADER, 46 SC_RENDERSTATE, 47 SC_SETSAMPLER, 48 SC_SAMPLERSTATE, 49 SC_TEXTURE, 50 SC_TEXTURESTAGE, 51 SC_TRANSFORM, 52 SC_VERTEXSHADER, 53 SC_SHADERCONST, 54 SC_UNKNOWN, 55 }; 56 57 enum MATERIAL_TYPE 58 { 59 MT_DIFFUSE, 60 MT_AMBIENT, 61 MT_SPECULAR, 62 MT_EMISSIVE, 63 MT_POWER, 64 }; 65 66 enum LIGHT_TYPE 67 { 68 LT_TYPE, 69 LT_DIFFUSE, 70 LT_SPECULAR, 71 LT_AMBIENT, 72 LT_POSITION, 73 LT_DIRECTION, 74 LT_RANGE, 75 LT_FALLOFF, 76 LT_ATTENUATION0, 77 LT_ATTENUATION1, 78 LT_ATTENUATION2, 79 LT_THETA, 80 LT_PHI, 81 }; 82 83 enum SHADER_CONSTANT_TYPE 84 { 85 SCT_VSFLOAT, 86 SCT_VSBOOL, 87 SCT_VSINT, 88 SCT_PSFLOAT, 89 SCT_PSBOOL, 90 SCT_PSINT, 91 }; 92 93 enum STATE_TYPE 94 { 95 ST_CONSTANT, 96 ST_PARAMETER, 97 ST_FXLC, 98 ST_ARRAY_SELECTOR, 99 }; 100 101 struct d3dx_object 102 { 103 UINT size; 104 void *data; 105 struct d3dx_parameter *param; 106 BOOL creation_failed; 107 }; 108 109 struct d3dx_state 110 { 111 UINT operation; 112 UINT index; 113 enum STATE_TYPE type; 114 struct d3dx_parameter parameter; 115 struct d3dx_parameter *referenced_param; 116 }; 117 118 struct d3dx_sampler 119 { 120 UINT state_count; 121 struct d3dx_state *states; 122 }; 123 124 struct d3dx_pass 125 { 126 char *name; 127 UINT state_count; 128 UINT annotation_count; 129 130 struct d3dx_state *states; 131 struct d3dx_parameter *annotations; 132 133 ULONG64 update_version; 134 }; 135 136 struct d3dx_technique 137 { 138 char *name; 139 UINT pass_count; 140 UINT annotation_count; 141 142 struct d3dx_parameter *annotations; 143 struct d3dx_pass *passes; 144 145 struct IDirect3DStateBlock9 *saved_state; 146 }; 147 148 struct d3dx9_base_effect 149 { 150 struct ID3DXEffectImpl *effect; 151 152 UINT parameter_count; 153 UINT technique_count; 154 UINT object_count; 155 156 struct d3dx_top_level_parameter *parameters; 157 struct d3dx_technique *techniques; 158 struct d3dx_object *objects; 159 160 struct d3dx_effect_pool *pool; 161 DWORD flags; 162 163 ULONG64 version_counter; 164 }; 165 166 struct ID3DXEffectImpl 167 { 168 ID3DXEffect ID3DXEffect_iface; 169 LONG ref; 170 171 struct d3dx9_base_effect base_effect; 172 173 struct ID3DXEffectStateManager *manager; 174 struct IDirect3DDevice9 *device; 175 struct ID3DXEffectPool *pool; 176 struct d3dx_technique *active_technique; 177 struct d3dx_pass *active_pass; 178 BOOL started; 179 DWORD begin_flags; 180 181 D3DLIGHT9 current_light[8]; 182 unsigned int light_updated; 183 D3DMATERIAL9 current_material; 184 BOOL material_updated; 185 }; 186 187 #define INITIAL_SHARED_DATA_SIZE 4 188 189 struct d3dx_effect_pool 190 { 191 ID3DXEffectPool ID3DXEffectPool_iface; 192 LONG refcount; 193 194 struct d3dx_shared_data *shared_data; 195 unsigned int size; 196 197 ULONG64 version_counter; 198 }; 199 200 struct ID3DXEffectCompilerImpl 201 { 202 ID3DXEffectCompiler ID3DXEffectCompiler_iface; 203 LONG ref; 204 205 struct d3dx9_base_effect base_effect; 206 }; 207 208 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *parameters, 209 const char *name); 210 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state, 211 const char *data, const char **ptr, struct d3dx_object *objects); 212 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child); 213 214 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param); 215 216 static const struct 217 { 218 enum STATE_CLASS class; 219 UINT op; 220 const char *name; 221 } 222 state_table[] = 223 { 224 /* Render states */ 225 {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */ 226 {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"}, 227 {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"}, 228 {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"}, 229 {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"}, 230 {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"}, 231 {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"}, 232 {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"}, 233 {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"}, 234 {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"}, 235 {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"}, 236 {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"}, 237 {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"}, 238 {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"}, 239 {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"}, 240 {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"}, 241 {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */ 242 {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"}, 243 {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"}, 244 {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"}, 245 {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"}, 246 {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"}, 247 {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"}, 248 {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"}, 249 {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"}, 250 {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"}, 251 {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"}, 252 {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"}, 253 {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"}, 254 {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"}, 255 {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"}, 256 {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"}, 257 {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */ 258 {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"}, 259 {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"}, 260 {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"}, 261 {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"}, 262 {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"}, 263 {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"}, 264 {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"}, 265 {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"}, 266 {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"}, 267 {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"}, 268 {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"}, 269 {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"}, 270 {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"}, 271 {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"}, 272 {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"}, 273 {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */ 274 {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"}, 275 {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"}, 276 {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"}, 277 {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"}, 278 {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"}, 279 {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"}, 280 {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"}, 281 {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"}, 282 {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"}, 283 {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"}, 284 {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"}, 285 {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"}, 286 {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"}, 287 {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"}, 288 {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"}, 289 {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */ 290 {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"}, 291 {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"}, 292 {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"}, 293 {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"}, 294 {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"}, 295 {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"}, 296 {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"}, 297 {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"}, 298 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"}, 299 {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"}, 300 {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"}, 301 {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"}, 302 {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"}, 303 {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"}, 304 {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"}, 305 {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */ 306 {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"}, 307 {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"}, 308 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"}, 309 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"}, 310 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"}, 311 {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"}, 312 {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"}, 313 {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"}, 314 {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"}, 315 {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"}, 316 {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"}, 317 {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"}, 318 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"}, 319 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"}, 320 {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"}, 321 {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */ 322 {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"}, 323 {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"}, 324 {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"}, 325 {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"}, 326 {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"}, 327 {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"}, 328 /* Texture stages */ 329 {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"}, 330 {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"}, 331 {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"}, 332 {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"}, 333 {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"}, 334 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"}, 335 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"}, 336 {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"}, 337 {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"}, 338 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */ 339 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"}, 340 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"}, 341 {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"}, 342 {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"}, 343 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"}, 344 {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"}, 345 {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"}, 346 {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"}, 347 /* NPatchMode */ 348 {SC_NPATCHMODE, 0, "NPatchMode"}, 349 /* FVF */ 350 {SC_FVF, 0, "FVF"}, 351 /* Transform */ 352 {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"}, 353 {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"}, 354 {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"}, 355 {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"}, 356 /* Material */ 357 {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"}, 358 {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */ 359 {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"}, 360 {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"}, 361 {SC_MATERIAL, MT_POWER, "MaterialPower"}, 362 /* Light */ 363 {SC_LIGHT, LT_TYPE, "LightType"}, 364 {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"}, 365 {SC_LIGHT, LT_SPECULAR, "LightSpecular"}, 366 {SC_LIGHT, LT_AMBIENT, "LightAmbient"}, 367 {SC_LIGHT, LT_POSITION, "LightPosition"}, 368 {SC_LIGHT, LT_DIRECTION, "LightDirection"}, 369 {SC_LIGHT, LT_RANGE, "LightRange"}, 370 {SC_LIGHT, LT_FALLOFF, "LightFallOff"}, 371 {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"}, 372 {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"}, 373 {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"}, 374 {SC_LIGHT, LT_THETA, "LightTheta"}, 375 {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */ 376 /* Lightenable */ 377 {SC_LIGHTENABLE, 0, "LightEnable"}, 378 /* Vertexshader */ 379 {SC_VERTEXSHADER, 0, "Vertexshader"}, 380 /* Pixelshader */ 381 {SC_PIXELSHADER, 0, "Pixelshader"}, 382 /* Shader constants */ 383 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"}, 384 {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"}, 385 {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"}, 386 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"}, 387 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"}, 388 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"}, 389 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"}, 390 {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"}, 391 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"}, 392 {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"}, 393 {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"}, 394 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"}, 395 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */ 396 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"}, 397 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"}, 398 {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"}, 399 /* Texture */ 400 {SC_TEXTURE, 0, "Texture"}, 401 /* Sampler states */ 402 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"}, 403 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"}, 404 {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"}, 405 {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"}, 406 {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"}, 407 {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"}, 408 {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"}, 409 {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"}, 410 {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"}, 411 {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"}, 412 {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"}, 413 {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */ 414 {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"}, 415 /* Set sampler */ 416 {SC_SETSAMPLER, 0, "Sampler"}, 417 }; 418 419 static inline void read_dword(const char **ptr, DWORD *d) 420 { 421 memcpy(d, *ptr, sizeof(*d)); 422 *ptr += sizeof(*d); 423 } 424 425 static void skip_dword_unknown(const char **ptr, unsigned int count) 426 { 427 unsigned int i; 428 DWORD d; 429 430 WARN("Skipping %u unknown DWORDs:\n", count); 431 for (i = 0; i < count; ++i) 432 { 433 read_dword(ptr, &d); 434 WARN("\t0x%08x\n", d); 435 } 436 } 437 438 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter) 439 { 440 return (D3DXHANDLE)parameter; 441 } 442 443 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique) 444 { 445 return (D3DXHANDLE)technique; 446 } 447 448 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass) 449 { 450 return (D3DXHANDLE)pass; 451 } 452 453 static struct d3dx_technique *get_technique_by_name(struct d3dx9_base_effect *base, const char *name) 454 { 455 UINT i; 456 457 if (!name) return NULL; 458 459 for (i = 0; i < base->technique_count; ++i) 460 { 461 if (!strcmp(base->techniques[i].name, name)) 462 return &base->techniques[i]; 463 } 464 465 return NULL; 466 } 467 468 static struct d3dx_technique *get_valid_technique(struct d3dx9_base_effect *base, D3DXHANDLE technique) 469 { 470 unsigned int i; 471 472 for (i = 0; i < base->technique_count; ++i) 473 { 474 if (get_technique_handle(&base->techniques[i]) == technique) 475 return &base->techniques[i]; 476 } 477 478 return get_technique_by_name(base, technique); 479 } 480 481 static struct d3dx_pass *get_valid_pass(struct d3dx9_base_effect *base, D3DXHANDLE pass) 482 { 483 unsigned int i, k; 484 485 for (i = 0; i < base->technique_count; ++i) 486 { 487 struct d3dx_technique *technique = &base->techniques[i]; 488 489 for (k = 0; k < technique->pass_count; ++k) 490 { 491 if (get_pass_handle(&technique->passes[k]) == pass) 492 return &technique->passes[k]; 493 } 494 } 495 496 return NULL; 497 } 498 499 static struct d3dx_parameter *get_valid_parameter(struct d3dx9_base_effect *base, D3DXHANDLE parameter) 500 { 501 struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter; 502 503 if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string, 504 sizeof(parameter_magic_string))) 505 return handle_param; 506 507 return base->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(base, NULL, parameter); 508 } 509 510 static void free_state(struct d3dx_state *state) 511 { 512 free_parameter(&state->parameter, FALSE, FALSE); 513 } 514 515 static void free_object(struct d3dx_object *object) 516 { 517 HeapFree(GetProcessHeap(), 0, object->data); 518 } 519 520 static void free_sampler(struct d3dx_sampler *sampler) 521 { 522 UINT i; 523 524 for (i = 0; i < sampler->state_count; ++i) 525 { 526 free_state(&sampler->states[i]); 527 } 528 HeapFree(GetProcessHeap(), 0, sampler->states); 529 } 530 531 static void d3dx_pool_release_shared_parameter(struct d3dx_top_level_parameter *param); 532 533 static void free_parameter_data(struct d3dx_parameter *param, BOOL child) 534 { 535 if (!param->data) 536 return; 537 if (param->class == D3DXPC_OBJECT && !param->element_count) 538 { 539 switch (param->type) 540 { 541 case D3DXPT_STRING: 542 HeapFree(GetProcessHeap(), 0, *(char **)param->data); 543 break; 544 545 case D3DXPT_TEXTURE: 546 case D3DXPT_TEXTURE1D: 547 case D3DXPT_TEXTURE2D: 548 case D3DXPT_TEXTURE3D: 549 case D3DXPT_TEXTURECUBE: 550 case D3DXPT_PIXELSHADER: 551 case D3DXPT_VERTEXSHADER: 552 if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data); 553 break; 554 555 case D3DXPT_SAMPLER: 556 case D3DXPT_SAMPLER1D: 557 case D3DXPT_SAMPLER2D: 558 case D3DXPT_SAMPLER3D: 559 case D3DXPT_SAMPLERCUBE: 560 free_sampler((struct d3dx_sampler *)param->data); 561 break; 562 563 default: 564 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type)); 565 break; 566 } 567 } 568 if (!child) 569 HeapFree(GetProcessHeap(), 0, param->data); 570 } 571 572 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child) 573 { 574 unsigned int i; 575 576 TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name, 577 debug_d3dxparameter_type(param->type), element, child); 578 579 if (param->param_eval) 580 d3dx_free_param_eval(param->param_eval); 581 582 if (param->members) 583 { 584 unsigned int count = param->element_count ? param->element_count : param->member_count; 585 586 for (i = 0; i < count; ++i) 587 free_parameter(¶m->members[i], param->element_count != 0, TRUE); 588 HeapFree(GetProcessHeap(), 0, param->members); 589 } 590 591 free_parameter_data(param, child); 592 593 /* only the parent has to release name and semantic */ 594 if (!element) 595 { 596 HeapFree(GetProcessHeap(), 0, param->name); 597 HeapFree(GetProcessHeap(), 0, param->semantic); 598 } 599 } 600 601 static void free_top_level_parameter(struct d3dx_top_level_parameter *param) 602 { 603 if (param->annotations) 604 { 605 unsigned int i; 606 607 for (i = 0; i < param->annotation_count; ++i) 608 free_parameter(¶m->annotations[i], FALSE, FALSE); 609 HeapFree(GetProcessHeap(), 0, param->annotations); 610 } 611 d3dx_pool_release_shared_parameter(param); 612 free_parameter(¶m->param, FALSE, FALSE); 613 } 614 615 static void free_pass(struct d3dx_pass *pass) 616 { 617 unsigned int i; 618 619 TRACE("Free pass %p\n", pass); 620 621 if (!pass) 622 return; 623 624 if (pass->annotations) 625 { 626 for (i = 0; i < pass->annotation_count; ++i) 627 free_parameter(&pass->annotations[i], FALSE, FALSE); 628 HeapFree(GetProcessHeap(), 0, pass->annotations); 629 pass->annotations = NULL; 630 } 631 632 if (pass->states) 633 { 634 for (i = 0; i < pass->state_count; ++i) 635 free_state(&pass->states[i]); 636 HeapFree(GetProcessHeap(), 0, pass->states); 637 pass->states = NULL; 638 } 639 640 HeapFree(GetProcessHeap(), 0, pass->name); 641 pass->name = NULL; 642 } 643 644 static void free_technique(struct d3dx_technique *technique) 645 { 646 unsigned int i; 647 648 TRACE("Free technique %p\n", technique); 649 650 if (!technique) 651 return; 652 653 if (technique->saved_state) 654 { 655 IDirect3DStateBlock9_Release(technique->saved_state); 656 technique->saved_state = NULL; 657 } 658 659 if (technique->annotations) 660 { 661 for (i = 0; i < technique->annotation_count; ++i) 662 free_parameter(&technique->annotations[i], FALSE, FALSE); 663 HeapFree(GetProcessHeap(), 0, technique->annotations); 664 technique->annotations = NULL; 665 } 666 667 if (technique->passes) 668 { 669 for (i = 0; i < technique->pass_count; ++i) 670 free_pass(&technique->passes[i]); 671 HeapFree(GetProcessHeap(), 0, technique->passes); 672 technique->passes = NULL; 673 } 674 675 HeapFree(GetProcessHeap(), 0, technique->name); 676 technique->name = NULL; 677 } 678 679 static void d3dx9_base_effect_cleanup(struct d3dx9_base_effect *base) 680 { 681 unsigned int i; 682 683 TRACE("base %p.\n", base); 684 685 if (base->parameters) 686 { 687 for (i = 0; i < base->parameter_count; ++i) 688 free_top_level_parameter(&base->parameters[i]); 689 HeapFree(GetProcessHeap(), 0, base->parameters); 690 base->parameters = NULL; 691 } 692 693 if (base->techniques) 694 { 695 for (i = 0; i < base->technique_count; ++i) 696 free_technique(&base->techniques[i]); 697 HeapFree(GetProcessHeap(), 0, base->techniques); 698 base->techniques = NULL; 699 } 700 701 if (base->objects) 702 { 703 for (i = 0; i < base->object_count; ++i) 704 { 705 free_object(&base->objects[i]); 706 } 707 HeapFree(GetProcessHeap(), 0, base->objects); 708 base->objects = NULL; 709 } 710 } 711 712 static void free_effect(struct ID3DXEffectImpl *effect) 713 { 714 TRACE("Free effect %p\n", effect); 715 716 d3dx9_base_effect_cleanup(&effect->base_effect); 717 718 if (effect->pool) 719 { 720 effect->pool->lpVtbl->Release(effect->pool); 721 } 722 723 if (effect->manager) 724 { 725 IUnknown_Release(effect->manager); 726 } 727 728 IDirect3DDevice9_Release(effect->device); 729 } 730 731 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler) 732 { 733 TRACE("Free effect compiler %p\n", compiler); 734 735 d3dx9_base_effect_cleanup(&compiler->base_effect); 736 } 737 738 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector) 739 { 740 UINT i; 741 742 for (i = 0; i < 4; ++i) 743 { 744 if (i < param->columns) 745 set_number((FLOAT *)vector + i, D3DXPT_FLOAT, (DWORD *)param->data + i, param->type); 746 else 747 ((FLOAT *)vector)[i] = 0.0f; 748 } 749 } 750 751 static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector) 752 { 753 UINT i; 754 755 for (i = 0; i < param->columns; ++i) 756 { 757 set_number((FLOAT *)param->data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT); 758 } 759 } 760 761 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose) 762 { 763 UINT i, k; 764 765 for (i = 0; i < 4; ++i) 766 { 767 for (k = 0; k < 4; ++k) 768 { 769 FLOAT *tmp = transpose ? (FLOAT *)&matrix->u.m[k][i] : (FLOAT *)&matrix->u.m[i][k]; 770 771 if ((i < param->rows) && (k < param->columns)) 772 set_number(tmp, D3DXPT_FLOAT, (DWORD *)param->data + i * param->columns + k, param->type); 773 else 774 *tmp = 0.0f; 775 } 776 } 777 } 778 779 static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix) 780 { 781 UINT i, k; 782 783 if (param->type == D3DXPT_FLOAT) 784 { 785 if (param->columns == 4) 786 memcpy(param->data, matrix->u.m, param->rows * 4 * sizeof(float)); 787 else 788 for (i = 0; i < param->rows; ++i) 789 memcpy((float *)param->data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float)); 790 return; 791 } 792 793 for (i = 0; i < param->rows; ++i) 794 { 795 for (k = 0; k < param->columns; ++k) 796 { 797 set_number((FLOAT *)param->data + i * param->columns + k, param->type, 798 &matrix->u.m[i][k], D3DXPT_FLOAT); 799 } 800 } 801 } 802 803 static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix) 804 { 805 UINT i, k; 806 807 for (i = 0; i < param->rows; ++i) 808 { 809 for (k = 0; k < param->columns; ++k) 810 { 811 set_number((FLOAT *)param->data + i * param->columns + k, param->type, 812 &matrix->u.m[k][i], D3DXPT_FLOAT); 813 } 814 } 815 } 816 817 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_parameter *parameter, const char *name) 818 { 819 UINT element; 820 struct d3dx_parameter *temp_parameter; 821 const char *part; 822 823 TRACE("parameter %p, name %s\n", parameter, debugstr_a(name)); 824 825 if (!name || !*name) return NULL; 826 827 element = atoi(name); 828 part = strchr(name, ']') + 1; 829 830 /* check for empty [] && element range */ 831 if ((part - name) > 1 && parameter->element_count > element) 832 { 833 temp_parameter = ¶meter->members[element]; 834 835 switch (*part++) 836 { 837 case '.': 838 return get_parameter_by_name(NULL, temp_parameter, part); 839 840 case '\0': 841 TRACE("Returning parameter %p\n", temp_parameter); 842 return temp_parameter; 843 844 default: 845 FIXME("Unhandled case \"%c\"\n", *--part); 846 break; 847 } 848 } 849 850 TRACE("Parameter not found\n"); 851 return NULL; 852 } 853 854 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *annotations, 855 const char *name) 856 { 857 UINT i, length; 858 struct d3dx_parameter *temp_parameter; 859 const char *part; 860 861 TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name)); 862 863 if (!name || !*name) return NULL; 864 865 length = strcspn( name, "[.@" ); 866 part = name + length; 867 868 for (i = 0; i < count; ++i) 869 { 870 temp_parameter = &annotations[i]; 871 872 if (!strcmp(temp_parameter->name, name)) 873 { 874 TRACE("Returning annotation %p\n", temp_parameter); 875 return temp_parameter; 876 } 877 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length)) 878 { 879 switch (*part++) 880 { 881 case '.': 882 return get_parameter_by_name(NULL, temp_parameter, part); 883 884 case '[': 885 return get_parameter_element_by_name(temp_parameter, part); 886 887 default: 888 FIXME("Unhandled case \"%c\"\n", *--part); 889 break; 890 } 891 } 892 } 893 894 TRACE("Annotation not found\n"); 895 return NULL; 896 } 897 898 struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, 899 struct d3dx_parameter *parameter, const char *name) 900 { 901 UINT i, count, length; 902 struct d3dx_parameter *temp_parameter; 903 const char *part; 904 905 TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name)); 906 907 if (!name || !*name) return NULL; 908 909 count = parameter ? parameter->member_count : base->parameter_count; 910 length = strcspn( name, "[.@" ); 911 part = name + length; 912 913 for (i = 0; i < count; i++) 914 { 915 temp_parameter = !parameter ? &base->parameters[i].param 916 : ¶meter->members[i]; 917 918 if (!strcmp(temp_parameter->name, name)) 919 { 920 TRACE("Returning parameter %p\n", temp_parameter); 921 return temp_parameter; 922 } 923 else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length)) 924 { 925 switch (*part++) 926 { 927 case '.': 928 return get_parameter_by_name(NULL, temp_parameter, part); 929 930 case '@': 931 { 932 struct d3dx_top_level_parameter *top_param 933 = top_level_parameter_from_parameter(temp_parameter); 934 935 return parameter ? NULL : get_annotation_by_name(top_param->annotation_count, 936 top_param->annotations, part); 937 } 938 case '[': 939 return get_parameter_element_by_name(temp_parameter, part); 940 941 default: 942 FIXME("Unhandled case \"%c\"\n", *--part); 943 break; 944 } 945 } 946 } 947 948 TRACE("Parameter not found\n"); 949 return NULL; 950 } 951 952 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor) 953 { 954 return (0xfeff0000 | ((major) << 8) | (minor)); 955 } 956 957 static HRESULT d3dx9_base_effect_get_desc(struct d3dx9_base_effect *base, D3DXEFFECT_DESC *desc) 958 { 959 if (!desc) 960 { 961 WARN("Invalid argument specified.\n"); 962 return D3DERR_INVALIDCALL; 963 } 964 965 FIXME("partial stub!\n"); 966 967 /* TODO: add creator and function count. */ 968 desc->Creator = NULL; 969 desc->Functions = 0; 970 desc->Parameters = base->parameter_count; 971 desc->Techniques = base->technique_count; 972 973 return D3D_OK; 974 } 975 976 static HRESULT d3dx9_base_effect_get_parameter_desc(struct d3dx9_base_effect *base, 977 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc) 978 { 979 struct d3dx_parameter *param = get_valid_parameter(base, parameter); 980 981 if (!desc || !param) 982 { 983 WARN("Invalid argument specified.\n"); 984 return D3DERR_INVALIDCALL; 985 } 986 987 desc->Name = param->name; 988 desc->Semantic = param->semantic; 989 desc->Class = param->class; 990 desc->Type = param->type; 991 desc->Rows = param->rows; 992 desc->Columns = param->columns; 993 desc->Elements = param->element_count; 994 desc->Annotations = is_top_level_parameter(param) 995 ? top_level_parameter_from_parameter(param)->annotation_count : 0; 996 desc->StructMembers = param->member_count; 997 desc->Flags = param->flags; 998 desc->Bytes = param->bytes; 999 1000 return D3D_OK; 1001 } 1002 1003 static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *base, 1004 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc) 1005 { 1006 struct d3dx_technique *tech = technique ? get_valid_technique(base, technique) : &base->techniques[0]; 1007 1008 if (!desc || !tech) 1009 { 1010 WARN("Invalid argument specified.\n"); 1011 return D3DERR_INVALIDCALL; 1012 } 1013 1014 desc->Name = tech->name; 1015 desc->Passes = tech->pass_count; 1016 desc->Annotations = tech->annotation_count; 1017 1018 return D3D_OK; 1019 } 1020 1021 static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state, 1022 void **param_value, struct d3dx_parameter **out_param, 1023 BOOL update_all, BOOL *param_dirty) 1024 { 1025 struct d3dx_parameter *param = &state->parameter; 1026 1027 *param_value = NULL; 1028 *out_param = NULL; 1029 *param_dirty = FALSE; 1030 1031 switch (state->type) 1032 { 1033 case ST_PARAMETER: 1034 param = state->referenced_param; 1035 *param_dirty = is_param_dirty(param, pass->update_version); 1036 /* fallthrough */ 1037 case ST_CONSTANT: 1038 *out_param = param; 1039 *param_value = param->data; 1040 return D3D_OK; 1041 case ST_ARRAY_SELECTOR: 1042 { 1043 unsigned int array_idx; 1044 static const struct d3dx_parameter array_idx_param = 1045 {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)}; 1046 HRESULT hr; 1047 struct d3dx_parameter *ref_param, *selected_param; 1048 1049 if (!param->param_eval) 1050 { 1051 FIXME("Preshader structure is null.\n"); 1052 return D3DERR_INVALIDCALL; 1053 } 1054 /* We override with the update_version of the pass because we want 1055 * to force index recomputation and check for out of bounds. */ 1056 if (is_param_eval_input_dirty(param->param_eval, pass->update_version)) 1057 { 1058 if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx))) 1059 return hr; 1060 } 1061 else 1062 { 1063 array_idx = state->index; 1064 } 1065 ref_param = state->referenced_param; 1066 TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index, 1067 ref_param->element_count); 1068 /* According to the tests, native d3dx handles the case of array index evaluated to -1 1069 * in a specific way, always selecting first array element and not returning error. */ 1070 if (array_idx == ~0u) 1071 { 1072 WARN("Array index is -1, setting to 0.\n"); 1073 array_idx = 0; 1074 } 1075 1076 if (array_idx >= ref_param->element_count) 1077 { 1078 WARN("Computed array index %u is larger than array size %u.\n", 1079 array_idx, ref_param->element_count); 1080 return E_FAIL; 1081 } 1082 selected_param = &ref_param->members[array_idx]; 1083 *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version); 1084 state->index = array_idx; 1085 1086 *param_value = selected_param->data; 1087 *out_param = selected_param; 1088 return D3D_OK; 1089 } 1090 case ST_FXLC: 1091 if (param->param_eval) 1092 { 1093 *out_param = param; 1094 *param_value = param->data; 1095 /* We check with the update_version of the pass because the 1096 * same preshader might be used by both the vertex and the 1097 * pixel shader (that can happen e.g. for sampler states). */ 1098 if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version)) 1099 { 1100 *param_dirty = TRUE; 1101 return d3dx_evaluate_parameter(param->param_eval, param, *param_value); 1102 } 1103 else 1104 return D3D_OK; 1105 } 1106 else 1107 { 1108 FIXME("No preshader for FXLC parameter.\n"); 1109 return D3DERR_INVALIDCALL; 1110 } 1111 } 1112 return E_NOTIMPL; 1113 } 1114 1115 static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base, 1116 D3DXHANDLE pass_handle, D3DXPASS_DESC *desc) 1117 { 1118 struct d3dx_pass *pass = get_valid_pass(base, pass_handle); 1119 unsigned int i; 1120 1121 if (!desc || !pass) 1122 { 1123 WARN("Invalid argument specified.\n"); 1124 return D3DERR_INVALIDCALL; 1125 } 1126 1127 desc->Name = pass->name; 1128 desc->Annotations = pass->annotation_count; 1129 1130 desc->pVertexShaderFunction = NULL; 1131 desc->pPixelShaderFunction = NULL; 1132 1133 if (base->flags & D3DXFX_NOT_CLONEABLE) 1134 return D3D_OK; 1135 1136 for (i = 0; i < pass->state_count; ++i) 1137 { 1138 struct d3dx_state *state = &pass->states[i]; 1139 1140 if (state_table[state->operation].class == SC_VERTEXSHADER 1141 || state_table[state->operation].class == SC_PIXELSHADER) 1142 { 1143 struct d3dx_parameter *param; 1144 void *param_value; 1145 BOOL param_dirty; 1146 HRESULT hr; 1147 void *data; 1148 1149 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], ¶m_value, ¶m, 1150 FALSE, ¶m_dirty))) 1151 return hr; 1152 1153 data = param->object_id ? base->objects[param->object_id].data : NULL; 1154 if (state_table[state->operation].class == SC_VERTEXSHADER) 1155 desc->pVertexShaderFunction = data; 1156 else 1157 desc->pPixelShaderFunction = 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 *effect = impl_from_ID3DXEffect(iface); 3942 struct d3dx9_base_effect *base = &effect->base_effect; 3943 struct d3dx_technique *tech = get_valid_technique(base, technique); 3944 HRESULT ret = D3D_OK; 3945 unsigned int i, j; 3946 3947 FIXME("iface %p, technique %p semi-stub.\n", iface, technique); 3948 3949 if (!tech) 3950 { 3951 ret = D3DERR_INVALIDCALL; 3952 goto done; 3953 } 3954 for (i = 0; i < tech->pass_count; ++i) 3955 { 3956 struct d3dx_pass *pass = &tech->passes[i]; 3957 3958 for (j = 0; j < pass->state_count; ++j) 3959 { 3960 struct d3dx_state *state = &pass->states[j]; 3961 3962 if (state_table[state->operation].class == SC_VERTEXSHADER 3963 || state_table[state->operation].class == SC_PIXELSHADER) 3964 { 3965 struct d3dx_parameter *param; 3966 void *param_value; 3967 BOOL param_dirty; 3968 HRESULT hr; 3969 3970 if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[j], ¶m_value, ¶m, 3971 FALSE, ¶m_dirty))) 3972 return hr; 3973 3974 if (param->object_id && base->objects[param->object_id].creation_failed) 3975 { 3976 ret = E_FAIL; 3977 goto done; 3978 } 3979 } 3980 } 3981 } 3982 done: 3983 TRACE("Returning %#x.\n", ret); 3984 return ret; 3985 } 3986 3987 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect *iface, 3988 D3DXHANDLE technique, D3DXHANDLE *next_technique) 3989 { 3990 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 3991 struct d3dx9_base_effect *base_effect = &This->base_effect; 3992 UINT i = 0; 3993 3994 TRACE("iface %p, technique %p, next_technique %p\n", iface, technique, next_technique); 3995 3996 if (!next_technique) 3997 return D3DERR_INVALIDCALL; 3998 3999 if (technique) 4000 { 4001 for (; i < base_effect->technique_count; i++) 4002 { 4003 if (technique == get_technique_handle(&base_effect->techniques[i])) 4004 { 4005 i++; /* Go to next technique */ 4006 break; 4007 } 4008 } 4009 } 4010 4011 for (; i < base_effect->technique_count; i++) 4012 { 4013 if (SUCCEEDED(iface->lpVtbl->ValidateTechnique(iface, get_technique_handle(&base_effect->techniques[i])))) 4014 { 4015 *next_technique = get_technique_handle(&base_effect->techniques[i]); 4016 return D3D_OK; 4017 } 4018 } 4019 4020 *next_technique = NULL; 4021 return S_FALSE; 4022 } 4023 4024 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func, 4025 void *data); 4026 4027 static BOOL walk_param_eval_dep(struct d3dx_param_eval *param_eval, walk_parameter_dep_func param_func, 4028 void *data) 4029 { 4030 struct d3dx_parameter **params; 4031 unsigned int i, param_count; 4032 4033 if (!param_eval) 4034 return FALSE; 4035 4036 params = param_eval->shader_inputs.inputs_param; 4037 param_count = param_eval->shader_inputs.input_count; 4038 for (i = 0; i < param_count; ++i) 4039 { 4040 if (walk_parameter_dep(params[i], param_func, data)) 4041 return TRUE; 4042 } 4043 4044 params = param_eval->pres.inputs.inputs_param; 4045 param_count = param_eval->pres.inputs.input_count; 4046 for (i = 0; i < param_count; ++i) 4047 { 4048 if (walk_parameter_dep(params[i], param_func, data)) 4049 return TRUE; 4050 } 4051 return FALSE; 4052 } 4053 4054 static BOOL walk_state_dep(struct d3dx_state *state, walk_parameter_dep_func param_func, 4055 void *data) 4056 { 4057 if (state->type == ST_CONSTANT && is_param_type_sampler(state->parameter.type)) 4058 { 4059 if (walk_parameter_dep(&state->parameter, param_func, data)) 4060 return TRUE; 4061 } 4062 else if (state->type == ST_ARRAY_SELECTOR || state->type == ST_PARAMETER) 4063 { 4064 if (walk_parameter_dep(state->referenced_param, param_func, data)) 4065 return TRUE; 4066 } 4067 return walk_param_eval_dep(state->parameter.param_eval, param_func, data); 4068 } 4069 4070 static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func, 4071 void *data) 4072 { 4073 unsigned int i; 4074 unsigned int member_count; 4075 4076 param = ¶m->top_level_param->param; 4077 if (param_func(data, param)) 4078 return TRUE; 4079 4080 if (walk_param_eval_dep(param->param_eval, param_func, data)) 4081 return TRUE; 4082 4083 if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type)) 4084 { 4085 struct d3dx_sampler *sampler; 4086 unsigned int sampler_idx; 4087 unsigned int samplers_count = max(param->element_count, 1); 4088 4089 for (sampler_idx = 0; sampler_idx < samplers_count; ++sampler_idx) 4090 { 4091 sampler = param->element_count ? param->members[sampler_idx].data : param->data; 4092 for (i = 0; i < sampler->state_count; ++i) 4093 { 4094 if (walk_state_dep(&sampler->states[i], param_func, data)) 4095 return TRUE; 4096 } 4097 } 4098 return FALSE; 4099 } 4100 4101 member_count = param->element_count ? param->element_count : param->member_count; 4102 for (i = 0; i < member_count; ++i) 4103 { 4104 if (walk_param_eval_dep(param->members[i].param_eval, param_func, data)) 4105 return TRUE; 4106 } 4107 4108 return FALSE; 4109 } 4110 4111 static BOOL is_parameter_used(struct d3dx_parameter *param, struct d3dx_technique *tech) 4112 { 4113 unsigned int i, j; 4114 struct d3dx_pass *pass; 4115 4116 if (!tech || !param) 4117 return FALSE; 4118 4119 for (i = 0; i < tech->pass_count; ++i) 4120 { 4121 pass = &tech->passes[i]; 4122 for (j = 0; j < pass->state_count; ++j) 4123 { 4124 if (walk_state_dep(&pass->states[j], is_same_parameter, param)) 4125 return TRUE; 4126 } 4127 } 4128 return FALSE; 4129 } 4130 4131 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique) 4132 { 4133 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface); 4134 struct d3dx_parameter *param = get_valid_parameter(&effect->base_effect, parameter); 4135 struct d3dx_technique *tech = get_valid_technique(&effect->base_effect, technique); 4136 BOOL ret; 4137 4138 TRACE("iface %p, parameter %p, technique %p.\n", iface, parameter, technique); 4139 TRACE("param %p, name %s, tech %p.\n", param, param ? debugstr_a(param->name) : "", tech); 4140 4141 ret = is_parameter_used(param, tech); 4142 TRACE("Returning %#x.\n", ret); 4143 return ret; 4144 } 4145 4146 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags) 4147 { 4148 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface); 4149 struct d3dx_technique *technique = effect->active_technique; 4150 4151 TRACE("iface %p, passes %p, flags %#x.\n", iface, passes, flags); 4152 4153 if (passes && technique) 4154 { 4155 if (flags & ~(D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE | D3DXFX_DONOTSAVESHADERSTATE)) 4156 WARN("Invalid flags (%#x) specified.\n", flags); 4157 4158 if (flags & D3DXFX_DONOTSAVESTATE) 4159 { 4160 TRACE("State capturing disabled.\n"); 4161 } 4162 else 4163 { 4164 HRESULT hr; 4165 unsigned int i; 4166 4167 if (!technique->saved_state) 4168 { 4169 ID3DXEffectStateManager *manager; 4170 4171 manager = effect->manager; 4172 effect->manager = NULL; 4173 if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device))) 4174 ERR("BeginStateBlock failed, hr %#x.\n", hr); 4175 for (i = 0; i < technique->pass_count; i++) 4176 d3dx9_apply_pass_states(effect, &technique->passes[i], TRUE); 4177 if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state))) 4178 ERR("EndStateBlock failed, hr %#x.\n", hr); 4179 effect->manager = manager; 4180 } 4181 if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state))) 4182 ERR("StateBlock Capture failed, hr %#x.\n", hr); 4183 } 4184 4185 *passes = technique->pass_count; 4186 effect->started = TRUE; 4187 effect->begin_flags = flags; 4188 4189 return D3D_OK; 4190 } 4191 4192 WARN("Invalid argument supplied.\n"); 4193 4194 return D3DERR_INVALIDCALL; 4195 } 4196 4197 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass) 4198 { 4199 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface); 4200 struct d3dx_technique *technique = effect->active_technique; 4201 4202 TRACE("iface %p, pass %u\n", effect, pass); 4203 4204 if (technique && pass < technique->pass_count && !effect->active_pass) 4205 { 4206 HRESULT hr; 4207 4208 memset(effect->current_light, 0, sizeof(effect->current_light)); 4209 memset(&effect->current_material, 0, sizeof(effect->current_material)); 4210 4211 if (SUCCEEDED(hr = d3dx9_apply_pass_states(effect, &technique->passes[pass], TRUE))) 4212 effect->active_pass = &technique->passes[pass]; 4213 return hr; 4214 } 4215 4216 WARN("Invalid argument supplied.\n"); 4217 4218 return D3DERR_INVALIDCALL; 4219 } 4220 4221 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect *iface) 4222 { 4223 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface); 4224 4225 TRACE("iface %p.\n", iface); 4226 4227 if (!effect->active_pass) 4228 { 4229 WARN("Called without an active pass.\n"); 4230 return D3D_OK; 4231 } 4232 return d3dx9_apply_pass_states(effect, effect->active_pass, FALSE); 4233 } 4234 4235 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface) 4236 { 4237 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4238 4239 TRACE("iface %p\n", This); 4240 4241 if (This->active_pass) 4242 { 4243 This->active_pass = NULL; 4244 return D3D_OK; 4245 } 4246 4247 WARN("Invalid call.\n"); 4248 4249 return D3DERR_INVALIDCALL; 4250 } 4251 4252 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect *iface) 4253 { 4254 struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface); 4255 struct d3dx_technique *technique = effect->active_technique; 4256 4257 TRACE("iface %p.\n", iface); 4258 4259 if (!effect->started) 4260 return D3D_OK; 4261 4262 if (effect->begin_flags & D3DXFX_DONOTSAVESTATE) 4263 { 4264 TRACE("State restoring disabled.\n"); 4265 } 4266 else 4267 { 4268 HRESULT hr; 4269 4270 if (technique && technique->saved_state) 4271 { 4272 if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state))) 4273 ERR("State block apply failed, hr %#x.\n", hr); 4274 } 4275 else 4276 ERR("No saved state.\n"); 4277 } 4278 4279 effect->started = FALSE; 4280 4281 return D3D_OK; 4282 } 4283 4284 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, struct IDirect3DDevice9 **device) 4285 { 4286 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4287 4288 TRACE("iface %p, device %p\n", This, device); 4289 4290 if (!device) 4291 { 4292 WARN("Invalid argument supplied.\n"); 4293 return D3DERR_INVALIDCALL; 4294 } 4295 4296 IDirect3DDevice9_AddRef(This->device); 4297 4298 *device = This->device; 4299 4300 TRACE("Returning device %p\n", *device); 4301 4302 return S_OK; 4303 } 4304 4305 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface) 4306 { 4307 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4308 4309 FIXME("(%p)->(): stub\n", This); 4310 4311 return E_NOTIMPL; 4312 } 4313 4314 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface) 4315 { 4316 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4317 4318 FIXME("(%p)->(): stub\n", This); 4319 4320 return E_NOTIMPL; 4321 } 4322 4323 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager *manager) 4324 { 4325 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4326 4327 TRACE("iface %p, manager %p\n", This, manager); 4328 4329 if (manager) IUnknown_AddRef(manager); 4330 if (This->manager) IUnknown_Release(This->manager); 4331 4332 This->manager = manager; 4333 4334 return D3D_OK; 4335 } 4336 4337 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, ID3DXEffectStateManager **manager) 4338 { 4339 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4340 4341 TRACE("iface %p, manager %p\n", This, manager); 4342 4343 if (!manager) 4344 { 4345 WARN("Invalid argument supplied.\n"); 4346 return D3DERR_INVALIDCALL; 4347 } 4348 4349 if (This->manager) IUnknown_AddRef(This->manager); 4350 *manager = This->manager; 4351 4352 return D3D_OK; 4353 } 4354 4355 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface) 4356 { 4357 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4358 4359 FIXME("(%p)->(): stub\n", This); 4360 4361 return E_NOTIMPL; 4362 } 4363 4364 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface) 4365 { 4366 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4367 4368 FIXME("(%p)->(): stub\n", This); 4369 4370 return NULL; 4371 } 4372 4373 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block) 4374 { 4375 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4376 4377 FIXME("(%p)->(%p): stub\n", This, parameter_block); 4378 4379 return E_NOTIMPL; 4380 } 4381 4382 #if _D3DX9_VER >= 26 4383 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block) 4384 { 4385 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4386 4387 FIXME("(%p)->(%p): stub\n", This, parameter_block); 4388 4389 return E_NOTIMPL; 4390 } 4391 #endif 4392 4393 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface, 4394 struct IDirect3DDevice9 *device, struct ID3DXEffect **effect) 4395 { 4396 struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); 4397 4398 FIXME("(%p)->(%p, %p): stub\n", This, device, effect); 4399 4400 if (!effect) 4401 return D3DXERR_INVALIDDATA; 4402 4403 iface->lpVtbl->AddRef(iface); 4404 *effect = iface; 4405 return S_OK; 4406 } 4407 4408 #if _D3DX9_VER >= 27 4409 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface, 4410 D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes) 4411 { 4412 FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n", 4413 iface, parameter, data, byte_offset, bytes); 4414 4415 return E_NOTIMPL; 4416 } 4417 #endif 4418 4419 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl = 4420 { 4421 /*** IUnknown methods ***/ 4422 ID3DXEffectImpl_QueryInterface, 4423 ID3DXEffectImpl_AddRef, 4424 ID3DXEffectImpl_Release, 4425 /*** ID3DXBaseEffect methods ***/ 4426 ID3DXEffectImpl_GetDesc, 4427 ID3DXEffectImpl_GetParameterDesc, 4428 ID3DXEffectImpl_GetTechniqueDesc, 4429 ID3DXEffectImpl_GetPassDesc, 4430 ID3DXEffectImpl_GetFunctionDesc, 4431 ID3DXEffectImpl_GetParameter, 4432 ID3DXEffectImpl_GetParameterByName, 4433 ID3DXEffectImpl_GetParameterBySemantic, 4434 ID3DXEffectImpl_GetParameterElement, 4435 ID3DXEffectImpl_GetTechnique, 4436 ID3DXEffectImpl_GetTechniqueByName, 4437 ID3DXEffectImpl_GetPass, 4438 ID3DXEffectImpl_GetPassByName, 4439 ID3DXEffectImpl_GetFunction, 4440 ID3DXEffectImpl_GetFunctionByName, 4441 ID3DXEffectImpl_GetAnnotation, 4442 ID3DXEffectImpl_GetAnnotationByName, 4443 ID3DXEffectImpl_SetValue, 4444 ID3DXEffectImpl_GetValue, 4445 ID3DXEffectImpl_SetBool, 4446 ID3DXEffectImpl_GetBool, 4447 ID3DXEffectImpl_SetBoolArray, 4448 ID3DXEffectImpl_GetBoolArray, 4449 ID3DXEffectImpl_SetInt, 4450 ID3DXEffectImpl_GetInt, 4451 ID3DXEffectImpl_SetIntArray, 4452 ID3DXEffectImpl_GetIntArray, 4453 ID3DXEffectImpl_SetFloat, 4454 ID3DXEffectImpl_GetFloat, 4455 ID3DXEffectImpl_SetFloatArray, 4456 ID3DXEffectImpl_GetFloatArray, 4457 ID3DXEffectImpl_SetVector, 4458 ID3DXEffectImpl_GetVector, 4459 ID3DXEffectImpl_SetVectorArray, 4460 ID3DXEffectImpl_GetVectorArray, 4461 ID3DXEffectImpl_SetMatrix, 4462 ID3DXEffectImpl_GetMatrix, 4463 ID3DXEffectImpl_SetMatrixArray, 4464 ID3DXEffectImpl_GetMatrixArray, 4465 ID3DXEffectImpl_SetMatrixPointerArray, 4466 ID3DXEffectImpl_GetMatrixPointerArray, 4467 ID3DXEffectImpl_SetMatrixTranspose, 4468 ID3DXEffectImpl_GetMatrixTranspose, 4469 ID3DXEffectImpl_SetMatrixTransposeArray, 4470 ID3DXEffectImpl_GetMatrixTransposeArray, 4471 ID3DXEffectImpl_SetMatrixTransposePointerArray, 4472 ID3DXEffectImpl_GetMatrixTransposePointerArray, 4473 ID3DXEffectImpl_SetString, 4474 ID3DXEffectImpl_GetString, 4475 ID3DXEffectImpl_SetTexture, 4476 ID3DXEffectImpl_GetTexture, 4477 ID3DXEffectImpl_GetPixelShader, 4478 ID3DXEffectImpl_GetVertexShader, 4479 ID3DXEffectImpl_SetArrayRange, 4480 /*** ID3DXEffect methods ***/ 4481 ID3DXEffectImpl_GetPool, 4482 ID3DXEffectImpl_SetTechnique, 4483 ID3DXEffectImpl_GetCurrentTechnique, 4484 ID3DXEffectImpl_ValidateTechnique, 4485 ID3DXEffectImpl_FindNextValidTechnique, 4486 ID3DXEffectImpl_IsParameterUsed, 4487 ID3DXEffectImpl_Begin, 4488 ID3DXEffectImpl_BeginPass, 4489 ID3DXEffectImpl_CommitChanges, 4490 ID3DXEffectImpl_EndPass, 4491 ID3DXEffectImpl_End, 4492 ID3DXEffectImpl_GetDevice, 4493 ID3DXEffectImpl_OnLostDevice, 4494 ID3DXEffectImpl_OnResetDevice, 4495 ID3DXEffectImpl_SetStateManager, 4496 ID3DXEffectImpl_GetStateManager, 4497 ID3DXEffectImpl_BeginParameterBlock, 4498 ID3DXEffectImpl_EndParameterBlock, 4499 ID3DXEffectImpl_ApplyParameterBlock, 4500 #if _D3DX9_VER >= 26 4501 ID3DXEffectImpl_DeleteParameterBlock, 4502 #endif 4503 ID3DXEffectImpl_CloneEffect, 4504 #if _D3DX9_VER >= 27 4505 ID3DXEffectImpl_SetRawValue 4506 #endif 4507 }; 4508 4509 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface) 4510 { 4511 return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface); 4512 } 4513 4514 /*** IUnknown methods ***/ 4515 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object) 4516 { 4517 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 4518 4519 if (IsEqualGUID(riid, &IID_IUnknown) || 4520 IsEqualGUID(riid, &IID_ID3DXEffectCompiler)) 4521 { 4522 iface->lpVtbl->AddRef(iface); 4523 *object = iface; 4524 return S_OK; 4525 } 4526 4527 ERR("Interface %s not found\n", debugstr_guid(riid)); 4528 4529 return E_NOINTERFACE; 4530 } 4531 4532 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface) 4533 { 4534 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface); 4535 4536 TRACE("iface %p: AddRef from %u\n", iface, This->ref); 4537 4538 return InterlockedIncrement(&This->ref); 4539 } 4540 4541 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface) 4542 { 4543 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface); 4544 ULONG ref = InterlockedDecrement(&This->ref); 4545 4546 TRACE("iface %p: Release from %u\n", iface, ref + 1); 4547 4548 if (!ref) 4549 { 4550 free_effect_compiler(This); 4551 HeapFree(GetProcessHeap(), 0, This); 4552 } 4553 4554 return ref; 4555 } 4556 4557 /*** ID3DXBaseEffect methods ***/ 4558 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc) 4559 { 4560 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4561 4562 TRACE("iface %p, desc %p.\n", iface, desc); 4563 4564 return d3dx9_base_effect_get_desc(&compiler->base_effect, desc); 4565 } 4566 4567 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, 4568 D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc) 4569 { 4570 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4571 4572 TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc); 4573 4574 return d3dx9_base_effect_get_parameter_desc(&compiler->base_effect, parameter, desc); 4575 } 4576 4577 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, 4578 D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc) 4579 { 4580 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4581 4582 TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc); 4583 4584 return d3dx9_base_effect_get_technique_desc(&compiler->base_effect, technique, desc); 4585 } 4586 4587 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, 4588 D3DXHANDLE pass, D3DXPASS_DESC *desc) 4589 { 4590 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4591 4592 TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc); 4593 4594 return d3dx9_base_effect_get_pass_desc(&compiler->base_effect, pass, desc); 4595 } 4596 4597 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, 4598 D3DXHANDLE shader, D3DXFUNCTION_DESC *desc) 4599 { 4600 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4601 4602 TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc); 4603 4604 return d3dx9_base_effect_get_function_desc(&compiler->base_effect, shader, desc); 4605 } 4606 4607 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, 4608 D3DXHANDLE parameter, UINT index) 4609 { 4610 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4611 4612 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index); 4613 4614 return d3dx9_base_effect_get_parameter(&compiler->base_effect, parameter, index); 4615 } 4616 4617 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, 4618 D3DXHANDLE parameter, const char *name) 4619 { 4620 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4621 4622 TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name)); 4623 4624 return d3dx9_base_effect_get_parameter_by_name(&compiler->base_effect, parameter, name); 4625 } 4626 4627 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, 4628 D3DXHANDLE parameter, const char *semantic) 4629 { 4630 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4631 4632 TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic)); 4633 4634 return d3dx9_base_effect_get_parameter_by_semantic(&compiler->base_effect, parameter, semantic); 4635 } 4636 4637 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, 4638 D3DXHANDLE parameter, UINT index) 4639 { 4640 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4641 4642 TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index); 4643 4644 return d3dx9_base_effect_get_parameter_element(&compiler->base_effect, parameter, index); 4645 } 4646 4647 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index) 4648 { 4649 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4650 4651 TRACE("iface %p, index %u.\n", iface, index); 4652 4653 return d3dx9_base_effect_get_technique(&compiler->base_effect, index); 4654 } 4655 4656 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, const char *name) 4657 { 4658 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4659 4660 TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); 4661 4662 return d3dx9_base_effect_get_technique_by_name(&compiler->base_effect, name); 4663 } 4664 4665 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index) 4666 { 4667 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4668 4669 TRACE("iface %p, technique %p, index %u.\n", iface, technique, index); 4670 4671 return d3dx9_base_effect_get_pass(&compiler->base_effect, technique, index); 4672 } 4673 4674 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, 4675 D3DXHANDLE technique, const char *name) 4676 { 4677 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4678 4679 TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name)); 4680 4681 return d3dx9_base_effect_get_pass_by_name(&compiler->base_effect, technique, name); 4682 } 4683 4684 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index) 4685 { 4686 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4687 4688 TRACE("iface %p, index %u.\n", iface, index); 4689 4690 return d3dx9_base_effect_get_function(&compiler->base_effect, index); 4691 } 4692 4693 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, const char *name) 4694 { 4695 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4696 4697 TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); 4698 4699 return d3dx9_base_effect_get_function_by_name(&compiler->base_effect, name); 4700 } 4701 4702 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, 4703 D3DXHANDLE object, UINT index) 4704 { 4705 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4706 4707 TRACE("iface %p, object %p, index %u.\n", iface, object, index); 4708 4709 return d3dx9_base_effect_get_annotation(&compiler->base_effect, object, index); 4710 } 4711 4712 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, 4713 D3DXHANDLE object, const char *name) 4714 { 4715 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4716 4717 TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name)); 4718 4719 return d3dx9_base_effect_get_annotation_by_name(&compiler->base_effect, object, name); 4720 } 4721 4722 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, 4723 D3DXHANDLE parameter, const void *data, UINT bytes) 4724 { 4725 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4726 4727 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes); 4728 4729 return d3dx9_base_effect_set_value(&compiler->base_effect, parameter, data, bytes); 4730 } 4731 4732 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, 4733 D3DXHANDLE parameter, void *data, UINT bytes) 4734 { 4735 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4736 4737 TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes); 4738 4739 return d3dx9_base_effect_get_value(&compiler->base_effect, parameter, data, bytes); 4740 } 4741 4742 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b) 4743 { 4744 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4745 4746 TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b); 4747 4748 return d3dx9_base_effect_set_bool(&compiler->base_effect, parameter, b); 4749 } 4750 4751 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b) 4752 { 4753 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4754 4755 TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b); 4756 4757 return d3dx9_base_effect_get_bool(&compiler->base_effect, parameter, b); 4758 } 4759 4760 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, 4761 D3DXHANDLE parameter, const BOOL *b, UINT count) 4762 { 4763 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4764 4765 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count); 4766 4767 return d3dx9_base_effect_set_bool_array(&compiler->base_effect, parameter, b, count); 4768 } 4769 4770 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, 4771 D3DXHANDLE parameter, BOOL *b, UINT count) 4772 { 4773 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4774 4775 TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count); 4776 4777 return d3dx9_base_effect_get_bool_array(&compiler->base_effect, parameter, b, count); 4778 } 4779 4780 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n) 4781 { 4782 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4783 4784 TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n); 4785 4786 return d3dx9_base_effect_set_int(&compiler->base_effect, parameter, n); 4787 } 4788 4789 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n) 4790 { 4791 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4792 4793 TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n); 4794 4795 return d3dx9_base_effect_get_int(&compiler->base_effect, parameter, n); 4796 } 4797 4798 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, 4799 D3DXHANDLE parameter, const INT *n, UINT count) 4800 { 4801 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4802 4803 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count); 4804 4805 return d3dx9_base_effect_set_int_array(&compiler->base_effect, parameter, n, count); 4806 } 4807 4808 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, 4809 D3DXHANDLE parameter, INT *n, UINT count) 4810 { 4811 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4812 4813 TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count); 4814 4815 return d3dx9_base_effect_get_int_array(&compiler->base_effect, parameter, n, count); 4816 } 4817 4818 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float f) 4819 { 4820 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4821 4822 TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f); 4823 4824 return d3dx9_base_effect_set_float(&compiler->base_effect, parameter, f); 4825 } 4826 4827 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, float *f) 4828 { 4829 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4830 4831 TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f); 4832 4833 return d3dx9_base_effect_get_float(&compiler->base_effect, parameter, f); 4834 } 4835 4836 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, 4837 D3DXHANDLE parameter, const float *f, UINT count) 4838 { 4839 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4840 4841 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count); 4842 4843 return d3dx9_base_effect_set_float_array(&compiler->base_effect, parameter, f, count); 4844 } 4845 4846 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, 4847 D3DXHANDLE parameter, float *f, UINT count) 4848 { 4849 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4850 4851 TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count); 4852 4853 return d3dx9_base_effect_get_float_array(&compiler->base_effect, parameter, f, count); 4854 } 4855 4856 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, 4857 D3DXHANDLE parameter, const D3DXVECTOR4 *vector) 4858 { 4859 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4860 4861 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector); 4862 4863 return d3dx9_base_effect_set_vector(&compiler->base_effect, parameter, vector); 4864 } 4865 4866 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, 4867 D3DXHANDLE parameter, D3DXVECTOR4 *vector) 4868 { 4869 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4870 4871 TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector); 4872 4873 return d3dx9_base_effect_get_vector(&compiler->base_effect, parameter, vector); 4874 } 4875 4876 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, 4877 D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count) 4878 { 4879 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4880 4881 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count); 4882 4883 return d3dx9_base_effect_set_vector_array(&compiler->base_effect, parameter, vector, count); 4884 } 4885 4886 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, 4887 D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count) 4888 { 4889 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4890 4891 TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count); 4892 4893 return d3dx9_base_effect_get_vector_array(&compiler->base_effect, parameter, vector, count); 4894 } 4895 4896 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, 4897 D3DXHANDLE parameter, const D3DXMATRIX *matrix) 4898 { 4899 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4900 4901 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix); 4902 4903 return d3dx9_base_effect_set_matrix(&compiler->base_effect, parameter, matrix); 4904 } 4905 4906 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, 4907 D3DXHANDLE parameter, D3DXMATRIX *matrix) 4908 { 4909 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4910 4911 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix); 4912 4913 return d3dx9_base_effect_get_matrix(&compiler->base_effect, parameter, matrix); 4914 } 4915 4916 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, 4917 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count) 4918 { 4919 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4920 4921 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 4922 4923 return d3dx9_base_effect_set_matrix_array(&compiler->base_effect, parameter, matrix, count); 4924 } 4925 4926 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, 4927 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count) 4928 { 4929 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4930 4931 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 4932 4933 return d3dx9_base_effect_get_matrix_array(&compiler->base_effect, parameter, matrix, count); 4934 } 4935 4936 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface, 4937 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count) 4938 { 4939 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4940 4941 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 4942 4943 return d3dx9_base_effect_set_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count); 4944 } 4945 4946 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface, 4947 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count) 4948 { 4949 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4950 4951 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 4952 4953 return d3dx9_base_effect_get_matrix_pointer_array(&compiler->base_effect, parameter, matrix, count); 4954 } 4955 4956 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, 4957 D3DXHANDLE parameter, const D3DXMATRIX *matrix) 4958 { 4959 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4960 4961 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix); 4962 4963 return d3dx9_base_effect_set_matrix_transpose(&compiler->base_effect, parameter, matrix); 4964 } 4965 4966 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, 4967 D3DXHANDLE parameter, D3DXMATRIX *matrix) 4968 { 4969 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4970 4971 TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix); 4972 4973 return d3dx9_base_effect_get_matrix_transpose(&compiler->base_effect, parameter, matrix); 4974 } 4975 4976 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, 4977 D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count) 4978 { 4979 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4980 4981 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 4982 4983 return d3dx9_base_effect_set_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count); 4984 } 4985 4986 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, 4987 D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count) 4988 { 4989 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 4990 4991 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 4992 4993 return d3dx9_base_effect_get_matrix_transpose_array(&compiler->base_effect, parameter, matrix, count); 4994 } 4995 4996 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, 4997 D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count) 4998 { 4999 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5000 5001 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 5002 5003 return d3dx9_base_effect_set_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count); 5004 } 5005 5006 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, 5007 D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count) 5008 { 5009 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5010 5011 TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count); 5012 5013 return d3dx9_base_effect_get_matrix_transpose_pointer_array(&compiler->base_effect, parameter, matrix, count); 5014 } 5015 5016 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, 5017 D3DXHANDLE parameter, const char *string) 5018 { 5019 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5020 5021 TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string)); 5022 5023 return d3dx9_base_effect_set_string(&compiler->base_effect, parameter, string); 5024 } 5025 5026 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, 5027 D3DXHANDLE parameter, const char **string) 5028 { 5029 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5030 5031 TRACE("iface %p, parameter %p, string %p.\n", iface, parameter, string); 5032 5033 return d3dx9_base_effect_get_string(&compiler->base_effect, parameter, string); 5034 } 5035 5036 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(struct ID3DXEffectCompiler *iface, 5037 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture) 5038 { 5039 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5040 5041 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture); 5042 5043 return d3dx9_base_effect_set_texture(&compiler->base_effect, parameter, texture); 5044 } 5045 5046 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(struct ID3DXEffectCompiler *iface, 5047 D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture) 5048 { 5049 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5050 5051 TRACE("iface %p, parameter %p, texture %p.\n", iface, parameter, texture); 5052 5053 return d3dx9_base_effect_get_texture(&compiler->base_effect, parameter, texture); 5054 } 5055 5056 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface, 5057 D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader) 5058 { 5059 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5060 5061 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader); 5062 5063 return d3dx9_base_effect_get_pixel_shader(&compiler->base_effect, parameter, shader); 5064 } 5065 5066 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(struct ID3DXEffectCompiler *iface, 5067 D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader) 5068 { 5069 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5070 5071 TRACE("iface %p, parameter %p, shader %p.\n", iface, parameter, shader); 5072 5073 return d3dx9_base_effect_get_vertex_shader(&compiler->base_effect, parameter, shader); 5074 } 5075 5076 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, 5077 D3DXHANDLE parameter, UINT start, UINT end) 5078 { 5079 struct ID3DXEffectCompilerImpl *compiler = impl_from_ID3DXEffectCompiler(iface); 5080 5081 TRACE("iface %p, parameter %p, start %u, end %u.\n", iface, parameter, start, end); 5082 5083 return d3dx9_base_effect_set_array_range(&compiler->base_effect, parameter, start, end); 5084 } 5085 5086 /*** ID3DXEffectCompiler methods ***/ 5087 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal) 5088 { 5089 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface); 5090 5091 FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal); 5092 5093 return E_NOTIMPL; 5094 } 5095 5096 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal) 5097 { 5098 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface); 5099 5100 FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal); 5101 5102 return E_NOTIMPL; 5103 } 5104 5105 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags, 5106 ID3DXBuffer **effect, ID3DXBuffer **error_msgs) 5107 { 5108 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface); 5109 5110 FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs); 5111 5112 return E_NOTIMPL; 5113 } 5114 5115 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function, 5116 const char *target, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs, 5117 ID3DXConstantTable **constant_table) 5118 { 5119 struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface); 5120 5121 FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n", 5122 This, function, target, flags, shader, error_msgs, constant_table); 5123 5124 return E_NOTIMPL; 5125 } 5126 5127 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl = 5128 { 5129 /*** IUnknown methods ***/ 5130 ID3DXEffectCompilerImpl_QueryInterface, 5131 ID3DXEffectCompilerImpl_AddRef, 5132 ID3DXEffectCompilerImpl_Release, 5133 /*** ID3DXBaseEffect methods ***/ 5134 ID3DXEffectCompilerImpl_GetDesc, 5135 ID3DXEffectCompilerImpl_GetParameterDesc, 5136 ID3DXEffectCompilerImpl_GetTechniqueDesc, 5137 ID3DXEffectCompilerImpl_GetPassDesc, 5138 ID3DXEffectCompilerImpl_GetFunctionDesc, 5139 ID3DXEffectCompilerImpl_GetParameter, 5140 ID3DXEffectCompilerImpl_GetParameterByName, 5141 ID3DXEffectCompilerImpl_GetParameterBySemantic, 5142 ID3DXEffectCompilerImpl_GetParameterElement, 5143 ID3DXEffectCompilerImpl_GetTechnique, 5144 ID3DXEffectCompilerImpl_GetTechniqueByName, 5145 ID3DXEffectCompilerImpl_GetPass, 5146 ID3DXEffectCompilerImpl_GetPassByName, 5147 ID3DXEffectCompilerImpl_GetFunction, 5148 ID3DXEffectCompilerImpl_GetFunctionByName, 5149 ID3DXEffectCompilerImpl_GetAnnotation, 5150 ID3DXEffectCompilerImpl_GetAnnotationByName, 5151 ID3DXEffectCompilerImpl_SetValue, 5152 ID3DXEffectCompilerImpl_GetValue, 5153 ID3DXEffectCompilerImpl_SetBool, 5154 ID3DXEffectCompilerImpl_GetBool, 5155 ID3DXEffectCompilerImpl_SetBoolArray, 5156 ID3DXEffectCompilerImpl_GetBoolArray, 5157 ID3DXEffectCompilerImpl_SetInt, 5158 ID3DXEffectCompilerImpl_GetInt, 5159 ID3DXEffectCompilerImpl_SetIntArray, 5160 ID3DXEffectCompilerImpl_GetIntArray, 5161 ID3DXEffectCompilerImpl_SetFloat, 5162 ID3DXEffectCompilerImpl_GetFloat, 5163 ID3DXEffectCompilerImpl_SetFloatArray, 5164 ID3DXEffectCompilerImpl_GetFloatArray, 5165 ID3DXEffectCompilerImpl_SetVector, 5166 ID3DXEffectCompilerImpl_GetVector, 5167 ID3DXEffectCompilerImpl_SetVectorArray, 5168 ID3DXEffectCompilerImpl_GetVectorArray, 5169 ID3DXEffectCompilerImpl_SetMatrix, 5170 ID3DXEffectCompilerImpl_GetMatrix, 5171 ID3DXEffectCompilerImpl_SetMatrixArray, 5172 ID3DXEffectCompilerImpl_GetMatrixArray, 5173 ID3DXEffectCompilerImpl_SetMatrixPointerArray, 5174 ID3DXEffectCompilerImpl_GetMatrixPointerArray, 5175 ID3DXEffectCompilerImpl_SetMatrixTranspose, 5176 ID3DXEffectCompilerImpl_GetMatrixTranspose, 5177 ID3DXEffectCompilerImpl_SetMatrixTransposeArray, 5178 ID3DXEffectCompilerImpl_GetMatrixTransposeArray, 5179 ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray, 5180 ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray, 5181 ID3DXEffectCompilerImpl_SetString, 5182 ID3DXEffectCompilerImpl_GetString, 5183 ID3DXEffectCompilerImpl_SetTexture, 5184 ID3DXEffectCompilerImpl_GetTexture, 5185 ID3DXEffectCompilerImpl_GetPixelShader, 5186 ID3DXEffectCompilerImpl_GetVertexShader, 5187 ID3DXEffectCompilerImpl_SetArrayRange, 5188 /*** ID3DXEffectCompiler methods ***/ 5189 ID3DXEffectCompilerImpl_SetLiteral, 5190 ID3DXEffectCompilerImpl_GetLiteral, 5191 ID3DXEffectCompilerImpl_CompileEffect, 5192 ID3DXEffectCompilerImpl_CompileShader, 5193 }; 5194 5195 static HRESULT d3dx9_parse_sampler(struct d3dx9_base_effect *base, struct d3dx_sampler *sampler, 5196 const char *data, const char **ptr, struct d3dx_object *objects) 5197 { 5198 HRESULT hr; 5199 UINT i; 5200 5201 read_dword(ptr, &sampler->state_count); 5202 TRACE("Count: %u\n", sampler->state_count); 5203 5204 sampler->states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler->states) * sampler->state_count); 5205 if (!sampler->states) 5206 { 5207 ERR("Out of memory\n"); 5208 return E_OUTOFMEMORY; 5209 } 5210 5211 for (i = 0; i < sampler->state_count; ++i) 5212 { 5213 hr = d3dx9_parse_state(base, &sampler->states[i], data, ptr, objects); 5214 if (hr != D3D_OK) 5215 { 5216 WARN("Failed to parse state %u\n", i); 5217 goto err_out; 5218 } 5219 } 5220 5221 return D3D_OK; 5222 5223 err_out: 5224 5225 for (i = 0; i < sampler->state_count; ++i) 5226 { 5227 free_state(&sampler->states[i]); 5228 } 5229 HeapFree(GetProcessHeap(), 0, sampler->states); 5230 sampler->states = NULL; 5231 5232 return hr; 5233 } 5234 5235 static HRESULT d3dx9_parse_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param, 5236 void *value, const char *data, const char **ptr, struct d3dx_object *objects) 5237 { 5238 unsigned int i; 5239 HRESULT hr; 5240 UINT old_size = 0; 5241 5242 if (param->element_count) 5243 { 5244 param->data = value; 5245 5246 for (i = 0; i < param->element_count; ++i) 5247 { 5248 struct d3dx_parameter *member = ¶m->members[i]; 5249 5250 hr = d3dx9_parse_value(base, member, value ? (char *)value + old_size : NULL, data, ptr, objects); 5251 if (hr != D3D_OK) 5252 { 5253 WARN("Failed to parse value %u\n", i); 5254 return hr; 5255 } 5256 5257 old_size += member->bytes; 5258 } 5259 5260 return D3D_OK; 5261 } 5262 5263 switch(param->class) 5264 { 5265 case D3DXPC_SCALAR: 5266 case D3DXPC_VECTOR: 5267 case D3DXPC_MATRIX_ROWS: 5268 case D3DXPC_MATRIX_COLUMNS: 5269 param->data = value; 5270 break; 5271 5272 case D3DXPC_STRUCT: 5273 param->data = value; 5274 5275 for (i = 0; i < param->member_count; ++i) 5276 { 5277 struct d3dx_parameter *member = ¶m->members[i]; 5278 5279 hr = d3dx9_parse_value(base, member, (char *)value + old_size, data, ptr, objects); 5280 if (hr != D3D_OK) 5281 { 5282 WARN("Failed to parse value %u\n", i); 5283 return hr; 5284 } 5285 5286 old_size += member->bytes; 5287 } 5288 break; 5289 5290 case D3DXPC_OBJECT: 5291 switch (param->type) 5292 { 5293 case D3DXPT_STRING: 5294 case D3DXPT_TEXTURE: 5295 case D3DXPT_TEXTURE1D: 5296 case D3DXPT_TEXTURE2D: 5297 case D3DXPT_TEXTURE3D: 5298 case D3DXPT_TEXTURECUBE: 5299 case D3DXPT_PIXELSHADER: 5300 case D3DXPT_VERTEXSHADER: 5301 read_dword(ptr, ¶m->object_id); 5302 TRACE("Id: %u\n", param->object_id); 5303 objects[param->object_id].param = param; 5304 param->data = value; 5305 break; 5306 5307 case D3DXPT_SAMPLER: 5308 case D3DXPT_SAMPLER1D: 5309 case D3DXPT_SAMPLER2D: 5310 case D3DXPT_SAMPLER3D: 5311 case D3DXPT_SAMPLERCUBE: 5312 { 5313 struct d3dx_sampler *sampler; 5314 5315 sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler)); 5316 if (!sampler) 5317 return E_OUTOFMEMORY; 5318 5319 hr = d3dx9_parse_sampler(base, sampler, data, ptr, objects); 5320 if (hr != D3D_OK) 5321 { 5322 HeapFree(GetProcessHeap(), 0, sampler); 5323 WARN("Failed to parse sampler\n"); 5324 return hr; 5325 } 5326 5327 param->data = sampler; 5328 break; 5329 } 5330 5331 default: 5332 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type)); 5333 break; 5334 } 5335 break; 5336 5337 default: 5338 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class)); 5339 break; 5340 } 5341 5342 return D3D_OK; 5343 } 5344 5345 static HRESULT d3dx9_parse_init_value(struct d3dx9_base_effect *base, struct d3dx_parameter *param, 5346 const char *data, const char *ptr, struct d3dx_object *objects) 5347 { 5348 UINT size = param->bytes; 5349 HRESULT hr; 5350 void *value = NULL; 5351 5352 TRACE("param size: %u\n", size); 5353 5354 if (size) 5355 { 5356 value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 5357 if (!value) 5358 { 5359 ERR("Failed to allocate data memory.\n"); 5360 return E_OUTOFMEMORY; 5361 } 5362 5363 switch(param->class) 5364 { 5365 case D3DXPC_OBJECT: 5366 break; 5367 5368 case D3DXPC_SCALAR: 5369 case D3DXPC_VECTOR: 5370 case D3DXPC_MATRIX_ROWS: 5371 case D3DXPC_MATRIX_COLUMNS: 5372 case D3DXPC_STRUCT: 5373 TRACE("Data: %s.\n", debugstr_an(ptr, size)); 5374 memcpy(value, ptr, size); 5375 break; 5376 5377 default: 5378 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class)); 5379 break; 5380 } 5381 } 5382 5383 hr = d3dx9_parse_value(base, param, value, data, &ptr, objects); 5384 if (hr != D3D_OK) 5385 { 5386 WARN("Failed to parse value\n"); 5387 HeapFree(GetProcessHeap(), 0, value); 5388 return hr; 5389 } 5390 5391 return D3D_OK; 5392 } 5393 5394 static HRESULT d3dx9_parse_name(char **name, const char *ptr) 5395 { 5396 DWORD size; 5397 5398 read_dword(&ptr, &size); 5399 TRACE("Name size: %#x\n", size); 5400 5401 if (!size) 5402 { 5403 return D3D_OK; 5404 } 5405 5406 *name = HeapAlloc(GetProcessHeap(), 0, size); 5407 if (!*name) 5408 { 5409 ERR("Failed to allocate name memory.\n"); 5410 return E_OUTOFMEMORY; 5411 } 5412 5413 TRACE("Name: %s.\n", debugstr_an(ptr, size)); 5414 memcpy(*name, ptr, size); 5415 5416 return D3D_OK; 5417 } 5418 5419 static HRESULT d3dx9_copy_data(struct d3dx9_base_effect *base, unsigned int object_id, const char **ptr) 5420 { 5421 struct d3dx_object *object = &base->objects[object_id]; 5422 5423 if (object->size || object->data) 5424 { 5425 if (object_id) 5426 FIXME("Overwriting object id %u!\n", object_id); 5427 else 5428 TRACE("Overwriting object id 0.\n"); 5429 5430 HeapFree(GetProcessHeap(), 0, object->data); 5431 object->data = NULL; 5432 } 5433 5434 read_dword(ptr, &object->size); 5435 TRACE("Data size: %#x.\n", object->size); 5436 5437 if (!object->size) 5438 return D3D_OK; 5439 5440 object->data = HeapAlloc(GetProcessHeap(), 0, object->size); 5441 if (!object->data) 5442 { 5443 ERR("Failed to allocate object memory.\n"); 5444 return E_OUTOFMEMORY; 5445 } 5446 5447 TRACE("Data: %s.\n", debugstr_an(*ptr, object->size)); 5448 memcpy(object->data, *ptr, object->size); 5449 5450 *ptr += ((object->size + 3) & ~3); 5451 5452 return D3D_OK; 5453 } 5454 5455 static void param_set_magic_number(struct d3dx_parameter *param) 5456 { 5457 memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string)); 5458 } 5459 5460 static HRESULT d3dx9_parse_effect_typedef(struct d3dx9_base_effect *base, struct d3dx_parameter *param, 5461 const char *data, const char **ptr, struct d3dx_parameter *parent, UINT flags) 5462 { 5463 DWORD offset; 5464 HRESULT hr; 5465 UINT i; 5466 5467 param->flags = flags; 5468 5469 if (!parent) 5470 { 5471 read_dword(ptr, (DWORD *)¶m->type); 5472 TRACE("Type: %s\n", debug_d3dxparameter_type(param->type)); 5473 5474 read_dword(ptr, (DWORD *)¶m->class); 5475 TRACE("Class: %s\n", debug_d3dxparameter_class(param->class)); 5476 5477 read_dword(ptr, &offset); 5478 TRACE("Type name offset: %#x\n", offset); 5479 hr = d3dx9_parse_name(¶m->name, data + offset); 5480 if (hr != D3D_OK) 5481 { 5482 WARN("Failed to parse name\n"); 5483 goto err_out; 5484 } 5485 5486 read_dword(ptr, &offset); 5487 TRACE("Type semantic offset: %#x\n", offset); 5488 hr = d3dx9_parse_name(¶m->semantic, data + offset); 5489 if (hr != D3D_OK) 5490 { 5491 WARN("Failed to parse semantic\n"); 5492 goto err_out; 5493 } 5494 5495 read_dword(ptr, ¶m->element_count); 5496 TRACE("Elements: %u\n", param->element_count); 5497 5498 switch (param->class) 5499 { 5500 case D3DXPC_VECTOR: 5501 read_dword(ptr, ¶m->columns); 5502 TRACE("Columns: %u\n", param->columns); 5503 5504 read_dword(ptr, ¶m->rows); 5505 TRACE("Rows: %u\n", param->rows); 5506 5507 /* sizeof(DWORD) * rows * columns */ 5508 param->bytes = 4 * param->rows * param->columns; 5509 break; 5510 5511 case D3DXPC_SCALAR: 5512 case D3DXPC_MATRIX_ROWS: 5513 case D3DXPC_MATRIX_COLUMNS: 5514 read_dword(ptr, ¶m->rows); 5515 TRACE("Rows: %u\n", param->rows); 5516 5517 read_dword(ptr, ¶m->columns); 5518 TRACE("Columns: %u\n", param->columns); 5519 5520 /* sizeof(DWORD) * rows * columns */ 5521 param->bytes = 4 * param->rows * param->columns; 5522 break; 5523 5524 case D3DXPC_STRUCT: 5525 read_dword(ptr, ¶m->member_count); 5526 TRACE("Members: %u\n", param->member_count); 5527 break; 5528 5529 case D3DXPC_OBJECT: 5530 switch (param->type) 5531 { 5532 case D3DXPT_STRING: 5533 case D3DXPT_PIXELSHADER: 5534 case D3DXPT_VERTEXSHADER: 5535 case D3DXPT_TEXTURE: 5536 case D3DXPT_TEXTURE1D: 5537 case D3DXPT_TEXTURE2D: 5538 case D3DXPT_TEXTURE3D: 5539 case D3DXPT_TEXTURECUBE: 5540 param->bytes = sizeof(void *); 5541 break; 5542 5543 case D3DXPT_SAMPLER: 5544 case D3DXPT_SAMPLER1D: 5545 case D3DXPT_SAMPLER2D: 5546 case D3DXPT_SAMPLER3D: 5547 case D3DXPT_SAMPLERCUBE: 5548 param->bytes = 0; 5549 break; 5550 5551 default: 5552 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type)); 5553 break; 5554 } 5555 break; 5556 5557 default: 5558 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class)); 5559 break; 5560 } 5561 } 5562 else 5563 { 5564 /* elements */ 5565 param->type = parent->type; 5566 param->class = parent->class; 5567 param->name = parent->name; 5568 param->semantic = parent->semantic; 5569 param->element_count = 0; 5570 param->member_count = parent->member_count; 5571 param->bytes = parent->bytes; 5572 param->rows = parent->rows; 5573 param->columns = parent->columns; 5574 } 5575 5576 if (param->element_count) 5577 { 5578 unsigned int param_bytes = 0; 5579 const char *save_ptr = *ptr; 5580 5581 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->element_count); 5582 if (!param->members) 5583 { 5584 ERR("Out of memory\n"); 5585 hr = E_OUTOFMEMORY; 5586 goto err_out; 5587 } 5588 5589 for (i = 0; i < param->element_count; ++i) 5590 { 5591 *ptr = save_ptr; 5592 5593 param_set_magic_number(¶m->members[i]); 5594 hr = d3dx9_parse_effect_typedef(base, ¶m->members[i], data, ptr, param, flags); 5595 if (hr != D3D_OK) 5596 { 5597 WARN("Failed to parse member %u\n", i); 5598 goto err_out; 5599 } 5600 5601 param_bytes += param->members[i].bytes; 5602 } 5603 5604 param->bytes = param_bytes; 5605 } 5606 else if (param->member_count) 5607 { 5608 param->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*param->members) * param->member_count); 5609 if (!param->members) 5610 { 5611 ERR("Out of memory\n"); 5612 hr = E_OUTOFMEMORY; 5613 goto err_out; 5614 } 5615 5616 for (i = 0; i < param->member_count; ++i) 5617 { 5618 param_set_magic_number(¶m->members[i]); 5619 hr = d3dx9_parse_effect_typedef(base, ¶m->members[i], data, ptr, NULL, flags); 5620 if (hr != D3D_OK) 5621 { 5622 WARN("Failed to parse member %u\n", i); 5623 goto err_out; 5624 } 5625 5626 param->bytes += param->members[i].bytes; 5627 } 5628 } 5629 return D3D_OK; 5630 5631 err_out: 5632 5633 if (param->members) 5634 { 5635 unsigned int count = param->element_count ? param->element_count : param->member_count; 5636 5637 for (i = 0; i < count; ++i) 5638 free_parameter(¶m->members[i], param->element_count != 0, TRUE); 5639 HeapFree(GetProcessHeap(), 0, param->members); 5640 param->members = NULL; 5641 } 5642 5643 if (!parent) 5644 { 5645 HeapFree(GetProcessHeap(), 0, param->name); 5646 HeapFree(GetProcessHeap(), 0, param->semantic); 5647 } 5648 param->name = NULL; 5649 param->semantic = NULL; 5650 5651 return hr; 5652 } 5653 5654 static HRESULT d3dx9_parse_effect_annotation(struct d3dx9_base_effect *base, struct d3dx_parameter *anno, 5655 const char *data, const char **ptr, struct d3dx_object *objects) 5656 { 5657 DWORD offset; 5658 const char *ptr2; 5659 HRESULT hr; 5660 5661 anno->flags = D3DX_PARAMETER_ANNOTATION; 5662 5663 read_dword(ptr, &offset); 5664 TRACE("Typedef offset: %#x\n", offset); 5665 ptr2 = data + offset; 5666 hr = d3dx9_parse_effect_typedef(base, anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION); 5667 if (hr != D3D_OK) 5668 { 5669 WARN("Failed to parse type definition\n"); 5670 return hr; 5671 } 5672 5673 read_dword(ptr, &offset); 5674 TRACE("Value offset: %#x\n", offset); 5675 hr = d3dx9_parse_init_value(base, anno, data, data + offset, objects); 5676 if (hr != D3D_OK) 5677 { 5678 WARN("Failed to parse value\n"); 5679 return hr; 5680 } 5681 5682 return D3D_OK; 5683 } 5684 5685 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state, 5686 const char *data, const char **ptr, struct d3dx_object *objects) 5687 { 5688 DWORD offset; 5689 const char *ptr2; 5690 HRESULT hr; 5691 5692 state->type = ST_CONSTANT; 5693 5694 read_dword(ptr, &state->operation); 5695 TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name); 5696 5697 read_dword(ptr, &state->index); 5698 TRACE("Index: %#x\n", state->index); 5699 5700 read_dword(ptr, &offset); 5701 TRACE("Typedef offset: %#x\n", offset); 5702 ptr2 = data + offset; 5703 hr = d3dx9_parse_effect_typedef(base, &state->parameter, data, &ptr2, NULL, 0); 5704 if (hr != D3D_OK) 5705 { 5706 WARN("Failed to parse type definition\n"); 5707 goto err_out; 5708 } 5709 5710 read_dword(ptr, &offset); 5711 TRACE("Value offset: %#x\n", offset); 5712 hr = d3dx9_parse_init_value(base, &state->parameter, data, data + offset, objects); 5713 if (hr != D3D_OK) 5714 { 5715 WARN("Failed to parse value\n"); 5716 goto err_out; 5717 } 5718 5719 return D3D_OK; 5720 5721 err_out: 5722 5723 free_parameter(&state->parameter, FALSE, FALSE); 5724 5725 return hr; 5726 } 5727 5728 static HRESULT d3dx9_parse_effect_parameter(struct d3dx9_base_effect *base, struct d3dx_top_level_parameter *param, 5729 const char *data, const char **ptr, struct d3dx_object *objects) 5730 { 5731 DWORD offset; 5732 HRESULT hr; 5733 unsigned int i; 5734 const char *ptr2; 5735 5736 read_dword(ptr, &offset); 5737 TRACE("Typedef offset: %#x.\n", offset); 5738 ptr2 = data + offset; 5739 5740 read_dword(ptr, &offset); 5741 TRACE("Value offset: %#x.\n", offset); 5742 5743 read_dword(ptr, ¶m->param.flags); 5744 TRACE("Flags: %#x.\n", param->param.flags); 5745 5746 read_dword(ptr, ¶m->annotation_count); 5747 TRACE("Annotation count: %u.\n", param->annotation_count); 5748 5749 hr = d3dx9_parse_effect_typedef(base, ¶m->param, data, &ptr2, NULL, param->param.flags); 5750 if (hr != D3D_OK) 5751 { 5752 WARN("Failed to parse type definition.\n"); 5753 return hr; 5754 } 5755 5756 hr = d3dx9_parse_init_value(base, ¶m->param, data, data + offset, objects); 5757 if (hr != D3D_OK) 5758 { 5759 WARN("Failed to parse value.\n"); 5760 return hr; 5761 } 5762 5763 if (param->annotation_count) 5764 { 5765 param->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 5766 sizeof(*param->annotations) * param->annotation_count); 5767 if (!param->annotations) 5768 { 5769 ERR("Out of memory.\n"); 5770 hr = E_OUTOFMEMORY; 5771 goto err_out; 5772 } 5773 5774 for (i = 0; i < param->annotation_count; ++i) 5775 { 5776 param_set_magic_number(¶m->annotations[i]); 5777 hr = d3dx9_parse_effect_annotation(base, ¶m->annotations[i], data, ptr, objects); 5778 if (hr != D3D_OK) 5779 { 5780 WARN("Failed to parse annotation.\n"); 5781 goto err_out; 5782 } 5783 } 5784 } 5785 5786 return D3D_OK; 5787 5788 err_out: 5789 5790 if (param->annotations) 5791 { 5792 for (i = 0; i < param->annotation_count; ++i) 5793 free_parameter(¶m->annotations[i], FALSE, FALSE); 5794 HeapFree(GetProcessHeap(), 0, param->annotations); 5795 param->annotations = NULL; 5796 } 5797 5798 return hr; 5799 } 5800 5801 static HRESULT d3dx9_parse_effect_pass(struct d3dx9_base_effect *base, struct d3dx_pass *pass, 5802 const char *data, const char **ptr, struct d3dx_object *objects) 5803 { 5804 DWORD offset; 5805 HRESULT hr; 5806 unsigned int i; 5807 struct d3dx_state *states = NULL; 5808 char *name = NULL; 5809 5810 read_dword(ptr, &offset); 5811 TRACE("Pass name offset: %#x\n", offset); 5812 hr = d3dx9_parse_name(&name, data + offset); 5813 if (hr != D3D_OK) 5814 { 5815 WARN("Failed to parse name\n"); 5816 goto err_out; 5817 } 5818 5819 read_dword(ptr, &pass->annotation_count); 5820 TRACE("Annotation count: %u\n", pass->annotation_count); 5821 5822 read_dword(ptr, &pass->state_count); 5823 TRACE("State count: %u\n", pass->state_count); 5824 5825 if (pass->annotation_count) 5826 { 5827 pass->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 5828 sizeof(*pass->annotations) * pass->annotation_count); 5829 if (!pass->annotations) 5830 { 5831 ERR("Out of memory\n"); 5832 hr = E_OUTOFMEMORY; 5833 goto err_out; 5834 } 5835 5836 for (i = 0; i < pass->annotation_count; ++i) 5837 { 5838 param_set_magic_number(&pass->annotations[i]); 5839 hr = d3dx9_parse_effect_annotation(base, &pass->annotations[i], data, ptr, objects); 5840 if (hr != D3D_OK) 5841 { 5842 WARN("Failed to parse annotation %u\n", i); 5843 goto err_out; 5844 } 5845 } 5846 } 5847 5848 if (pass->state_count) 5849 { 5850 states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count); 5851 if (!states) 5852 { 5853 ERR("Out of memory\n"); 5854 hr = E_OUTOFMEMORY; 5855 goto err_out; 5856 } 5857 5858 for (i = 0; i < pass->state_count; ++i) 5859 { 5860 hr = d3dx9_parse_state(base, &states[i], data, ptr, objects); 5861 if (hr != D3D_OK) 5862 { 5863 WARN("Failed to parse annotation %u\n", i); 5864 goto err_out; 5865 } 5866 } 5867 } 5868 5869 pass->name = name; 5870 pass->states = states; 5871 5872 return D3D_OK; 5873 5874 err_out: 5875 5876 if (pass->annotations) 5877 { 5878 for (i = 0; i < pass->annotation_count; ++i) 5879 free_parameter(&pass->annotations[i], FALSE, FALSE); 5880 HeapFree(GetProcessHeap(), 0, pass->annotations); 5881 pass->annotations = NULL; 5882 } 5883 5884 if (states) 5885 { 5886 for (i = 0; i < pass->state_count; ++i) 5887 { 5888 free_state(&states[i]); 5889 } 5890 HeapFree(GetProcessHeap(), 0, states); 5891 } 5892 5893 HeapFree(GetProcessHeap(), 0, name); 5894 5895 return hr; 5896 } 5897 5898 static HRESULT d3dx9_parse_effect_technique(struct d3dx9_base_effect *base, struct d3dx_technique *technique, 5899 const char *data, const char **ptr, struct d3dx_object *objects) 5900 { 5901 DWORD offset; 5902 HRESULT hr; 5903 unsigned int i; 5904 char *name = NULL; 5905 5906 read_dword(ptr, &offset); 5907 TRACE("Technique name offset: %#x\n", offset); 5908 hr = d3dx9_parse_name(&name, data + offset); 5909 if (hr != D3D_OK) 5910 { 5911 WARN("Failed to parse name\n"); 5912 goto err_out; 5913 } 5914 5915 read_dword(ptr, &technique->annotation_count); 5916 TRACE("Annotation count: %u\n", technique->annotation_count); 5917 5918 read_dword(ptr, &technique->pass_count); 5919 TRACE("Pass count: %u\n", technique->pass_count); 5920 5921 if (technique->annotation_count) 5922 { 5923 technique->annotations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 5924 sizeof(*technique->annotations) * technique->annotation_count); 5925 if (!technique->annotations) 5926 { 5927 ERR("Out of memory\n"); 5928 hr = E_OUTOFMEMORY; 5929 goto err_out; 5930 } 5931 5932 for (i = 0; i < technique->annotation_count; ++i) 5933 { 5934 param_set_magic_number(&technique->annotations[i]); 5935 hr = d3dx9_parse_effect_annotation(base, &technique->annotations[i], data, ptr, objects); 5936 if (hr != D3D_OK) 5937 { 5938 WARN("Failed to parse annotation %u\n", i); 5939 goto err_out; 5940 } 5941 } 5942 } 5943 5944 if (technique->pass_count) 5945 { 5946 technique->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 5947 sizeof(*technique->passes) * technique->pass_count); 5948 if (!technique->passes) 5949 { 5950 ERR("Out of memory\n"); 5951 hr = E_OUTOFMEMORY; 5952 goto err_out; 5953 } 5954 5955 for (i = 0; i < technique->pass_count; ++i) 5956 { 5957 hr = d3dx9_parse_effect_pass(base, &technique->passes[i], data, ptr, objects); 5958 if (hr != D3D_OK) 5959 { 5960 WARN("Failed to parse pass %u\n", i); 5961 goto err_out; 5962 } 5963 } 5964 } 5965 5966 technique->name = name; 5967 5968 return D3D_OK; 5969 5970 err_out: 5971 5972 if (technique->passes) 5973 { 5974 for (i = 0; i < technique->pass_count; ++i) 5975 free_pass(&technique->passes[i]); 5976 HeapFree(GetProcessHeap(), 0, technique->passes); 5977 technique->passes = NULL; 5978 } 5979 5980 if (technique->annotations) 5981 { 5982 for (i = 0; i < technique->annotation_count; ++i) 5983 free_parameter(&technique->annotations[i], FALSE, FALSE); 5984 HeapFree(GetProcessHeap(), 0, technique->annotations); 5985 technique->annotations = NULL; 5986 } 5987 5988 HeapFree(GetProcessHeap(), 0, name); 5989 5990 return hr; 5991 } 5992 5993 static HRESULT d3dx9_create_object(struct d3dx9_base_effect *base, struct d3dx_object *object) 5994 { 5995 struct d3dx_parameter *param = object->param; 5996 struct IDirect3DDevice9 *device = base->effect->device; 5997 HRESULT hr; 5998 5999 if (*(char **)param->data) 6000 ERR("Parameter data already allocated.\n"); 6001 6002 switch (param->type) 6003 { 6004 case D3DXPT_STRING: 6005 *(char **)param->data = HeapAlloc(GetProcessHeap(), 0, object->size); 6006 if (!*(char **)param->data) 6007 { 6008 ERR("Out of memory.\n"); 6009 return E_OUTOFMEMORY; 6010 } 6011 memcpy(*(char **)param->data, object->data, object->size); 6012 break; 6013 case D3DXPT_VERTEXSHADER: 6014 if (FAILED(hr = IDirect3DDevice9_CreateVertexShader(device, object->data, 6015 (IDirect3DVertexShader9 **)param->data))) 6016 { 6017 WARN("Failed to create vertex shader.\n"); 6018 object->creation_failed = TRUE; 6019 } 6020 break; 6021 case D3DXPT_PIXELSHADER: 6022 if (FAILED(hr = IDirect3DDevice9_CreatePixelShader(device, object->data, 6023 (IDirect3DPixelShader9 **)param->data))) 6024 { 6025 WARN("Failed to create pixel shader.\n"); 6026 object->creation_failed = TRUE; 6027 } 6028 break; 6029 default: 6030 break; 6031 } 6032 return D3D_OK; 6033 } 6034 6035 static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct d3dx_state *state, 6036 const char **skip_constants, unsigned int skip_constants_count) 6037 { 6038 DWORD string_size; 6039 struct d3dx_parameter *param = &state->parameter; 6040 struct d3dx_object *object = &base->objects[param->object_id]; 6041 char *ptr = object->data; 6042 HRESULT ret; 6043 6044 TRACE("Parsing array entry selection state for parameter %p.\n", param); 6045 6046 string_size = *(DWORD *)ptr; 6047 state->referenced_param = get_parameter_by_name(base, NULL, ptr + 4); 6048 if (state->referenced_param) 6049 { 6050 TRACE("Mapping to parameter %s.\n", debugstr_a(state->referenced_param->name)); 6051 } 6052 else 6053 { 6054 FIXME("Referenced parameter %s not found.\n", ptr + 4); 6055 return D3DXERR_INVALIDDATA; 6056 } 6057 TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size)); 6058 6059 if (string_size % sizeof(DWORD)) 6060 FIXME("Unaligned string_size %u.\n", string_size); 6061 if (FAILED(ret = d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1, 6062 object->size - (string_size + sizeof(DWORD)), D3DXPT_INT, ¶m->param_eval, 6063 get_version_counter_ptr(base), NULL, 0))) 6064 return ret; 6065 ret = D3D_OK; 6066 param = state->referenced_param; 6067 if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER) 6068 { 6069 unsigned int i; 6070 6071 for (i = 0; i < param->element_count; i++) 6072 { 6073 if (param->members[i].type != param->type) 6074 { 6075 FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type); 6076 return D3DXERR_INVALIDDATA; 6077 } 6078 if (!param->members[i].param_eval) 6079 { 6080 TRACE("Creating preshader for object %u.\n", param->members[i].object_id); 6081 object = &base->objects[param->members[i].object_id]; 6082 if (FAILED(ret = d3dx_create_param_eval(base, object->data, object->size, param->type, 6083 ¶m->members[i].param_eval, get_version_counter_ptr(base), 6084 skip_constants, skip_constants_count))) 6085 break; 6086 } 6087 } 6088 } 6089 return ret; 6090 } 6091 6092 static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr, 6093 const char **skip_constants, unsigned int skip_constants_count) 6094 { 6095 DWORD technique_index; 6096 DWORD index, state_index, usage, element_index; 6097 struct d3dx_state *state; 6098 struct d3dx_parameter *param; 6099 struct d3dx_object *object; 6100 HRESULT hr = E_FAIL; 6101 6102 read_dword(ptr, &technique_index); 6103 TRACE("technique_index: %u\n", technique_index); 6104 6105 read_dword(ptr, &index); 6106 TRACE("index: %u\n", index); 6107 6108 read_dword(ptr, &element_index); 6109 TRACE("element_index: %u\n", element_index); 6110 6111 read_dword(ptr, &state_index); 6112 TRACE("state_index: %u\n", state_index); 6113 6114 read_dword(ptr, &usage); 6115 TRACE("usage: %u\n", usage); 6116 6117 if (technique_index == 0xffffffff) 6118 { 6119 struct d3dx_parameter *parameter; 6120 struct d3dx_sampler *sampler; 6121 6122 if (index >= base->parameter_count) 6123 { 6124 FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count); 6125 return E_FAIL; 6126 } 6127 6128 parameter = &base->parameters[index].param; 6129 if (element_index != 0xffffffff) 6130 { 6131 if (element_index >= parameter->element_count && parameter->element_count != 0) 6132 { 6133 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count); 6134 return E_FAIL; 6135 } 6136 6137 if (parameter->element_count) 6138 parameter = ¶meter->members[element_index]; 6139 } 6140 6141 sampler = parameter->data; 6142 if (state_index >= sampler->state_count) 6143 { 6144 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count); 6145 return E_FAIL; 6146 } 6147 6148 state = &sampler->states[state_index]; 6149 } 6150 else 6151 { 6152 struct d3dx_technique *technique; 6153 struct d3dx_pass *pass; 6154 6155 if (technique_index >= base->technique_count) 6156 { 6157 FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count); 6158 return E_FAIL; 6159 } 6160 6161 technique = &base->techniques[technique_index]; 6162 if (index >= technique->pass_count) 6163 { 6164 FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count); 6165 return E_FAIL; 6166 } 6167 6168 pass = &technique->passes[index]; 6169 if (state_index >= pass->state_count) 6170 { 6171 FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count); 6172 return E_FAIL; 6173 } 6174 6175 state = &pass->states[state_index]; 6176 } 6177 6178 TRACE("State operation %#x (%s).\n", state->operation, state_table[state->operation].name); 6179 param = &state->parameter; 6180 TRACE("Using object id %u.\n", param->object_id); 6181 object = &base->objects[param->object_id]; 6182 6183 TRACE("Usage %u: class %s, type %s.\n", usage, debug_d3dxparameter_class(param->class), 6184 debug_d3dxparameter_type(param->type)); 6185 switch (usage) 6186 { 6187 case 0: 6188 switch (param->type) 6189 { 6190 case D3DXPT_VERTEXSHADER: 6191 case D3DXPT_PIXELSHADER: 6192 state->type = ST_CONSTANT; 6193 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr))) 6194 return hr; 6195 6196 if (object->data) 6197 { 6198 if (FAILED(hr = d3dx9_create_object(base, object))) 6199 return hr; 6200 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type, 6201 ¶m->param_eval, get_version_counter_ptr(base), 6202 skip_constants, skip_constants_count))) 6203 return hr; 6204 } 6205 break; 6206 6207 case D3DXPT_BOOL: 6208 case D3DXPT_INT: 6209 case D3DXPT_FLOAT: 6210 case D3DXPT_STRING: 6211 state->type = ST_FXLC; 6212 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr))) 6213 return hr; 6214 if (FAILED(hr = d3dx_create_param_eval(base, object->data, object->size, param->type, 6215 ¶m->param_eval, get_version_counter_ptr(base), NULL, 0))) 6216 return hr; 6217 break; 6218 6219 default: 6220 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type)); 6221 break; 6222 } 6223 break; 6224 6225 case 1: 6226 state->type = ST_PARAMETER; 6227 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr))) 6228 return hr; 6229 6230 TRACE("Looking for parameter %s.\n", debugstr_a(object->data)); 6231 state->referenced_param = get_parameter_by_name(base, NULL, object->data); 6232 if (state->referenced_param) 6233 { 6234 struct d3dx_parameter *refpar = state->referenced_param; 6235 6236 TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id); 6237 if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER) 6238 { 6239 struct d3dx_object *refobj = &base->objects[refpar->object_id]; 6240 6241 if (!refpar->param_eval) 6242 { 6243 if (FAILED(hr = d3dx_create_param_eval(base, refobj->data, refobj->size, 6244 refpar->type, &refpar->param_eval, get_version_counter_ptr(base), 6245 skip_constants, skip_constants_count))) 6246 return hr; 6247 } 6248 } 6249 } 6250 else 6251 { 6252 FIXME("Referenced parameter %s not found.\n", (char *)object->data); 6253 return D3DXERR_INVALIDDATA; 6254 } 6255 break; 6256 6257 case 2: 6258 state->type = ST_ARRAY_SELECTOR; 6259 if (FAILED(hr = d3dx9_copy_data(base, param->object_id, ptr))) 6260 return hr; 6261 hr = d3dx9_parse_array_selector(base, state, skip_constants, skip_constants_count); 6262 break; 6263 6264 default: 6265 FIXME("Unknown usage %x\n", usage); 6266 break; 6267 } 6268 6269 return hr; 6270 } 6271 6272 static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_parameter *param) 6273 { 6274 param->top_level_param = top_level_param; 6275 return FALSE; 6276 } 6277 6278 static HRESULT d3dx9_parse_effect(struct d3dx9_base_effect *base, const char *data, UINT data_size, 6279 DWORD start, const char **skip_constants, unsigned int skip_constants_count) 6280 { 6281 const char *ptr = data + start; 6282 UINT stringcount, resourcecount; 6283 HRESULT hr; 6284 UINT i; 6285 6286 read_dword(&ptr, &base->parameter_count); 6287 TRACE("Parameter count: %u.\n", base->parameter_count); 6288 6289 read_dword(&ptr, &base->technique_count); 6290 TRACE("Technique count: %u.\n", base->technique_count); 6291 6292 skip_dword_unknown(&ptr, 1); 6293 6294 read_dword(&ptr, &base->object_count); 6295 TRACE("Object count: %u.\n", base->object_count); 6296 6297 base->objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base->objects) * base->object_count); 6298 if (!base->objects) 6299 { 6300 ERR("Out of memory.\n"); 6301 hr = E_OUTOFMEMORY; 6302 goto err_out; 6303 } 6304 6305 if (base->parameter_count) 6306 { 6307 base->parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 6308 sizeof(*base->parameters) * base->parameter_count); 6309 if (!base->parameters) 6310 { 6311 ERR("Out of memory.\n"); 6312 hr = E_OUTOFMEMORY; 6313 goto err_out; 6314 } 6315 6316 for (i = 0; i < base->parameter_count; ++i) 6317 { 6318 param_set_magic_number(&base->parameters[i].param); 6319 hr = d3dx9_parse_effect_parameter(base, &base->parameters[i], data, &ptr, base->objects); 6320 if (hr != D3D_OK) 6321 { 6322 WARN("Failed to parse parameter %u.\n", i); 6323 goto err_out; 6324 } 6325 walk_parameter_tree(&base->parameters[i].param, param_set_top_level_param, 6326 &base->parameters[i]); 6327 } 6328 } 6329 6330 if (base->technique_count) 6331 { 6332 base->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 6333 sizeof(*base->techniques) * base->technique_count); 6334 if (!base->techniques) 6335 { 6336 ERR("Out of memory.\n"); 6337 hr = E_OUTOFMEMORY; 6338 goto err_out; 6339 } 6340 6341 for (i = 0; i < base->technique_count; ++i) 6342 { 6343 TRACE("Parsing technique %u.\n", i); 6344 hr = d3dx9_parse_effect_technique(base, &base->techniques[i], data, &ptr, base->objects); 6345 if (hr != D3D_OK) 6346 { 6347 WARN("Failed to parse technique %u.\n", i); 6348 goto err_out; 6349 } 6350 } 6351 } 6352 6353 read_dword(&ptr, &stringcount); 6354 TRACE("String count: %u.\n", stringcount); 6355 6356 read_dword(&ptr, &resourcecount); 6357 TRACE("Resource count: %u.\n", resourcecount); 6358 6359 for (i = 0; i < stringcount; ++i) 6360 { 6361 DWORD id; 6362 6363 read_dword(&ptr, &id); 6364 TRACE("id: %u.\n", id); 6365 6366 if (FAILED(hr = d3dx9_copy_data(base, id, &ptr))) 6367 goto err_out; 6368 6369 if (base->objects[id].data) 6370 { 6371 if (FAILED(hr = d3dx9_create_object(base, &base->objects[id]))) 6372 goto err_out; 6373 } 6374 } 6375 6376 for (i = 0; i < resourcecount; ++i) 6377 { 6378 TRACE("parse resource %u.\n", i); 6379 6380 hr = d3dx9_parse_resource(base, data, &ptr, skip_constants, skip_constants_count); 6381 if (hr != D3D_OK) 6382 { 6383 WARN("Failed to parse resource %u.\n", i); 6384 goto err_out; 6385 } 6386 } 6387 6388 for (i = 0; i < base->parameter_count; ++i) 6389 { 6390 if (FAILED(hr = d3dx_pool_sync_shared_parameter(base->pool, &base->parameters[i]))) 6391 goto err_out; 6392 base->parameters[i].version_counter = base->pool 6393 ? &base->pool->version_counter 6394 : &base->version_counter; 6395 set_dirty(&base->parameters[i].param); 6396 } 6397 return D3D_OK; 6398 6399 err_out: 6400 6401 if (base->techniques) 6402 { 6403 for (i = 0; i < base->technique_count; ++i) 6404 free_technique(&base->techniques[i]); 6405 HeapFree(GetProcessHeap(), 0, base->techniques); 6406 base->techniques = NULL; 6407 } 6408 6409 if (base->parameters) 6410 { 6411 for (i = 0; i < base->parameter_count; ++i) 6412 { 6413 free_top_level_parameter(&base->parameters[i]); 6414 } 6415 HeapFree(GetProcessHeap(), 0, base->parameters); 6416 base->parameters = NULL; 6417 } 6418 6419 if (base->objects) 6420 { 6421 for (i = 0; i < base->object_count; ++i) 6422 { 6423 free_object(&base->objects[i]); 6424 } 6425 HeapFree(GetProcessHeap(), 0, base->objects); 6426 base->objects = NULL; 6427 } 6428 6429 return hr; 6430 } 6431 6432 #define INITIAL_CONST_NAMES_SIZE 4 6433 6434 static char *next_valid_constant_name(char **string) 6435 { 6436 char *ret = *string; 6437 char *next; 6438 6439 while (*ret && !isalpha(*ret) && *ret != '_') 6440 ++ret; 6441 if (!*ret) 6442 return NULL; 6443 6444 next = ret + 1; 6445 while (isalpha(*next) || isdigit(*next) || *next == '_') 6446 ++next; 6447 if (*next) 6448 *next++ = 0; 6449 *string = next; 6450 return ret; 6451 } 6452 6453 static const char **parse_skip_constants_string(char *skip_constants_string, unsigned int *names_count) 6454 { 6455 const char **names, **new_alloc; 6456 const char *name; 6457 char *s; 6458 unsigned int size = INITIAL_CONST_NAMES_SIZE; 6459 6460 names = HeapAlloc(GetProcessHeap(), 0, sizeof(*names) * size); 6461 if (!names) 6462 return NULL; 6463 6464 *names_count = 0; 6465 s = skip_constants_string; 6466 while ((name = next_valid_constant_name(&s))) 6467 { 6468 if (*names_count == size) 6469 { 6470 size *= 2; 6471 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, sizeof(*names) * size); 6472 if (!new_alloc) 6473 { 6474 HeapFree(GetProcessHeap(), 0, names); 6475 return NULL; 6476 } 6477 names = new_alloc; 6478 } 6479 names[(*names_count)++] = name; 6480 } 6481 new_alloc = HeapReAlloc(GetProcessHeap(), 0, names, *names_count * sizeof(*names)); 6482 if (!new_alloc) 6483 return names; 6484 return new_alloc; 6485 } 6486 6487 static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base, 6488 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include, 6489 UINT eflags, ID3DBlob **errors, struct ID3DXEffectImpl *effect, struct d3dx_effect_pool *pool, 6490 const char *skip_constants_string) 6491 { 6492 DWORD tag, offset; 6493 const char *ptr = data; 6494 HRESULT hr; 6495 ID3DBlob *bytecode = NULL, *temp_errors = NULL; 6496 char *skip_constants_buffer = NULL; 6497 const char **skip_constants = NULL; 6498 unsigned int skip_constants_count = 0; 6499 #if D3DX_SDK_VERSION <= 36 6500 UINT compile_flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; 6501 #else 6502 UINT compile_flags = 0; 6503 #endif 6504 unsigned int i, j; 6505 6506 TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n", 6507 base, data, data_size, effect, pool, debugstr_a(skip_constants_string)); 6508 6509 base->effect = effect; 6510 base->pool = pool; 6511 base->flags = eflags; 6512 6513 read_dword(&ptr, &tag); 6514 TRACE("Tag: %x\n", tag); 6515 6516 if (tag != d3dx9_effect_version(9, 1)) 6517 { 6518 TRACE("HLSL ASCII effect, trying to compile it.\n"); 6519 hr = D3DCompile(data, data_size, NULL, defines, include, 6520 "main", "fx_2_0", compile_flags, eflags, &bytecode, &temp_errors); 6521 if (FAILED(hr)) 6522 { 6523 WARN("Failed to compile ASCII effect.\n"); 6524 if (bytecode) 6525 ID3D10Blob_Release(bytecode); 6526 if (temp_errors) 6527 { 6528 const char *error_string = ID3D10Blob_GetBufferPointer(temp_errors); 6529 const char *string_ptr; 6530 6531 while (*error_string) 6532 { 6533 string_ptr = error_string; 6534 while (*string_ptr && *string_ptr != '\n' && *string_ptr != '\r' 6535 && string_ptr - error_string < 80) 6536 ++string_ptr; 6537 TRACE("%s\n", debugstr_an(error_string, string_ptr - error_string)); 6538 error_string = string_ptr; 6539 while (*error_string == '\n' || *error_string == '\r') 6540 ++error_string; 6541 } 6542 } 6543 if (errors) 6544 *errors = temp_errors; 6545 else if (temp_errors) 6546 ID3D10Blob_Release(temp_errors); 6547 return hr; 6548 } 6549 if (!bytecode) 6550 { 6551 FIXME("No output from effect compilation.\n"); 6552 return D3DERR_INVALIDCALL; 6553 } 6554 if (errors) 6555 *errors = temp_errors; 6556 else if (temp_errors) 6557 ID3D10Blob_Release(temp_errors); 6558 6559 ptr = ID3D10Blob_GetBufferPointer(bytecode); 6560 read_dword(&ptr, &tag); 6561 TRACE("Tag: %x\n", tag); 6562 } 6563 6564 if (skip_constants_string) 6565 { 6566 skip_constants_buffer = HeapAlloc(GetProcessHeap(), 0, 6567 sizeof(*skip_constants_buffer) * (strlen(skip_constants_string) + 1)); 6568 if (!skip_constants_buffer) 6569 { 6570 if (bytecode) 6571 ID3D10Blob_Release(bytecode); 6572 return E_OUTOFMEMORY; 6573 } 6574 strcpy(skip_constants_buffer, skip_constants_string); 6575 6576 if (!(skip_constants = parse_skip_constants_string(skip_constants_buffer, &skip_constants_count))) 6577 { 6578 HeapFree(GetProcessHeap(), 0, skip_constants_buffer); 6579 if (bytecode) 6580 ID3D10Blob_Release(bytecode); 6581 return E_OUTOFMEMORY; 6582 } 6583 } 6584 read_dword(&ptr, &offset); 6585 TRACE("Offset: %x\n", offset); 6586 6587 hr = d3dx9_parse_effect(base, ptr, data_size, offset, skip_constants, skip_constants_count); 6588 if (bytecode) 6589 ID3D10Blob_Release(bytecode); 6590 if (hr != D3D_OK) 6591 { 6592 FIXME("Failed to parse effect.\n"); 6593 HeapFree(GetProcessHeap(), 0, skip_constants_buffer); 6594 HeapFree(GetProcessHeap(), 0, skip_constants); 6595 return hr; 6596 } 6597 6598 for (i = 0; i < skip_constants_count; ++i) 6599 { 6600 struct d3dx_parameter *param; 6601 param = get_parameter_by_name(base, NULL, skip_constants[i]); 6602 if (param) 6603 { 6604 for (j = 0; j < base->technique_count; ++j) 6605 { 6606 if (is_parameter_used(param, &base->techniques[j])) 6607 { 6608 WARN("skip_constants parameter %s is used in technique %u.\n", 6609 debugstr_a(skip_constants[i]), j); 6610 HeapFree(GetProcessHeap(), 0, skip_constants_buffer); 6611 HeapFree(GetProcessHeap(), 0, skip_constants); 6612 d3dx9_base_effect_cleanup(base); 6613 return D3DERR_INVALIDCALL; 6614 } 6615 } 6616 } 6617 else 6618 { 6619 TRACE("skip_constants parameter %s not found.\n", 6620 debugstr_a(skip_constants[i])); 6621 } 6622 } 6623 6624 HeapFree(GetProcessHeap(), 0, skip_constants_buffer); 6625 HeapFree(GetProcessHeap(), 0, skip_constants); 6626 6627 return D3D_OK; 6628 } 6629 6630 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, struct IDirect3DDevice9 *device, 6631 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include, 6632 UINT eflags, ID3DBlob **error_messages, struct ID3DXEffectPool *pool, const char *skip_constants) 6633 { 6634 HRESULT hr; 6635 struct d3dx_effect_pool *pool_impl = NULL; 6636 6637 TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool); 6638 6639 effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl; 6640 effect->ref = 1; 6641 6642 if (pool) 6643 { 6644 pool->lpVtbl->AddRef(pool); 6645 pool_impl = impl_from_ID3DXEffectPool(pool); 6646 } 6647 effect->pool = pool; 6648 6649 IDirect3DDevice9_AddRef(device); 6650 effect->device = device; 6651 6652 if (FAILED(hr = d3dx9_base_effect_init(&effect->base_effect, data, data_size, defines, include, 6653 eflags, error_messages, effect, pool_impl, skip_constants))) 6654 { 6655 FIXME("Failed to parse effect, hr %#x.\n", hr); 6656 free_effect(effect); 6657 return hr; 6658 } 6659 6660 /* initialize defaults - check because of unsupported ascii effects */ 6661 if (effect->base_effect.techniques) 6662 { 6663 effect->active_technique = &effect->base_effect.techniques[0]; 6664 effect->active_pass = NULL; 6665 } 6666 6667 return D3D_OK; 6668 } 6669 6670 HRESULT WINAPI D3DXCreateEffectEx(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen, 6671 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skip_constants, DWORD flags, 6672 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors) 6673 { 6674 struct ID3DXEffectImpl *object; 6675 HRESULT hr; 6676 6677 TRACE("device %p, srcdata %p, srcdatalen %u, defines %p, include %p," 6678 " skip_constants %p, flags %#x, pool %p, effect %p, compilation_errors %p.\n", 6679 device, srcdata, srcdatalen, defines, include, 6680 skip_constants, flags, pool, effect, compilation_errors); 6681 6682 if (compilation_errors) 6683 *compilation_errors = NULL; 6684 6685 if (!device || !srcdata) 6686 return D3DERR_INVALIDCALL; 6687 6688 if (!srcdatalen) 6689 return E_FAIL; 6690 6691 /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */ 6692 if (!effect) 6693 return D3D_OK; 6694 6695 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 6696 if (!object) 6697 return E_OUTOFMEMORY; 6698 6699 hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines, 6700 (ID3DInclude *)include, flags, (ID3DBlob **)compilation_errors, pool, skip_constants); 6701 if (FAILED(hr)) 6702 { 6703 WARN("Failed to create effect object.\n"); 6704 HeapFree(GetProcessHeap(), 0, object); 6705 return hr; 6706 } 6707 6708 *effect = &object->ID3DXEffect_iface; 6709 6710 TRACE("Created ID3DXEffect %p\n", object); 6711 6712 return D3D_OK; 6713 } 6714 6715 HRESULT WINAPI D3DXCreateEffect(struct IDirect3DDevice9 *device, const void *srcdata, UINT srcdatalen, 6716 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, 6717 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilation_errors) 6718 { 6719 TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines, 6720 include, flags, pool, effect, compilation_errors); 6721 6722 return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors); 6723 } 6724 6725 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, 6726 const char *data, SIZE_T data_size, const D3D_SHADER_MACRO *defines, ID3DInclude *include, 6727 UINT eflags, ID3DBlob **error_messages) 6728 { 6729 HRESULT hr; 6730 6731 TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size); 6732 6733 compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl; 6734 compiler->ref = 1; 6735 6736 if (FAILED(hr = d3dx9_base_effect_init(&compiler->base_effect, data, data_size, defines, 6737 include, eflags, error_messages, NULL, NULL, NULL))) 6738 { 6739 FIXME("Failed to parse effect, hr %#x.\n", hr); 6740 free_effect_compiler(compiler); 6741 return hr; 6742 } 6743 6744 return D3D_OK; 6745 } 6746 6747 HRESULT WINAPI D3DXCreateEffectCompiler(const char *srcdata, UINT srcdatalen, const D3DXMACRO *defines, 6748 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **compiler, ID3DXBuffer **parse_errors) 6749 { 6750 struct ID3DXEffectCompilerImpl *object; 6751 HRESULT hr; 6752 6753 TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n", 6754 srcdata, srcdatalen, defines, include, flags, compiler, parse_errors); 6755 6756 if (!srcdata || !compiler) 6757 { 6758 WARN("Invalid arguments supplied\n"); 6759 return D3DERR_INVALIDCALL; 6760 } 6761 6762 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 6763 if (!object) 6764 return E_OUTOFMEMORY; 6765 6766 hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen, (const D3D_SHADER_MACRO *)defines, 6767 (ID3DInclude *)include, flags, (ID3DBlob **)parse_errors); 6768 if (FAILED(hr)) 6769 { 6770 WARN("Failed to initialize effect compiler\n"); 6771 HeapFree(GetProcessHeap(), 0, object); 6772 return hr; 6773 } 6774 6775 *compiler = &object->ID3DXEffectCompiler_iface; 6776 6777 TRACE("Created ID3DXEffectCompiler %p\n", object); 6778 6779 return D3D_OK; 6780 } 6781 6782 /*** IUnknown methods ***/ 6783 static HRESULT WINAPI d3dx_effect_pool_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object) 6784 { 6785 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 6786 6787 if (IsEqualGUID(riid, &IID_IUnknown) || 6788 IsEqualGUID(riid, &IID_ID3DXEffectPool)) 6789 { 6790 iface->lpVtbl->AddRef(iface); 6791 *object = iface; 6792 return S_OK; 6793 } 6794 6795 WARN("Interface %s not found\n", debugstr_guid(riid)); 6796 6797 return E_NOINTERFACE; 6798 } 6799 6800 static ULONG WINAPI d3dx_effect_pool_AddRef(ID3DXEffectPool *iface) 6801 { 6802 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface); 6803 ULONG refcount = InterlockedIncrement(&pool->refcount); 6804 6805 TRACE("%p increasing refcount to %u.\n", pool, refcount); 6806 6807 return refcount; 6808 } 6809 6810 static void free_effect_pool(struct d3dx_effect_pool *pool) 6811 { 6812 unsigned int i; 6813 6814 for (i = 0; i < pool->size; ++i) 6815 { 6816 if (pool->shared_data[i].count) 6817 { 6818 unsigned int j; 6819 6820 WARN("Releasing pool with referenced parameters.\n"); 6821 6822 param_set_data_pointer(&pool->shared_data[i].parameters[0]->param, NULL, FALSE, TRUE); 6823 pool->shared_data[i].parameters[0]->shared_data = NULL; 6824 6825 for (j = 1; j < pool->shared_data[i].count; ++j) 6826 { 6827 walk_parameter_tree(&pool->shared_data[i].parameters[j]->param, param_zero_data_func, NULL); 6828 pool->shared_data[i].parameters[j]->shared_data = NULL; 6829 } 6830 HeapFree(GetProcessHeap(), 0, pool->shared_data[i].parameters); 6831 } 6832 } 6833 HeapFree(GetProcessHeap(), 0, pool->shared_data); 6834 HeapFree(GetProcessHeap(), 0, pool); 6835 } 6836 6837 static ULONG WINAPI d3dx_effect_pool_Release(ID3DXEffectPool *iface) 6838 { 6839 struct d3dx_effect_pool *pool = impl_from_ID3DXEffectPool(iface); 6840 ULONG refcount = InterlockedDecrement(&pool->refcount); 6841 6842 TRACE("%p decreasing refcount to %u.\n", pool, refcount); 6843 6844 if (!refcount) 6845 free_effect_pool(pool); 6846 6847 return refcount; 6848 } 6849 6850 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl = 6851 { 6852 /*** IUnknown methods ***/ 6853 d3dx_effect_pool_QueryInterface, 6854 d3dx_effect_pool_AddRef, 6855 d3dx_effect_pool_Release 6856 }; 6857 6858 HRESULT WINAPI D3DXCreateEffectPool(ID3DXEffectPool **pool) 6859 { 6860 struct d3dx_effect_pool *object; 6861 6862 TRACE("pool %p.\n", pool); 6863 6864 if (!pool) 6865 return D3DERR_INVALIDCALL; 6866 6867 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 6868 if (!object) 6869 return E_OUTOFMEMORY; 6870 6871 object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl; 6872 object->refcount = 1; 6873 6874 *pool = &object->ID3DXEffectPool_iface; 6875 6876 return S_OK; 6877 } 6878 6879 HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile, 6880 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags, 6881 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 6882 { 6883 void *buffer; 6884 HRESULT ret; 6885 DWORD size; 6886 6887 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, " 6888 "flags %#x, pool %p, effect %p, compilationerrors %p.\n", 6889 device, debugstr_w(srcfile), defines, include, debugstr_a(skipconstants), 6890 flags, pool, effect, compilationerrors); 6891 6892 if (!device || !srcfile) 6893 return D3DERR_INVALIDCALL; 6894 6895 ret = map_view_of_file(srcfile, &buffer, &size); 6896 6897 if (FAILED(ret)) 6898 return D3DXERR_INVALIDDATA; 6899 6900 ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors); 6901 UnmapViewOfFile(buffer); 6902 6903 return ret; 6904 } 6905 6906 HRESULT WINAPI D3DXCreateEffectFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile, 6907 const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags, 6908 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 6909 { 6910 WCHAR *srcfileW; 6911 HRESULT ret; 6912 DWORD len; 6913 6914 TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, " 6915 "flags %#x, pool %p, effect %p, compilationerrors %p.\n", 6916 device, debugstr_a(srcfile), defines, include, debugstr_a(skipconstants), 6917 flags, pool, effect, compilationerrors); 6918 6919 if (!srcfile) 6920 return D3DERR_INVALIDCALL; 6921 6922 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0); 6923 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW)); 6924 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len); 6925 6926 ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors); 6927 HeapFree(GetProcessHeap(), 0, srcfileW); 6928 6929 return ret; 6930 } 6931 6932 HRESULT WINAPI D3DXCreateEffectFromFileW(struct IDirect3DDevice9 *device, const WCHAR *srcfile, 6933 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool, 6934 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 6935 { 6936 TRACE("(void): relay\n"); 6937 return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors); 6938 } 6939 6940 HRESULT WINAPI D3DXCreateEffectFromFileA(struct IDirect3DDevice9 *device, const char *srcfile, 6941 const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, struct ID3DXEffectPool *pool, 6942 struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 6943 { 6944 TRACE("(void): relay\n"); 6945 return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors); 6946 } 6947 6948 HRESULT WINAPI D3DXCreateEffectFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule, 6949 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, 6950 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 6951 { 6952 HRSRC resinfo; 6953 void *buffer; 6954 DWORD size; 6955 6956 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, " 6957 "flags %#x, pool %p, effect %p, compilationerrors %p.\n", 6958 device, srcmodule, debugstr_w(srcresource), defines, include, debugstr_a(skipconstants), 6959 flags, pool, effect, compilationerrors); 6960 6961 if (!device) 6962 return D3DERR_INVALIDCALL; 6963 6964 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA))) 6965 return D3DXERR_INVALIDDATA; 6966 6967 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size))) 6968 return D3DXERR_INVALIDDATA; 6969 6970 return D3DXCreateEffectEx(device, buffer, size, defines, include, 6971 skipconstants, flags, pool, effect, compilationerrors); 6972 } 6973 6974 HRESULT WINAPI D3DXCreateEffectFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule, 6975 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, 6976 DWORD flags, struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 6977 { 6978 HRSRC resinfo; 6979 void *buffer; 6980 DWORD size; 6981 6982 TRACE("device %p, srcmodule %p, srcresource %s, defines %p, include %p, skipconstants %s, " 6983 "flags %#x, pool %p, effect %p, compilationerrors %p.\n", 6984 device, srcmodule, debugstr_a(srcresource), defines, include, debugstr_a(skipconstants), 6985 flags, pool, effect, compilationerrors); 6986 6987 if (!device) 6988 return D3DERR_INVALIDCALL; 6989 6990 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA))) 6991 return D3DXERR_INVALIDDATA; 6992 6993 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size))) 6994 return D3DXERR_INVALIDDATA; 6995 6996 return D3DXCreateEffectEx(device, buffer, size, defines, include, 6997 skipconstants, flags, pool, effect, compilationerrors); 6998 } 6999 7000 HRESULT WINAPI D3DXCreateEffectFromResourceW(struct IDirect3DDevice9 *device, HMODULE srcmodule, 7001 const WCHAR *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, 7002 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 7003 { 7004 TRACE("(void): relay\n"); 7005 return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors); 7006 } 7007 7008 HRESULT WINAPI D3DXCreateEffectFromResourceA(struct IDirect3DDevice9 *device, HMODULE srcmodule, 7009 const char *srcresource, const D3DXMACRO *defines, struct ID3DXInclude *include, DWORD flags, 7010 struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) 7011 { 7012 TRACE("(void): relay\n"); 7013 return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors); 7014 } 7015 7016 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(const WCHAR *srcfile, const D3DXMACRO *defines, 7017 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors) 7018 { 7019 void *buffer; 7020 HRESULT ret; 7021 DWORD size; 7022 7023 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n", 7024 debugstr_w(srcfile), defines, include, flags, effectcompiler, parseerrors); 7025 7026 if (!srcfile) 7027 return D3DERR_INVALIDCALL; 7028 7029 ret = map_view_of_file(srcfile, &buffer, &size); 7030 7031 if (FAILED(ret)) 7032 return D3DXERR_INVALIDDATA; 7033 7034 ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors); 7035 UnmapViewOfFile(buffer); 7036 7037 return ret; 7038 } 7039 7040 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(const char *srcfile, const D3DXMACRO *defines, 7041 ID3DXInclude *include, DWORD flags, ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors) 7042 { 7043 WCHAR *srcfileW; 7044 HRESULT ret; 7045 DWORD len; 7046 7047 TRACE("srcfile %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n", 7048 debugstr_a(srcfile), defines, include, flags, effectcompiler, parseerrors); 7049 7050 if (!srcfile) 7051 return D3DERR_INVALIDCALL; 7052 7053 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0); 7054 srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW)); 7055 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len); 7056 7057 ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors); 7058 HeapFree(GetProcessHeap(), 0, srcfileW); 7059 7060 return ret; 7061 } 7062 7063 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, const char *srcresource, 7064 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags, 7065 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors) 7066 { 7067 HRSRC resinfo; 7068 void *buffer; 7069 DWORD size; 7070 7071 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n", 7072 srcmodule, debugstr_a(srcresource), defines, include, flags, effectcompiler, parseerrors); 7073 7074 if (!(resinfo = FindResourceA(srcmodule, srcresource, (const char *)RT_RCDATA))) 7075 return D3DXERR_INVALIDDATA; 7076 7077 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size))) 7078 return D3DXERR_INVALIDDATA; 7079 7080 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors); 7081 } 7082 7083 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WCHAR *srcresource, 7084 const D3DXMACRO *defines, ID3DXInclude *include, DWORD flags, 7085 ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors) 7086 { 7087 HRSRC resinfo; 7088 void *buffer; 7089 DWORD size; 7090 7091 TRACE("srcmodule %p, srcresource %s, defines %p, include %p, flags %#x, effectcompiler %p, parseerrors %p.\n", 7092 srcmodule, debugstr_w(srcresource), defines, include, flags, effectcompiler, parseerrors); 7093 7094 if (!(resinfo = FindResourceW(srcmodule, srcresource, (const WCHAR *)RT_RCDATA))) 7095 return D3DXERR_INVALIDDATA; 7096 7097 if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size))) 7098 return D3DXERR_INVALIDDATA; 7099 7100 return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors); 7101 } 7102 7103 HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly) 7104 { 7105 FIXME("(%p, %u, %p): stub\n", effect, enable_color_code, disassembly); 7106 7107 return D3DXERR_INVALIDDATA; 7108 } 7109