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