ReactOS  0.4.15-dev-489-g75a0787
effect.c
Go to the documentation of this file.
1 /*
2  * Copyright 2010 Christian Costa
3  * Copyright 2011 Rico Schüller
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include "config.h"
21 #include "wine/port.h"
22 
23 #include <stdio.h>
24 #include <assert.h>
25 
26 #include "d3dx9_private.h"
27 #include "d3dcompiler.h"
28 
29 /* Constants for special INT/FLOAT conversation */
30 #define INT_FLOAT_MULTI 255.0f
31 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
32 
33 static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
34 
35 #define PARAMETER_FLAG_SHARED 1
36 
37 #define INITIAL_POOL_SIZE 16
38 
40 
42 {
58 };
59 
61 {
67 };
68 
70 {
84 };
85 
87 {
94 };
95 
97 {
102 };
103 
105 {
107  void *data;
110 };
111 
113 {
119 };
120 
122 {
125 };
126 
127 struct d3dx_pass
128 {
129  char *name;
132 
135 
137 };
138 
140 {
141  char *name;
144 
146  struct d3dx_pass *passes;
147 
148  struct IDirect3DStateBlock9 *saved_state;
149 };
150 
152 {
154 
158 
162 
165 
167 
170  unsigned int full_name_tmp_size;
171 };
172 
174 {
175  ID3DXEffect ID3DXEffect_iface;
177 
179 
180  struct ID3DXEffectStateManager *manager;
181  struct IDirect3DDevice9 *device;
182  struct ID3DXEffectPool *pool;
187 
189  unsigned int light_updated;
192 };
193 
194 #define INITIAL_SHARED_DATA_SIZE 4
195 
197 {
198  ID3DXEffectPool ID3DXEffectPool_iface;
200 
202  unsigned int size;
203 
205 };
206 
208 {
209  ID3DXEffectCompiler ID3DXEffectCompiler_iface;
211 };
212 
214  unsigned int count, struct d3dx_parameter *parameters, const char *name);
216  const char *data, const char **ptr, struct d3dx_object *objects);
217 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
218 
220 
221 static const struct
222 {
223  enum STATE_CLASS class;
225  const char *name;
226 }
227 state_table[] =
228 {
229  /* Render states */
230  {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
231  {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
232  {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
233  {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
234  {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
235  {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
236  {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
237  {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
238  {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
239  {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
240  {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
241  {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
242  {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
243  {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
244  {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
245  {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
246  {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
247  {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
248  {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
249  {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
250  {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
251  {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
252  {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
253  {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
254  {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
255  {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
256  {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
257  {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
258  {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
259  {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
260  {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
261  {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
262  {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
263  {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
264  {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
265  {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
266  {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
267  {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
268  {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
269  {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
270  {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
271  {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
272  {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
273  {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
274  {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
275  {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
276  {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
277  {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
278  {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
279  {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
280  {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
281  {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
282  {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
283  {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
284  {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
285  {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
286  {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
287  {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
288  {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
289  {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
290  {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
291  {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
292  {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
293  {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
294  {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
295  {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
296  {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
297  {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
298  {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
299  {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
300  {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
301  {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
302  {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
303  {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
304  {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
305  {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
306  {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
307  {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
308  {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
309  {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
310  {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
311  {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
312  {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
313  {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
314  {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
315  {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
316  {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
317  {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
318  {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
319  {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
320  {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
321  {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
322  {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
323  {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
324  {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
325  {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
326  {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
327  {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
328  {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
329  {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
330  {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
331  {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
332  {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
333  /* Texture stages */
334  {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
335  {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
336  {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
337  {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
338  {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
339  {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
340  {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
341  {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
342  {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
343  {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
344  {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
345  {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
346  {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
347  {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
348  {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
349  {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
350  {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
351  {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
352  /* NPatchMode */
353  {SC_NPATCHMODE, 0, "NPatchMode"},
354  /* FVF */
355  {SC_FVF, 0, "FVF"},
356  /* Transform */
357  {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
358  {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
359  {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
360  {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
361  /* Material */
362  {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
363  {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
364  {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
365  {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
366  {SC_MATERIAL, MT_POWER, "MaterialPower"},
367  /* Light */
368  {SC_LIGHT, LT_TYPE, "LightType"},
369  {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
370  {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
371  {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
372  {SC_LIGHT, LT_POSITION, "LightPosition"},
373  {SC_LIGHT, LT_DIRECTION, "LightDirection"},
374  {SC_LIGHT, LT_RANGE, "LightRange"},
375  {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
376  {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
377  {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
378  {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
379  {SC_LIGHT, LT_THETA, "LightTheta"},
380  {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
381  /* Lightenable */
382  {SC_LIGHTENABLE, 0, "LightEnable"},
383  /* Vertexshader */
384  {SC_VERTEXSHADER, 0, "Vertexshader"},
385  /* Pixelshader */
386  {SC_PIXELSHADER, 0, "Pixelshader"},
387  /* Shader constants */
388  {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
389  {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
390  {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
391  {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
392  {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
393  {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
394  {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
395  {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
396  {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
397  {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
398  {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
399  {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
400  {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
401  {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
402  {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
403  {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
404  /* Texture */
405  {SC_TEXTURE, 0, "Texture"},
406  /* Sampler states */
407  {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
408  {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
409  {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
410  {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
411  {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
412  {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
413  {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
414  {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
415  {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
416  {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
417  {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
418  {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
419  {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
420  /* Set sampler */
421  {SC_SETSAMPLER, 0, "Sampler"},
422 };
423 
424 static inline void read_dword(const char **ptr, DWORD *d)
425 {
426  memcpy(d, *ptr, sizeof(*d));
427  *ptr += sizeof(*d);
428 }
429 
430 static void skip_dword_unknown(const char **ptr, unsigned int count)
431 {
432  unsigned int i;
433  DWORD d;
434 
435  WARN("Skipping %u unknown DWORDs:\n", count);
436  for (i = 0; i < count; ++i)
437  {
438  read_dword(ptr, &d);
439  WARN("\t0x%08x\n", d);
440  }
441 }
442 
443 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
444 {
445  return (D3DXHANDLE)parameter;
446 }
447 
448 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
449 {
450  return (D3DXHANDLE)technique;
451 }
452 
453 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
454 {
455  return (D3DXHANDLE)pass;
456 }
457 
458 static struct d3dx_technique *get_technique_by_name(struct d3dx9_base_effect *base, const char *name)
459 {
460  UINT i;
461 
462  if (!name) return NULL;
463 
464  for (i = 0; i < base->technique_count; ++i)
465  {
466  if (!strcmp(base->techniques[i].name, name))
467  return &base->techniques[i];
468  }
469 
470  return NULL;
471 }
472 
474 {
475  unsigned int i;
476 
477  for (i = 0; i < base->technique_count; ++i)
478  {
479  if (get_technique_handle(&base->techniques[i]) == technique)
480  return &base->techniques[i];
481  }
482 
483  return get_technique_by_name(base, technique);
484 }
485 
487 {
488  unsigned int i, k;
489 
490  for (i = 0; i < base->technique_count; ++i)
491  {
492  struct d3dx_technique *technique = &base->techniques[i];
493 
494  for (k = 0; k < technique->pass_count; ++k)
495  {
496  if (get_pass_handle(&technique->passes[k]) == pass)
497  return &technique->passes[k];
498  }
499  }
500 
501  return NULL;
502 }
503 
505 {
506  struct d3dx_parameter *handle_param = (struct d3dx_parameter *)parameter;
507 
508  if (handle_param && !strncmp(handle_param->magic_string, parameter_magic_string,
509  sizeof(parameter_magic_string)))
510  return handle_param;
511 
512  return base->flags & D3DXFX_LARGEADDRESSAWARE ? NULL : get_parameter_by_name(base, NULL, parameter);
513 }
514 
515 static void free_state(struct d3dx_state *state)
516 {
517  free_parameter(&state->parameter, FALSE, FALSE);
518 }
519 
520 static void free_object(struct d3dx_object *object)
521 {
522  HeapFree(GetProcessHeap(), 0, object->data);
523 }
524 
525 static void free_sampler(struct d3dx_sampler *sampler)
526 {
527  UINT i;
528 
529  for (i = 0; i < sampler->state_count; ++i)
530  {
531  free_state(&sampler->states[i]);
532  }
533  HeapFree(GetProcessHeap(), 0, sampler->states);
534 }
535 
537 
539 {
540  if (!param->data)
541  return;
542  if (param->class == D3DXPC_OBJECT && !param->element_count)
543  {
544  switch (param->type)
545  {
546  case D3DXPT_STRING:
547  HeapFree(GetProcessHeap(), 0, *(char **)param->data);
548  break;
549 
550  case D3DXPT_TEXTURE:
551  case D3DXPT_TEXTURE1D:
552  case D3DXPT_TEXTURE2D:
553  case D3DXPT_TEXTURE3D:
554  case D3DXPT_TEXTURECUBE:
555  case D3DXPT_PIXELSHADER:
556  case D3DXPT_VERTEXSHADER:
557  if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
558  break;
559 
560  case D3DXPT_SAMPLER:
561  case D3DXPT_SAMPLER1D:
562  case D3DXPT_SAMPLER2D:
563  case D3DXPT_SAMPLER3D:
564  case D3DXPT_SAMPLERCUBE:
565  free_sampler((struct d3dx_sampler *)param->data);
566  break;
567 
568  default:
569  FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
570  break;
571  }
572  }
573  if (!child)
574  HeapFree(GetProcessHeap(), 0, param->data);
575 }
576 
578 {
579  unsigned int i;
580 
581  TRACE("Free parameter %p, name %s, type %s, element %#x, child %#x.\n", param, param->name,
583 
584  if (param->param_eval)
585  d3dx_free_param_eval(param->param_eval);
586 
587  if (param->members)
588  {
589  unsigned int count = param->element_count ? param->element_count : param->member_count;
590 
591  for (i = 0; i < count; ++i)
592  free_parameter(&param->members[i], param->element_count != 0, TRUE);
593  HeapFree(GetProcessHeap(), 0, param->members);
594  }
595 
597 
598  /* only the parent has to release name and semantic */
599  if (!element)
600  {
602  HeapFree(GetProcessHeap(), 0, param->semantic);
603  }
604 }
605 
607 {
608  if (param->annotations)
609  {
610  unsigned int i;
611 
612  for (i = 0; i < param->annotation_count; ++i)
613  free_parameter(&param->annotations[i], FALSE, FALSE);
614  HeapFree(GetProcessHeap(), 0, param->annotations);
615  }
617  free_parameter(&param->param, FALSE, FALSE);
618 }
619 
620 static void free_pass(struct d3dx_pass *pass)
621 {
622  unsigned int i;
623 
624  TRACE("Free pass %p\n", pass);
625 
626  if (!pass)
627  return;
628 
629  if (pass->annotations)
630  {
631  for (i = 0; i < pass->annotation_count; ++i)
632  free_parameter(&pass->annotations[i], FALSE, FALSE);
633  HeapFree(GetProcessHeap(), 0, pass->annotations);
634  pass->annotations = NULL;
635  }
636 
637  if (pass->states)
638  {
639  for (i = 0; i < pass->state_count; ++i)
640  free_state(&pass->states[i]);
641  HeapFree(GetProcessHeap(), 0, pass->states);
642  pass->states = NULL;
643  }
644 
646  pass->name = NULL;
647 }
648 
649 static void free_technique(struct d3dx_technique *technique)
650 {
651  unsigned int i;
652 
653  TRACE("Free technique %p\n", technique);
654 
655  if (!technique)
656  return;
657 
658  if (technique->saved_state)
659  {
661  technique->saved_state = NULL;
662  }
663 
664  if (technique->annotations)
665  {
666  for (i = 0; i < technique->annotation_count; ++i)
667  free_parameter(&technique->annotations[i], FALSE, FALSE);
668  HeapFree(GetProcessHeap(), 0, technique->annotations);
669  technique->annotations = NULL;
670  }
671 
672  if (technique->passes)
673  {
674  for (i = 0; i < technique->pass_count; ++i)
675  free_pass(&technique->passes[i]);
676  HeapFree(GetProcessHeap(), 0, technique->passes);
677  technique->passes = NULL;
678  }
679 
680  HeapFree(GetProcessHeap(), 0, technique->name);
681  technique->name = NULL;
682 }
683 
685 {
686  unsigned int i;
687 
688  TRACE("base %p.\n", base);
689 
690  heap_free(base->full_name_tmp);
691 
692  if (base->parameters)
693  {
694  for (i = 0; i < base->parameter_count; ++i)
695  free_top_level_parameter(&base->parameters[i]);
696  HeapFree(GetProcessHeap(), 0, base->parameters);
697  base->parameters = NULL;
698  }
699 
700  if (base->techniques)
701  {
702  for (i = 0; i < base->technique_count; ++i)
703  free_technique(&base->techniques[i]);
704  HeapFree(GetProcessHeap(), 0, base->techniques);
705  base->techniques = NULL;
706  }
707 
708  if (base->objects)
709  {
710  for (i = 0; i < base->object_count; ++i)
711  {
712  free_object(&base->objects[i]);
713  }
714  HeapFree(GetProcessHeap(), 0, base->objects);
715  base->objects = NULL;
716  }
717 }
718 
719 static void free_effect(struct ID3DXEffectImpl *effect)
720 {
721  TRACE("Free effect %p\n", effect);
722 
724 
725  if (effect->pool)
726  {
727  effect->pool->lpVtbl->Release(effect->pool);
728  }
729 
730  if (effect->manager)
731  {
732  IUnknown_Release(effect->manager);
733  }
734 
736 }
737 
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 
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 
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 
818  struct d3dx_parameter *parameter, const char *name)
819 {
820  UINT element;
821  struct d3dx_parameter *temp_parameter;
822  const char *part;
823 
824  TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
825 
826  if (!name || !*name) return NULL;
827 
828  element = atoi(name);
829  part = strchr(name, ']') + 1;
830 
831  /* check for empty [] && element range */
832  if ((part - name) > 1 && parameter->element_count > element)
833  {
834  temp_parameter = &parameter->members[element];
835 
836  switch (*part++)
837  {
838  case '.':
839  return get_parameter_by_name(base, temp_parameter, part);
840 
841  case '\0':
842  TRACE("Returning parameter %p\n", temp_parameter);
843  return temp_parameter;
844 
845  default:
846  FIXME("Unhandled case \"%c\"\n", *--part);
847  break;
848  }
849  }
850 
851  TRACE("Parameter not found\n");
852  return NULL;
853 }
854 
856  unsigned int count, struct d3dx_parameter *annotations, const char *name)
857 {
858  UINT i, length;
859  struct d3dx_parameter *temp_parameter;
860  const char *part;
861 
862  TRACE("count %u, annotations %p, name %s\n", count, annotations, debugstr_a(name));
863 
864  if (!name || !*name) return NULL;
865 
866  length = strcspn( name, "[.@" );
867  part = name + length;
868 
869  for (i = 0; i < count; ++i)
870  {
871  temp_parameter = &annotations[i];
872 
873  if (!strcmp(temp_parameter->name, name))
874  {
875  TRACE("Returning annotation %p\n", temp_parameter);
876  return temp_parameter;
877  }
878  else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
879  {
880  switch (*part++)
881  {
882  case '.':
883  return get_parameter_by_name(base, temp_parameter, part);
884 
885  case '[':
886  return get_parameter_element_by_name(base, temp_parameter, part);
887 
888  default:
889  FIXME("Unhandled case \"%c\"\n", *--part);
890  break;
891  }
892  }
893  }
894 
895  TRACE("Annotation not found\n");
896  return NULL;
897 }
898 
900  struct d3dx_parameter *parameter, const char *name)
901 {
902  struct d3dx_parameter *temp_parameter;
903  unsigned int name_len, param_name_len;
904  unsigned int i, count, length;
905  struct wine_rb_entry *entry;
906  unsigned int full_name_size;
907  const char *part;
908  char *full_name;
909 
910  TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
911 
912  if (!name || !*name) return NULL;
913 
914  if (!parameter)
915  {
916  if ((entry = wine_rb_get(&base->param_tree, name)))
918  return NULL;
919  }
920 
921  /* Pass / technique annotations are not in the parameters tree. */
922  if (parameter->full_name)
923  {
924  name_len = strlen(name);
925  param_name_len = strlen(parameter->full_name);
926  full_name_size = name_len + param_name_len + 2;
927  if (base->full_name_tmp_size < full_name_size)
928  {
929  if (!(full_name = heap_realloc(base->full_name_tmp, full_name_size)))
930  {
931  ERR("Out of memory.\n");
932  return NULL;
933  }
934  base->full_name_tmp = full_name;
935  base->full_name_tmp_size = full_name_size;
936  }
937  else
938  {
939  full_name = base->full_name_tmp;
940  }
941  memcpy(full_name, parameter->full_name, param_name_len);
942  full_name[param_name_len] = '.';
943  memcpy(full_name + param_name_len + 1, name, name_len);
944  full_name[param_name_len + 1 + name_len] = 0;
945 
946  if ((entry = wine_rb_get(&base->param_tree, full_name)))
948  return NULL;
949  }
950 
951  count = parameter ? parameter->member_count : base->parameter_count;
952 
953  length = strcspn( name, "[.@" );
954  part = name + length;
955 
956  for (i = 0; i < count; i++)
957  {
958  temp_parameter = !parameter ? &base->parameters[i].param
959  : &parameter->members[i];
960 
961  if (!strcmp(temp_parameter->name, name))
962  {
963  TRACE("Returning parameter %p\n", temp_parameter);
964  return temp_parameter;
965  }
966  else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
967  {
968  switch (*part++)
969  {
970  case '.':
971  return get_parameter_by_name(base, temp_parameter, part);
972 
973  case '@':
974  {
975  struct d3dx_top_level_parameter *top_param
976  = top_level_parameter_from_parameter(temp_parameter);
977 
978  return parameter ? NULL : get_annotation_by_name(base, top_param->annotation_count,
979  top_param->annotations, part);
980  }
981  case '[':
982  return get_parameter_element_by_name(base, temp_parameter, part);
983 
984  default:
985  FIXME("Unhandled case \"%c\"\n", *--part);
986  break;
987  }
988  }
989  }
990 
991  TRACE("Parameter not found\n");
992  return NULL;
993 }
994 
996 {
997  return (0xfeff0000 | ((major) << 8) | (minor));
998 }
999 
1001 {
1002  if (!desc)
1003  {
1004  WARN("Invalid argument specified.\n");
1005  return D3DERR_INVALIDCALL;
1006  }
1007 
1008  FIXME("partial stub!\n");
1009 
1010  /* TODO: add creator and function count. */
1011  desc->Creator = NULL;
1012  desc->Functions = 0;
1013  desc->Parameters = base->parameter_count;
1014  desc->Techniques = base->technique_count;
1015 
1016  return D3D_OK;
1017 }
1018 
1020  D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
1021 {
1022  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1023 
1024  if (!desc || !param)
1025  {
1026  WARN("Invalid argument specified.\n");
1027  return D3DERR_INVALIDCALL;
1028  }
1029 
1030  desc->Name = param->name;
1031  desc->Semantic = param->semantic;
1032  desc->Class = param->class;
1033  desc->Type = param->type;
1034  desc->Rows = param->rows;
1035  desc->Columns = param->columns;
1036  desc->Elements = param->element_count;
1037  desc->Annotations = is_top_level_parameter(param)
1038  ? top_level_parameter_from_parameter(param)->annotation_count : 0;
1039  desc->StructMembers = param->member_count;
1040  desc->Flags = param->flags;
1041  desc->Bytes = param->bytes;
1042 
1043  return D3D_OK;
1044 }
1045 
1047  D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1048 {
1049  struct d3dx_technique *tech = technique ? get_valid_technique(base, technique) : &base->techniques[0];
1050 
1051  if (!desc || !tech)
1052  {
1053  WARN("Invalid argument specified.\n");
1054  return D3DERR_INVALIDCALL;
1055  }
1056 
1057  desc->Name = tech->name;
1058  desc->Passes = tech->pass_count;
1059  desc->Annotations = tech->annotation_count;
1060 
1061  return D3D_OK;
1062 }
1063 
1065  void **param_value, struct d3dx_parameter **out_param,
1066  BOOL update_all, BOOL *param_dirty)
1067 {
1068  struct d3dx_parameter *param = &state->parameter;
1069 
1070  *param_value = NULL;
1071  *out_param = NULL;
1072  *param_dirty = FALSE;
1073 
1074  switch (state->type)
1075  {
1076  case ST_PARAMETER:
1077  param = state->referenced_param;
1078  *param_dirty = is_param_dirty(param, pass->update_version);
1079  /* fallthrough */
1080  case ST_CONSTANT:
1081  *out_param = param;
1082  *param_value = param->data;
1083  return D3D_OK;
1084  case ST_ARRAY_SELECTOR:
1085  {
1086  unsigned int array_idx;
1087  static const struct d3dx_parameter array_idx_param =
1088  {"", NULL, NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, sizeof(array_idx)};
1089  HRESULT hr;
1090  struct d3dx_parameter *ref_param, *selected_param;
1091 
1092  if (!param->param_eval)
1093  {
1094  FIXME("Preshader structure is null.\n");
1095  return D3DERR_INVALIDCALL;
1096  }
1097  /* We override with the update_version of the pass because we want
1098  * to force index recomputation and check for out of bounds. */
1099  if (is_param_eval_input_dirty(param->param_eval, pass->update_version))
1100  {
1101  if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param, &array_idx)))
1102  return hr;
1103  }
1104  else
1105  {
1106  array_idx = state->index;
1107  }
1108  ref_param = state->referenced_param;
1109  TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
1110  ref_param->element_count);
1111  /* According to the tests, native d3dx handles the case of array index evaluated to -1
1112  * in a specific way, always selecting first array element and not returning error. */
1113  if (array_idx == ~0u)
1114  {
1115  WARN("Array index is -1, setting to 0.\n");
1116  array_idx = 0;
1117  }
1118 
1119  if (array_idx >= ref_param->element_count)
1120  {
1121  WARN("Computed array index %u is larger than array size %u.\n",
1122  array_idx, ref_param->element_count);
1123  return E_FAIL;
1124  }
1125  selected_param = &ref_param->members[array_idx];
1126  *param_dirty = state->index != array_idx || is_param_dirty(selected_param, pass->update_version);
1127  state->index = array_idx;
1128 
1129  *param_value = selected_param->data;
1130  *out_param = selected_param;
1131  return D3D_OK;
1132  }
1133  case ST_FXLC:
1134  if (param->param_eval)
1135  {
1136  *out_param = param;
1137  *param_value = param->data;
1138  /* We check with the update_version of the pass because the
1139  * same preshader might be used by both the vertex and the
1140  * pixel shader (that can happen e.g. for sampler states). */
1141  if (update_all || is_param_eval_input_dirty(param->param_eval, pass->update_version))
1142  {
1143  *param_dirty = TRUE;
1144  return d3dx_evaluate_parameter(param->param_eval, param, *param_value);
1145  }
1146  else
1147  return D3D_OK;
1148  }
1149  else
1150  {
1151  FIXME("No preshader for FXLC parameter.\n");
1152  return D3DERR_INVALIDCALL;
1153  }
1154  }
1155  return E_NOTIMPL;
1156 }
1157 
1159  D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
1160 {
1161  struct d3dx_pass *pass = get_valid_pass(base, pass_handle);
1162  unsigned int i;
1163 
1164  if (!desc || !pass)
1165  {
1166  WARN("Invalid argument specified.\n");
1167  return D3DERR_INVALIDCALL;
1168  }
1169 
1170  desc->Name = pass->name;
1171  desc->Annotations = pass->annotation_count;
1172 
1173  desc->pVertexShaderFunction = NULL;
1174  desc->pPixelShaderFunction = NULL;
1175 
1176  if (base->flags & D3DXFX_NOT_CLONEABLE)
1177  return D3D_OK;
1178 
1179  for (i = 0; i < pass->state_count; ++i)
1180  {
1181  struct d3dx_state *state = &pass->states[i];
1182 
1183  if (state_table[state->operation].class == SC_VERTEXSHADER
1184  || state_table[state->operation].class == SC_PIXELSHADER)
1185  {
1186  struct d3dx_parameter *param;
1187  void *param_value;
1188  BOOL param_dirty;
1189  HRESULT hr;
1190  void *data;
1191 
1192  if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
1193  FALSE, &param_dirty)))
1194  return hr;
1195 
1196  data = param->object_id ? base->objects[param->object_id].data : NULL;
1197  if (state_table[state->operation].class == SC_VERTEXSHADER)
1198  desc->pVertexShaderFunction = data;
1199  else
1200  desc->pPixelShaderFunction = data;
1201  }
1202  }
1203 
1204  return D3D_OK;
1205 }
1206 
1209 {
1210  FIXME("stub!\n");
1211 
1212  return E_NOTIMPL;
1213 }
1214 
1216  D3DXHANDLE parameter, UINT index)
1217 {
1218  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1219 
1220  if (!parameter)
1221  {
1222  if (index < base->parameter_count)
1223  {
1224  TRACE("Returning parameter %p.\n", &base->parameters[index]);
1225  return get_parameter_handle(&base->parameters[index].param);
1226  }
1227  }
1228  else
1229  {
1230  if (param && !param->element_count && index < param->member_count)
1231  {
1232  TRACE("Returning parameter %p.\n", &param->members[index]);
1233  return get_parameter_handle(&param->members[index]);
1234  }
1235  }
1236 
1237  WARN("Parameter not found.\n");
1238 
1239  return NULL;
1240 }
1241 
1243  D3DXHANDLE parameter, const char *name)
1244 {
1245  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1247 
1248  if (!name)
1249  {
1251  TRACE("Returning parameter %p.\n", handle);
1252  return handle;
1253  }
1254 
1256  TRACE("Returning parameter %p.\n", handle);
1257 
1258  return handle;
1259 }
1260 
1262  D3DXHANDLE parameter, const char *semantic)
1263 {
1264  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1265  struct d3dx_parameter *temp_param;
1266  UINT i;
1267 
1268  if (!parameter)
1269  {
1270  for (i = 0; i < base->parameter_count; ++i)
1271  {
1272  temp_param = &base->parameters[i].param;
1273 
1274  if (!temp_param->semantic)
1275  {
1276  if (!semantic)
1277  {
1278  TRACE("Returning parameter %p\n", temp_param);
1279  return get_parameter_handle(temp_param);
1280  }
1281  continue;
1282  }
1283 
1284  if (!strcasecmp(temp_param->semantic, semantic))
1285  {
1286  TRACE("Returning parameter %p\n", temp_param);
1287  return get_parameter_handle(temp_param);
1288  }
1289  }
1290  }
1291  else if (param)
1292  {
1293  for (i = 0; i < param->member_count; ++i)
1294  {
1295  temp_param = &param->members[i];
1296 
1297  if (!temp_param->semantic)
1298  {
1299  if (!semantic)
1300  {
1301  TRACE("Returning parameter %p\n", temp_param);
1302  return get_parameter_handle(temp_param);
1303  }
1304  continue;
1305  }
1306 
1307  if (!strcasecmp(temp_param->semantic, semantic))
1308  {
1309  TRACE("Returning parameter %p\n", temp_param);
1310  return get_parameter_handle(temp_param);
1311  }
1312  }
1313  }
1314 
1315  WARN("Parameter not found.\n");
1316 
1317  return NULL;
1318 }
1319 
1321  D3DXHANDLE parameter, UINT index)
1322 {
1323  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1324 
1325  if (!param)
1326  {
1327  if (index < base->parameter_count)
1328  {
1329  TRACE("Returning parameter %p.\n", &base->parameters[index]);
1330  return get_parameter_handle(&base->parameters[index].param);
1331  }
1332  }
1333  else
1334  {
1336  {
1337  TRACE("Returning parameter %p.\n", &param->members[index]);
1338  return get_parameter_handle(&param->members[index]);
1339  }
1340  }
1341 
1342  WARN("Parameter not found.\n");
1343 
1344  return NULL;
1345 }
1346 
1348 {
1349  if (index >= base->technique_count)
1350  {
1351  WARN("Invalid argument specified.\n");
1352  return NULL;
1353  }
1354 
1355  TRACE("Returning technique %p.\n", &base->techniques[index]);
1356 
1357  return get_technique_handle(&base->techniques[index]);
1358 }
1359 
1361 {
1362  struct d3dx_technique *tech = get_technique_by_name(base, name);
1363 
1364  if (tech)
1365  {
1367  TRACE("Returning technique %p\n", t);
1368  return t;
1369  }
1370 
1371  WARN("Technique not found.\n");
1372 
1373  return NULL;
1374 }
1375 
1377  D3DXHANDLE technique, UINT index)
1378 {
1379  struct d3dx_technique *tech = get_valid_technique(base, technique);
1380 
1381  if (tech && index < tech->pass_count)
1382  {
1383  TRACE("Returning pass %p\n", &tech->passes[index]);
1384  return get_pass_handle(&tech->passes[index]);
1385  }
1386 
1387  WARN("Pass not found.\n");
1388 
1389  return NULL;
1390 }
1391 
1393  D3DXHANDLE technique, const char *name)
1394 {
1395  struct d3dx_technique *tech = get_valid_technique(base, technique);
1396 
1397  if (tech && name)
1398  {
1399  unsigned int i;
1400 
1401  for (i = 0; i < tech->pass_count; ++i)
1402  {
1403  struct d3dx_pass *pass = &tech->passes[i];
1404 
1405  if (!strcmp(pass->name, name))
1406  {
1407  TRACE("Returning pass %p\n", pass);
1408  return get_pass_handle(pass);
1409  }
1410  }
1411  }
1412 
1413  WARN("Pass not found.\n");
1414 
1415  return NULL;
1416 }
1417 
1419 {
1420  FIXME("stub!\n");
1421 
1422  return NULL;
1423 }
1424 
1426 {
1427  FIXME("stub!\n");
1428 
1429  return NULL;
1430 }
1431 
1433  D3DXHANDLE object, struct d3dx_parameter **annotations)
1434 {
1435  struct d3dx_parameter *param = get_valid_parameter(base, object);
1436  struct d3dx_pass *pass = get_valid_pass(base, object);
1437  struct d3dx_technique *technique = get_valid_technique(base, object);
1438 
1439  if (pass)
1440  {
1441  *annotations = pass->annotations;
1442  return pass->annotation_count;
1443  }
1444  else if (technique)
1445  {
1446  *annotations = technique->annotations;
1447  return technique->annotation_count;
1448  }
1449  else if (param)
1450  {
1452  {
1453  struct d3dx_top_level_parameter *top_param
1455 
1456  *annotations = top_param->annotations;
1457  return top_param->annotation_count;
1458  }
1459  else
1460  {
1461  *annotations = NULL;
1462  return 0;
1463  }
1464  }
1465  else
1466  {
1467  FIXME("Functions are not handled, yet!\n");
1468  return 0;
1469  }
1470 }
1471 
1473  D3DXHANDLE object, UINT index)
1474 {
1475  struct d3dx_parameter *annotations = NULL;
1476  UINT annotation_count = 0;
1477 
1478  annotation_count = get_annotation_from_object(base, object, &annotations);
1479 
1480  if (index < annotation_count)
1481  {
1482  TRACE("Returning parameter %p\n", &annotations[index]);
1483  return get_parameter_handle(&annotations[index]);
1484  }
1485 
1486  WARN("Annotation not found.\n");
1487 
1488  return NULL;
1489 }
1490 
1492  D3DXHANDLE object, const char *name)
1493 {
1494  struct d3dx_parameter *annotation = NULL;
1495  struct d3dx_parameter *annotations = NULL;
1496  UINT annotation_count = 0;
1497 
1498  if (!name)
1499  {
1500  WARN("Invalid argument specified\n");
1501  return NULL;
1502  }
1503 
1504  annotation_count = get_annotation_from_object(base, object, &annotations);
1505 
1506  annotation = get_annotation_by_name(base, annotation_count, annotations, name);
1507  if (annotation)
1508  {
1509  TRACE("Returning parameter %p\n", annotation);
1511  }
1512 
1513  WARN("Annotation not found.\n");
1514 
1515  return NULL;
1516 }
1517 
1519  void *data)
1520 {
1521  unsigned int i;
1522  unsigned int member_count;
1523 
1524  if (param_func(data, param))
1525  return TRUE;
1526 
1527  member_count = param->element_count ? param->element_count : param->member_count;
1528  for (i = 0; i < member_count; ++i)
1529  {
1530  if (walk_parameter_tree(&param->members[i], param_func, data))
1531  return TRUE;
1532  }
1533  return FALSE;
1534 }
1535 
1537 {
1538  return base->pool ? &base->pool->version_counter : &base->version_counter;
1539 }
1540 
1542 {
1544 }
1545 
1546 static void set_dirty(struct d3dx_parameter *param)
1547 {
1548  struct d3dx_shared_data *shared_data;
1549  struct d3dx_top_level_parameter *top_param = param->top_level_param;
1550  ULONG64 new_update_version = next_update_version(top_param->version_counter);
1551 
1552  if ((shared_data = top_param->shared_data))
1553  shared_data->update_version = new_update_version;
1554  else
1555  top_param->update_version = new_update_version;
1556 }
1557 
1558 static HRESULT set_string(char **param_data, const char *string)
1559 {
1560  HeapFree(GetProcessHeap(), 0, *param_data);
1561  *param_data = HeapAlloc(GetProcessHeap(), 0, strlen(string) + 1);
1562  if (!*param_data)
1563  {
1564  ERR("Out of memory.\n");
1565  return E_OUTOFMEMORY;
1566  }
1567  strcpy(*param_data, string);
1568  return D3D_OK;
1569 }
1570 
1572  D3DXHANDLE parameter, const void *data, UINT bytes)
1573 {
1574  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1575  unsigned int i;
1576 
1577  if (!param)
1578  {
1579  WARN("Invalid parameter %p specified\n", parameter);
1580  return D3DERR_INVALIDCALL;
1581  }
1582 
1583  /* samplers don't touch data */
1584  if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1585  {
1586  TRACE("Sampler: returning E_FAIL\n");
1587  return E_FAIL;
1588  }
1589 
1590  if (data && param->bytes <= bytes)
1591  {
1592  switch (param->type)
1593  {
1594  case D3DXPT_TEXTURE:
1595  case D3DXPT_TEXTURE1D:
1596  case D3DXPT_TEXTURE2D:
1597  case D3DXPT_TEXTURE3D:
1598  case D3DXPT_TEXTURECUBE:
1599  for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1600  {
1601  IUnknown *old_texture = ((IUnknown **)param->data)[i];
1602  IUnknown *new_texture = ((IUnknown **)data)[i];
1603 
1604  if (new_texture == old_texture)
1605  continue;
1606 
1607  if (new_texture)
1608  IUnknown_AddRef(new_texture);
1609  if (old_texture)
1610  IUnknown_Release(old_texture);
1611  }
1612  /* fallthrough */
1613  case D3DXPT_VOID:
1614  case D3DXPT_BOOL:
1615  case D3DXPT_INT:
1616  case D3DXPT_FLOAT:
1617  TRACE("Copy %u bytes.\n", param->bytes);
1618  memcpy(param->data, data, param->bytes);
1619  set_dirty(param);
1620  break;
1621 
1622  case D3DXPT_STRING:
1623  {
1624  HRESULT hr;
1625 
1626  set_dirty(param);
1627  for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1628  {
1629  if (FAILED(hr = set_string(&((char **)param->data)[i], ((const char **)data)[i])))
1630  return hr;
1631  }
1632  break;
1633  }
1634 
1635  default:
1636  FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type));
1637  break;
1638  }
1639 
1640  return D3D_OK;
1641  }
1642 
1643  WARN("Invalid argument specified\n");
1644 
1645  return D3DERR_INVALIDCALL;
1646 }
1647 
1649  D3DXHANDLE parameter, void *data, UINT bytes)
1650 {
1651  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1652 
1653  if (!param)
1654  {
1655  WARN("Invalid parameter %p specified\n", parameter);
1656  return D3DERR_INVALIDCALL;
1657  }
1658 
1659  /* samplers don't touch data */
1660  if (param->class == D3DXPC_OBJECT && is_param_type_sampler(param->type))
1661  {
1662  TRACE("Sampler: returning E_FAIL\n");
1663  return E_FAIL;
1664  }
1665 
1666  if (data && param->bytes <= bytes)
1667  {
1668  TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1669 
1670  switch (param->type)
1671  {
1672  case D3DXPT_VOID:
1673  case D3DXPT_BOOL:
1674  case D3DXPT_INT:
1675  case D3DXPT_FLOAT:
1676  case D3DXPT_STRING:
1677  break;
1678 
1679  case D3DXPT_VERTEXSHADER:
1680  case D3DXPT_PIXELSHADER:
1681  case D3DXPT_TEXTURE:
1682  case D3DXPT_TEXTURE1D:
1683  case D3DXPT_TEXTURE2D:
1684  case D3DXPT_TEXTURE3D:
1685  case D3DXPT_TEXTURECUBE:
1686  {
1687  UINT i;
1688 
1689  for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1690  {
1691  IUnknown *unk = ((IUnknown **)param->data)[i];
1692  if (unk) IUnknown_AddRef(unk);
1693  }
1694  break;
1695  }
1696 
1697  default:
1698  FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1699  break;
1700  }
1701 
1702  TRACE("Copy %u bytes\n", param->bytes);
1703  memcpy(data, param->data, param->bytes);
1704  return D3D_OK;
1705  }
1706 
1707  WARN("Parameter not found.\n");
1708 
1709  return D3DERR_INVALIDCALL;
1710 }
1711 
1713 {
1714  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1715 
1716  if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1717  {
1718  set_number(param->data, param->type, &b, D3DXPT_BOOL);
1719  set_dirty(param);
1720  return D3D_OK;
1721  }
1722 
1723  WARN("Parameter not found.\n");
1724 
1725  return D3DERR_INVALIDCALL;
1726 }
1727 
1729 {
1730  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1731 
1732  if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
1733  {
1734  set_number(b, D3DXPT_BOOL, param->data, param->type);
1735  TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1736  return D3D_OK;
1737  }
1738 
1739  WARN("Parameter not found.\n");
1740 
1741  return D3DERR_INVALIDCALL;
1742 }
1743 
1745  D3DXHANDLE parameter, const BOOL *b, UINT count)
1746 {
1747  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1748 
1749  if (param)
1750  {
1751  UINT i, size = min(count, param->bytes / sizeof(DWORD));
1752 
1753  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1754 
1755  switch (param->class)
1756  {
1757  case D3DXPC_SCALAR:
1758  case D3DXPC_VECTOR:
1759  case D3DXPC_MATRIX_ROWS:
1760  for (i = 0; i < size; ++i)
1761  {
1762  /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
1763  set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
1764  }
1765  set_dirty(param);
1766  return D3D_OK;
1767 
1768  case D3DXPC_OBJECT:
1769  case D3DXPC_STRUCT:
1770  break;
1771 
1772  default:
1773  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1774  break;
1775  }
1776  }
1777 
1778  WARN("Parameter not found.\n");
1779 
1780  return D3DERR_INVALIDCALL;
1781 }
1782 
1784  D3DXHANDLE parameter, BOOL *b, UINT count)
1785 {
1786  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1787 
1788  if (b && param && (param->class == D3DXPC_SCALAR
1789  || param->class == D3DXPC_VECTOR
1790  || param->class == D3DXPC_MATRIX_ROWS
1791  || param->class == D3DXPC_MATRIX_COLUMNS))
1792  {
1793  UINT i, size = min(count, param->bytes / sizeof(DWORD));
1794 
1795  for (i = 0; i < size; ++i)
1796  {
1797  set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
1798  }
1799  return D3D_OK;
1800  }
1801 
1802  WARN("Parameter not found.\n");
1803 
1804  return D3DERR_INVALIDCALL;
1805 }
1806 
1808 {
1809  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1810 
1811  if (param && !param->element_count)
1812  {
1813  if (param->rows == 1 && param->columns == 1)
1814  {
1815  DWORD value;
1816 
1818  if (value != *(DWORD *)param->data)
1819  set_dirty(param);
1820  *(DWORD *)param->data = value;
1821  return D3D_OK;
1822  }
1823 
1824  /*
1825  * Split the value, if parameter is a vector with dimension 3 or 4.
1826  */
1827  if (param->type == D3DXPT_FLOAT &&
1828  ((param->class == D3DXPC_VECTOR && param->columns != 2) ||
1829  (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1830  {
1831  TRACE("Vector fixup\n");
1832 
1833  *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
1834  ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
1835  ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
1836  if (param->rows * param->columns > 3)
1837  {
1838  ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
1839  }
1840  set_dirty(param);
1841  return D3D_OK;
1842  }
1843  }
1844 
1845  WARN("Parameter not found.\n");
1846 
1847  return D3DERR_INVALIDCALL;
1848 }
1849 
1851 {
1852  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1853 
1854  if (n && param && !param->element_count)
1855  {
1856  if (param->columns == 1 && param->rows == 1)
1857  {
1858  set_number(n, D3DXPT_INT, param->data, param->type);
1859  TRACE("Returning %i\n", *n);
1860  return D3D_OK;
1861  }
1862 
1863  if (param->type == D3DXPT_FLOAT &&
1864  ((param->class == D3DXPC_VECTOR && param->columns != 2)
1865  || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1866  {
1867  TRACE("Vector fixup\n");
1868 
1869  /* all components (3,4) are clamped (0,255) and put in the INT */
1870  *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
1871  *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
1872  *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
1873  if (param->columns * param->rows > 3)
1874  {
1875  *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
1876  }
1877 
1878  TRACE("Returning %i\n", *n);
1879  return D3D_OK;
1880  }
1881  }
1882 
1883  WARN("Parameter not found.\n");
1884 
1885  return D3DERR_INVALIDCALL;
1886 }
1887 
1889  D3DXHANDLE parameter, const INT *n, UINT count)
1890 {
1891  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1892 
1893  if (param)
1894  {
1895  UINT i, size = min(count, param->bytes / sizeof(DWORD));
1896 
1897  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1898 
1899  switch (param->class)
1900  {
1901  case D3DXPC_SCALAR:
1902  case D3DXPC_VECTOR:
1903  case D3DXPC_MATRIX_ROWS:
1904  for (i = 0; i < size; ++i)
1905  {
1906  set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
1907  }
1908  set_dirty(param);
1909  return D3D_OK;
1910 
1911  case D3DXPC_OBJECT:
1912  case D3DXPC_STRUCT:
1913  break;
1914 
1915  default:
1916  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1917  break;
1918  }
1919  }
1920 
1921  WARN("Parameter not found.\n");
1922 
1923  return D3DERR_INVALIDCALL;
1924 }
1925 
1927  D3DXHANDLE parameter, INT *n, UINT count)
1928 {
1929  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1930 
1931  if (n && param && (param->class == D3DXPC_SCALAR
1932  || param->class == D3DXPC_VECTOR
1933  || param->class == D3DXPC_MATRIX_ROWS
1934  || param->class == D3DXPC_MATRIX_COLUMNS))
1935  {
1936  UINT i, size = min(count, param->bytes / sizeof(DWORD));
1937 
1938  for (i = 0; i < size; ++i)
1939  {
1940  set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
1941  }
1942  return D3D_OK;
1943  }
1944 
1945  WARN("Parameter not found.\n");
1946 
1947  return D3DERR_INVALIDCALL;
1948 }
1949 
1951 {
1952  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1953 
1954  if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1955  {
1956  DWORD value;
1957 
1959  if (value != *(DWORD *)param->data)
1960  set_dirty(param);
1961  *(DWORD *)param->data = value;
1962  return D3D_OK;
1963  }
1964 
1965  WARN("Parameter not found.\n");
1966 
1967  return D3DERR_INVALIDCALL;
1968 }
1969 
1971 {
1972  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1973 
1974  if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
1975  {
1976  set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
1977  TRACE("Returning %f\n", *f);
1978  return D3D_OK;
1979  }
1980 
1981  WARN("Parameter not found.\n");
1982 
1983  return D3DERR_INVALIDCALL;
1984 }
1985 
1987  D3DXHANDLE parameter, const float *f, UINT count)
1988 {
1989  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
1990 
1991  if (param)
1992  {
1993  UINT i, size = min(count, param->bytes / sizeof(DWORD));
1994 
1995  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1996 
1997  switch (param->class)
1998  {
1999  case D3DXPC_SCALAR:
2000  case D3DXPC_VECTOR:
2001  case D3DXPC_MATRIX_ROWS:
2002  for (i = 0; i < size; ++i)
2003  {
2004  set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
2005  }
2006  set_dirty(param);
2007  return D3D_OK;
2008 
2009  case D3DXPC_OBJECT:
2010  case D3DXPC_STRUCT:
2011  break;
2012 
2013  default:
2014  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2015  break;
2016  }
2017  }
2018 
2019  WARN("Parameter not found.\n");
2020 
2021  return D3DERR_INVALIDCALL;
2022 }
2023 
2025  D3DXHANDLE parameter, float *f, UINT count)
2026 {
2027  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2028 
2029  if (f && param && (param->class == D3DXPC_SCALAR
2030  || param->class == D3DXPC_VECTOR
2031  || param->class == D3DXPC_MATRIX_ROWS
2032  || param->class == D3DXPC_MATRIX_COLUMNS))
2033  {
2034  UINT i, size = min(count, param->bytes / sizeof(DWORD));
2035 
2036  for (i = 0; i < size; ++i)
2037  {
2038  set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
2039  }
2040  return D3D_OK;
2041  }
2042 
2043  WARN("Parameter not found.\n");
2044 
2045  return D3DERR_INVALIDCALL;
2046 }
2047 
2049  D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
2050 {
2051  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2052 
2053  if (param && !param->element_count)
2054  {
2055  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2056 
2057  switch (param->class)
2058  {
2059  case D3DXPC_SCALAR:
2060  case D3DXPC_VECTOR:
2061  set_dirty(param);
2062  if (param->type == D3DXPT_INT && param->bytes == 4)
2063  {
2064  DWORD tmp;
2065 
2066  TRACE("INT fixup\n");
2067  tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
2068  tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2069  tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2070  tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2071 
2072  *(INT *)param->data = tmp;
2073  return D3D_OK;
2074  }
2075  if (param->type == D3DXPT_FLOAT)
2076  {
2077  memcpy(param->data, vector, param->columns * sizeof(float));
2078  return D3D_OK;
2079  }
2080 
2082  return D3D_OK;
2083 
2084  case D3DXPC_MATRIX_ROWS:
2085  case D3DXPC_OBJECT:
2086  case D3DXPC_STRUCT:
2087  break;
2088 
2089  default:
2090  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2091  break;
2092  }
2093  }
2094 
2095  WARN("Parameter not found.\n");
2096 
2097  return D3DERR_INVALIDCALL;
2098 }
2099 
2101  D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2102 {
2103  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2104 
2105  if (vector && param && !param->element_count)
2106  {
2107  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2108 
2109  switch (param->class)
2110  {
2111  case D3DXPC_SCALAR:
2112  case D3DXPC_VECTOR:
2113  if (param->type == D3DXPT_INT && param->bytes == 4)
2114  {
2115  TRACE("INT fixup\n");
2116  vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2117  vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2118  vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2119  vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2120  return D3D_OK;
2121  }
2123  return D3D_OK;
2124 
2125  case D3DXPC_MATRIX_ROWS:
2126  case D3DXPC_OBJECT:
2127  case D3DXPC_STRUCT:
2128  break;
2129 
2130  default:
2131  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2132  break;
2133  }
2134  }
2135 
2136  WARN("Parameter not found.\n");
2137 
2138  return D3DERR_INVALIDCALL;
2139 }
2140 
2142  D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
2143 {
2144  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2145 
2146  if (param && param->element_count && param->element_count >= count)
2147  {
2148  UINT i;
2149 
2150  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2151 
2152  switch (param->class)
2153  {
2154  case D3DXPC_VECTOR:
2155  set_dirty(param);
2156  if (param->type == D3DXPT_FLOAT)
2157  {
2158  if (param->columns == 4)
2159  memcpy(param->data, vector, count * 4 * sizeof(float));
2160  else
2161  for (i = 0; i < count; ++i)
2162  memcpy((float *)param->data + param->columns * i, vector + i,
2163  param->columns * sizeof(float));
2164  return D3D_OK;
2165  }
2166 
2167  for (i = 0; i < count; ++i)
2168  {
2169  set_vector(&param->members[i], &vector[i]);
2170  }
2171  return D3D_OK;
2172 
2173  case D3DXPC_SCALAR:
2174  case D3DXPC_MATRIX_ROWS:
2175  case D3DXPC_OBJECT:
2176  case D3DXPC_STRUCT:
2177  break;
2178 
2179  default:
2180  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2181  break;
2182  }
2183  }
2184 
2185  WARN("Parameter not found.\n");
2186 
2187  return D3DERR_INVALIDCALL;
2188 }
2189 
2191  D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2192 {
2193  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2194 
2195  if (!count) return D3D_OK;
2196 
2198  {
2199  UINT i;
2200 
2201  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2202 
2203  switch (param->class)
2204  {
2205  case D3DXPC_VECTOR:
2206  for (i = 0; i < count; ++i)
2207  {
2208  get_vector(&param->members[i], &vector[i]);
2209  }
2210  return D3D_OK;
2211 
2212  case D3DXPC_SCALAR:
2213  case D3DXPC_MATRIX_ROWS:
2214  case D3DXPC_OBJECT:
2215  case D3DXPC_STRUCT:
2216  break;
2217 
2218  default:
2219  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2220  break;
2221  }
2222  }
2223 
2224  WARN("Parameter not found.\n");
2225 
2226  return D3DERR_INVALIDCALL;
2227 }
2228 
2230  D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2231 {
2232  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2233 
2234  if (param && !param->element_count)
2235  {
2236  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2237 
2238  switch (param->class)
2239  {
2240  case D3DXPC_MATRIX_ROWS:
2242  set_dirty(param);
2243  return D3D_OK;
2244 
2245  case D3DXPC_SCALAR:
2246  case D3DXPC_VECTOR:
2247  case D3DXPC_OBJECT:
2248  case D3DXPC_STRUCT:
2249  break;
2250 
2251  default:
2252  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2253  break;
2254  }
2255  }
2256 
2257  WARN("Parameter not found.\n");
2258 
2259  return D3DERR_INVALIDCALL;
2260 }
2261 
2263  D3DXHANDLE parameter, D3DXMATRIX *matrix)
2264 {
2265  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2266 
2267  if (matrix && param && !param->element_count)
2268  {
2269  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2270 
2271  switch (param->class)
2272  {
2273  case D3DXPC_MATRIX_ROWS:
2275  return D3D_OK;
2276 
2277  case D3DXPC_SCALAR:
2278  case D3DXPC_VECTOR:
2279  case D3DXPC_OBJECT:
2280  case D3DXPC_STRUCT:
2281  break;
2282 
2283  default:
2284  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2285  break;
2286  }
2287  }
2288 
2289  WARN("Parameter not found.\n");
2290 
2291  return D3DERR_INVALIDCALL;
2292 }
2293 
2295  D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2296 {
2297  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2298 
2299  if (param && param->element_count >= count)
2300  {
2301  UINT i;
2302 
2303  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2304 
2305  switch (param->class)
2306  {
2307  case D3DXPC_MATRIX_ROWS:
2308  set_dirty(param);
2309  for (i = 0; i < count; ++i)
2310  {
2311  set_matrix(&param->members[i], &matrix[i]);
2312  }
2313  return D3D_OK;
2314 
2315  case D3DXPC_SCALAR:
2316  case D3DXPC_VECTOR:
2317  case D3DXPC_OBJECT:
2318  case D3DXPC_STRUCT:
2319  break;
2320 
2321  default:
2322  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2323  break;
2324  }
2325  }
2326 
2327  WARN("Parameter not found.\n");
2328 
2329  return D3DERR_INVALIDCALL;
2330 }
2331 
2333  D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2334 {
2335  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2336 
2337  if (!count) return D3D_OK;
2338 
2340  {
2341  UINT i;
2342 
2343  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2344 
2345  switch (param->class)
2346  {
2347  case D3DXPC_MATRIX_ROWS:
2348  for (i = 0; i < count; ++i)
2349  {
2350  get_matrix(&param->members[i], &matrix[i], FALSE);
2351  }
2352  return D3D_OK;
2353 
2354  case D3DXPC_SCALAR:
2355  case D3DXPC_VECTOR:
2356  case D3DXPC_OBJECT:
2357  case D3DXPC_STRUCT:
2358  break;
2359 
2360  default:
2361  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2362  break;
2363  }
2364  }
2365 
2366  WARN("Parameter not found.\n");
2367 
2368  return D3DERR_INVALIDCALL;
2369 }
2370 
2372  D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2373 {
2374  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2375 
2377  {
2378  UINT i;
2379 
2380  switch (param->class)
2381  {
2382  case D3DXPC_MATRIX_ROWS:
2383  set_dirty(param);
2384  for (i = 0; i < count; ++i)
2385  {
2386  set_matrix(&param->members[i], matrix[i]);
2387  }
2388  return D3D_OK;
2389 
2390  case D3DXPC_SCALAR:
2391  case D3DXPC_VECTOR:
2392  case D3DXPC_OBJECT:
2393  break;
2394 
2395  default:
2396  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2397  break;
2398  }
2399  }
2400 
2401  WARN("Parameter not found.\n");
2402 
2403  return D3DERR_INVALIDCALL;
2404 }
2405 
2407  D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2408 {
2409  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2410 
2411  if (!count) return D3D_OK;
2412 
2414  {
2415  UINT i;
2416 
2417  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2418 
2419  switch (param->class)
2420  {
2421  case D3DXPC_MATRIX_ROWS:
2422  for (i = 0; i < count; ++i)
2423  {
2424  get_matrix(&param->members[i], matrix[i], FALSE);
2425  }
2426  return D3D_OK;
2427 
2428  case D3DXPC_SCALAR:
2429  case D3DXPC_VECTOR:
2430  case D3DXPC_OBJECT:
2431  break;
2432 
2433  default:
2434  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2435  break;
2436  }
2437  }
2438 
2439  WARN("Parameter not found.\n");
2440 
2441  return D3DERR_INVALIDCALL;
2442 }
2443 
2445  D3DXHANDLE parameter, const D3DXMATRIX *matrix)
2446 {
2447  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2448 
2449  if (param && !param->element_count)
2450  {
2451  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2452 
2453  switch (param->class)
2454  {
2455  case D3DXPC_MATRIX_ROWS:
2456  set_dirty(param);
2458  return D3D_OK;
2459 
2460  case D3DXPC_SCALAR:
2461  case D3DXPC_VECTOR:
2462  case D3DXPC_OBJECT:
2463  case D3DXPC_STRUCT:
2464  break;
2465 
2466  default:
2467  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2468  break;
2469  }
2470  }
2471 
2472  WARN("Parameter not found.\n");
2473 
2474  return D3DERR_INVALIDCALL;
2475 }
2476 
2478  D3DXHANDLE parameter, D3DXMATRIX *matrix)
2479 {
2480  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2481 
2482  if (matrix && param && !param->element_count)
2483  {
2484  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2485 
2486  switch (param->class)
2487  {
2488  case D3DXPC_SCALAR:
2489  case D3DXPC_VECTOR:
2491  return D3D_OK;
2492 
2493  case D3DXPC_MATRIX_ROWS:
2495  return D3D_OK;
2496 
2497  case D3DXPC_OBJECT:
2498  case D3DXPC_STRUCT:
2499  break;
2500 
2501  default:
2502  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2503  break;
2504  }
2505  }
2506 
2507  WARN("Parameter not found.\n");
2508 
2509  return D3DERR_INVALIDCALL;
2510 }
2511 
2513  D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
2514 {
2515  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2516 
2517  if (param && param->element_count >= count)
2518  {
2519  UINT i;
2520 
2521  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2522 
2523  switch (param->class)
2524  {
2525  case D3DXPC_MATRIX_ROWS:
2526  set_dirty(param);
2527  for (i = 0; i < count; ++i)
2528  {
2529  set_matrix_transpose(&param->members[i], &matrix[i]);
2530  }
2531  return D3D_OK;
2532 
2533  case D3DXPC_SCALAR:
2534  case D3DXPC_VECTOR:
2535  case D3DXPC_OBJECT:
2536  case D3DXPC_STRUCT:
2537  break;
2538 
2539  default:
2540  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2541  break;
2542  }
2543  }
2544 
2545  WARN("Parameter not found.\n");
2546 
2547  return D3DERR_INVALIDCALL;
2548 }
2549 
2551  D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2552 {
2553  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2554 
2555  if (!count) return D3D_OK;
2556 
2558  {
2559  UINT i;
2560 
2561  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2562 
2563  switch (param->class)
2564  {
2565  case D3DXPC_MATRIX_ROWS:
2566  for (i = 0; i < count; ++i)
2567  {
2568  get_matrix(&param->members[i], &matrix[i], TRUE);
2569  }
2570  return D3D_OK;
2571 
2572  case D3DXPC_SCALAR:
2573  case D3DXPC_VECTOR:
2574  case D3DXPC_OBJECT:
2575  case D3DXPC_STRUCT:
2576  break;
2577 
2578  default:
2579  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2580  break;
2581  }
2582  }
2583 
2584  WARN("Parameter not found.\n");
2585 
2586  return D3DERR_INVALIDCALL;
2587 }
2588 
2590  D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
2591 {
2592  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2593 
2595  {
2596  UINT i;
2597 
2598  switch (param->class)
2599  {
2600  case D3DXPC_MATRIX_ROWS:
2601  set_dirty(param);
2602  for (i = 0; i < count; ++i)
2603  {
2604  set_matrix_transpose(&param->members[i], matrix[i]);
2605  }
2606  return D3D_OK;
2607 
2608  case D3DXPC_SCALAR:
2609  case D3DXPC_VECTOR:
2610  case D3DXPC_OBJECT:
2611  break;
2612 
2613  default:
2614  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2615  break;
2616  }
2617  }
2618 
2619  WARN("Parameter not found.\n");
2620 
2621  return D3DERR_INVALIDCALL;
2622 }
2623 
2625  D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2626 {
2627  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2628 
2629  if (!count) return D3D_OK;
2630 
2632  {
2633  UINT i;
2634 
2635  TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2636 
2637  switch (param->class)
2638  {
2639  case D3DXPC_MATRIX_ROWS:
2640  for (i = 0; i < count; ++i)
2641  {
2642  get_matrix(&param->members[i], matrix[i], TRUE);
2643  }
2644  return D3D_OK;
2645 
2646  case D3DXPC_SCALAR:
2647  case D3DXPC_VECTOR:
2648  case D3DXPC_OBJECT:
2649  break;
2650 
2651  default:
2652  FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2653  break;
2654  }
2655  }
2656 
2657  WARN("Parameter not found.\n");
2658 
2659  return D3DERR_INVALIDCALL;
2660 }
2661 
2663  D3DXHANDLE parameter, const char *string)
2664 {
2665  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2666 
2667  if (param && param->type == D3DXPT_STRING)
2668  {
2669  set_dirty(param);
2670  return set_string(param->data, string);
2671  }
2672 
2673  WARN("Parameter not found.\n");
2674 
2675  return D3DERR_INVALIDCALL;
2676 }
2677 
2679  D3DXHANDLE parameter, const char **string)
2680 {
2681  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2682 
2683  if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2684  {
2685  *string = *(const char **)param->data;
2686  TRACE("Returning %s.\n", debugstr_a(*string));
2687  return D3D_OK;
2688  }
2689 
2690  WARN("Parameter not found.\n");
2691 
2692  return D3DERR_INVALIDCALL;
2693 }
2694 
2696  D3DXHANDLE parameter, struct IDirect3DBaseTexture9 *texture)
2697 {
2698  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2699 
2700  if (param && !param->element_count &&
2701  (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2702  || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2703  || param->type == D3DXPT_TEXTURECUBE))
2704  {
2705  struct IDirect3DBaseTexture9 *oltexture = *(struct IDirect3DBaseTexture9 **)param->data;
2706 
2707  if (texture == oltexture)
2708  return D3D_OK;
2709 
2711  if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2712 
2713  *(struct IDirect3DBaseTexture9 **)param->data = texture;
2714  set_dirty(param);
2715 
2716  return D3D_OK;
2717  }
2718 
2719  WARN("Parameter not found.\n");
2720 
2721  return D3DERR_INVALIDCALL;
2722 }
2723 
2725  D3DXHANDLE parameter, struct IDirect3DBaseTexture9 **texture)
2726 {
2727  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2728 
2729  if (texture && param && !param->element_count &&
2730  (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2731  || param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
2732  || param->type == D3DXPT_TEXTURECUBE))
2733  {
2734  *texture = *(struct IDirect3DBaseTexture9 **)param->data;
2736  TRACE("Returning %p\n", *texture);
2737  return D3D_OK;
2738  }
2739 
2740  WARN("Parameter not found.\n");
2741 
2742  return D3DERR_INVALIDCALL;
2743 }
2744 
2746  D3DXHANDLE parameter, struct IDirect3DPixelShader9 **shader)
2747 {
2748  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2749 
2750  if (shader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2751  {
2752  if ((*shader = *(struct IDirect3DPixelShader9 **)param->data))
2754  TRACE("Returning %p.\n", *shader);
2755  return D3D_OK;
2756  }
2757 
2758  WARN("Parameter not found.\n");
2759 
2760  return D3DERR_INVALIDCALL;
2761 }
2762 
2764  D3DXHANDLE parameter, struct IDirect3DVertexShader9 **shader)
2765 {
2766  struct d3dx_parameter *param = get_valid_parameter(base, parameter);
2767 
2768  if (shader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2769  {
2770  if ((*shader = *(struct IDirect3DVertexShader9 **)param->data))
2772  TRACE("Returning %p.\n", *shader);
2773  return D3D_OK;
2774  }
2775 
2776  WARN("Parameter not found.\n");
2777 
2778  return D3DERR_INVALIDCALL;
2779 }
2780 
2782  D3DXHANDLE parameter, UINT start, UINT end)
2783 {
2784  FIXME("stub!\n");
2785 
2786  return E_NOTIMPL;
2787 }
2788 
2790 {
2791  static const struct
2792  {
2793  unsigned int offset;
2794  const char *name;
2795  }
2796  light_tbl[] =
2797  {
2798  {FIELD_OFFSET(D3DLIGHT9, Type), "LC_TYPE"},
2799  {FIELD_OFFSET(D3DLIGHT9, Diffuse), "LT_DIFFUSE"},
2800  {FIELD_OFFSET(D3DLIGHT9, Specular), "LT_SPECULAR"},
2801  {FIELD_OFFSET(D3DLIGHT9, Ambient), "LT_AMBIENT"},
2802  {FIELD_OFFSET(D3DLIGHT9, Position), "LT_POSITION"},
2803  {FIELD_OFFSET(D3DLIGHT9, Direction), "LT_DIRECTION"},
2804  {FIELD_OFFSET(D3DLIGHT9, Range), "LT_RANGE"},
2805  {FIELD_OFFSET(D3DLIGHT9, Falloff), "LT_FALLOFF"},
2806  {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
2807  {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
2808  {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
2809  {FIELD_OFFSET(D3DLIGHT9, Theta), "LT_THETA"},
2810  {FIELD_OFFSET(D3DLIGHT9, Phi), "LT_PHI"}
2811  };
2812  switch (op)
2813  {
2814  case LT_TYPE:
2815  TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
2816  light->Type = *(D3DLIGHTTYPE *)value;
2817  break;
2818  case LT_DIFFUSE:
2819  case LT_SPECULAR:
2820  case LT_AMBIENT:
2821  {
2823 
2824  TRACE("%s (%.8e %.8e %.8e %.8e).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
2825  *(D3DCOLORVALUE *)((BYTE *)light + light_tbl[op].offset) = c;
2826  break;
2827  }
2828  case LT_POSITION:
2829  case LT_DIRECTION:
2830  {
2831  D3DVECTOR v = *(D3DVECTOR *)value;
2832 
2833  TRACE("%s (%.8e %.8e %.8e).\n", light_tbl[op].name, v.x, v.y, v.z);
2834  *(D3DVECTOR *)((BYTE *)light + light_tbl[op].offset) = v;
2835  break;
2836  }
2837  case LT_RANGE:
2838  case LT_FALLOFF:
2839  case LT_ATTENUATION0:
2840  case LT_ATTENUATION1:
2841  case LT_ATTENUATION2:
2842  case LT_THETA:
2843  case LT_PHI:
2844  {
2845  float v = *(float *)value;
2846  TRACE("%s %.8e.\n", light_tbl[op].name, v);
2847  *(float *)((BYTE *)light + light_tbl[op].offset) = v;
2848  break;
2849  }
2850  default:
2851  WARN("Unknown light parameter %u.\n", op);
2852  break;
2853  }
2854 }
2855 
2857 {
2858  static const struct
2859  {
2860  unsigned int offset;
2861  const char *name;
2862  }
2863  material_tbl[] =
2864  {
2865  {FIELD_OFFSET(D3DMATERIAL9, Diffuse), "MT_DIFFUSE"},
2866  {FIELD_OFFSET(D3DMATERIAL9, Ambient), "MT_AMBIENT"},
2867  {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
2868  {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
2869  {FIELD_OFFSET(D3DMATERIAL9, Power), "MT_POWER"}
2870  };
2871 
2872  switch (op)
2873  {
2874  case MT_POWER:
2875  {
2876  float v = *(float *)value;
2877 
2878  TRACE("%s %.8e.\n", material_tbl[op].name, v);
2879  material->Power = v;
2880  break;
2881  }
2882  case MT_DIFFUSE:
2883  case MT_AMBIENT:
2884  case MT_SPECULAR:
2885  case MT_EMISSIVE:
2886  {
2888 
2889  TRACE("%s, value (%.8e %.8e %.8e %.8e).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
2890  *(D3DCOLORVALUE *)((BYTE *)material + material_tbl[op].offset) = c;
2891  break;
2892  }
2893  default:
2894  WARN("Unknown material parameter %u.\n", op);
2895  break;
2896  }
2897 }
2898 
2900  struct d3dx_parameter *param, void *value_ptr)
2901 {
2902  static const struct
2903  {
2905  UINT elem_size;
2906  const char *name;
2907  }
2908  const_tbl[] =
2909  {
2910  {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_VSFLOAT"},
2911  {D3DXPT_BOOL, sizeof(BOOL), "SCT_VSBOOL"},
2912  {D3DXPT_INT, sizeof(int) * 4, "SCT_VSINT"},
2913  {D3DXPT_FLOAT, sizeof(float) * 4, "SCT_PSFLOAT"},
2914  {D3DXPT_BOOL, sizeof(BOOL), "SCT_PSBOOL"},
2915  {D3DXPT_INT, sizeof(int) * 4, "SCT_PSINT"},
2916  };
2917 
2918  BOOL is_heap_buffer = FALSE;
2919  unsigned int element_count;
2920  void *buffer = value_ptr;
2922  HRESULT ret;
2923 
2924  if (op < 0 || op > SCT_PSINT)
2925  {
2926  FIXME("Unknown op %u.\n", op);
2927  return D3DERR_INVALIDCALL;
2928  }
2929  element_count = param->bytes / const_tbl[op].elem_size;
2930  TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
2931  if (param->type != const_tbl[op].type)
2932  {
2933  FIXME("Unexpected param type %u.\n", param->type);
2934  return D3DERR_INVALIDCALL;
2935  }
2936 
2937  if (param->bytes % const_tbl[op].elem_size || element_count > 1)
2938  {
2939  unsigned int param_data_size;
2940 
2941  TRACE("Parameter size %u, rows %u, cols %u.\n", param->bytes, param->rows, param->columns);
2942 
2943  if (param->bytes % const_tbl[op].elem_size)
2944  ++element_count;
2945  if (element_count > 1)
2946  {
2947  WARN("Setting %u elements.\n", element_count);
2948  buffer = HeapAlloc(GetProcessHeap(), 0, const_tbl[op].elem_size * element_count);
2949  if (!buffer)
2950  {
2951  ERR("Out of memory.\n");
2952  return E_OUTOFMEMORY;
2953  }
2954  is_heap_buffer = TRUE;
2955  }
2956  else
2957  {
2958  assert(const_tbl[op].elem_size <= sizeof(value));
2959  buffer = &value;
2960  }
2961  param_data_size = min(param->bytes, const_tbl[op].elem_size);
2962  memcpy(buffer, value_ptr, param_data_size);
2963  memset((unsigned char *)buffer + param_data_size, 0,
2964  const_tbl[op].elem_size * element_count - param_data_size);
2965  }
2966 
2967  switch (op)
2968  {
2969  case SCT_VSFLOAT:
2970  ret = SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)buffer, element_count);
2971  break;
2972  case SCT_VSBOOL:
2973  ret = SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)buffer, element_count);
2974  break;
2975  case SCT_VSINT:
2976  ret = SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)buffer, element_count);
2977  break;
2978  case SCT_PSFLOAT:
2979  ret = SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)buffer, element_count);
2980  break;
2981  case SCT_PSBOOL:
2982  ret = SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)buffer, element_count);
2983  break;
2984  case SCT_PSINT:
2985  ret = SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)buffer, element_count);
2986  break;
2987  default:
2989  break;
2990  }
2991 
2992  if (is_heap_buffer)
2994 
2995  return ret;
2996 }
2997 
2998 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
2999  struct d3dx_state *state, unsigned int parent_index, BOOL update_all);
3000 
3002  struct d3dx_parameter *param, BOOL vs, BOOL update_all)
3003 {
3004  HRESULT hr, ret;
3005  struct d3dx_parameter **params;
3006  D3DXCONSTANT_DESC *cdesc;
3007  unsigned int parameters_count;
3008  unsigned int i, j;
3009 
3010  if (!param->param_eval)
3011  {
3012  FIXME("param_eval structure is null.\n");
3013  return D3DERR_INVALIDCALL;
3014  }
3016  param->param_eval, update_all)))
3017  return hr;
3018  params = param->param_eval->shader_inputs.inputs_param;
3019  cdesc = param->param_eval->shader_inputs.inputs;
3020  parameters_count = param->param_eval->shader_inputs.input_count;
3021  ret = D3D_OK;
3022  for (i = 0; i < parameters_count; ++i)
3023  {
3024  if (params[i] && params[i]->class == D3DXPC_OBJECT && is_param_type_sampler(params[i]->type))
3025  {
3026  struct d3dx_sampler *sampler;
3027  unsigned int sampler_idx;
3028 
3029  for (sampler_idx = 0; sampler_idx < cdesc[i].RegisterCount; ++sampler_idx)
3030  {
3031  sampler = params[i]->element_count ? params[i]->members[sampler_idx].data : params[i]->data;
3032  TRACE("sampler %s, register index %u, state count %u.\n", debugstr_a(params[i]->name),
3033  cdesc[i].RegisterIndex, sampler->state_count);
3034  for (j = 0; j < sampler->state_count; ++j)
3035  {
3036  if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[j],
3037  cdesc[i].RegisterIndex + sampler_idx + (vs ? D3DVERTEXTEXTURESAMPLER0 : 0),
3038  update_all)))
3039  ret = hr;
3040  }
3041  }
3042  }
3043  }
3044  return ret;
3045 }
3046 
3047 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
3048  struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
3049 {
3050  struct d3dx_parameter *param;
3051  void *param_value;
3052  BOOL param_dirty;
3053  HRESULT hr;
3054 
3055  TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
3056 
3057  if (FAILED(hr = d3dx9_get_param_value_ptr(pass, state, &param_value, &param,
3058  update_all, &param_dirty)))
3059  {
3060  if (!update_all && hr == E_FAIL)
3061  {
3062  /* Native d3dx9 returns D3D_OK from CommitChanges() involving
3063  * out of bounds array access and does not touch the affected
3064  * states. */
3065  WARN("Returning D3D_OK on out of bounds array access.\n");
3066  return D3D_OK;
3067  }
3068  return hr;
3069  }
3070 
3071  if (!(update_all || param_dirty
3072  || state_table[state->operation].class == SC_VERTEXSHADER
3073  || state_table[state->operation].class == SC_PIXELSHADER
3074  || state_table[state->operation].class == SC_SETSAMPLER))
3075  return D3D_OK;
3076 
3077  switch (state_table[state->operation].class)
3078  {
3079  case SC_RENDERSTATE:
3080  TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
3081  state_table[state->operation].op, *(DWORD *)param_value);
3082  return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
3083  case SC_FVF:
3084  TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
3085  return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
3086  case SC_TEXTURE:
3087  {
3088  UINT unit;
3089 
3090  unit = parent_index == ~0u ? state->index : parent_index;
3091  TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
3092  *(IDirect3DBaseTexture9 **)param_value);
3093  return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
3094  }
3095  case SC_TEXTURESTAGE:
3096  TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
3097  return SET_D3D_STATE(effect, SetTextureStageState, state->index,
3098  state_table[state->operation].op, *(DWORD *)param_value);
3099  case SC_SETSAMPLER:
3100  {
3101  struct d3dx_sampler *sampler;
3102  HRESULT ret, hr;
3103  unsigned int i;
3104 
3105  sampler = (struct d3dx_sampler *)param_value;
3106  TRACE("%s, sampler %u, applying %u states.\n", state_table[state->operation].name, state->index,
3107  sampler->state_count);
3108  ret = D3D_OK;
3109  for (i = 0; i < sampler->state_count; i++)
3110  {
3111  if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index, update_all)))
3112  ret = hr;
3113  }
3114  return ret;
3115  }
3116  case SC_SAMPLERSTATE:
3117  {
3118  UINT sampler;
3119 
3120  sampler = parent_index == ~0u ? state->index : parent_index;
3121  TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
3122  return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
3123  *(DWORD *)param_value);
3124  }
3125  case SC_VERTEXSHADER:
3126  TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
3127  if ((update_all || param_dirty)
3128  && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
3129  *(IDirect3DVertexShader9 **)param_value)))
3130  ERR("Could not set vertex shader, hr %#x.\n", hr);
3131  else if (*(IDirect3DVertexShader9 **)param_value)
3132  hr = d3dx_set_shader_constants(effect, pass, param, TRUE, update_all || param_dirty);
3133  return hr;
3134  case SC_PIXELSHADER:
3135  TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
3136  if ((update_all || param_dirty)
3137  && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
3138  *(IDirect3DPixelShader9 **)param_value)))
3139  ERR("Could not set pixel shader, hr %#x.\n", hr);
3140  else if (*(IDirect3DPixelShader9 **)param_value)
3141  hr = d3dx_set_shader_constants(effect, pass, param, FALSE, update_all || param_dirty);
3142  return hr;
3143  case SC_TRANSFORM:
3144  TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
3145  return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
3146  (D3DMATRIX *)param_value);
3147  case SC_LIGHTENABLE:
3148  TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
3149  return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
3150  case SC_LIGHT:
3151  {
3152  TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3153  state_table[state->operation].op);
3155  &effect->current_light[state->index], param_value);
3156  effect->light_updated |= 1u << state->index;
3157  return D3D_OK;
3158  }
3159  case SC_MATERIAL:
3160  {
3161  TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3162  state_table[state->operation].op);
3164  &effect->current_material, param_value);
3165  effect->material_updated = TRUE;
3166  return D3D_OK;
3167  }
3168  case SC_NPATCHMODE:
3169  TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
3170  return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
3171  case SC_SHADERCONST:
3172  TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
3173  state_table[state->operation].op);
3174  return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
3175  param, param_value);
3176  default:
3177  FIXME("%s not handled.\n", state_table[state->operation].name);
3178  break;
3179  }
3180  return D3D_OK;
3181 }
3182 
3183 static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass, BOOL update_all)
3184 {
3185  unsigned int i;
3186  HRESULT ret;
3187  HRESULT hr;
3188  ULONG64 new_update_version = next_effect_update_version(&effect->base_effect);
3189 
3190  TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
3191 
3192  ret = D3D_OK;
3193  for (i = 0; i < pass->state_count; ++i)
3194  {
3195  if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
3196  {
3197  WARN("Error applying state, hr %#x.\n", hr);
3198  ret = hr;
3199  }
3200  }
3201 
3202  if (effect->light_updated)
3203  {
3204  for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
3205  {
3206  if ((effect->light_updated & (1u << i))
3207  && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
3208  {
3209  WARN("Error setting light, hr %#x.\n", hr);
3210  ret = hr;
3211  }
3212  }
3213  effect->light_updated = 0;
3214  }
3215 
3216  if (effect->material_updated
3217  && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
3218  {
3219  WARN("Error setting material, hr %#x.\n", hr);
3220  ret = hr;
3221  }
3222  effect->material_updated = FALSE;
3223 
3224  pass->update_version = new_update_version;
3225  return ret;
3226 }
3227 
3228 static void param_set_data_pointer(struct d3dx_parameter *param, unsigned char *data, BOOL child, BOOL free_data)
3229 {
3230  unsigned char *member_data = data;
3231  unsigned int i, count;
3232 
3233  count = param->element_count ? param->element_count : param->member_count;
3234  for (i = 0; i < count; ++i)
3235  {
3236  param_set_data_pointer(&param->members[i], member_data, TRUE, free_data);
3237  if (data)
3238  member_data += param->members[i].bytes;
3239  }
3240  if (free_data)
3242  param->data = data;
3243 }
3244 
3245 static BOOL is_same_parameter(void *param1_, struct d3dx_parameter *param2)
3246 {
3247  struct d3dx_parameter *param1 = (struct d3dx_parameter *)param1_;
3248  BOOL matches;
3249  unsigned int i, member_count;
3250 
3251  matches = !strcmp(param1->name, param2->name) && param1->class == param2->class
3252  && param1->type == param2->type && param1->rows == param2->rows
3253  && param1->columns == param2->columns && param1->element_count == param2->element_count
3254  && param1->member_count == param2->member_count;
3255 
3256  member_count = param1->element_count ? param1->element_count : param1->member_count;
3257 
3258  if (!matches || !member_count)
3259  return matches;
3260 
3261  for (i = 0; i < member_count; ++i)
3262  {
3263  if (!is_same_parameter(&param1->members[i], &param2->members[i]))
3264  return FALSE;
3265  }
3266  return TRUE;
3267 }
3268 
3270 {
3271  unsigned int i, free_entry_index;
3272  unsigned int new_size, new_count;
3273 
3274  if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !pool || is_param_type_sampler(param->param.type))
3275  return D3D_OK;
3276 
3277  free_entry_index = pool->size;
3278  for (i = 0; i < pool->size; ++i)
3279  {
3280  if (!pool->shared_data[i].count)
3281  free_entry_index = i;
3282  else if (is_same_parameter(&param->param, &pool->shared_data[i].parameters[0]->param))
3283  break;
3284  }
3285  if (i == pool->size)
3286  {
3287  i = free_entry_index;
3288  if (i == pool->size)
3289  {
3290  struct d3dx_shared_data *new_alloc;
3291 
3292  if (!pool->size)
3293  {
3294  new_size = INITIAL_POOL_SIZE;
3295  new_alloc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3296  sizeof(*pool->shared_data) * new_size);
3297  if (!new_alloc)
3298  {
3299  ERR("Out of memory.\n");
3300  return E_OUTOFMEMORY;
3301  }
3302  }
3303  else
3304  {
3305  new_size = pool->size * 2;
3306  new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->shared_data,
3307  sizeof(*pool->shared_data) * new_size);
3308  if (!new_alloc)
3309  {
3310  ERR("Out of memory.\n");
3311  return E_OUTOFMEMORY;
3312  }
3313  if (new_alloc != pool->shared_data)
3314  {
3315  unsigned int j, k;
3316 
3317  for (j = 0; j < pool->size; ++j)
3318  for (k = 0; k < new_alloc[j].count; ++k)
3319  new_alloc[j].parameters[k]->shared_data = &new_alloc[j];
3320  }
3321  }
3322  pool->shared_data = new_alloc;
3323  pool->size = new_size;
3324  }
3325  pool->shared_data[i].data = param->param.data;
3326  }
3327  else
3328  {
3329  param_set_data_pointer(&param->param, pool->shared_data[i].data, FALSE, TRUE);
3330  }
3331  new_count = ++pool->shared_data[i].count;
3332  if (new_count >= pool->shared_data[i].size)
3333  {
3334  if (!pool->shared_data[i].size)
3335  {
3336  new_size = INITIAL_SHARED_DATA_SIZE;
3337  pool->shared_data[i].parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3338  sizeof(*pool->shared_data[i].parameters) * INITIAL_SHARED_DATA_SIZE);
3339  }
3340  else
3341  {
3342  new_size = pool->shared_data[i].size * 2;
3343  pool->shared_data[i].parameters = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
3344  pool->shared_data[i].parameters,
3345  sizeof(*pool->shared_data[i].parameters) * new_size);
3346  }
3347  pool->shared_data[i].size = new_size;
3348  }
3349 
3350  param->shared_data = &pool->shared_data[i];
3351  pool->shared_data[i].parameters[new_count - 1] = param;
3352 
3353  TRACE("name %s, parameter idx %u, new refcount %u.\n", debugstr_a(param->param.name), i,
3354  new_count);
3355 
3356  return D3D_OK;
3357 }
3358 
3360 {
3361  param->data = NULL;
3362  return FALSE;
3363 }
3364 
3366 {
3367  unsigned int new_count;
3368 
3369  if (!(param->param.flags & PARAMETER_FLAG_SHARED) || !param->shared_data)
3370  return;
3371  new_count = --param->shared_data->count;
3372 
3373  TRACE("param %p, param->shared_data %p, new_count %d.\n", param, param->shared_data, new_count);
3374 
3375  if (new_count)
3376  {
3377  unsigned int i;
3378 
3379  for (i = 0; i < new_count; ++i)
3380  {
3381  if (param->shared_data->parameters[i] == param)
3382  {
3383  memmove(&param->shared_data->parameters[i],
3384  &param->shared_data->parameters[i + 1],
3385  sizeof(param->shared_data->parameters[i]) * (new_count - i));
3386  break;
3387  }
3388  }
3390  }
3391  else
3392  {
3393  HeapFree(GetProcessHeap(), 0, param->shared_data->parameters);
3394  /* Zeroing table size is required as the entry in pool parameters table can be reused. */
3395  param->shared_data->size = 0;
3396  param->shared_data = NULL;
3397  }
3398 }
3399 
3400 static inline struct d3dx_effect_pool *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
3401 {
3403 }
3404 
3405 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
3406 {
3407  return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
3408 }
3409 
3410 /*** IUnknown methods ***/
3411 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
3412 {
3413  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
3414 
3415  if (IsEqualGUID(riid, &IID_IUnknown) ||
3416  IsEqualGUID(riid, &IID_ID3DXEffect))
3417  {
3418  iface->lpVtbl->AddRef(iface);
3419  *object = iface;
3420  return S_OK;
3421  }
3422 
3423  ERR("Interface %s not found\n", debugstr_guid(riid));
3424 
3425  return E_NOINTERFACE;
3426 }
3427 
3428 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
3429 {
3430  struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3431 
3432  TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
3433 
3434  return InterlockedIncrement(&This->ref);
3435 }
3436 
3437 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
3438 {
3439  struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3441 
3442  TRACE("(%p)->(): Release from %u\n", This, ref + 1);
3443 
3444  if (!ref)
3445  {
3446  free_effect(This);
3447  HeapFree(GetProcessHeap(), 0, This);
3448  }
3449 
3450  return ref;
3451 }
3452 
3453 /*** ID3DXBaseEffect methods ***/
3455 {
3456  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3457 
3458  TRACE("iface %p, desc %p.\n", iface, desc);
3459 
3460  return d3dx9_base_effect_get_desc(&effect->base_effect, desc);
3461 }
3462 
3464  D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3465 {
3466  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3467 
3468  TRACE("iface %p, parameter %p, desc %p.\n", iface, parameter, desc);
3469 
3470  return d3dx9_base_effect_get_parameter_desc(&effect->base_effect, parameter, desc);
3471 }
3472 
3474  D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3475 {
3476  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3477 
3478  TRACE("iface %p, technique %p, desc %p.\n", iface, technique, desc);
3479 
3480  return d3dx9_base_effect_get_technique_desc(&effect->base_effect, technique, desc);
3481 }
3482 
3484 {
3485  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3486 
3487  TRACE("iface %p, pass %p, desc %p.\n", iface, pass, desc);
3488 
3490 }
3491 
3493 {
3494  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3495 
3496  TRACE("iface %p, shader %p, desc %p.\n", iface, shader, desc);
3497 
3499 }
3500 
3501 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
3502 {
3503  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3504 
3505  TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3506 
3507  return d3dx9_base_effect_get_parameter(&effect->base_effect, parameter, index);
3508 }
3509 
3511  D3DXHANDLE parameter, const char *name)
3512 {
3513  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3514 
3515  TRACE("iface %p, parameter %p, name %s.\n", iface, parameter, debugstr_a(name));
3516 
3517  return d3dx9_base_effect_get_parameter_by_name(&effect->base_effect, parameter, name);
3518 }
3519 
3521  D3DXHANDLE parameter, const char *semantic)
3522 {
3523  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3524 
3525  TRACE("iface %p, parameter %p, semantic %s.\n", iface, parameter, debugstr_a(semantic));
3526 
3527  return d3dx9_base_effect_get_parameter_by_semantic(&effect->base_effect, parameter, semantic);
3528 }
3529 
3531 {
3532  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3533 
3534  TRACE("iface %p, parameter %p, index %u.\n", iface, parameter, index);
3535 
3536  return d3dx9_base_effect_get_parameter_element(&effect->base_effect, parameter, index);
3537 }
3538 
3540 {
3541  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3542 
3543  TRACE("iface %p, index %u.\n", iface, index);
3544 
3546 }
3547 
3548 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, const char *name)
3549 {
3550  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3551 
3552  TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3553 
3555 }
3556 
3557 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
3558 {
3559  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3560 
3561  TRACE("iface %p, technique %p, index %u.\n", iface, technique, index);
3562 
3563  return d3dx9_base_effect_get_pass(&effect->base_effect, technique, index);
3564 }
3565 
3567  D3DXHANDLE technique, const char *name)
3568 {
3569  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3570 
3571  TRACE("iface %p, technique %p, name %s.\n", iface, technique, debugstr_a(name));
3572 
3573  return d3dx9_base_effect_get_pass_by_name(&effect->base_effect, technique, name);
3574 }
3575 
3577 {
3578  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3579 
3580  TRACE("iface %p, index %u.\n", iface, index);
3581 
3583 }
3584 
3585 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, const char *name)
3586 {
3587  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3588 
3589  TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
3590 
3592 }
3593 
3595 {
3596  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3597 
3598  TRACE("iface %p, object %p, index %u.\n", iface, object, index);
3599 
3600  return d3dx9_base_effect_get_annotation(&effect->base_effect, object, index);
3601 }
3602 
3604  D3DXHANDLE object, const char *name)
3605 {
3606  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3607 
3608  TRACE("iface %p, object %p, name %s.\n", iface, object, debugstr_a(name));
3609 
3610  return d3dx9_base_effect_get_annotation_by_name(&effect->base_effect, object, name);
3611 }
3612 
3613 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface,
3614  D3DXHANDLE parameter, const void *data, UINT bytes)
3615 {
3616  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3617 
3618  TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3619 
3620  return d3dx9_base_effect_set_value(&effect->base_effect, parameter, data, bytes);
3621 }
3622 
3623 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface,
3624  D3DXHANDLE parameter, void *data, UINT bytes)
3625 {
3626  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3627 
3628  TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
3629 
3630  return d3dx9_base_effect_get_value(&effect->base_effect, parameter, data, bytes);
3631 }
3632 
3633 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
3634 {
3635  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3636 
3637  TRACE("iface %p, parameter %p, b %#x.\n", iface, parameter, b);
3638 
3639  return d3dx9_base_effect_set_bool(&effect->base_effect, parameter, b);
3640 }
3641 
3642 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
3643 {
3644  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3645 
3646  TRACE("iface %p, parameter %p, b %p.\n", iface, parameter, b);
3647 
3648  return d3dx9_base_effect_get_bool(&effect->base_effect, parameter, b);
3649 }
3650 
3651 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface,
3652  D3DXHANDLE parameter, const BOOL *b, UINT count)
3653 {
3654  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3655 
3656  TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3657 
3658  return d3dx9_base_effect_set_bool_array(&effect->base_effect, parameter, b, count);
3659 }
3660 
3661 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface,
3662  D3DXHANDLE parameter, BOOL *b, UINT count)
3663 {
3664  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3665 
3666  TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
3667 
3668  return d3dx9_base_effect_get_bool_array(&effect->base_effect, parameter, b, count);
3669 }
3670 
3671 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
3672 {
3673  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3674 
3675  TRACE("iface %p, parameter %p, n %d.\n", iface, parameter, n);
3676 
3677  return d3dx9_base_effect_set_int(&effect->base_effect, parameter, n);
3678 }
3679 
3680 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
3681 {
3682  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3683 
3684  TRACE("iface %p, parameter %p, n %p.\n", iface, parameter, n);
3685 
3686  return d3dx9_base_effect_get_int(&effect->base_effect, parameter, n);
3687 }
3688 
3689 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface,
3690  D3DXHANDLE parameter, const INT *n, UINT count)
3691 {
3692  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3693 
3694  TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3695 
3696  return d3dx9_base_effect_set_int_array(&effect->base_effect, parameter, n, count);
3697 }
3698 
3699 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface,
3700  D3DXHANDLE parameter, INT *n, UINT count)
3701 {
3702  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3703 
3704  TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
3705 
3706  return d3dx9_base_effect_get_int_array(&effect->base_effect, parameter, n, count);
3707 }
3708 
3709 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float f)
3710 {
3711  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3712 
3713  TRACE("iface %p, parameter %p, f %.8e.\n", iface, parameter, f);
3714 
3715  return d3dx9_base_effect_set_float(&effect->base_effect, parameter, f);
3716 }
3717 
3718 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, float *f)
3719 {
3720  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3721 
3722  TRACE("iface %p, parameter %p, f %p.\n", iface, parameter, f);
3723 
3724  return d3dx9_base_effect_get_float(&effect->base_effect, parameter, f);
3725 }
3726 
3728  D3DXHANDLE parameter, const float *f, UINT count)
3729 {
3730  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3731 
3732  TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3733 
3734  return d3dx9_base_effect_set_float_array(&effect->base_effect, parameter, f, count);
3735 }
3736 
3738  D3DXHANDLE parameter, float *f, UINT count)
3739 {
3740  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3741 
3742  TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
3743 
3744  return d3dx9_base_effect_get_float_array(&effect->base_effect, parameter, f, count);
3745 }
3746 
3747 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface,
3748  D3DXHANDLE parameter, const D3DXVECTOR4 *vector)
3749 {
3750  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3751 
3752  TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3753 
3754  return d3dx9_base_effect_set_vector(&effect->base_effect, parameter, vector);
3755 }
3756 
3757 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface,
3758  D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3759 {
3760  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3761 
3762  TRACE("iface %p, parameter %p, vector %p.\n", iface, parameter, vector);
3763 
3764  return d3dx9_base_effect_get_vector(&effect->base_effect, parameter, vector);
3765 }
3766 
3768  D3DXHANDLE parameter, const D3DXVECTOR4 *vector, UINT count)
3769 {
3770  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3771 
3772  TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3773 
3774  return d3dx9_base_effect_set_vector_array(&effect->base_effect, parameter, vector, count);
3775 }
3776 
3778  D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3779 {
3780  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3781 
3782  TRACE("iface %p, parameter %p, vector %p, count %u.\n", iface, parameter, vector, count);
3783 
3784  return d3dx9_base_effect_get_vector_array(&effect->base_effect, parameter, vector, count);
3785 }
3786 
3787 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface,
3788  D3DXHANDLE parameter, const D3DXMATRIX *matrix)
3789 {
3790  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3791 
3792  TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3793 
3794  return d3dx9_base_effect_set_matrix(&effect->base_effect, parameter, matrix);
3795 }
3796 
3797 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface,
3798  D3DXHANDLE parameter, D3DXMATRIX *matrix)
3799 {
3800  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3801 
3802  TRACE("iface %p, parameter %p, matrix %p.\n", iface, parameter, matrix);
3803 
3804  return d3dx9_base_effect_get_matrix(&effect->base_effect, parameter, matrix);
3805 }
3806 
3808  D3DXHANDLE parameter, const D3DXMATRIX *matrix, UINT count)
3809 {
3810  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3811 
3812  TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3813 
3814  return d3dx9_base_effect_set_matrix_array(&effect->base_effect, parameter, matrix, count);
3815 }
3816 
3818  D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3819 {
3820  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3821 
3822  TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3823 
3824  return d3dx9_base_effect_get_matrix_array(&effect->base_effect, parameter, matrix, count);
3825 }
3826 
3828  D3DXHANDLE parameter, const D3DXMATRIX **matrix, UINT count)
3829 {
3830  struct ID3DXEffectImpl *effect = impl_from_ID3DXEffect(iface);
3831 
3832  TRACE("iface %p, parameter %p, matrix %p, count %u.\n", iface, parameter, matrix, count);
3833 
3835 }
3836 
3838  D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3839 {
3840