d3dx9: Implement ID3DXBaseEffect::GetInt().
[wine] / dlls / d3dx9_36 / effect.c
1 /*
2  * Copyright 2010 Christian Costa
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wine/debug.h"
22 #include "wine/unicode.h"
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "d3dx9_36_private.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
28
29 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl;
30 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl;
31 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl;
32
33 struct d3dx_parameter
34 {
35     struct ID3DXBaseEffectImpl *base;
36
37     char *name;
38     char *semantic;
39     void *data;
40     D3DXPARAMETER_CLASS class;
41     D3DXPARAMETER_TYPE  type;
42     UINT rows;
43     UINT columns;
44     UINT element_count;
45     UINT annotation_count;
46     UINT member_count;
47     DWORD flags;
48     UINT bytes;
49
50     D3DXHANDLE *annotation_handles;
51     D3DXHANDLE *member_handles;
52 };
53
54 struct d3dx_pass
55 {
56     struct ID3DXBaseEffectImpl *base;
57
58     char *name;
59     UINT state_count;
60     UINT annotation_count;
61
62     D3DXHANDLE *annotation_handles;
63 };
64
65 struct d3dx_technique
66 {
67     struct ID3DXBaseEffectImpl *base;
68
69     char *name;
70     UINT pass_count;
71     UINT annotation_count;
72
73     D3DXHANDLE *annotation_handles;
74     D3DXHANDLE *pass_handles;
75 };
76
77 struct ID3DXBaseEffectImpl
78 {
79     ID3DXBaseEffect ID3DXBaseEffect_iface;
80     LONG ref;
81
82     struct ID3DXEffectImpl *effect;
83
84     UINT parameter_count;
85     UINT technique_count;
86     UINT object_count;
87
88     D3DXHANDLE *parameter_handles;
89     D3DXHANDLE *technique_handles;
90     D3DXHANDLE *objects;
91 };
92
93 struct ID3DXEffectImpl
94 {
95     ID3DXEffect ID3DXEffect_iface;
96     LONG ref;
97
98     LPDIRECT3DDEVICE9 device;
99     LPD3DXEFFECTPOOL pool;
100
101     ID3DXBaseEffect *base_effect;
102 };
103
104 struct ID3DXEffectCompilerImpl
105 {
106     ID3DXEffectCompiler ID3DXEffectCompiler_iface;
107     LONG ref;
108
109     ID3DXBaseEffect *base_effect;
110 };
111
112 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
113         struct d3dx_parameter *parameter, LPCSTR name);
114 static struct d3dx_parameter *get_parameter_annotation_by_name(struct ID3DXBaseEffectImpl *base,
115         struct d3dx_parameter *parameter, LPCSTR name);
116
117 static inline void read_dword(const char **ptr, DWORD *d)
118 {
119     memcpy(d, *ptr, sizeof(*d));
120     *ptr += sizeof(*d);
121 }
122
123 static void skip_dword_unknown(const char **ptr, unsigned int count)
124 {
125     unsigned int i;
126     DWORD d;
127
128     FIXME("Skipping %u unknown DWORDs:\n", count);
129     for (i = 0; i < count; ++i)
130     {
131         read_dword(ptr, &d);
132         FIXME("\t0x%08x\n", d);
133     }
134 }
135
136 static inline struct d3dx_parameter *get_parameter_struct(D3DXHANDLE handle)
137 {
138     return (struct d3dx_parameter *) handle;
139 }
140
141 static inline struct d3dx_pass *get_pass_struct(D3DXHANDLE handle)
142 {
143     return (struct d3dx_pass *) handle;
144 }
145
146 static inline struct d3dx_technique *get_technique_struct(D3DXHANDLE handle)
147 {
148     return (struct d3dx_technique *) handle;
149 }
150
151 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
152 {
153     return (D3DXHANDLE) parameter;
154 }
155
156 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
157 {
158     return (D3DXHANDLE) technique;
159 }
160
161 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
162 {
163     return (D3DXHANDLE) pass;
164 }
165
166 static struct d3dx_technique *is_valid_technique(struct ID3DXBaseEffectImpl *base, D3DXHANDLE technique)
167 {
168     unsigned int i;
169
170     for (i = 0; i < base->technique_count; ++i)
171     {
172         if (base->technique_handles[i] == technique)
173         {
174             return get_technique_struct(technique);
175         }
176     }
177
178     return NULL;
179 }
180
181 static struct d3dx_pass *is_valid_pass(struct ID3DXBaseEffectImpl *base, D3DXHANDLE pass)
182 {
183     unsigned int i, k;
184
185     for (i = 0; i < base->technique_count; ++i)
186     {
187         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
188
189         for (k = 0; k < technique->pass_count; ++k)
190         {
191             if (technique->pass_handles[k] == pass)
192             {
193                 return get_pass_struct(pass);
194             }
195         }
196     }
197
198     return NULL;
199 }
200
201 static struct d3dx_parameter *is_valid_sub_parameter(struct d3dx_parameter *param, D3DXHANDLE parameter)
202 {
203     unsigned int i, count;
204     struct d3dx_parameter *p;
205
206     for (i = 0; i < param->annotation_count; ++i)
207     {
208         if (param->annotation_handles[i] == parameter)
209         {
210             return get_parameter_struct(parameter);
211         }
212
213         p = is_valid_sub_parameter(get_parameter_struct(param->annotation_handles[i]), parameter);
214         if (p) return p;
215     }
216
217     if (param->element_count) count = param->element_count;
218     else count = param->member_count;
219
220     for (i = 0; i < count; ++i)
221     {
222         if (param->member_handles[i] == parameter)
223         {
224             return get_parameter_struct(parameter);
225         }
226
227         p = is_valid_sub_parameter(get_parameter_struct(param->member_handles[i]), parameter);
228         if (p) return p;
229     }
230
231     return NULL;
232 }
233
234 static struct d3dx_parameter *is_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
235 {
236     unsigned int i, k, m;
237     struct d3dx_parameter *p;
238
239     for (i = 0; i < base->parameter_count; ++i)
240     {
241         if (base->parameter_handles[i] == parameter)
242         {
243             return get_parameter_struct(parameter);
244         }
245
246         p = is_valid_sub_parameter(get_parameter_struct(base->parameter_handles[i]), parameter);
247         if (p) return p;
248     }
249
250     for (i = 0; i < base->technique_count; ++i)
251     {
252         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
253
254         for (k = 0; k < technique->pass_count; ++k)
255         {
256             struct d3dx_pass *pass = get_pass_struct(technique->pass_handles[k]);
257
258             for (m = 0; m < pass->annotation_count; ++m)
259             {
260                 if (pass->annotation_handles[i] == parameter)
261                 {
262                     return get_parameter_struct(parameter);
263                 }
264
265                 p = is_valid_sub_parameter(get_parameter_struct(pass->annotation_handles[m]), parameter);
266                 if (p) return p;
267             }
268         }
269
270         for (k = 0; k < technique->annotation_count; ++k)
271         {
272             if (technique->annotation_handles[k] == parameter)
273             {
274                 return get_parameter_struct(parameter);
275             }
276
277             p = is_valid_sub_parameter(get_parameter_struct(technique->annotation_handles[k]), parameter);
278             if (p) return p;
279         }
280     }
281
282     return NULL;
283 }
284
285 static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
286 {
287     unsigned int i;
288     struct d3dx_parameter *param = get_parameter_struct(handle);
289
290     TRACE("Free parameter %p, child %s\n", param, child ? "yes" : "no");
291
292     if (!param)
293     {
294         return;
295     }
296
297     if (param->annotation_handles)
298     {
299         for (i = 0; i < param->annotation_count; ++i)
300         {
301             free_parameter(param->annotation_handles[i], FALSE, FALSE);
302         }
303         HeapFree(GetProcessHeap(), 0, param->annotation_handles);
304     }
305
306     if (param->member_handles)
307     {
308         unsigned int count;
309
310         if (param->element_count) count = param->element_count;
311         else count = param->member_count;
312
313         for (i = 0; i < count; ++i)
314         {
315             free_parameter(param->member_handles[i], param->element_count != 0, TRUE);
316         }
317         HeapFree(GetProcessHeap(), 0, param->member_handles);
318     }
319
320     if (param->class == D3DXPC_OBJECT && !param->element_count)
321     {
322         switch(param->type)
323         {
324             case D3DXPT_STRING:
325                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
326                 break;
327
328             case D3DXPT_PIXELSHADER:
329             case D3DXPT_VERTEXSHADER:
330                 if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
331                 break;
332
333             default:
334                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
335                 break;
336         }
337     }
338
339     if (!child)
340     {
341         HeapFree(GetProcessHeap(), 0, param->data);
342     }
343
344     /* only the parent has to release name and semantic */
345     if (!element)
346     {
347         HeapFree(GetProcessHeap(), 0, param->name);
348         HeapFree(GetProcessHeap(), 0, param->semantic);
349     }
350
351     HeapFree(GetProcessHeap(), 0, param);
352 }
353
354 static void free_pass(D3DXHANDLE handle)
355 {
356     unsigned int i;
357     struct d3dx_pass *pass = get_pass_struct(handle);
358
359     TRACE("Free pass %p\n", pass);
360
361     if (!pass)
362     {
363         return;
364     }
365
366     if (pass->annotation_handles)
367     {
368         for (i = 0; i < pass->annotation_count; ++i)
369         {
370             free_parameter(pass->annotation_handles[i], FALSE, FALSE);
371         }
372         HeapFree(GetProcessHeap(), 0, pass->annotation_handles);
373     }
374
375     HeapFree(GetProcessHeap(), 0, pass->name);
376     HeapFree(GetProcessHeap(), 0, pass);
377 }
378
379 static void free_technique(D3DXHANDLE handle)
380 {
381     unsigned int i;
382     struct d3dx_technique *technique = get_technique_struct(handle);
383
384     TRACE("Free technique %p\n", technique);
385
386     if (!technique)
387     {
388         return;
389     }
390
391     if (technique->annotation_handles)
392     {
393         for (i = 0; i < technique->annotation_count; ++i)
394         {
395             free_parameter(technique->annotation_handles[i], FALSE, FALSE);
396         }
397         HeapFree(GetProcessHeap(), 0, technique->annotation_handles);
398     }
399
400     if (technique->pass_handles)
401     {
402         for (i = 0; i < technique->pass_count; ++i)
403         {
404             free_pass(technique->pass_handles[i]);
405         }
406         HeapFree(GetProcessHeap(), 0, technique->pass_handles);
407     }
408
409     HeapFree(GetProcessHeap(), 0, technique->name);
410     HeapFree(GetProcessHeap(), 0, technique);
411 }
412
413 static void free_base_effect(struct ID3DXBaseEffectImpl *base)
414 {
415     unsigned int i;
416
417     TRACE("Free base effect %p\n", base);
418
419     if (base->parameter_handles)
420     {
421         for (i = 0; i < base->parameter_count; ++i)
422         {
423             free_parameter(base->parameter_handles[i], FALSE, FALSE);
424         }
425         HeapFree(GetProcessHeap(), 0, base->parameter_handles);
426     }
427
428     if (base->technique_handles)
429     {
430         for (i = 0; i < base->technique_count; ++i)
431         {
432             free_technique(base->technique_handles[i]);
433         }
434         HeapFree(GetProcessHeap(), 0, base->technique_handles);
435     }
436 }
437
438 static void free_effect(struct ID3DXEffectImpl *effect)
439 {
440     TRACE("Free effect %p\n", effect);
441
442     if (effect->base_effect)
443     {
444         effect->base_effect->lpVtbl->Release(effect->base_effect);
445     }
446
447     if (effect->pool)
448     {
449         effect->pool->lpVtbl->Release(effect->pool);
450     }
451
452     IDirect3DDevice9_Release(effect->device);
453 }
454
455 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
456 {
457     TRACE("Free effect compiler %p\n", compiler);
458
459     if (compiler->base_effect)
460     {
461         compiler->base_effect->lpVtbl->Release(compiler->base_effect);
462     }
463 }
464
465 static INT get_int(D3DXPARAMETER_TYPE type, void *data)
466 {
467     INT i;
468
469     switch (type)
470     {
471         case D3DXPT_FLOAT:
472             i = *(FLOAT *)data;
473             break;
474
475         case D3DXPT_INT:
476             i = *(INT *)data;
477             break;
478
479         case D3DXPT_BOOL:
480             i = *(BOOL *)data;
481             break;
482
483         default:
484             i = 0;
485             FIXME("Unhandled type %s. This should not happen!\n", debug_d3dxparameter_type(type));
486             break;
487     }
488
489     return i;
490 }
491
492 static inline BOOL get_bool(void *data)
493 {
494     return (*(DWORD *)data) ? TRUE : FALSE;
495 }
496
497 static struct d3dx_parameter *get_parameter_element_by_name(struct ID3DXBaseEffectImpl *base,
498         struct d3dx_parameter *parameter, LPCSTR name)
499 {
500     UINT element;
501     struct d3dx_parameter *temp_parameter;
502     LPCSTR part;
503
504     TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
505
506     if (!name || !*name) return parameter;
507
508     element = atoi(name);
509     part = strchr(name, ']') + 1;
510
511     if (parameter->element_count > element)
512     {
513         temp_parameter = get_parameter_struct(parameter->member_handles[element]);
514
515         switch (*part++)
516         {
517             case '.':
518                 return get_parameter_by_name(base, temp_parameter, part);
519
520             case '@':
521                 return get_parameter_annotation_by_name(base, temp_parameter, part);
522
523             case '\0':
524                 TRACE("Returning parameter %p\n", temp_parameter);
525                 return temp_parameter;
526
527             default:
528                 FIXME("Unhandled case \"%c\"\n", *--part);
529                 break;
530         }
531     }
532
533     TRACE("Parameter not found\n");
534     return NULL;
535 }
536
537 static struct d3dx_parameter *get_parameter_annotation_by_name(struct ID3DXBaseEffectImpl *base,
538         struct d3dx_parameter *parameter, LPCSTR name)
539 {
540     UINT i, length;
541     struct d3dx_parameter *temp_parameter;
542     LPCSTR part;
543
544     TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
545
546     if (!name || !*name) return parameter;
547
548     length = strcspn( name, "[.@" );
549     part = name + length;
550
551     for (i = 0; i < parameter->annotation_count; ++i)
552     {
553         temp_parameter = get_parameter_struct(parameter->annotation_handles[i]);
554
555         if (!strcmp(temp_parameter->name, name))
556         {
557             TRACE("Returning parameter %p\n", temp_parameter);
558             return temp_parameter;
559         }
560         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
561         {
562             switch (*part++)
563             {
564                 case '.':
565                     return get_parameter_by_name(base, temp_parameter, part);
566
567                 case '[':
568                     return get_parameter_element_by_name(base, temp_parameter, part);
569
570                 default:
571                     FIXME("Unhandled case \"%c\"\n", *--part);
572                     break;
573             }
574         }
575     }
576
577     TRACE("Parameter not found\n");
578     return NULL;
579 }
580
581 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
582         struct d3dx_parameter *parameter, LPCSTR name)
583 {
584     UINT i, count, length;
585     struct d3dx_parameter *temp_parameter;
586     D3DXHANDLE *handles;
587     LPCSTR part;
588
589     TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
590
591     if (!name || !*name) return parameter;
592
593     if (!parameter)
594     {
595         count = base->parameter_count;
596         handles = base->parameter_handles;
597     }
598     else
599     {
600         count = parameter->member_count;
601         handles = parameter->member_handles;
602     }
603
604     length = strcspn( name, "[.@" );
605     part = name + length;
606
607     for (i = 0; i < count; i++)
608     {
609         temp_parameter = get_parameter_struct(handles[i]);
610
611         if (!strcmp(temp_parameter->name, name))
612         {
613             TRACE("Returning parameter %p\n", temp_parameter);
614             return temp_parameter;
615         }
616         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
617         {
618             switch (*part++)
619             {
620                 case '.':
621                     return get_parameter_by_name(base, temp_parameter, part);
622
623                 case '@':
624                     return get_parameter_annotation_by_name(base, temp_parameter, part);
625
626                 case '[':
627                     return get_parameter_element_by_name(base, temp_parameter, part);
628
629                 default:
630                     FIXME("Unhandled case \"%c\"\n", *--part);
631                     break;
632             }
633         }
634     }
635
636     TRACE("Parameter not found\n");
637     return NULL;
638 }
639
640 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
641 {
642     return (0xfeff0000 | ((major) << 8) | (minor));
643 }
644
645 static inline struct ID3DXBaseEffectImpl *impl_from_ID3DXBaseEffect(ID3DXBaseEffect *iface)
646 {
647     return CONTAINING_RECORD(iface, struct ID3DXBaseEffectImpl, ID3DXBaseEffect_iface);
648 }
649
650 /*** IUnknown methods ***/
651 static HRESULT WINAPI ID3DXBaseEffectImpl_QueryInterface(ID3DXBaseEffect *iface, REFIID riid, void **object)
652 {
653     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
654
655     TRACE("iface %p, riid %s, object %p\n", This, debugstr_guid(riid), object);
656
657     if (IsEqualGUID(riid, &IID_IUnknown) ||
658         IsEqualGUID(riid, &IID_ID3DXBaseEffect))
659     {
660         This->ID3DXBaseEffect_iface.lpVtbl->AddRef(iface);
661         *object = This;
662         return S_OK;
663     }
664
665     ERR("Interface %s not found\n", debugstr_guid(riid));
666
667     return E_NOINTERFACE;
668 }
669
670 static ULONG WINAPI ID3DXBaseEffectImpl_AddRef(ID3DXBaseEffect *iface)
671 {
672     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
673
674     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
675
676     return InterlockedIncrement(&This->ref);
677 }
678
679 static ULONG WINAPI ID3DXBaseEffectImpl_Release(ID3DXBaseEffect *iface)
680 {
681     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
682     ULONG ref = InterlockedDecrement(&This->ref);
683
684     TRACE("iface %p: Release from %u\n", iface, ref + 1);
685
686     if (!ref)
687     {
688         free_base_effect(This);
689         HeapFree(GetProcessHeap(), 0, This);
690     }
691
692     return ref;
693 }
694
695 /*** ID3DXBaseEffect methods ***/
696 static HRESULT WINAPI ID3DXBaseEffectImpl_GetDesc(ID3DXBaseEffect *iface, D3DXEFFECT_DESC *desc)
697 {
698     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
699
700     FIXME("iface %p, desc %p partial stub\n", This, desc);
701
702     if (!desc)
703     {
704         WARN("Invalid argument specified.\n");
705         return D3DERR_INVALIDCALL;
706     }
707
708     /* Todo: add creator and function count */
709     desc->Creator = NULL;
710     desc->Functions = 0;
711     desc->Parameters = This->parameter_count;
712     desc->Techniques = This->technique_count;
713
714     return D3D_OK;
715 }
716
717 static HRESULT WINAPI ID3DXBaseEffectImpl_GetParameterDesc(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
718 {
719     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
720     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
721
722     TRACE("iface %p, parameter %p, desc %p\n", This, parameter, desc);
723
724     if (!param) param = get_parameter_struct(iface->lpVtbl->GetParameterByName(iface, NULL, parameter));
725
726     if (!desc || !param)
727     {
728         WARN("Invalid argument specified.\n");
729         return D3DERR_INVALIDCALL;
730     }
731
732     desc->Name = param->name;
733     desc->Semantic = param->semantic;
734     desc->Class = param->class;
735     desc->Type = param->type;
736     desc->Rows = param->rows;
737     desc->Columns = param->columns;
738     desc->Elements = param->element_count;
739     desc->Annotations = param->annotation_count;
740     desc->StructMembers = param->member_count;
741     desc->Flags = param->flags;
742     desc->Bytes = param->bytes;
743
744     return D3D_OK;
745 }
746
747 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTechniqueDesc(ID3DXBaseEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
748 {
749     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
750     struct d3dx_technique *tech = technique ? is_valid_technique(This, technique) : get_technique_struct(This->technique_handles[0]);
751
752     TRACE("iface %p, technique %p, desc %p\n", This, technique, desc);
753
754     if (!desc || !tech)
755     {
756         WARN("Invalid argument specified.\n");
757         return D3DERR_INVALIDCALL;
758     }
759
760     desc->Name = tech->name;
761     desc->Passes = tech->pass_count;
762     desc->Annotations = tech->annotation_count;
763
764     return D3D_OK;
765 }
766
767 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPassDesc(ID3DXBaseEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
768 {
769     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
770     struct d3dx_pass *p = is_valid_pass(This, pass);
771
772     TRACE("iface %p, pass %p, desc %p\n", This, pass, desc);
773
774     if (!desc || !p)
775     {
776         WARN("Invalid argument specified.\n");
777         return D3DERR_INVALIDCALL;
778     }
779
780     desc->Name = p->name;
781     desc->Annotations = p->annotation_count;
782
783     FIXME("Pixel shader and vertex shader are not supported, yet.\n");
784     desc->pVertexShaderFunction = NULL;
785     desc->pVertexShaderFunction = NULL;
786
787     return D3D_OK;
788 }
789
790 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFunctionDesc(ID3DXBaseEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
791 {
792     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
793
794     FIXME("iface %p, shader %p, desc %p stub\n", This, shader, desc);
795
796     return E_NOTIMPL;
797 }
798
799 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
800 {
801     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
802     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
803
804     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
805
806     if (!param) param = get_parameter_by_name(This, NULL, parameter);
807
808     if (!parameter)
809     {
810         if (index < This->parameter_count)
811         {
812             TRACE("Returning parameter %p\n", This->parameter_handles[index]);
813             return This->parameter_handles[index];
814         }
815     }
816     else
817     {
818         if (param && !param->element_count && index < param->member_count)
819         {
820             TRACE("Returning parameter %p\n", param->member_handles[index]);
821             return param->member_handles[index];
822         }
823     }
824
825     WARN("Invalid argument specified.\n");
826
827     return NULL;
828 }
829
830 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR name)
831 {
832     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
833     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
834     D3DXHANDLE handle;
835
836     TRACE("iface %p, parameter %p, name %s\n", This, parameter, debugstr_a(name));
837
838     if (!param) param = get_parameter_by_name(This, NULL, parameter);
839
840     if (!name)
841     {
842         handle = get_parameter_handle(param);
843         TRACE("Returning parameter %p\n", handle);
844         return handle;
845     }
846
847     handle = get_parameter_handle(get_parameter_by_name(This, param, name));
848     TRACE("Returning parameter %p\n", handle);
849
850     return handle;
851 }
852
853 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterBySemantic(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
854 {
855     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
856     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
857     struct d3dx_parameter *temp_param;
858     UINT i;
859
860     TRACE("iface %p, parameter %p, semantic %s\n", This, parameter, debugstr_a(semantic));
861
862     if (!param) param = get_parameter_by_name(This, NULL, parameter);
863
864     if (!parameter)
865     {
866         for (i = 0; i < This->parameter_count; ++i)
867         {
868             temp_param = get_parameter_struct(This->parameter_handles[i]);
869
870             if (!temp_param->semantic)
871             {
872                 if (!semantic)
873                 {
874                     TRACE("Returning parameter %p\n", This->parameter_handles[i]);
875                     return This->parameter_handles[i];
876                 }
877                 continue;
878             }
879
880             if (!strcasecmp(temp_param->semantic, semantic))
881             {
882                 TRACE("Returning parameter %p\n", This->parameter_handles[i]);
883                 return This->parameter_handles[i];
884             }
885         }
886     }
887     else if (param)
888     {
889         for (i = 0; i < param->member_count; ++i)
890         {
891             temp_param = get_parameter_struct(param->member_handles[i]);
892
893             if (!temp_param->semantic)
894             {
895                 if (!semantic)
896                 {
897                     TRACE("Returning parameter %p\n", param->member_handles[i]);
898                     return param->member_handles[i];
899                 }
900                 continue;
901             }
902
903             if (!strcasecmp(temp_param->semantic, semantic))
904             {
905                 TRACE("Returning parameter %p\n", param->member_handles[i]);
906                 return param->member_handles[i];
907             }
908         }
909     }
910
911     WARN("Invalid argument specified\n");
912
913     return NULL;
914 }
915
916 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterElement(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
917 {
918     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
919     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
920
921     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
922
923     if (!param) param = get_parameter_by_name(This, NULL, parameter);
924
925     if (!param)
926     {
927         if (index < This->parameter_count)
928         {
929             TRACE("Returning parameter %p\n", This->parameter_handles[index]);
930             return This->parameter_handles[index];
931         }
932     }
933     else
934     {
935         if (index < param->element_count)
936         {
937             TRACE("Returning parameter %p\n", param->member_handles[index]);
938             return param->member_handles[index];
939         }
940     }
941
942     WARN("Invalid argument specified\n");
943
944     return NULL;
945 }
946
947 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechnique(ID3DXBaseEffect *iface, UINT index)
948 {
949     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
950
951     TRACE("iface %p, index %u\n", This, index);
952
953     if (index >= This->technique_count)
954     {
955         WARN("Invalid argument specified.\n");
956         return NULL;
957     }
958
959     TRACE("Returning technique %p\n", This->technique_handles[index]);
960
961     return This->technique_handles[index];
962 }
963
964 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechniqueByName(ID3DXBaseEffect *iface, LPCSTR name)
965 {
966     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
967     unsigned int i;
968
969     TRACE("iface %p, name %s stub\n", This, debugstr_a(name));
970
971     if (!name)
972     {
973         WARN("Invalid argument specified.\n");
974         return NULL;
975     }
976
977     for (i = 0; i < This->technique_count; ++i)
978     {
979         struct d3dx_technique *tech = get_technique_struct(This->technique_handles[i]);
980
981         if (!strcmp(tech->name, name))
982         {
983             TRACE("Returning technique %p\n", This->technique_handles[i]);
984             return This->technique_handles[i];
985         }
986     }
987
988     WARN("Invalid argument specified.\n");
989
990     return NULL;
991 }
992
993 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPass(ID3DXBaseEffect *iface, D3DXHANDLE technique, UINT index)
994 {
995     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
996     struct d3dx_technique *tech = is_valid_technique(This, technique);
997
998     TRACE("iface %p, technique %p, index %u\n", This, technique, index);
999
1000     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
1001
1002     if (tech && index < tech->pass_count)
1003     {
1004         TRACE("Returning pass %p\n", tech->pass_handles[index]);
1005         return tech->pass_handles[index];
1006     }
1007
1008     WARN("Invalid argument specified.\n");
1009
1010     return NULL;
1011 }
1012
1013 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPassByName(ID3DXBaseEffect *iface, D3DXHANDLE technique, LPCSTR name)
1014 {
1015     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1016     struct d3dx_technique *tech = is_valid_technique(This, technique);
1017
1018     TRACE("iface %p, technique %p, name %s\n", This, technique, debugstr_a(name));
1019
1020     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
1021
1022     if (tech && name)
1023     {
1024         unsigned int i;
1025
1026         for (i = 0; i < tech->pass_count; ++i)
1027         {
1028             struct d3dx_pass *pass = get_pass_struct(tech->pass_handles[i]);
1029
1030             if (!strcmp(pass->name, name))
1031             {
1032                 TRACE("Returning pass %p\n", tech->pass_handles[i]);
1033                 return tech->pass_handles[i];
1034             }
1035         }
1036     }
1037
1038     WARN("Invalid argument specified.\n");
1039
1040     return NULL;
1041 }
1042
1043 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunction(ID3DXBaseEffect *iface, UINT index)
1044 {
1045     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1046
1047     FIXME("iface %p, index %u stub\n", This, index);
1048
1049     return NULL;
1050 }
1051
1052 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunctionByName(ID3DXBaseEffect *iface, LPCSTR name)
1053 {
1054     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1055
1056     FIXME("iface %p, name %s stub\n", This, debugstr_a(name));
1057
1058     return NULL;
1059 }
1060
1061 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotation(ID3DXBaseEffect *iface, D3DXHANDLE object, UINT index)
1062 {
1063     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1064     struct d3dx_parameter *param = is_valid_parameter(This, object);
1065     struct d3dx_pass *pass = is_valid_pass(This, object);
1066     struct d3dx_technique *technique = is_valid_technique(This, object);
1067     UINT annotation_count = 0;
1068     D3DXHANDLE *annotation_handles = NULL;
1069
1070     FIXME("iface %p, object %p, index %u partial stub\n", This, object, index);
1071
1072     if (pass)
1073     {
1074         annotation_count = pass->annotation_count;
1075         annotation_handles = pass->annotation_handles;
1076     }
1077     else if (technique)
1078     {
1079         annotation_count = technique->annotation_count;
1080         annotation_handles = technique->annotation_handles;
1081     }
1082     else
1083     {
1084         if (!param) param = get_parameter_by_name(This, NULL, object);
1085
1086         if (param)
1087         {
1088             annotation_count = param->annotation_count;
1089             annotation_handles = param->annotation_handles;
1090         }
1091     }
1092     /* Todo: add funcs */
1093
1094     if (index < annotation_count)
1095     {
1096         TRACE("Returning parameter %p\n", annotation_handles[index]);
1097         return annotation_handles[index];
1098     }
1099
1100     WARN("Invalid argument specified\n");
1101
1102     return NULL;
1103 }
1104
1105 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotationByName(ID3DXBaseEffect *iface, D3DXHANDLE object, LPCSTR name)
1106 {
1107     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1108     struct d3dx_parameter *param = is_valid_parameter(This, object);
1109     struct d3dx_pass *pass = is_valid_pass(This, object);
1110     struct d3dx_technique *technique = is_valid_technique(This, object);
1111     UINT annotation_count = 0, i;
1112     D3DXHANDLE *annotation_handles = NULL;
1113
1114     FIXME("iface %p, object %p, name %s partial stub\n", This, object, debugstr_a(name));
1115
1116     if (!name)
1117     {
1118         WARN("Invalid argument specified\n");
1119         return NULL;
1120     }
1121
1122     if (pass)
1123     {
1124         annotation_count = pass->annotation_count;
1125         annotation_handles = pass->annotation_handles;
1126     }
1127     else if (technique)
1128     {
1129         annotation_count = technique->annotation_count;
1130         annotation_handles = technique->annotation_handles;
1131     }
1132     else
1133     {
1134         if (!param) param = get_parameter_by_name(This, NULL, object);
1135
1136         if (param)
1137         {
1138             annotation_count = param->annotation_count;
1139             annotation_handles = param->annotation_handles;
1140         }
1141     }
1142     /* Todo: add funcs */
1143
1144     for (i = 0; i < annotation_count; i++)
1145     {
1146         struct d3dx_parameter *anno = get_parameter_struct(annotation_handles[i]);
1147
1148         if (!strcmp(anno->name, name))
1149         {
1150             TRACE("Returning parameter %p\n", anno);
1151             return get_parameter_handle(anno);
1152         }
1153     }
1154
1155     WARN("Invalid argument specified\n");
1156
1157     return NULL;
1158 }
1159
1160 static HRESULT WINAPI ID3DXBaseEffectImpl_SetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
1161 {
1162     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1163
1164     FIXME("iface %p, parameter %p, data %p, bytes %u stub\n", This, parameter, data, bytes);
1165
1166     return E_NOTIMPL;
1167 }
1168
1169 static HRESULT WINAPI ID3DXBaseEffectImpl_GetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
1170 {
1171     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1172     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
1173
1174     TRACE("iface %p, parameter %p, data %p, bytes %u\n", This, parameter, data, bytes);
1175
1176     if (!param) param = get_parameter_by_name(This, NULL, parameter);
1177
1178     if (data && param && param->data && param->bytes <= bytes)
1179     {
1180         if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
1181         {
1182             UINT i;
1183
1184             for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1185             {
1186                 IUnknown *unk = ((IUnknown **)param->data)[i];
1187                 if (unk) IUnknown_AddRef(unk);
1188                 ((IUnknown **)data)[i] = unk;
1189             }
1190         }
1191         else
1192         {
1193             TRACE("Copy %u bytes\n", param->bytes);
1194             memcpy(data, param->data, param->bytes);
1195         }
1196         return D3D_OK;
1197     }
1198
1199     WARN("Invalid argument specified\n");
1200
1201     return D3DERR_INVALIDCALL;
1202 }
1203
1204 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL b)
1205 {
1206     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1207
1208     FIXME("iface %p, parameter %p, b %u stub\n", This, parameter, b);
1209
1210     return E_NOTIMPL;
1211 }
1212
1213 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b)
1214 {
1215     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1216     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
1217
1218     TRACE("iface %p, parameter %p, b %p\n", This, parameter, b);
1219
1220     if (!param) param = get_parameter_by_name(This, NULL, parameter);
1221
1222     if (b && param && !param->element_count && param->class == D3DXPC_SCALAR)
1223     {
1224         *b = get_bool(param->data);
1225         TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1226         return D3D_OK;
1227     }
1228
1229     WARN("Invalid argument specified\n");
1230
1231     return D3DERR_INVALIDCALL;
1232 }
1233
1234 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
1235 {
1236     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1237
1238     FIXME("iface %p, parameter %p, b %p, count %u stub\n", This, parameter, b, count);
1239
1240     return E_NOTIMPL;
1241 }
1242
1243 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
1244 {
1245     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1246
1247     FIXME("iface %p, parameter %p, b %p, count %u stub\n", This, parameter, b, count);
1248
1249     return E_NOTIMPL;
1250 }
1251
1252 static HRESULT WINAPI ID3DXBaseEffectImpl_SetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT n)
1253 {
1254     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1255
1256     FIXME("iface %p, parameter %p, n %u stub\n", This, parameter, n);
1257
1258     return E_NOTIMPL;
1259 }
1260
1261 static HRESULT WINAPI ID3DXBaseEffectImpl_GetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n)
1262 {
1263     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1264     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
1265
1266     TRACE("iface %p, parameter %p, n %p\n", This, parameter, n);
1267
1268     if (!param) param = get_parameter_by_name(This, NULL, parameter);
1269
1270     if (n && param && !param->element_count && param->class == D3DXPC_SCALAR)
1271     {
1272         *n = get_int(param->type, param->data);
1273         TRACE("Returning %i\n", *n);
1274         return D3D_OK;
1275     }
1276
1277     WARN("Invalid argument specified\n");
1278
1279     return D3DERR_INVALIDCALL;
1280 }
1281
1282 static HRESULT WINAPI ID3DXBaseEffectImpl_SetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
1283 {
1284     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1285
1286     FIXME("iface %p, parameter %p, n %p, count %u stub\n", This, parameter, n, count);
1287
1288     return E_NOTIMPL;
1289 }
1290
1291 static HRESULT WINAPI ID3DXBaseEffectImpl_GetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
1292 {
1293     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1294
1295     FIXME("iface %p, parameter %p, n %p, count %u stub\n", This, parameter, n, count);
1296
1297     return E_NOTIMPL;
1298 }
1299
1300 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT f)
1301 {
1302     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1303
1304     FIXME("iface %p, parameter %p, f %f stub\n", This, parameter, f);
1305
1306     return E_NOTIMPL;
1307 }
1308
1309 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f)
1310 {
1311     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1312
1313     FIXME("iface %p, parameter %p, f %p stub\n", This, parameter, f);
1314
1315     return E_NOTIMPL;
1316 }
1317
1318 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
1319 {
1320     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1321
1322     FIXME("iface %p, parameter %p, f %p, count %u stub\n", This, parameter, f, count);
1323
1324     return E_NOTIMPL;
1325 }
1326
1327 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
1328 {
1329     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1330
1331     FIXME("iface %p, parameter %p, f %p, count %u stub\n", This, parameter, f, count);
1332
1333     return E_NOTIMPL;
1334 }
1335
1336 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVector(ID3DXBaseEffect* iface, D3DXHANDLE parameter, CONST D3DXVECTOR4* vector)
1337 {
1338     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1339
1340     FIXME("iface %p, parameter %p, vector %p stub\n", This, parameter, vector);
1341
1342     return E_NOTIMPL;
1343 }
1344
1345 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVector(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
1346 {
1347     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1348
1349     FIXME("iface %p, parameter %p, vector %p stub\n", This, parameter, vector);
1350
1351     return E_NOTIMPL;
1352 }
1353
1354 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
1355 {
1356     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1357
1358     FIXME("iface %p, parameter %p, vector %p, count %u stub\n", This, parameter, vector, count);
1359
1360     return E_NOTIMPL;
1361 }
1362
1363 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
1364 {
1365     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1366
1367     FIXME("iface %p, parameter %p, vector %p, count %u stub\n", This, parameter, vector, count);
1368
1369     return E_NOTIMPL;
1370 }
1371
1372 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
1373 {
1374     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1375
1376     FIXME("iface %p, parameter %p, matrix %p stub\n", This, parameter, matrix);
1377
1378     return E_NOTIMPL;
1379 }
1380
1381 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
1382 {
1383     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1384
1385     FIXME("iface %p, parameter %p, matrix %p stub\n", This, parameter, matrix);
1386
1387     return E_NOTIMPL;
1388 }
1389
1390 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
1391 {
1392     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1393
1394     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1395
1396     return E_NOTIMPL;
1397 }
1398
1399 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
1400 {
1401     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1402
1403     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1404
1405     return E_NOTIMPL;
1406 }
1407
1408 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
1409 {
1410     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1411
1412     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1413
1414     return E_NOTIMPL;
1415 }
1416
1417 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
1418 {
1419     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1420
1421     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1422
1423     return E_NOTIMPL;
1424 }
1425
1426 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
1427 {
1428     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1429
1430     FIXME("iface %p, parameter %p, matrix %p stub\n", This, parameter, matrix);
1431
1432     return E_NOTIMPL;
1433 }
1434
1435 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
1436 {
1437     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1438
1439     FIXME("iface %p, parameter %p, matrix %p stub\n", This, parameter, matrix);
1440
1441     return E_NOTIMPL;
1442 }
1443
1444 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
1445 {
1446     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1447
1448     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1449
1450     return E_NOTIMPL;
1451 }
1452
1453 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
1454 {
1455     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1456
1457     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1458
1459     return E_NOTIMPL;
1460 }
1461
1462 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
1463 {
1464     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1465
1466     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1467
1468     return E_NOTIMPL;
1469 }
1470
1471 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
1472 {
1473     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1474
1475     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
1476
1477     return E_NOTIMPL;
1478 }
1479
1480 static HRESULT WINAPI ID3DXBaseEffectImpl_SetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR string)
1481 {
1482     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1483
1484     FIXME("iface %p, parameter %p, string %p stub\n", This, parameter, string);
1485
1486     return E_NOTIMPL;
1487 }
1488
1489 static HRESULT WINAPI ID3DXBaseEffectImpl_GetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
1490 {
1491     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1492     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
1493
1494     TRACE("iface %p, parameter %p, string %p\n", This, parameter, string);
1495
1496     if (!param) param = get_parameter_by_name(This, NULL, parameter);
1497
1498     if (string && param && !param->element_count && param->type == D3DXPT_STRING)
1499     {
1500         *string = *(LPCSTR *)param->data;
1501         TRACE("Returning %s\n", debugstr_a(*string));
1502         return D3D_OK;
1503     }
1504
1505     WARN("Invalid argument specified\n");
1506
1507     return D3DERR_INVALIDCALL;
1508 }
1509
1510 static HRESULT WINAPI ID3DXBaseEffectImpl_SetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
1511 {
1512     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1513
1514     FIXME("iface %p, parameter %p, texture %p stub\n", This, parameter, texture);
1515
1516     return E_NOTIMPL;
1517 }
1518
1519 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
1520 {
1521     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1522
1523     FIXME("iface %p, parameter %p, texture %p stub\n", This, parameter, texture);
1524
1525     return E_NOTIMPL;
1526 }
1527
1528 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPixelShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
1529 {
1530     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1531     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
1532
1533     TRACE("iface %p, parameter %p, pshader %p\n", This, parameter, pshader);
1534
1535     if (!param) param = get_parameter_by_name(This, NULL, parameter);
1536
1537     if (pshader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
1538     {
1539         *pshader = *(LPDIRECT3DPIXELSHADER9 *)param->data;
1540         if (*pshader) IDirect3DPixelShader9_AddRef(*pshader);
1541         TRACE("Returning %p\n", *pshader);
1542         return D3D_OK;
1543     }
1544
1545     WARN("Invalid argument specified\n");
1546
1547     return D3DERR_INVALIDCALL;
1548 }
1549
1550 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVertexShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
1551 {
1552     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1553     struct d3dx_parameter *param = is_valid_parameter(This, parameter);
1554
1555     TRACE("iface %p, parameter %p, vshader %p\n", This, parameter, vshader);
1556
1557     if (!param) param = get_parameter_by_name(This, NULL, parameter);
1558
1559     if (vshader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
1560     {
1561         *vshader = *(LPDIRECT3DVERTEXSHADER9 *)param->data;
1562         if (*vshader) IDirect3DVertexShader9_AddRef(*vshader);
1563         TRACE("Returning %p\n", *vshader);
1564         return D3D_OK;
1565     }
1566
1567     WARN("Invalid argument specified\n");
1568
1569     return D3DERR_INVALIDCALL;
1570 }
1571
1572 static HRESULT WINAPI ID3DXBaseEffectImpl_SetArrayRange(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
1573 {
1574     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1575
1576     FIXME("iface %p, parameter %p, start %u, end %u stub\n", This, parameter, start, end);
1577
1578     return E_NOTIMPL;
1579 }
1580
1581 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl =
1582 {
1583     /*** IUnknown methods ***/
1584     ID3DXBaseEffectImpl_QueryInterface,
1585     ID3DXBaseEffectImpl_AddRef,
1586     ID3DXBaseEffectImpl_Release,
1587     /*** ID3DXBaseEffect methods ***/
1588     ID3DXBaseEffectImpl_GetDesc,
1589     ID3DXBaseEffectImpl_GetParameterDesc,
1590     ID3DXBaseEffectImpl_GetTechniqueDesc,
1591     ID3DXBaseEffectImpl_GetPassDesc,
1592     ID3DXBaseEffectImpl_GetFunctionDesc,
1593     ID3DXBaseEffectImpl_GetParameter,
1594     ID3DXBaseEffectImpl_GetParameterByName,
1595     ID3DXBaseEffectImpl_GetParameterBySemantic,
1596     ID3DXBaseEffectImpl_GetParameterElement,
1597     ID3DXBaseEffectImpl_GetTechnique,
1598     ID3DXBaseEffectImpl_GetTechniqueByName,
1599     ID3DXBaseEffectImpl_GetPass,
1600     ID3DXBaseEffectImpl_GetPassByName,
1601     ID3DXBaseEffectImpl_GetFunction,
1602     ID3DXBaseEffectImpl_GetFunctionByName,
1603     ID3DXBaseEffectImpl_GetAnnotation,
1604     ID3DXBaseEffectImpl_GetAnnotationByName,
1605     ID3DXBaseEffectImpl_SetValue,
1606     ID3DXBaseEffectImpl_GetValue,
1607     ID3DXBaseEffectImpl_SetBool,
1608     ID3DXBaseEffectImpl_GetBool,
1609     ID3DXBaseEffectImpl_SetBoolArray,
1610     ID3DXBaseEffectImpl_GetBoolArray,
1611     ID3DXBaseEffectImpl_SetInt,
1612     ID3DXBaseEffectImpl_GetInt,
1613     ID3DXBaseEffectImpl_SetIntArray,
1614     ID3DXBaseEffectImpl_GetIntArray,
1615     ID3DXBaseEffectImpl_SetFloat,
1616     ID3DXBaseEffectImpl_GetFloat,
1617     ID3DXBaseEffectImpl_SetFloatArray,
1618     ID3DXBaseEffectImpl_GetFloatArray,
1619     ID3DXBaseEffectImpl_SetVector,
1620     ID3DXBaseEffectImpl_GetVector,
1621     ID3DXBaseEffectImpl_SetVectorArray,
1622     ID3DXBaseEffectImpl_GetVectorArray,
1623     ID3DXBaseEffectImpl_SetMatrix,
1624     ID3DXBaseEffectImpl_GetMatrix,
1625     ID3DXBaseEffectImpl_SetMatrixArray,
1626     ID3DXBaseEffectImpl_GetMatrixArray,
1627     ID3DXBaseEffectImpl_SetMatrixPointerArray,
1628     ID3DXBaseEffectImpl_GetMatrixPointerArray,
1629     ID3DXBaseEffectImpl_SetMatrixTranspose,
1630     ID3DXBaseEffectImpl_GetMatrixTranspose,
1631     ID3DXBaseEffectImpl_SetMatrixTransposeArray,
1632     ID3DXBaseEffectImpl_GetMatrixTransposeArray,
1633     ID3DXBaseEffectImpl_SetMatrixTransposePointerArray,
1634     ID3DXBaseEffectImpl_GetMatrixTransposePointerArray,
1635     ID3DXBaseEffectImpl_SetString,
1636     ID3DXBaseEffectImpl_GetString,
1637     ID3DXBaseEffectImpl_SetTexture,
1638     ID3DXBaseEffectImpl_GetTexture,
1639     ID3DXBaseEffectImpl_GetPixelShader,
1640     ID3DXBaseEffectImpl_GetVertexShader,
1641     ID3DXBaseEffectImpl_SetArrayRange,
1642 };
1643
1644 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
1645 {
1646     return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
1647 }
1648
1649 /*** IUnknown methods ***/
1650 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
1651 {
1652     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1653
1654     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
1655
1656     if (IsEqualGUID(riid, &IID_IUnknown) ||
1657         IsEqualGUID(riid, &IID_ID3DXEffect))
1658     {
1659         This->ID3DXEffect_iface.lpVtbl->AddRef(iface);
1660         *object = This;
1661         return S_OK;
1662     }
1663
1664     ERR("Interface %s not found\n", debugstr_guid(riid));
1665
1666     return E_NOINTERFACE;
1667 }
1668
1669 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
1670 {
1671     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1672
1673     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
1674
1675     return InterlockedIncrement(&This->ref);
1676 }
1677
1678 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
1679 {
1680     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1681     ULONG ref = InterlockedDecrement(&This->ref);
1682
1683     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
1684
1685     if (!ref)
1686     {
1687         free_effect(This);
1688         HeapFree(GetProcessHeap(), 0, This);
1689     }
1690
1691     return ref;
1692 }
1693
1694 /*** ID3DXBaseEffect methods ***/
1695 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
1696 {
1697     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1698     ID3DXBaseEffect *base = This->base_effect;
1699
1700     TRACE("Forward iface %p, base %p\n", This, base);
1701
1702     return ID3DXBaseEffectImpl_GetDesc(base, desc);
1703 }
1704
1705 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
1706 {
1707     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1708     ID3DXBaseEffect *base = This->base_effect;
1709
1710     TRACE("Forward iface %p, base %p\n", This, base);
1711
1712     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
1713 }
1714
1715 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1716 {
1717     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1718     ID3DXBaseEffect *base = This->base_effect;
1719
1720     TRACE("Forward iface %p, base %p\n", This, base);
1721
1722     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
1723 }
1724
1725 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
1726 {
1727     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1728     ID3DXBaseEffect *base = This->base_effect;
1729
1730     TRACE("Forward iface %p, base %p\n", This, base);
1731
1732     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
1733 }
1734
1735 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
1736 {
1737     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1738     ID3DXBaseEffect *base = This->base_effect;
1739
1740     TRACE("Forward iface %p, base %p\n", This, base);
1741
1742     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
1743 }
1744
1745 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
1746 {
1747     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1748     ID3DXBaseEffect *base = This->base_effect;
1749
1750     TRACE("Forward iface %p, base %p\n", This, base);
1751
1752     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
1753 }
1754
1755 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR name)
1756 {
1757     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1758     ID3DXBaseEffect *base = This->base_effect;
1759
1760     TRACE("Forward iface %p, base %p\n", This, base);
1761
1762     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
1763 }
1764
1765 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
1766 {
1767     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1768     ID3DXBaseEffect *base = This->base_effect;
1769
1770     TRACE("Forward iface %p, base %p\n", This, base);
1771
1772     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
1773 }
1774
1775 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
1776 {
1777     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1778     ID3DXBaseEffect *base = This->base_effect;
1779
1780     TRACE("Forward iface %p, base %p\n", This, base);
1781
1782     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
1783 }
1784
1785 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
1786 {
1787     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1788     ID3DXBaseEffect *base = This->base_effect;
1789
1790     TRACE("Forward iface %p, base %p\n", This, base);
1791
1792     return ID3DXBaseEffectImpl_GetTechnique(base, index);
1793 }
1794
1795 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, LPCSTR name)
1796 {
1797     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1798     ID3DXBaseEffect *base = This->base_effect;
1799
1800     TRACE("Forward iface %p, base %p\n", This, base);
1801
1802     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
1803 }
1804
1805 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
1806 {
1807     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1808     ID3DXBaseEffect *base = This->base_effect;
1809
1810     TRACE("Forward iface %p, base %p\n", This, base);
1811
1812     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
1813 }
1814
1815 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, LPCSTR name)
1816 {
1817     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1818     ID3DXBaseEffect *base = This->base_effect;
1819
1820     TRACE("Forward iface %p, base %p\n", This, base);
1821
1822     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
1823 }
1824
1825 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
1826 {
1827     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1828     ID3DXBaseEffect *base = This->base_effect;
1829
1830     TRACE("Forward iface %p, base %p\n", This, base);
1831
1832     return ID3DXBaseEffectImpl_GetFunction(base, index);
1833 }
1834
1835 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, LPCSTR name)
1836 {
1837     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1838     ID3DXBaseEffect *base = This->base_effect;
1839
1840     TRACE("Forward iface %p, base %p\n", This, base);
1841
1842     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
1843 }
1844
1845 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
1846 {
1847     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1848     ID3DXBaseEffect *base = This->base_effect;
1849
1850     TRACE("Forward iface %p, base %p\n", This, base);
1851
1852     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
1853 }
1854
1855 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object, LPCSTR name)
1856 {
1857     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1858     ID3DXBaseEffect *base = This->base_effect;
1859
1860     TRACE("Forward iface %p, base %p\n", This, base);
1861
1862     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
1863 }
1864
1865 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
1866 {
1867     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1868     ID3DXBaseEffect *base = This->base_effect;
1869
1870     TRACE("Forward iface %p, base %p\n", This, base);
1871
1872     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
1873 }
1874
1875 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
1876 {
1877     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1878     ID3DXBaseEffect *base = This->base_effect;
1879
1880     TRACE("Forward iface %p, base %p\n", This, base);
1881
1882     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
1883 }
1884
1885 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
1886 {
1887     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1888     ID3DXBaseEffect *base = This->base_effect;
1889
1890     TRACE("Forward iface %p, base %p\n", This, base);
1891
1892     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
1893 }
1894
1895 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
1896 {
1897     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1898     ID3DXBaseEffect *base = This->base_effect;
1899
1900     TRACE("Forward iface %p, base %p\n", This, base);
1901
1902     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
1903 }
1904
1905 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
1906 {
1907     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1908     ID3DXBaseEffect *base = This->base_effect;
1909
1910     TRACE("Forward iface %p, base %p\n", This, base);
1911
1912     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
1913 }
1914
1915 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
1916 {
1917     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1918     ID3DXBaseEffect *base = This->base_effect;
1919
1920     TRACE("Forward iface %p, base %p\n", This, base);
1921
1922     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
1923 }
1924
1925 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
1926 {
1927     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1928     ID3DXBaseEffect *base = This->base_effect;
1929
1930     TRACE("Forward iface %p, base %p\n", This, base);
1931
1932     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
1933 }
1934
1935 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
1936 {
1937     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1938     ID3DXBaseEffect *base = This->base_effect;
1939
1940     TRACE("Forward iface %p, base %p\n", This, base);
1941
1942     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
1943 }
1944
1945 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
1946 {
1947     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1948     ID3DXBaseEffect *base = This->base_effect;
1949
1950     TRACE("Forward iface %p, base %p\n", This, base);
1951
1952     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
1953 }
1954
1955 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
1956 {
1957     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1958     ID3DXBaseEffect *base = This->base_effect;
1959
1960     TRACE("Forward iface %p, base %p\n", This, base);
1961
1962     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
1963 }
1964
1965 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT f)
1966 {
1967     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1968     ID3DXBaseEffect *base = This->base_effect;
1969
1970     TRACE("Forward iface %p, base %p\n", This, base);
1971
1972     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
1973 }
1974
1975 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f)
1976 {
1977     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1978     ID3DXBaseEffect *base = This->base_effect;
1979
1980     TRACE("Forward iface %p, base %p\n", This, base);
1981
1982     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
1983 }
1984
1985 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
1986 {
1987     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1988     ID3DXBaseEffect *base = This->base_effect;
1989
1990     TRACE("Forward iface %p, base %p\n", This, base);
1991
1992     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
1993 }
1994
1995 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
1996 {
1997     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
1998     ID3DXBaseEffect *base = This->base_effect;
1999
2000     TRACE("Forward iface %p, base %p\n", This, base);
2001
2002     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
2003 }
2004
2005 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
2006 {
2007     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2008     ID3DXBaseEffect *base = This->base_effect;
2009
2010     TRACE("Forward iface %p, base %p\n", This, base);
2011
2012     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
2013 }
2014
2015 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2016 {
2017     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2018     ID3DXBaseEffect *base = This->base_effect;
2019
2020     TRACE("Forward iface %p, base %p\n", This, base);
2021
2022     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
2023 }
2024
2025 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
2026 {
2027     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2028     ID3DXBaseEffect *base = This->base_effect;
2029
2030     TRACE("Forward iface %p, base %p\n", This, base);
2031
2032     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
2033 }
2034
2035 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2036 {
2037     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2038     ID3DXBaseEffect *base = This->base_effect;
2039
2040     TRACE("Forward iface %p, base %p\n", This, base);
2041
2042     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
2043 }
2044
2045 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2046 {
2047     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2048     ID3DXBaseEffect *base = This->base_effect;
2049
2050     TRACE("Forward iface %p, base %p\n", This, base);
2051
2052     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
2053 }
2054
2055 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2056 {
2057     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2058     ID3DXBaseEffect *base = This->base_effect;
2059
2060     TRACE("Forward iface %p, base %p\n", This, base);
2061
2062     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
2063 }
2064
2065 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2066 {
2067     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2068     ID3DXBaseEffect *base = This->base_effect;
2069
2070     TRACE("Forward iface %p, base %p\n", This, base);
2071
2072     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
2073 }
2074
2075 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2076 {
2077     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2078     ID3DXBaseEffect *base = This->base_effect;
2079
2080     TRACE("Forward iface %p, base %p\n", This, base);
2081
2082     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
2083 }
2084
2085 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2086 {
2087     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2088     ID3DXBaseEffect *base = This->base_effect;
2089
2090     TRACE("Forward iface %p, base %p\n", This, base);
2091
2092     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
2093 }
2094
2095 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2096 {
2097     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2098     ID3DXBaseEffect *base = This->base_effect;
2099
2100     TRACE("Forward iface %p, base %p\n", This, base);
2101
2102     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
2103 }
2104
2105 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2106 {
2107     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2108     ID3DXBaseEffect *base = This->base_effect;
2109
2110     TRACE("Forward iface %p, base %p\n", This, base);
2111
2112     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
2113 }
2114
2115 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2116 {
2117     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2118     ID3DXBaseEffect *base = This->base_effect;
2119
2120     TRACE("Forward iface %p, base %p\n", This, base);
2121
2122     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
2123 }
2124
2125 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2126 {
2127     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2128     ID3DXBaseEffect *base = This->base_effect;
2129
2130     TRACE("Forward iface %p, base %p\n", This, base);
2131
2132     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
2133 }
2134
2135 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2136 {
2137     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2138     ID3DXBaseEffect *base = This->base_effect;
2139
2140     TRACE("Forward iface %p, base %p\n", This, base);
2141
2142     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
2143 }
2144
2145 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2146 {
2147     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2148     ID3DXBaseEffect *base = This->base_effect;
2149
2150     TRACE("Forward iface %p, base %p\n", This, base);
2151
2152     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
2153 }
2154
2155 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2156 {
2157     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2158     ID3DXBaseEffect *base = This->base_effect;
2159
2160     TRACE("Forward iface %p, base %p\n", This, base);
2161
2162     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
2163 }
2164
2165 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR string)
2166 {
2167     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2168     ID3DXBaseEffect *base = This->base_effect;
2169
2170     TRACE("Forward iface %p, base %p\n", This, base);
2171
2172     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
2173 }
2174
2175 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
2176 {
2177     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2178     ID3DXBaseEffect *base = This->base_effect;
2179
2180     TRACE("Forward iface %p, base %p\n", This, base);
2181
2182     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
2183 }
2184
2185 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
2186 {
2187     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2188     ID3DXBaseEffect *base = This->base_effect;
2189
2190     TRACE("Forward iface %p, base %p\n", This, base);
2191
2192     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
2193 }
2194
2195 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
2196 {
2197     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2198     ID3DXBaseEffect *base = This->base_effect;
2199
2200     TRACE("Forward iface %p, base %p\n", This, base);
2201
2202     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
2203 }
2204
2205 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
2206 {
2207     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2208     ID3DXBaseEffect *base = This->base_effect;
2209
2210     TRACE("Forward iface %p, base %p\n", This, base);
2211
2212     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
2213 }
2214
2215 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
2216 {
2217     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2218     ID3DXBaseEffect *base = This->base_effect;
2219
2220     TRACE("Forward iface %p, base %p\n", This, base);
2221
2222     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
2223 }
2224
2225 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
2226 {
2227     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2228     ID3DXBaseEffect *base = This->base_effect;
2229
2230     TRACE("Forward iface %p, base %p\n", This, base);
2231
2232     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
2233 }
2234
2235 /*** ID3DXEffect methods ***/
2236 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, LPD3DXEFFECTPOOL *pool)
2237 {
2238     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2239
2240     TRACE("iface %p, pool %p\n", This, pool);
2241
2242     if (!pool)
2243     {
2244         WARN("Invalid argument supplied.\n");
2245         return D3DERR_INVALIDCALL;
2246     }
2247
2248     if (This->pool)
2249     {
2250         This->pool->lpVtbl->AddRef(This->pool);
2251     }
2252
2253     *pool = This->pool;
2254
2255     TRACE("Returning pool %p\n", *pool);
2256
2257     return S_OK;
2258 }
2259
2260 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
2261 {
2262     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2263
2264     FIXME("(%p)->(%p): stub\n", This, technique);
2265
2266     return E_NOTIMPL;
2267 }
2268
2269 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect* iface)
2270 {
2271     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2272
2273     FIXME("(%p)->(): stub\n", This);
2274
2275     return NULL;
2276 }
2277
2278 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
2279 {
2280     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2281
2282     FIXME("(%p)->(%p): stub\n", This, technique);
2283
2284     return D3D_OK;
2285 }
2286
2287 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
2288 {
2289     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2290
2291     FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
2292
2293     return E_NOTIMPL;
2294 }
2295
2296 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
2297 {
2298     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2299
2300     FIXME("(%p)->(%p, %p): stub\n", This, parameter, technique);
2301
2302     return FALSE;
2303 }
2304
2305 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect* iface, UINT *passes, DWORD flags)
2306 {
2307     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2308
2309     FIXME("(%p)->(%p, %#x): stub\n", This, passes, flags);
2310
2311     return E_NOTIMPL;
2312 }
2313
2314 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect* iface, UINT pass)
2315 {
2316     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2317
2318     FIXME("(%p)->(%u): stub\n", This, pass);
2319
2320     return E_NOTIMPL;
2321 }
2322
2323 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect* iface)
2324 {
2325     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2326
2327     FIXME("(%p)->(): stub\n", This);
2328
2329     return E_NOTIMPL;
2330 }
2331
2332 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect* iface)
2333 {
2334     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2335
2336     FIXME("(%p)->(): stub\n", This);
2337
2338     return E_NOTIMPL;
2339 }
2340
2341 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect* iface)
2342 {
2343     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2344
2345     FIXME("(%p)->(): stub\n", This);
2346
2347     return E_NOTIMPL;
2348 }
2349
2350 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, LPDIRECT3DDEVICE9 *device)
2351 {
2352     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2353
2354     TRACE("iface %p, device %p\n", This, device);
2355
2356     if (!device)
2357     {
2358         WARN("Invalid argument supplied.\n");
2359         return D3DERR_INVALIDCALL;
2360     }
2361
2362     IDirect3DDevice9_AddRef(This->device);
2363
2364     *device = This->device;
2365
2366     TRACE("Returning device %p\n", *device);
2367
2368     return S_OK;
2369 }
2370
2371 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
2372 {
2373     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2374
2375     FIXME("(%p)->(): stub\n", This);
2376
2377     return E_NOTIMPL;
2378 }
2379
2380 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
2381 {
2382     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2383
2384     FIXME("(%p)->(): stub\n", This);
2385
2386     return E_NOTIMPL;
2387 }
2388
2389 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect* iface, LPD3DXEFFECTSTATEMANAGER manager)
2390 {
2391     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2392
2393     FIXME("(%p)->(%p): stub\n", This, manager);
2394
2395     return E_NOTIMPL;
2396 }
2397
2398 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect* iface, LPD3DXEFFECTSTATEMANAGER* manager)
2399 {
2400     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2401
2402     FIXME("(%p)->(%p): stub\n", This, manager);
2403
2404     return E_NOTIMPL;
2405 }
2406
2407 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
2408 {
2409     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2410
2411     FIXME("(%p)->(): stub\n", This);
2412
2413     return E_NOTIMPL;
2414 }
2415
2416 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
2417 {
2418     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2419
2420     FIXME("(%p)->(): stub\n", This);
2421
2422     return NULL;
2423 }
2424
2425 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
2426 {
2427     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2428
2429     FIXME("(%p)->(%p): stub\n", This, parameter_block);
2430
2431     return E_NOTIMPL;
2432 }
2433
2434 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
2435 {
2436     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2437
2438     FIXME("(%p)->(%p): stub\n", This, parameter_block);
2439
2440     return E_NOTIMPL;
2441 }
2442
2443 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect* iface, LPDIRECT3DDEVICE9 device, LPD3DXEFFECT* effect)
2444 {
2445     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2446
2447     FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
2448
2449     return E_NOTIMPL;
2450 }
2451
2452 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect* iface, D3DXHANDLE parameter, LPCVOID data, UINT byte_offset, UINT bytes)
2453 {
2454     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2455
2456     FIXME("(%p)->(%p, %p, %u, %u): stub\n", This, parameter, data, byte_offset, bytes);
2457
2458     return E_NOTIMPL;
2459 }
2460
2461 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
2462 {
2463     /*** IUnknown methods ***/
2464     ID3DXEffectImpl_QueryInterface,
2465     ID3DXEffectImpl_AddRef,
2466     ID3DXEffectImpl_Release,
2467     /*** ID3DXBaseEffect methods ***/
2468     ID3DXEffectImpl_GetDesc,
2469     ID3DXEffectImpl_GetParameterDesc,
2470     ID3DXEffectImpl_GetTechniqueDesc,
2471     ID3DXEffectImpl_GetPassDesc,
2472     ID3DXEffectImpl_GetFunctionDesc,
2473     ID3DXEffectImpl_GetParameter,
2474     ID3DXEffectImpl_GetParameterByName,
2475     ID3DXEffectImpl_GetParameterBySemantic,
2476     ID3DXEffectImpl_GetParameterElement,
2477     ID3DXEffectImpl_GetTechnique,
2478     ID3DXEffectImpl_GetTechniqueByName,
2479     ID3DXEffectImpl_GetPass,
2480     ID3DXEffectImpl_GetPassByName,
2481     ID3DXEffectImpl_GetFunction,
2482     ID3DXEffectImpl_GetFunctionByName,
2483     ID3DXEffectImpl_GetAnnotation,
2484     ID3DXEffectImpl_GetAnnotationByName,
2485     ID3DXEffectImpl_SetValue,
2486     ID3DXEffectImpl_GetValue,
2487     ID3DXEffectImpl_SetBool,
2488     ID3DXEffectImpl_GetBool,
2489     ID3DXEffectImpl_SetBoolArray,
2490     ID3DXEffectImpl_GetBoolArray,
2491     ID3DXEffectImpl_SetInt,
2492     ID3DXEffectImpl_GetInt,
2493     ID3DXEffectImpl_SetIntArray,
2494     ID3DXEffectImpl_GetIntArray,
2495     ID3DXEffectImpl_SetFloat,
2496     ID3DXEffectImpl_GetFloat,
2497     ID3DXEffectImpl_SetFloatArray,
2498     ID3DXEffectImpl_GetFloatArray,
2499     ID3DXEffectImpl_SetVector,
2500     ID3DXEffectImpl_GetVector,
2501     ID3DXEffectImpl_SetVectorArray,
2502     ID3DXEffectImpl_GetVectorArray,
2503     ID3DXEffectImpl_SetMatrix,
2504     ID3DXEffectImpl_GetMatrix,
2505     ID3DXEffectImpl_SetMatrixArray,
2506     ID3DXEffectImpl_GetMatrixArray,
2507     ID3DXEffectImpl_SetMatrixPointerArray,
2508     ID3DXEffectImpl_GetMatrixPointerArray,
2509     ID3DXEffectImpl_SetMatrixTranspose,
2510     ID3DXEffectImpl_GetMatrixTranspose,
2511     ID3DXEffectImpl_SetMatrixTransposeArray,
2512     ID3DXEffectImpl_GetMatrixTransposeArray,
2513     ID3DXEffectImpl_SetMatrixTransposePointerArray,
2514     ID3DXEffectImpl_GetMatrixTransposePointerArray,
2515     ID3DXEffectImpl_SetString,
2516     ID3DXEffectImpl_GetString,
2517     ID3DXEffectImpl_SetTexture,
2518     ID3DXEffectImpl_GetTexture,
2519     ID3DXEffectImpl_GetPixelShader,
2520     ID3DXEffectImpl_GetVertexShader,
2521     ID3DXEffectImpl_SetArrayRange,
2522     /*** ID3DXEffect methods ***/
2523     ID3DXEffectImpl_GetPool,
2524     ID3DXEffectImpl_SetTechnique,
2525     ID3DXEffectImpl_GetCurrentTechnique,
2526     ID3DXEffectImpl_ValidateTechnique,
2527     ID3DXEffectImpl_FindNextValidTechnique,
2528     ID3DXEffectImpl_IsParameterUsed,
2529     ID3DXEffectImpl_Begin,
2530     ID3DXEffectImpl_BeginPass,
2531     ID3DXEffectImpl_CommitChanges,
2532     ID3DXEffectImpl_EndPass,
2533     ID3DXEffectImpl_End,
2534     ID3DXEffectImpl_GetDevice,
2535     ID3DXEffectImpl_OnLostDevice,
2536     ID3DXEffectImpl_OnResetDevice,
2537     ID3DXEffectImpl_SetStateManager,
2538     ID3DXEffectImpl_GetStateManager,
2539     ID3DXEffectImpl_BeginParameterBlock,
2540     ID3DXEffectImpl_EndParameterBlock,
2541     ID3DXEffectImpl_ApplyParameterBlock,
2542     ID3DXEffectImpl_DeleteParameterBlock,
2543     ID3DXEffectImpl_CloneEffect,
2544     ID3DXEffectImpl_SetRawValue
2545 };
2546
2547 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
2548 {
2549     return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
2550 }
2551
2552 /*** IUnknown methods ***/
2553 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
2554 {
2555     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2556
2557     TRACE("iface %p, riid %s, object %p\n", This, debugstr_guid(riid), object);
2558
2559     if (IsEqualGUID(riid, &IID_IUnknown) ||
2560         IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
2561     {
2562         This->ID3DXEffectCompiler_iface.lpVtbl->AddRef(iface);
2563         *object = This;
2564         return S_OK;
2565     }
2566
2567     ERR("Interface %s not found\n", debugstr_guid(riid));
2568
2569     return E_NOINTERFACE;
2570 }
2571
2572 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
2573 {
2574     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2575
2576     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
2577
2578     return InterlockedIncrement(&This->ref);
2579 }
2580
2581 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
2582 {
2583     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2584     ULONG ref = InterlockedDecrement(&This->ref);
2585
2586     TRACE("iface %p: Release from %u\n", iface, ref + 1);
2587
2588     if (!ref)
2589     {
2590         free_effect_compiler(This);
2591         HeapFree(GetProcessHeap(), 0, This);
2592     }
2593
2594     return ref;
2595 }
2596
2597 /*** ID3DXBaseEffect methods ***/
2598 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
2599 {
2600     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2601     ID3DXBaseEffect *base = This->base_effect;
2602
2603     TRACE("Forward iface %p, base %p\n", This, base);
2604
2605     return ID3DXBaseEffectImpl_GetDesc(base, desc);
2606 }
2607
2608 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
2609 {
2610     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2611     ID3DXBaseEffect *base = This->base_effect;
2612
2613     TRACE("Forward iface %p, base %p\n", This, base);
2614
2615     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
2616 }
2617
2618 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
2619 {
2620     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2621     ID3DXBaseEffect *base = This->base_effect;
2622
2623     TRACE("Forward iface %p, base %p\n", This, base);
2624
2625     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
2626 }
2627
2628 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
2629 {
2630     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2631     ID3DXBaseEffect *base = This->base_effect;
2632
2633     TRACE("Forward iface %p, base %p\n", This, base);
2634
2635     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
2636 }
2637
2638 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
2639 {
2640     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2641     ID3DXBaseEffect *base = This->base_effect;
2642
2643     TRACE("Forward iface %p, base %p\n", This, base);
2644
2645     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
2646 }
2647
2648 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
2649 {
2650     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2651     ID3DXBaseEffect *base = This->base_effect;
2652
2653     TRACE("Forward iface %p, base %p\n", This, base);
2654
2655     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
2656 }
2657
2658 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR name)
2659 {
2660     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2661     ID3DXBaseEffect *base = This->base_effect;
2662
2663     TRACE("Forward iface %p, base %p\n", This, base);
2664
2665     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
2666 }
2667
2668 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR semantic)
2669 {
2670     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2671     ID3DXBaseEffect *base = This->base_effect;
2672
2673     TRACE("Forward iface %p, base %p\n", This, base);
2674
2675     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
2676 }
2677
2678 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
2679 {
2680     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2681     ID3DXBaseEffect *base = This->base_effect;
2682
2683     TRACE("Forward iface %p, base %p\n", This, base);
2684
2685     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
2686 }
2687
2688 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
2689 {
2690     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2691     ID3DXBaseEffect *base = This->base_effect;
2692
2693     TRACE("Forward iface %p, base %p\n", This, base);
2694
2695     return ID3DXBaseEffectImpl_GetTechnique(base, index);
2696 }
2697
2698 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, LPCSTR name)
2699 {
2700     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2701     ID3DXBaseEffect *base = This->base_effect;
2702
2703     TRACE("Forward iface %p, base %p\n", This, base);
2704
2705     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
2706 }
2707
2708 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
2709 {
2710     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2711     ID3DXBaseEffect *base = This->base_effect;
2712
2713     TRACE("Forward iface %p, base %p\n", This, base);
2714
2715     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
2716 }
2717
2718 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, D3DXHANDLE technique, LPCSTR name)
2719 {
2720     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2721     ID3DXBaseEffect *base = This->base_effect;
2722
2723     TRACE("Forward iface %p, base %p\n", This, base);
2724
2725     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
2726 }
2727
2728 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
2729 {
2730     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2731     ID3DXBaseEffect *base = This->base_effect;
2732
2733     TRACE("Forward iface %p, base %p\n", This, base);
2734
2735     return ID3DXBaseEffectImpl_GetFunction(base, index);
2736 }
2737
2738 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, LPCSTR name)
2739 {
2740     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2741     ID3DXBaseEffect *base = This->base_effect;
2742
2743     TRACE("Forward iface %p, base %p\n", This, base);
2744
2745     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
2746 }
2747
2748 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, D3DXHANDLE object, UINT index)
2749 {
2750     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2751     ID3DXBaseEffect *base = This->base_effect;
2752
2753     TRACE("Forward iface %p, base %p\n", This, base);
2754
2755     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
2756 }
2757
2758 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, D3DXHANDLE object, LPCSTR name)
2759 {
2760     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2761     ID3DXBaseEffect *base = This->base_effect;
2762
2763     TRACE("Forward iface %p, base %p\n", This, base);
2764
2765     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
2766 }
2767
2768 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
2769 {
2770     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2771     ID3DXBaseEffect *base = This->base_effect;
2772
2773     TRACE("Forward iface %p, base %p\n", This, base);
2774
2775     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
2776 }
2777
2778 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
2779 {
2780     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2781     ID3DXBaseEffect *base = This->base_effect;
2782
2783     TRACE("Forward iface %p, base %p\n", This, base);
2784
2785     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
2786 }
2787
2788 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
2789 {
2790     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2791     ID3DXBaseEffect *base = This->base_effect;
2792
2793     TRACE("Forward iface %p, base %p\n", This, base);
2794
2795     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
2796 }
2797
2798 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
2799 {
2800     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2801     ID3DXBaseEffect *base = This->base_effect;
2802
2803     TRACE("Forward iface %p, base %p\n", This, base);
2804
2805     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
2806 }
2807
2808 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
2809 {
2810     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2811     ID3DXBaseEffect *base = This->base_effect;
2812
2813     TRACE("Forward iface %p, base %p\n", This, base);
2814
2815     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
2816 }
2817
2818 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
2819 {
2820     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2821     ID3DXBaseEffect *base = This->base_effect;
2822
2823     TRACE("Forward iface %p, base %p\n", This, base);
2824
2825     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
2826 }
2827
2828 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
2829 {
2830     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2831     ID3DXBaseEffect *base = This->base_effect;
2832
2833     TRACE("Forward iface %p, base %p\n", This, base);
2834
2835     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
2836 }
2837
2838 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
2839 {
2840     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2841     ID3DXBaseEffect *base = This->base_effect;
2842
2843     TRACE("Forward iface %p, base %p\n", This, base);
2844
2845     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
2846 }
2847
2848 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
2849 {
2850     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2851     ID3DXBaseEffect *base = This->base_effect;
2852
2853     TRACE("Forward iface %p, base %p\n", This, base);
2854
2855     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
2856 }
2857
2858 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n, UINT count)
2859 {
2860     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2861     ID3DXBaseEffect *base = This->base_effect;
2862
2863     TRACE("Forward iface %p, base %p\n", This, base);
2864
2865     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
2866 }
2867
2868 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT f)
2869 {
2870     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2871     ID3DXBaseEffect *base = This->base_effect;
2872
2873     TRACE("Forward iface %p, base %p\n", This, base);
2874
2875     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
2876 }
2877
2878 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f)
2879 {
2880     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2881     ID3DXBaseEffect *base = This->base_effect;
2882
2883     TRACE("Forward iface %p, base %p\n", This, base);
2884
2885     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
2886 }
2887
2888 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
2889 {
2890     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2891     ID3DXBaseEffect *base = This->base_effect;
2892
2893     TRACE("Forward iface %p, base %p\n", This, base);
2894
2895     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
2896 }
2897
2898 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
2899 {
2900     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2901     ID3DXBaseEffect *base = This->base_effect;
2902
2903     TRACE("Forward iface %p, base %p\n", This, base);
2904
2905     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
2906 }
2907
2908 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
2909 {
2910     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2911     ID3DXBaseEffect *base = This->base_effect;
2912
2913     TRACE("Forward iface %p, base %p\n", This, base);
2914
2915     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
2916 }
2917
2918 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2919 {
2920     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2921     ID3DXBaseEffect *base = This->base_effect;
2922
2923     TRACE("Forward iface %p, base %p\n", This, base);
2924
2925     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
2926 }
2927
2928 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
2929 {
2930     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2931     ID3DXBaseEffect *base = This->base_effect;
2932
2933     TRACE("Forward iface %p, base %p\n", This, base);
2934
2935     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
2936 }
2937
2938 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2939 {
2940     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2941     ID3DXBaseEffect *base = This->base_effect;
2942
2943     TRACE("Forward iface %p, base %p\n", This, base);
2944
2945     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
2946 }
2947
2948 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2949 {
2950     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2951     ID3DXBaseEffect *base = This->base_effect;
2952
2953     TRACE("Forward iface %p, base %p\n", This, base);
2954
2955     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
2956 }
2957
2958 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2959 {
2960     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2961     ID3DXBaseEffect *base = This->base_effect;
2962
2963     TRACE("Forward iface %p, base %p\n", This, base);
2964
2965     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
2966 }
2967
2968 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2969 {
2970     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2971     ID3DXBaseEffect *base = This->base_effect;
2972
2973     TRACE("Forward iface %p, base %p\n", This, base);
2974
2975     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
2976 }
2977
2978 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2979 {
2980     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2981     ID3DXBaseEffect *base = This->base_effect;
2982
2983     TRACE("Forward iface %p, base %p\n", This, base);
2984
2985     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
2986 }
2987
2988 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2989 {
2990     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
2991     ID3DXBaseEffect *base = This->base_effect;
2992
2993     TRACE("Forward iface %p, base %p\n", This, base);
2994
2995     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
2996 }
2997
2998 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2999 {
3000     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3001     ID3DXBaseEffect *base = This->base_effect;
3002
3003     TRACE("Forward iface %p, base %p\n", This, base);
3004
3005     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
3006 }
3007
3008 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
3009 {
3010     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3011     ID3DXBaseEffect *base = This->base_effect;
3012
3013     TRACE("Forward iface %p, base %p\n", This, base);
3014
3015     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
3016 }
3017
3018 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3019 {
3020     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3021     ID3DXBaseEffect *base = This->base_effect;
3022
3023     TRACE("Forward iface %p, base %p\n", This, base);
3024
3025     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
3026 }
3027
3028 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
3029 {
3030     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3031     ID3DXBaseEffect *base = This->base_effect;
3032
3033     TRACE("Forward iface %p, base %p\n", This, base);
3034
3035     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
3036 }
3037
3038 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3039 {
3040     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3041     ID3DXBaseEffect *base = This->base_effect;
3042
3043     TRACE("Forward iface %p, base %p\n", This, base);
3044
3045     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
3046 }
3047
3048 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
3049 {
3050     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3051     ID3DXBaseEffect *base = This->base_effect;
3052
3053     TRACE("Forward iface %p, base %p\n", This, base);
3054
3055     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
3056 }
3057
3058 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3059 {
3060     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3061     ID3DXBaseEffect *base = This->base_effect;
3062
3063     TRACE("Forward iface %p, base %p\n", This, base);
3064
3065     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
3066 }
3067
3068 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR string)
3069 {
3070     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3071     ID3DXBaseEffect *base = This->base_effect;
3072
3073     TRACE("Forward iface %p, base %p\n", This, base);
3074
3075     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
3076 }
3077
3078 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR *string)
3079 {
3080     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3081     ID3DXBaseEffect *base = This->base_effect;
3082
3083     TRACE("Forward iface %p, base %p\n", This, base);
3084
3085     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
3086 }
3087
3088 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
3089 {
3090     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3091     ID3DXBaseEffect *base = This->base_effect;
3092
3093     TRACE("Forward iface %p, base %p\n", This, base);
3094
3095     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
3096 }
3097
3098 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
3099 {
3100     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3101     ID3DXBaseEffect *base = This->base_effect;
3102
3103     TRACE("Forward iface %p, base %p\n", This, base);
3104
3105     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
3106 }
3107
3108 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
3109 {
3110     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3111     ID3DXBaseEffect *base = This->base_effect;
3112
3113     TRACE("Forward iface %p, base %p\n", This, base);
3114
3115     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
3116 }
3117
3118 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
3119 {
3120     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3121     ID3DXBaseEffect *base = This->base_effect;
3122
3123     TRACE("Forward iface %p, base %p\n", This, base);
3124
3125     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
3126 }
3127
3128 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT start, UINT end)
3129 {
3130     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3131     ID3DXBaseEffect *base = This->base_effect;
3132
3133     TRACE("Forward iface %p, base %p\n", This, base);
3134
3135     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
3136 }
3137
3138 /*** ID3DXEffectCompiler methods ***/
3139 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
3140 {
3141     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3142
3143     FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
3144
3145     return E_NOTIMPL;
3146 }
3147
3148 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
3149 {
3150     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3151
3152     FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
3153
3154     return E_NOTIMPL;
3155 }
3156
3157 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
3158         LPD3DXBUFFER *effect, LPD3DXBUFFER *error_msgs)
3159 {
3160     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3161
3162     FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
3163
3164     return E_NOTIMPL;
3165 }
3166
3167 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
3168         LPCSTR target, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *error_msgs, LPD3DXCONSTANTTABLE *constant_table)
3169 {
3170     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3171
3172     FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
3173             This, function, target, flags, shader, error_msgs, constant_table);
3174
3175     return E_NOTIMPL;
3176 }
3177
3178 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
3179 {
3180     /*** IUnknown methods ***/
3181     ID3DXEffectCompilerImpl_QueryInterface,
3182     ID3DXEffectCompilerImpl_AddRef,
3183     ID3DXEffectCompilerImpl_Release,
3184     /*** ID3DXBaseEffect methods ***/
3185     ID3DXEffectCompilerImpl_GetDesc,
3186     ID3DXEffectCompilerImpl_GetParameterDesc,
3187     ID3DXEffectCompilerImpl_GetTechniqueDesc,
3188     ID3DXEffectCompilerImpl_GetPassDesc,
3189     ID3DXEffectCompilerImpl_GetFunctionDesc,
3190     ID3DXEffectCompilerImpl_GetParameter,
3191     ID3DXEffectCompilerImpl_GetParameterByName,
3192     ID3DXEffectCompilerImpl_GetParameterBySemantic,
3193     ID3DXEffectCompilerImpl_GetParameterElement,
3194     ID3DXEffectCompilerImpl_GetTechnique,
3195     ID3DXEffectCompilerImpl_GetTechniqueByName,
3196     ID3DXEffectCompilerImpl_GetPass,
3197     ID3DXEffectCompilerImpl_GetPassByName,
3198     ID3DXEffectCompilerImpl_GetFunction,
3199     ID3DXEffectCompilerImpl_GetFunctionByName,
3200     ID3DXEffectCompilerImpl_GetAnnotation,
3201     ID3DXEffectCompilerImpl_GetAnnotationByName,
3202     ID3DXEffectCompilerImpl_SetValue,
3203     ID3DXEffectCompilerImpl_GetValue,
3204     ID3DXEffectCompilerImpl_SetBool,
3205     ID3DXEffectCompilerImpl_GetBool,
3206     ID3DXEffectCompilerImpl_SetBoolArray,
3207     ID3DXEffectCompilerImpl_GetBoolArray,
3208     ID3DXEffectCompilerImpl_SetInt,
3209     ID3DXEffectCompilerImpl_GetInt,
3210     ID3DXEffectCompilerImpl_SetIntArray,
3211     ID3DXEffectCompilerImpl_GetIntArray,
3212     ID3DXEffectCompilerImpl_SetFloat,
3213     ID3DXEffectCompilerImpl_GetFloat,
3214     ID3DXEffectCompilerImpl_SetFloatArray,
3215     ID3DXEffectCompilerImpl_GetFloatArray,
3216     ID3DXEffectCompilerImpl_SetVector,
3217     ID3DXEffectCompilerImpl_GetVector,
3218     ID3DXEffectCompilerImpl_SetVectorArray,
3219     ID3DXEffectCompilerImpl_GetVectorArray,
3220     ID3DXEffectCompilerImpl_SetMatrix,
3221     ID3DXEffectCompilerImpl_GetMatrix,
3222     ID3DXEffectCompilerImpl_SetMatrixArray,
3223     ID3DXEffectCompilerImpl_GetMatrixArray,
3224     ID3DXEffectCompilerImpl_SetMatrixPointerArray,
3225     ID3DXEffectCompilerImpl_GetMatrixPointerArray,
3226     ID3DXEffectCompilerImpl_SetMatrixTranspose,
3227     ID3DXEffectCompilerImpl_GetMatrixTranspose,
3228     ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
3229     ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
3230     ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
3231     ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
3232     ID3DXEffectCompilerImpl_SetString,
3233     ID3DXEffectCompilerImpl_GetString,
3234     ID3DXEffectCompilerImpl_SetTexture,
3235     ID3DXEffectCompilerImpl_GetTexture,
3236     ID3DXEffectCompilerImpl_GetPixelShader,
3237     ID3DXEffectCompilerImpl_GetVertexShader,
3238     ID3DXEffectCompilerImpl_SetArrayRange,
3239     /*** ID3DXEffectCompiler methods ***/
3240     ID3DXEffectCompilerImpl_SetLiteral,
3241     ID3DXEffectCompilerImpl_GetLiteral,
3242     ID3DXEffectCompilerImpl_CompileEffect,
3243     ID3DXEffectCompilerImpl_CompileShader,
3244 };
3245
3246 static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char **ptr)
3247 {
3248     unsigned int i;
3249     HRESULT hr;
3250     UINT old_size = 0;
3251     DWORD id;
3252
3253     if (param->element_count)
3254     {
3255         param->data = value;
3256
3257         for (i = 0; i < param->element_count; ++i)
3258         {
3259             struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
3260
3261             hr = d3dx9_parse_value(member, (char *)value + old_size, ptr);
3262             if (hr != D3D_OK)
3263             {
3264                 WARN("Failed to parse value\n");
3265                 return hr;
3266             }
3267
3268             old_size += member->bytes;
3269         }
3270
3271         return D3D_OK;
3272     }
3273
3274     switch(param->class)
3275     {
3276         case D3DXPC_SCALAR:
3277         case D3DXPC_VECTOR:
3278         case D3DXPC_MATRIX_ROWS:
3279         case D3DXPC_MATRIX_COLUMNS:
3280             param->data = value;
3281             break;
3282
3283         case D3DXPC_STRUCT:
3284             param->data = value;
3285
3286             for (i = 0; i < param->member_count; ++i)
3287             {
3288                 struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
3289
3290                 hr = d3dx9_parse_value(member, (char *)value + old_size, ptr);
3291                 if (hr != D3D_OK)
3292                 {
3293                     WARN("Failed to parse value\n");
3294                     return hr;
3295                 }
3296
3297                 old_size += member->bytes;
3298             }
3299             break;
3300
3301         case D3DXPC_OBJECT:
3302             switch (param->type)
3303             {
3304                 case D3DXPT_STRING:
3305                 case D3DXPT_PIXELSHADER:
3306                 case D3DXPT_VERTEXSHADER:
3307                     read_dword(ptr, &id);
3308                     TRACE("Id: %u\n", id);
3309                     param->base->objects[id] = get_parameter_handle(param);
3310                     param->data = value;
3311                     break;
3312
3313                 default:
3314                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
3315                     break;
3316             }
3317             break;
3318
3319         default:
3320             FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
3321             break;
3322     }
3323
3324     return D3D_OK;
3325 }
3326
3327 static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *ptr)
3328 {
3329     UINT size = param->bytes;
3330     HRESULT hr;
3331     void *value = NULL;
3332
3333     TRACE("param size: %u\n", size);
3334
3335     value = HeapAlloc(GetProcessHeap(), 0, size);
3336     if (!value)
3337     {
3338         ERR("Failed to allocate data memory.\n");
3339         return E_OUTOFMEMORY;
3340     }
3341
3342     TRACE("Data: %s.\n", debugstr_an(ptr, size));
3343     memcpy(value, ptr, size);
3344
3345     hr = d3dx9_parse_value(param, value, &ptr);
3346     if (hr != D3D_OK)
3347     {
3348         WARN("Failed to parse value\n");
3349         HeapFree(GetProcessHeap(), 0, value);
3350         return hr;
3351     }
3352
3353     param->data = value;
3354
3355     return D3D_OK;
3356 }
3357
3358 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
3359 {
3360     DWORD size;
3361
3362     read_dword(&ptr, &size);
3363     TRACE("Name size: %#x\n", size);
3364
3365     if (!size)
3366     {
3367         return D3D_OK;
3368     }
3369
3370     *name = HeapAlloc(GetProcessHeap(), 0, size);
3371     if (!*name)
3372     {
3373         ERR("Failed to allocate name memory.\n");
3374         return E_OUTOFMEMORY;
3375     }
3376
3377     TRACE("Name: %s.\n", debugstr_an(ptr, size));
3378     memcpy(*name, ptr, size);
3379
3380     return D3D_OK;
3381 }
3382
3383 static HRESULT d3dx9_parse_data(struct d3dx_parameter *param, const char **ptr)
3384 {
3385     DWORD size;
3386     HRESULT hr;
3387
3388     TRACE("Parse data for parameter %s, type %s\n", debugstr_a(param->name), debug_d3dxparameter_type(param->type));
3389
3390     read_dword(ptr, &size);
3391     TRACE("Data size: %#x\n", size);
3392
3393     if (!size)
3394     {
3395         TRACE("Size is 0\n");
3396         *(void **)param->data = NULL;
3397         return D3D_OK;
3398     }
3399
3400     switch (param->type)
3401     {
3402         case D3DXPT_STRING:
3403             /* re-read with size (sizeof(DWORD) = 4) */
3404             hr = d3dx9_parse_name((LPSTR *)param->data, *ptr - 4);
3405             if (hr != D3D_OK)
3406             {
3407                 WARN("Failed to parse string data\n");
3408                 return hr;
3409             }
3410             break;
3411
3412         case D3DXPT_VERTEXSHADER:
3413             hr = IDirect3DDevice9_CreateVertexShader(param->base->effect->device, (DWORD *)*ptr, (LPDIRECT3DVERTEXSHADER9 *)param->data);
3414             if (hr != D3D_OK)
3415             {
3416                 WARN("Failed to create vertex shader\n");
3417                 return hr;
3418             }
3419             break;
3420
3421         case D3DXPT_PIXELSHADER:
3422             hr = IDirect3DDevice9_CreatePixelShader(param->base->effect->device, (DWORD *)*ptr, (LPDIRECT3DPIXELSHADER9 *)param->data);
3423             if (hr != D3D_OK)
3424             {
3425                 WARN("Failed to create pixel shader\n");
3426                 return hr;
3427             }
3428             break;
3429
3430         default:
3431             FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
3432             break;
3433     }
3434
3435
3436     *ptr += ((size + 3) & ~3);
3437
3438     return D3D_OK;
3439 }
3440
3441 static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
3442         struct d3dx_parameter *parent, UINT flags)
3443 {
3444     DWORD offset;
3445     HRESULT hr;
3446     D3DXHANDLE *member_handles = NULL;
3447     UINT i;
3448
3449     param->flags = flags;
3450
3451     if (!parent)
3452     {
3453         read_dword(ptr, &param->type);
3454         TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
3455
3456         read_dword(ptr, &param->class);
3457         TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
3458
3459         read_dword(ptr, &offset);
3460         TRACE("Type name offset: %#x\n", offset);
3461         hr = d3dx9_parse_name(&param->name, data + offset);
3462         if (hr != D3D_OK)
3463         {
3464             WARN("Failed to parse name\n");
3465             goto err_out;
3466         }
3467
3468         read_dword(ptr, &offset);
3469         TRACE("Type semantic offset: %#x\n", offset);
3470         hr = d3dx9_parse_name(&param->semantic, data + offset);
3471         if (hr != D3D_OK)
3472         {
3473             WARN("Failed to parse semantic\n");
3474             goto err_out;
3475         }
3476
3477         read_dword(ptr, &param->element_count);
3478         TRACE("Elements: %u\n", param->element_count);
3479
3480         switch (param->class)
3481         {
3482             case D3DXPC_VECTOR:
3483                 read_dword(ptr, &param->columns);
3484                 TRACE("Columns: %u\n", param->columns);
3485
3486                 read_dword(ptr, &param->rows);
3487                 TRACE("Rows: %u\n", param->rows);
3488
3489                 /* sizeof(DWORD) * rows * columns */
3490                 param->bytes = 4 * param->rows * param->columns;
3491                 break;
3492
3493             case D3DXPC_SCALAR:
3494             case D3DXPC_MATRIX_ROWS:
3495             case D3DXPC_MATRIX_COLUMNS:
3496                 read_dword(ptr, &param->rows);
3497                 TRACE("Rows: %u\n", param->rows);
3498
3499                 read_dword(ptr, &param->columns);
3500                 TRACE("Columns: %u\n", param->columns);
3501
3502                 /* sizeof(DWORD) * rows * columns */
3503                 param->bytes = 4 * param->rows * param->columns;
3504                 break;
3505
3506             case D3DXPC_STRUCT:
3507                 read_dword(ptr, &param->member_count);
3508                 TRACE("Members: %u\n", param->member_count);
3509                 break;
3510
3511             case D3DXPC_OBJECT:
3512                 switch (param->type)
3513                 {
3514                     case D3DXPT_STRING:
3515                         param->bytes = sizeof(LPCSTR);
3516                         break;
3517
3518                     case D3DXPT_PIXELSHADER:
3519                         param->bytes = sizeof(LPDIRECT3DPIXELSHADER9);
3520                         break;
3521
3522                     case D3DXPT_VERTEXSHADER:
3523                         param->bytes = sizeof(LPDIRECT3DVERTEXSHADER9);
3524                         break;
3525
3526                     default:
3527                         FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
3528                         break;
3529                 }
3530                 break;
3531
3532             default:
3533                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
3534                 break;
3535         }
3536     }
3537     else
3538     {
3539         /* elements */
3540         param->type = parent->type;
3541         param->class = parent->class;
3542         param->name = parent->name;
3543         param->semantic = parent->semantic;
3544         param->element_count = 0;
3545         param->annotation_count = 0;
3546         param->member_count = parent->member_count;
3547         param->bytes = parent->bytes;
3548         param->rows = parent->rows;
3549         param->columns = parent->columns;
3550     }
3551
3552     if (param->element_count)
3553     {
3554         unsigned int param_bytes = 0;
3555         const char *save_ptr = *ptr;
3556
3557         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->element_count);
3558         if (!member_handles)
3559         {
3560             ERR("Out of memory\n");
3561             hr = E_OUTOFMEMORY;
3562             goto err_out;
3563         }
3564
3565         for (i = 0; i < param->element_count; ++i)
3566         {
3567             struct d3dx_parameter *member;
3568             *ptr = save_ptr;
3569
3570             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
3571             if (!member)
3572             {
3573                 ERR("Out of memory\n");
3574                 hr = E_OUTOFMEMORY;
3575                 goto err_out;
3576             }
3577
3578             member_handles[i] = get_parameter_handle(member);
3579             member->base = param->base;
3580
3581             hr = d3dx9_parse_effect_typedef(member, data, ptr, param, flags);
3582             if (hr != D3D_OK)
3583             {
3584                 WARN("Failed to parse member\n");
3585                 goto err_out;
3586             }
3587
3588             param_bytes += member->bytes;
3589         }
3590
3591         param->bytes = param_bytes;
3592     }
3593     else if (param->member_count)
3594     {
3595         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->member_count);
3596         if (!member_handles)
3597         {
3598             ERR("Out of memory\n");
3599             hr = E_OUTOFMEMORY;
3600             goto err_out;
3601         }
3602
3603         for (i = 0; i < param->member_count; ++i)
3604         {
3605             struct d3dx_parameter *member;
3606
3607             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
3608             if (!member)
3609             {
3610                 ERR("Out of memory\n");
3611                 hr = E_OUTOFMEMORY;
3612                 goto err_out;
3613             }
3614
3615             member_handles[i] = get_parameter_handle(member);
3616             member->base = param->base;
3617
3618             hr = d3dx9_parse_effect_typedef(member, data, ptr, NULL, flags);
3619             if (hr != D3D_OK)
3620             {
3621                 WARN("Failed to parse member\n");
3622                 goto err_out;
3623             }
3624
3625             param->bytes += member->bytes;
3626         }
3627     }
3628
3629     param->member_handles = member_handles;
3630
3631     return D3D_OK;
3632
3633 err_out:
3634
3635     if (member_handles)
3636     {
3637         unsigned int count;
3638
3639         if (param->element_count) count = param->element_count;
3640         else count = param->member_count;
3641
3642         for (i = 0; i < count; ++i)
3643         {
3644             free_parameter(member_handles[i], param->element_count != 0, TRUE);
3645         }
3646         HeapFree(GetProcessHeap(), 0, member_handles);
3647     }
3648
3649     if (!parent)
3650     {
3651         HeapFree(GetProcessHeap(), 0, param->name);
3652         HeapFree(GetProcessHeap(), 0, param->semantic);
3653     }
3654     param->name = NULL;
3655     param->semantic = NULL;
3656
3657     return hr;
3658 }
3659
3660 static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data, const char **ptr)
3661 {
3662     DWORD offset;
3663     const char *ptr2;
3664     HRESULT hr;
3665
3666     anno->flags = D3DX_PARAMETER_ANNOTATION;
3667
3668     read_dword(ptr, &offset);
3669     TRACE("Typedef offset: %#x\n", offset);
3670     ptr2 = data + offset;
3671     hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
3672     if (hr != D3D_OK)
3673     {
3674         WARN("Failed to parse type definition\n");
3675         return hr;
3676     }
3677
3678     read_dword(ptr, &offset);
3679     TRACE("Value offset: %#x\n", offset);
3680     hr = d3dx9_parse_init_value(anno, data + offset);
3681     if (hr != D3D_OK)
3682     {
3683         WARN("Failed to parse value\n");
3684         return hr;
3685     }
3686
3687     return D3D_OK;
3688 }
3689
3690 static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data, const char **ptr)
3691 {
3692     DWORD offset;
3693     HRESULT hr;
3694     unsigned int i;
3695     D3DXHANDLE *annotation_handles = NULL;
3696     const char *ptr2;
3697
3698     read_dword(ptr, &offset);
3699     TRACE("Typedef offset: %#x\n", offset);
3700     ptr2 = data + offset;
3701
3702     read_dword(ptr, &offset);
3703     TRACE("Value offset: %#x\n", offset);
3704
3705     read_dword(ptr, &param->flags);
3706     TRACE("Flags: %#x\n", param->flags);
3707
3708     read_dword(ptr, &param->annotation_count);
3709     TRACE("Annotation count: %u\n", param->annotation_count);
3710
3711     hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
3712     if (hr != D3D_OK)
3713     {
3714         WARN("Failed to parse type definition\n");
3715         return hr;
3716     }
3717
3718     hr = d3dx9_parse_init_value(param, data + offset);
3719     if (hr != D3D_OK)
3720     {
3721         WARN("Failed to parse value\n");
3722         return hr;
3723     }
3724
3725     if (param->annotation_count)
3726     {
3727         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * param->annotation_count);
3728         if (!annotation_handles)
3729         {
3730             ERR("Out of memory\n");
3731             hr = E_OUTOFMEMORY;
3732             goto err_out;
3733         }
3734
3735         for (i = 0; i < param->annotation_count; ++i)
3736         {
3737             struct d3dx_parameter *annotation;
3738
3739             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
3740             if (!annotation)
3741             {
3742                 ERR("Out of memory\n");
3743                 hr = E_OUTOFMEMORY;
3744                 goto err_out;
3745             }
3746
3747             annotation_handles[i] = get_parameter_handle(annotation);
3748             annotation->base = param->base;
3749
3750             hr = d3dx9_parse_effect_annotation(annotation, data, ptr);
3751             if (hr != D3D_OK)
3752             {
3753                 WARN("Failed to parse annotation\n");
3754                 goto err_out;
3755             }
3756         }
3757     }
3758
3759     param->annotation_handles = annotation_handles;
3760
3761     return D3D_OK;
3762
3763 err_out:
3764
3765     if (annotation_handles)
3766     {
3767         for (i = 0; i < param->annotation_count; ++i)
3768         {
3769             free_parameter(annotation_handles[i], FALSE, FALSE);
3770         }
3771         HeapFree(GetProcessHeap(), 0, annotation_handles);
3772     }
3773
3774     return hr;
3775 }
3776
3777 static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr)
3778 {
3779     DWORD offset;
3780     HRESULT hr;
3781     unsigned int i;
3782     D3DXHANDLE *annotation_handles = NULL;
3783     char *name = NULL;
3784
3785     read_dword(ptr, &offset);
3786     TRACE("Pass name offset: %#x\n", offset);
3787     hr = d3dx9_parse_name(&name, data + offset);
3788     if (hr != D3D_OK)
3789     {
3790         WARN("Failed to parse name\n");
3791         goto err_out;
3792     }
3793
3794     read_dword(ptr, &pass->annotation_count);
3795     TRACE("Annotation count: %u\n", pass->annotation_count);
3796
3797     read_dword(ptr, &pass->state_count);
3798     TRACE("State count: %u\n", pass->state_count);
3799
3800     if (pass->annotation_count)
3801     {
3802         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count);
3803         if (!annotation_handles)
3804         {
3805             ERR("Out of memory\n");
3806             hr = E_OUTOFMEMORY;
3807             goto err_out;
3808         }
3809
3810         for (i = 0; i < pass->annotation_count; ++i)
3811         {
3812             struct d3dx_parameter *annotation;
3813
3814             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
3815             if (!annotation)
3816             {
3817                 ERR("Out of memory\n");
3818                 hr = E_OUTOFMEMORY;
3819                 goto err_out;
3820             }
3821
3822             annotation_handles[i] = get_parameter_handle(annotation);
3823             annotation->base = pass->base;
3824
3825             hr = d3dx9_parse_effect_annotation(annotation, data, ptr);
3826             if (hr != D3D_OK)
3827             {
3828                 WARN("Failed to parse annotations\n");
3829                 goto err_out;
3830             }
3831         }
3832     }
3833
3834     if (pass->state_count)
3835     {
3836         for (i = 0; i < pass->state_count; ++i)
3837         {
3838             skip_dword_unknown(ptr, 4);
3839         }
3840     }
3841
3842     pass->name = name;
3843     pass->annotation_handles = annotation_handles;
3844
3845     return D3D_OK;
3846
3847 err_out:
3848
3849     if (annotation_handles)
3850     {
3851         for (i = 0; i < pass->annotation_count; ++i)
3852         {
3853             free_parameter(annotation_handles[i], FALSE, FALSE);
3854         }
3855         HeapFree(GetProcessHeap(), 0, annotation_handles);
3856     }
3857
3858     HeapFree(GetProcessHeap(), 0, name);
3859
3860     return hr;
3861 }
3862
3863 static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr)
3864 {
3865     DWORD offset;
3866     HRESULT hr;
3867     unsigned int i;
3868     D3DXHANDLE *annotation_handles = NULL;
3869     D3DXHANDLE *pass_handles = NULL;
3870     char *name = NULL;
3871
3872     read_dword(ptr, &offset);
3873     TRACE("Technique name offset: %#x\n", offset);
3874     hr = d3dx9_parse_name(&name, data + offset);
3875     if (hr != D3D_OK)
3876     {
3877         WARN("Failed to parse name\n");
3878         goto err_out;
3879     }
3880
3881     read_dword(ptr, &technique->annotation_count);
3882     TRACE("Annotation count: %u\n", technique->annotation_count);
3883
3884     read_dword(ptr, &technique->pass_count);
3885     TRACE("Pass count: %u\n", technique->pass_count);
3886
3887     if (technique->annotation_count)
3888     {
3889         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count);
3890         if (!annotation_handles)
3891         {
3892             ERR("Out of memory\n");
3893             hr = E_OUTOFMEMORY;
3894             goto err_out;
3895         }
3896
3897         for (i = 0; i < technique->annotation_count; ++i)
3898         {
3899             struct d3dx_parameter *annotation;
3900
3901             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
3902             if (!annotation)
3903             {
3904                 ERR("Out of memory\n");
3905                 hr = E_OUTOFMEMORY;
3906                 goto err_out;
3907             }
3908
3909             annotation_handles[i] = get_parameter_handle(annotation);
3910             annotation->base = technique->base;
3911
3912             hr = d3dx9_parse_effect_annotation(annotation, data, ptr);
3913             if (hr != D3D_OK)
3914             {
3915                 WARN("Failed to parse annotations\n");
3916                 goto err_out;
3917             }
3918         }
3919     }
3920
3921     if (technique->pass_count)
3922     {
3923         pass_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count);
3924         if (!pass_handles)
3925         {
3926             ERR("Out of memory\n");
3927             hr = E_OUTOFMEMORY;
3928             goto err_out;
3929         }
3930
3931         for (i = 0; i < technique->pass_count; ++i)
3932         {
3933             struct d3dx_pass *pass;
3934
3935             pass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass));
3936             if (!pass)
3937             {
3938                 ERR("Out of memory\n");
3939                 hr = E_OUTOFMEMORY;
3940                 goto err_out;
3941             }
3942
3943             pass_handles[i] = get_pass_handle(pass);
3944             pass->base = technique->base;
3945
3946             hr = d3dx9_parse_effect_pass(pass, data, ptr);
3947             if (hr != D3D_OK)
3948             {
3949                 WARN("Failed to parse passes\n");
3950                 goto err_out;
3951             }
3952         }
3953     }
3954
3955     technique->name = name;
3956     technique->pass_handles = pass_handles;
3957     technique->annotation_handles = annotation_handles;
3958
3959     return D3D_OK;
3960
3961 err_out:
3962
3963     if (pass_handles)
3964     {
3965         for (i = 0; i < technique->pass_count; ++i)
3966         {
3967             free_pass(pass_handles[i]);
3968         }
3969         HeapFree(GetProcessHeap(), 0, pass_handles);
3970     }
3971
3972     if (annotation_handles)
3973     {
3974         for (i = 0; i < technique->annotation_count; ++i)
3975         {
3976             free_parameter(annotation_handles[i], FALSE, FALSE);
3977         }
3978         HeapFree(GetProcessHeap(), 0, annotation_handles);
3979     }
3980
3981     HeapFree(GetProcessHeap(), 0, name);
3982
3983     return hr;
3984 }
3985
3986 static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start)
3987 {
3988     const char *ptr = data + start;
3989     D3DXHANDLE *parameter_handles = NULL;
3990     D3DXHANDLE *technique_handles = NULL;
3991     D3DXHANDLE *objects = NULL;
3992     unsigned int stringcount;
3993     HRESULT hr;
3994     unsigned int i;
3995
3996     read_dword(&ptr, &base->parameter_count);
3997     TRACE("Parameter count: %u\n", base->parameter_count);
3998
3999     read_dword(&ptr, &base->technique_count);
4000     TRACE("Technique count: %u\n", base->technique_count);
4001
4002     skip_dword_unknown(&ptr, 1);
4003
4004     read_dword(&ptr, &base->object_count);
4005     TRACE("Object count: %u\n", base->object_count);
4006
4007     objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*objects) * base->object_count);
4008     if (!objects)
4009     {
4010         ERR("Out of memory\n");
4011         hr = E_OUTOFMEMORY;
4012         goto err_out;
4013     }
4014
4015     base->objects = objects;
4016
4017     if (base->parameter_count)
4018     {
4019         parameter_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter_handles) * base->parameter_count);
4020         if (!parameter_handles)
4021         {
4022             ERR("Out of memory\n");
4023             hr = E_OUTOFMEMORY;
4024             goto err_out;
4025         }
4026
4027         for (i = 0; i < base->parameter_count; ++i)
4028         {
4029             struct d3dx_parameter *parameter;
4030
4031             parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
4032             if (!parameter)
4033             {
4034                 ERR("Out of memory\n");
4035                 hr = E_OUTOFMEMORY;
4036                 goto err_out;
4037             }
4038
4039             parameter_handles[i] = get_parameter_handle(parameter);
4040             parameter->base = base;
4041
4042             hr = d3dx9_parse_effect_parameter(parameter, data, &ptr);
4043             if (hr != D3D_OK)
4044             {
4045                 WARN("Failed to parse parameter\n");
4046                 goto err_out;
4047             }
4048         }
4049     }
4050
4051     if (base->technique_count)
4052     {
4053         technique_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count);
4054         if (!technique_handles)
4055         {
4056             ERR("Out of memory\n");
4057             hr = E_OUTOFMEMORY;
4058             goto err_out;
4059         }
4060
4061         for (i = 0; i < base->technique_count; ++i)
4062         {
4063             struct d3dx_technique *technique;
4064
4065             technique = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique));
4066             if (!technique)
4067             {
4068                 ERR("Out of memory\n");
4069                 hr = E_OUTOFMEMORY;
4070                 goto err_out;
4071             }
4072
4073             technique_handles[i] = get_technique_handle(technique);
4074             technique->base = base;
4075
4076             hr = d3dx9_parse_effect_technique(technique, data, &ptr);
4077             if (hr != D3D_OK)
4078             {
4079                 WARN("Failed to parse technique\n");
4080                 goto err_out;
4081             }
4082         }
4083     }
4084
4085     read_dword(&ptr, &stringcount);
4086     TRACE("String count: %u\n", stringcount);
4087
4088     skip_dword_unknown(&ptr, 1);
4089
4090     for (i = 0; i < stringcount; ++i)
4091     {
4092         DWORD id;
4093         struct d3dx_parameter *param;
4094
4095         read_dword(&ptr, &id);
4096         TRACE("Id: %u\n", id);
4097
4098         param = get_parameter_struct(base->objects[id]);
4099
4100         hr = d3dx9_parse_data(param, &ptr);
4101         if (hr != D3D_OK)
4102         {
4103             WARN("Failed to parse data\n");
4104             goto err_out;
4105         }
4106     }
4107
4108     HeapFree(GetProcessHeap(), 0, objects);
4109     base->objects = NULL;
4110
4111     base->technique_handles = technique_handles;
4112     base->parameter_handles = parameter_handles;
4113
4114     return D3D_OK;
4115
4116 err_out:
4117
4118     if (technique_handles)
4119     {
4120         for (i = 0; i < base->technique_count; ++i)
4121         {
4122             free_technique(technique_handles[i]);
4123         }
4124         HeapFree(GetProcessHeap(), 0, technique_handles);
4125     }
4126
4127     if (parameter_handles)
4128     {
4129         for (i = 0; i < base->parameter_count; ++i)
4130         {
4131             free_parameter(parameter_handles[i], FALSE, FALSE);
4132         }
4133         HeapFree(GetProcessHeap(), 0, parameter_handles);
4134     }
4135
4136     HeapFree(GetProcessHeap(), 0, objects);
4137
4138     return hr;
4139 }
4140
4141 static HRESULT d3dx9_base_effect_init(struct ID3DXBaseEffectImpl *base,
4142         const char *data, SIZE_T data_size, struct ID3DXEffectImpl *effect)
4143 {
4144     DWORD tag, offset;
4145     const char *ptr = data;
4146     HRESULT hr;
4147
4148     TRACE("base %p, data %p, data_size %lu, effect %p\n", base, data, data_size, effect);
4149
4150     base->ID3DXBaseEffect_iface.lpVtbl = &ID3DXBaseEffect_Vtbl;
4151     base->ref = 1;
4152     base->effect = effect;
4153
4154     read_dword(&ptr, &tag);
4155     TRACE("Tag: %x\n", tag);
4156
4157     if (tag != d3dx9_effect_version(9, 1))
4158     {
4159         /* todo: compile hlsl ascii code */
4160         FIXME("HLSL ascii effects not supported, yet\n");
4161
4162         /* Show the start of the shader for debugging info. */
4163         TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
4164     }
4165     else
4166     {
4167         read_dword(&ptr, &offset);
4168         TRACE("Offset: %x\n", offset);
4169
4170         hr = d3dx9_parse_effect(base, ptr, data_size, offset);
4171         if (hr != D3D_OK)
4172         {
4173             FIXME("Failed to parse effect.\n");
4174             return hr;
4175         }
4176     }
4177
4178     return D3D_OK;
4179 }
4180
4181 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
4182         const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
4183 {
4184     HRESULT hr;
4185     struct ID3DXBaseEffectImpl *object = NULL;
4186
4187     TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
4188
4189     effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
4190     effect->ref = 1;
4191
4192     if (pool) pool->lpVtbl->AddRef(pool);
4193     effect->pool = pool;
4194
4195     IDirect3DDevice9_AddRef(device);
4196     effect->device = device;
4197
4198     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4199     if (!object)
4200     {
4201         ERR("Out of memory\n");
4202         hr = E_OUTOFMEMORY;
4203         goto err_out;
4204     }
4205
4206     hr = d3dx9_base_effect_init(object, data, data_size, effect);
4207     if (hr != D3D_OK)
4208     {
4209         FIXME("Failed to parse effect.\n");
4210         goto err_out;
4211     }
4212
4213     effect->base_effect = &object->ID3DXBaseEffect_iface;
4214
4215     return D3D_OK;
4216
4217 err_out:
4218
4219     HeapFree(GetProcessHeap(), 0, object);
4220     free_effect(effect);
4221
4222     return hr;
4223 }
4224
4225 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
4226                                   LPCVOID srcdata,
4227                                   UINT srcdatalen,
4228                                   CONST D3DXMACRO* defines,
4229                                   LPD3DXINCLUDE include,
4230                                   LPCSTR skip_constants,
4231                                   DWORD flags,
4232                                   LPD3DXEFFECTPOOL pool,
4233                                   LPD3DXEFFECT* effect,
4234                                   LPD3DXBUFFER* compilation_errors)
4235 {
4236     struct ID3DXEffectImpl *object;
4237     HRESULT hr;
4238
4239     FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
4240         skip_constants, flags, pool, effect, compilation_errors);
4241
4242     if (!device || !srcdata)
4243         return D3DERR_INVALIDCALL;
4244
4245     if (!srcdatalen)
4246         return E_FAIL;
4247
4248     /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
4249     if (!effect)
4250         return D3D_OK;
4251
4252     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4253     if (!object)
4254     {
4255         ERR("Out of memory\n");
4256         return E_OUTOFMEMORY;
4257     }
4258
4259     hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, pool);
4260     if (FAILED(hr))
4261     {
4262         WARN("Failed to initialize shader reflection\n");
4263         HeapFree(GetProcessHeap(), 0, object);
4264         return hr;
4265     }
4266
4267     *effect = &object->ID3DXEffect_iface;
4268
4269     TRACE("Created ID3DXEffect %p\n", object);
4270
4271     return D3D_OK;
4272 }
4273
4274 HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
4275                                 LPCVOID srcdata,
4276                                 UINT srcdatalen,
4277                                 CONST D3DXMACRO* defines,
4278                                 LPD3DXINCLUDE include,
4279                                 DWORD flags,
4280                                 LPD3DXEFFECTPOOL pool,
4281                                 LPD3DXEFFECT* effect,
4282                                 LPD3DXBUFFER* compilation_errors)
4283 {
4284     TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
4285         include, flags, pool, effect, compilation_errors);
4286
4287     return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
4288 }
4289
4290 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, const char *data, SIZE_T data_size)
4291 {
4292     HRESULT hr;
4293     struct ID3DXBaseEffectImpl *object = NULL;
4294
4295     TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
4296
4297     compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
4298     compiler->ref = 1;
4299
4300     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4301     if (!object)
4302     {
4303         ERR("Out of memory\n");
4304         hr = E_OUTOFMEMORY;
4305         goto err_out;
4306     }
4307
4308     hr = d3dx9_base_effect_init(object, data, data_size, NULL);
4309     if (hr != D3D_OK)
4310     {
4311         FIXME("Failed to parse effect.\n");
4312         goto err_out;
4313     }
4314
4315     compiler->base_effect = &object->ID3DXBaseEffect_iface;
4316
4317     return D3D_OK;
4318
4319 err_out:
4320
4321     HeapFree(GetProcessHeap(), 0, object);
4322     free_effect_compiler(compiler);
4323
4324     return hr;
4325 }
4326
4327 HRESULT WINAPI D3DXCreateEffectCompiler(LPCSTR srcdata,
4328                                         UINT srcdatalen,
4329                                         CONST D3DXMACRO *defines,
4330                                         LPD3DXINCLUDE include,
4331                                         DWORD flags,
4332                                         LPD3DXEFFECTCOMPILER *compiler,
4333                                         LPD3DXBUFFER *parse_errors)
4334 {
4335     struct ID3DXEffectCompilerImpl *object;
4336     HRESULT hr;
4337
4338     TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
4339             srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
4340
4341     if (!srcdata || !compiler)
4342     {
4343         WARN("Invalid arguments supplied\n");
4344         return D3DERR_INVALIDCALL;
4345     }
4346
4347     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4348     if (!object)
4349     {
4350         ERR("Out of memory\n");
4351         return E_OUTOFMEMORY;
4352     }
4353
4354     hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen);
4355     if (FAILED(hr))
4356     {
4357         WARN("Failed to initialize effect compiler\n");
4358         HeapFree(GetProcessHeap(), 0, object);
4359         return hr;
4360     }
4361
4362     *compiler = &object->ID3DXEffectCompiler_iface;
4363
4364     TRACE("Created ID3DXEffectCompiler %p\n", object);
4365
4366     return D3D_OK;
4367 }
4368
4369 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl;
4370
4371 struct ID3DXEffectPoolImpl
4372 {
4373     ID3DXEffectPool ID3DXEffectPool_iface;
4374     LONG ref;
4375 };
4376
4377 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
4378 {
4379     return CONTAINING_RECORD(iface, struct ID3DXEffectPoolImpl, ID3DXEffectPool_iface);
4380 }
4381
4382 /*** IUnknown methods ***/
4383 static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
4384 {
4385     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
4386
4387     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
4388
4389     if (IsEqualGUID(riid, &IID_IUnknown) ||
4390         IsEqualGUID(riid, &IID_ID3DXEffectPool))
4391     {
4392         This->ID3DXEffectPool_iface.lpVtbl->AddRef(iface);
4393         *object = This;
4394         return S_OK;
4395     }
4396
4397     WARN("Interface %s not found\n", debugstr_guid(riid));
4398
4399     return E_NOINTERFACE;
4400 }
4401
4402 static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool *iface)
4403 {
4404     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
4405
4406     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
4407
4408     return InterlockedIncrement(&This->ref);
4409 }
4410
4411 static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool *iface)
4412 {
4413     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
4414     ULONG ref = InterlockedDecrement(&This->ref);
4415
4416     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
4417
4418     if (!ref)
4419         HeapFree(GetProcessHeap(), 0, This);
4420
4421     return ref;
4422 }
4423
4424 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
4425 {
4426     /*** IUnknown methods ***/
4427     ID3DXEffectPoolImpl_QueryInterface,
4428     ID3DXEffectPoolImpl_AddRef,
4429     ID3DXEffectPoolImpl_Release
4430 };
4431
4432 HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL *pool)
4433 {
4434     struct ID3DXEffectPoolImpl *object;
4435
4436     TRACE("(%p)\n", pool);
4437
4438     if (!pool)
4439         return D3DERR_INVALIDCALL;
4440
4441     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
4442     if (!object)
4443     {
4444         ERR("Out of memory\n");
4445         return E_OUTOFMEMORY;
4446     }
4447
4448     object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
4449     object->ref = 1;
4450
4451     *pool = &object->ID3DXEffectPool_iface;
4452
4453     return S_OK;
4454 }
4455
4456 HRESULT WINAPI D3DXCreateEffectFromFileExW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
4457     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
4458     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4459 {
4460     LPVOID buffer;
4461     HRESULT ret;
4462     DWORD size;
4463
4464     TRACE("(%s): relay\n", debugstr_w(srcfile));
4465
4466     if (!device || !srcfile || !defines)
4467         return D3DERR_INVALIDCALL;
4468
4469     ret = map_view_of_file(srcfile, &buffer, &size);
4470
4471     if (FAILED(ret))
4472         return D3DXERR_INVALIDDATA;
4473
4474     ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
4475     UnmapViewOfFile(buffer);
4476
4477     return ret;
4478 }
4479
4480 HRESULT WINAPI D3DXCreateEffectFromFileExA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
4481     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
4482     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4483 {
4484     LPWSTR srcfileW;
4485     HRESULT ret;
4486     DWORD len;
4487
4488     TRACE("(void): relay\n");
4489
4490     if (!srcfile || !defines)
4491         return D3DERR_INVALIDCALL;
4492
4493     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
4494     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
4495     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
4496
4497     ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
4498     HeapFree(GetProcessHeap(), 0, srcfileW);
4499
4500     return ret;
4501 }
4502
4503 HRESULT WINAPI D3DXCreateEffectFromFileW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
4504     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
4505     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4506 {
4507     TRACE("(void): relay\n");
4508     return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
4509 }
4510
4511 HRESULT WINAPI D3DXCreateEffectFromFileA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
4512     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
4513     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4514 {
4515     TRACE("(void): relay\n");
4516     return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
4517 }
4518
4519 HRESULT WINAPI D3DXCreateEffectFromResourceExW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
4520     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
4521     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4522 {
4523     HRSRC resinfo;
4524
4525     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
4526
4527     if (!device || !defines)
4528         return D3DERR_INVALIDCALL;
4529
4530     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
4531
4532     if (resinfo)
4533     {
4534         LPVOID buffer;
4535         HRESULT ret;
4536         DWORD size;
4537
4538         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
4539
4540         if (FAILED(ret))
4541             return D3DXERR_INVALIDDATA;
4542
4543         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
4544     }
4545
4546     return D3DXERR_INVALIDDATA;
4547 }
4548
4549 HRESULT WINAPI D3DXCreateEffectFromResourceExA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
4550     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
4551     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4552 {
4553     HRSRC resinfo;
4554
4555     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
4556
4557     if (!device || !defines)
4558         return D3DERR_INVALIDCALL;
4559
4560     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
4561
4562     if (resinfo)
4563     {
4564         LPVOID buffer;
4565         HRESULT ret;
4566         DWORD size;
4567
4568         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
4569
4570         if (FAILED(ret))
4571             return D3DXERR_INVALIDDATA;
4572
4573         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
4574     }
4575
4576     return D3DXERR_INVALIDDATA;
4577 }
4578
4579 HRESULT WINAPI D3DXCreateEffectFromResourceW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
4580     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
4581     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4582 {
4583     TRACE("(void): relay\n");
4584     return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
4585 }
4586
4587 HRESULT WINAPI D3DXCreateEffectFromResourceA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
4588     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
4589     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
4590 {
4591     TRACE("(void): relay\n");
4592     return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
4593 }
4594
4595 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(LPCWSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
4596     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
4597 {
4598     LPVOID buffer;
4599     HRESULT ret;
4600     DWORD size;
4601
4602     TRACE("(%s): relay\n", debugstr_w(srcfile));
4603
4604     if (!srcfile || !defines)
4605         return D3DERR_INVALIDCALL;
4606
4607     ret = map_view_of_file(srcfile, &buffer, &size);
4608
4609     if (FAILED(ret))
4610         return D3DXERR_INVALIDDATA;
4611
4612     ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
4613     UnmapViewOfFile(buffer);
4614
4615     return ret;
4616 }
4617
4618 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
4619     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
4620 {
4621     LPWSTR srcfileW;
4622     HRESULT ret;
4623     DWORD len;
4624
4625     TRACE("(void): relay\n");
4626
4627     if (!srcfile || !defines)
4628         return D3DERR_INVALIDCALL;
4629
4630     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
4631     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
4632     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
4633
4634     ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
4635     HeapFree(GetProcessHeap(), 0, srcfileW);
4636
4637     return ret;
4638 }
4639
4640 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, LPCSTR srcresource, const D3DXMACRO *defines,
4641     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
4642 {
4643     HRSRC resinfo;
4644
4645     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
4646
4647     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
4648
4649     if (resinfo)
4650     {
4651         LPVOID buffer;
4652         HRESULT ret;
4653         DWORD size;
4654
4655         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
4656
4657         if (FAILED(ret))
4658             return D3DXERR_INVALIDDATA;
4659
4660         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
4661     }
4662
4663     return D3DXERR_INVALIDDATA;
4664 }
4665
4666 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, LPCWSTR srcresource, const D3DXMACRO *defines,
4667     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
4668 {
4669     HRSRC resinfo;
4670
4671     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
4672
4673     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
4674
4675     if (resinfo)
4676     {
4677         LPVOID buffer;
4678         HRESULT ret;
4679         DWORD size;
4680
4681         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
4682
4683         if (FAILED(ret))
4684             return D3DXERR_INVALIDDATA;
4685
4686         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
4687     }
4688
4689     return D3DXERR_INVALIDDATA;
4690 }