wininet: Don't delete the cache file when closing a request.
[wine] / dlls / d3d10 / effect.c
1 /*
2  * Copyright 2009 Henri Verbeet for CodeWeavers
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
20 #include "config.h"
21 #include "wine/port.h"
22
23 #include "d3d10_private.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d10);
26
27 #define MAKE_TAG(ch0, ch1, ch2, ch3) \
28     ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \
29     ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 ))
30 #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C')
31 #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0')
32 #define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N')
33
34 static const struct ID3D10EffectTechniqueVtbl d3d10_effect_technique_vtbl;
35 static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl;
36
37 static inline void read_dword(const char **ptr, DWORD *d)
38 {
39     memcpy(d, *ptr, sizeof(*d));
40     *ptr += sizeof(*d);
41 }
42
43 static inline void skip_dword_unknown(const char **ptr, unsigned int count)
44 {
45     unsigned int i;
46     DWORD d;
47
48     FIXME("Skipping %u unknown DWORDs:\n", count);
49     for (i = 0; i < count; ++i)
50     {
51         read_dword(ptr, &d);
52         FIXME("\t0x%08x\n", d);
53     }
54 }
55
56 static inline void write_dword(char **ptr, DWORD d)
57 {
58     memcpy(*ptr, &d, sizeof(d));
59     *ptr += sizeof(d);
60 }
61
62 static inline void write_dword_unknown(char **ptr, DWORD d)
63 {
64     FIXME("Writing unknown DWORD 0x%08x\n", d);
65     write_dword(ptr, d);
66 }
67
68 static inline void read_tag(const char **ptr, DWORD *t, char t_str[5])
69 {
70     read_dword(ptr, t);
71     memcpy(t_str, t, 4);
72     t_str[4] = '\0';
73 }
74
75 static HRESULT parse_dxbc(const char *data, SIZE_T data_size,
76         HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx)
77 {
78     const char *ptr = data;
79     HRESULT hr = S_OK;
80     DWORD chunk_count;
81     DWORD total_size;
82     char tag_str[5];
83     unsigned int i;
84     DWORD tag;
85
86     read_tag(&ptr, &tag, tag_str);
87     TRACE("tag: %s\n", tag_str);
88
89     if (tag != TAG_DXBC)
90     {
91         WARN("Wrong tag.\n");
92         return E_FAIL;
93     }
94
95     /* checksum? */
96     skip_dword_unknown(&ptr, 4);
97
98     skip_dword_unknown(&ptr, 1);
99
100     read_dword(&ptr, &total_size);
101     TRACE("total size: %#x\n", total_size);
102
103     read_dword(&ptr, &chunk_count);
104     TRACE("chunk count: %#x\n", chunk_count);
105
106     for (i = 0; i < chunk_count; ++i)
107     {
108         DWORD chunk_tag, chunk_size;
109         const char *chunk_ptr;
110         DWORD chunk_offset;
111
112         read_dword(&ptr, &chunk_offset);
113         TRACE("chunk %u at offset %#x\n", i, chunk_offset);
114
115         chunk_ptr = data + chunk_offset;
116
117         read_dword(&chunk_ptr, &chunk_tag);
118         read_dword(&chunk_ptr, &chunk_size);
119
120         hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx);
121         if (FAILED(hr)) break;
122     }
123
124     return hr;
125 }
126
127 static HRESULT parse_fx10_pass_index(struct d3d10_effect_pass *p, const char **ptr)
128 {
129     unsigned int i;
130
131     read_dword(ptr, &p->start);
132     TRACE("Pass starts at offset %#x\n", p->start);
133
134     read_dword(ptr, &p->variable_count);
135     TRACE("Pass has %u variables\n", p->variable_count);
136
137     skip_dword_unknown(ptr, 1);
138
139     p->variables = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, p->variable_count * sizeof(*p->variables));
140     if (!p->variables)
141     {
142         ERR("Failed to allocate variables memory\n");
143         return E_OUTOFMEMORY;
144     }
145
146     for (i = 0; i < p->variable_count; ++i)
147     {
148         struct d3d10_effect_variable *v = &p->variables[i];
149
150         v->pass = p;
151
152         read_dword(ptr, &v->type);
153         TRACE("Variable %u is of type %#x\n", i, v->type);
154
155         skip_dword_unknown(ptr, 2);
156
157         read_dword(ptr, &v->idx_offset);
158         TRACE("Variable %u idx is at offset %#x\n", i, v->idx_offset);
159     }
160
161     return S_OK;
162 }
163
164 static HRESULT parse_fx10_technique_index(struct d3d10_effect_technique *t, const char **ptr)
165 {
166     HRESULT hr = S_OK;
167     unsigned int i;
168
169     read_dword(ptr, &t->start);
170     TRACE("Technique starts at offset %#x\n", t->start);
171
172     read_dword(ptr, &t->pass_count);
173     TRACE("Technique has %u passes\n", t->pass_count);
174
175     skip_dword_unknown(ptr, 1);
176
177     t->passes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, t->pass_count * sizeof(*t->passes));
178     if (!t->passes)
179     {
180         ERR("Failed to allocate passes memory\n");
181         return E_OUTOFMEMORY;
182     }
183
184     for (i = 0; i < t->pass_count; ++i)
185     {
186         struct d3d10_effect_pass *p = &t->passes[i];
187
188         p->vtbl = &d3d10_effect_pass_vtbl;
189         p->technique = t;
190
191         hr = parse_fx10_pass_index(p, ptr);
192         if (FAILED(hr)) break;
193     }
194
195     return hr;
196 }
197
198 static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
199 {
200     struct d3d10_effect_shader_variable *s = ctx;
201     char tag_str[5];
202
203     memcpy(tag_str, &tag, 4);
204     tag_str[4] = '\0';
205     TRACE("tag: %s\n", tag_str);
206
207     TRACE("chunk size: %#x\n", data_size);
208
209     switch(tag)
210     {
211         case TAG_ISGN:
212         {
213             /* 32 (DXBC header) + 1 * 4 (chunk index) + 2 * 4 (chunk header) + data_size (chunk data) */
214             UINT size = 44 + data_size;
215             char *ptr;
216
217             s->input_signature = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
218             if (!s->input_signature)
219             {
220                 ERR("Failed to allocate input signature data\n");
221                 return E_OUTOFMEMORY;
222             }
223             s->input_signature_size = size;
224
225             ptr = s->input_signature;
226
227             write_dword(&ptr, TAG_DXBC);
228
229             /* signature(?) */
230             write_dword_unknown(&ptr, 0);
231             write_dword_unknown(&ptr, 0);
232             write_dword_unknown(&ptr, 0);
233             write_dword_unknown(&ptr, 0);
234
235             /* seems to be always 1 */
236             write_dword_unknown(&ptr, 1);
237
238             /* DXBC size */
239             write_dword(&ptr, size);
240
241             /* chunk count */
242             write_dword(&ptr, 1);
243
244             /* chunk index */
245             write_dword(&ptr, (ptr - s->input_signature) + 4);
246
247             /* chunk */
248             write_dword(&ptr, TAG_ISGN);
249             write_dword(&ptr, data_size);
250             memcpy(ptr, data, data_size);
251             break;
252         }
253
254         default:
255             FIXME("Unhandled chunk %s\n", tag_str);
256             break;
257     }
258
259     return S_OK;
260 }
261
262 static HRESULT parse_shader(struct d3d10_effect_variable *v, const char *data)
263 {
264     ID3D10Device *device = v->pass->technique->effect->device;
265     struct d3d10_effect_shader_variable *s;
266     const char *ptr = data;
267     DWORD dxbc_size;
268     HRESULT hr;
269
270     v->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct d3d10_effect_shader_variable));
271     if (!v->data)
272     {
273         ERR("Failed to allocate shader variable memory\n");
274         return E_OUTOFMEMORY;
275     }
276
277     if (!ptr) return S_OK;
278
279     s = v->data;
280
281     read_dword(&ptr, &dxbc_size);
282     TRACE("dxbc size: %#x\n", dxbc_size);
283
284     switch (v->type)
285     {
286         case D3D10_EVT_VERTEXSHADER:
287             hr = ID3D10Device_CreateVertexShader(device, ptr, dxbc_size, &s->shader.vs);
288             if (FAILED(hr)) return hr;
289             break;
290
291         case D3D10_EVT_PIXELSHADER:
292             hr = ID3D10Device_CreatePixelShader(device, ptr, dxbc_size, &s->shader.ps);
293             if (FAILED(hr)) return hr;
294             break;
295         case D3D10_EVT_GEOMETRYSHADER:
296             hr = ID3D10Device_CreateGeometryShader(device, ptr, dxbc_size, &s->shader.gs);
297             if (FAILED(hr)) return hr;
298             break;
299     }
300
301     return parse_dxbc(ptr, dxbc_size, shader_chunk_handler, s);
302 }
303
304 static HRESULT parse_fx10_variable(struct d3d10_effect_variable *v, const char *data)
305 {
306     const char *ptr;
307     DWORD offset;
308     HRESULT hr;
309
310     ptr = data + v->idx_offset;
311     read_dword(&ptr, &offset);
312
313     TRACE("Variable of type %#x starts at offset %#x\n", v->type, offset);
314
315     /* FIXME: This probably isn't completely correct. */
316     if (offset == 1)
317     {
318         WARN("Skipping variable\n");
319         ptr = NULL;
320     }
321     else
322     {
323         ptr = data + offset;
324     }
325
326     switch (v->type)
327     {
328         case D3D10_EVT_VERTEXSHADER:
329             TRACE("Vertex shader\n");
330             hr = parse_shader(v, ptr);
331             break;
332
333         case D3D10_EVT_PIXELSHADER:
334             TRACE("Pixel shader\n");
335             hr = parse_shader(v, ptr);
336             break;
337
338         case D3D10_EVT_GEOMETRYSHADER:
339             TRACE("Geometry shader\n");
340             hr = parse_shader(v, ptr);
341             break;
342
343         default:
344             FIXME("Unhandled variable type %#x\n", v->type);
345             hr = E_FAIL;
346             break;
347     }
348
349     return hr;
350 }
351
352 static HRESULT parse_fx10_pass(struct d3d10_effect_pass *p, const char *data)
353 {
354     HRESULT hr = S_OK;
355     const char *ptr;
356     size_t name_len;
357     unsigned int i;
358
359     ptr = data + p->start;
360
361     name_len = strlen(ptr) + 1;
362     p->name = HeapAlloc(GetProcessHeap(), 0, name_len);
363     if (!p->name)
364     {
365         ERR("Failed to allocate name memory\n");
366         return E_OUTOFMEMORY;
367     }
368
369     memcpy(p->name, ptr, name_len);
370     ptr += name_len;
371
372     TRACE("pass name: %s\n", p->name);
373
374     for (i = 0; i < p->variable_count; ++i)
375     {
376         hr = parse_fx10_variable(&p->variables[i], data);
377         if (FAILED(hr)) break;
378     }
379
380     return hr;
381 }
382
383 static HRESULT parse_fx10_technique(struct d3d10_effect_technique *t, const char *data)
384 {
385     HRESULT hr = S_OK;
386     const char *ptr;
387     size_t name_len;
388     unsigned int i;
389
390     ptr = data + t->start;
391
392     name_len = strlen(ptr) + 1;
393     t->name = HeapAlloc(GetProcessHeap(), 0, name_len);
394     if (!t->name)
395     {
396         ERR("Failed to allocate name memory\n");
397         return E_OUTOFMEMORY;
398     }
399
400     memcpy(t->name, ptr, name_len);
401     ptr += name_len;
402
403     TRACE("technique name: %s\n", t->name);
404
405     for (i = 0; i < t->pass_count; ++i)
406     {
407         hr = parse_fx10_pass(&t->passes[i], data);
408         if (FAILED(hr)) break;
409     }
410
411     return hr;
412 }
413
414 static HRESULT parse_fx10_body(struct d3d10_effect *e, const char *data, DWORD data_size)
415 {
416     const char *ptr = data + e->index_offset;
417     HRESULT hr = S_OK;
418     unsigned int i;
419
420     skip_dword_unknown(&ptr, 6);
421
422     e->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->technique_count * sizeof(*e->techniques));
423     if (!e->techniques)
424     {
425         ERR("Failed to allocate techniques memory\n");
426         return E_OUTOFMEMORY;
427     }
428
429     for (i = 0; i < e->technique_count; ++i)
430     {
431         struct d3d10_effect_technique *t = &e->techniques[i];
432
433         t->vtbl = &d3d10_effect_technique_vtbl;
434         t->effect = e;
435
436         hr = parse_fx10_technique_index(t, &ptr);
437         if (FAILED(hr)) break;
438
439         hr = parse_fx10_technique(t, data);
440         if (FAILED(hr)) break;
441     }
442
443     return hr;
444 }
445
446 static HRESULT parse_fx10(struct d3d10_effect *e, const char *data, DWORD data_size)
447 {
448     const char *ptr = data;
449     DWORD unknown;
450
451     /* Compiled target version (e.g. fx_4_0=0xfeff1001, fx_4_1=0xfeff1011). */
452     read_dword(&ptr, &e->version);
453     TRACE("Target: %#x\n", e->version);
454
455     read_dword(&ptr, &e->localbuffers_count);
456     TRACE("Localbuffers count: %u\n", e->localbuffers_count);
457
458     /* Number of variables in local buffers? */
459     read_dword(&ptr, &unknown);
460     FIXME("Unknown 0: %u\n", unknown);
461
462     read_dword(&ptr, &e->localobjects_count);
463     TRACE("Localobjects count: %u\n", e->localobjects_count);
464
465     read_dword(&ptr, &e->sharedbuffers_count);
466     TRACE("Sharedbuffers count: %u\n", e->sharedbuffers_count);
467
468     /* Number of variables in shared buffers? */
469     read_dword(&ptr, &unknown);
470     FIXME("Unknown 1: %u\n", unknown);
471
472     read_dword(&ptr, &e->sharedobjects_count);
473     TRACE("Sharedobjects count: %u\n", e->sharedobjects_count);
474
475     read_dword(&ptr, &e->technique_count);
476     TRACE("Technique count: %u\n", e->technique_count);
477
478     read_dword(&ptr, &e->index_offset);
479     TRACE("Index offset: %#x\n", e->index_offset);
480
481     read_dword(&ptr, &unknown);
482     FIXME("Unknown 2: %u\n", unknown);
483     read_dword(&ptr, &unknown);
484     FIXME("Unknown 3: %u\n", unknown);
485
486     read_dword(&ptr, &e->dephstencilstate_count);
487     TRACE("Depthstencilstate count: %u\n", e->dephstencilstate_count);
488
489     read_dword(&ptr, &e->blendstate_count);
490     TRACE("Blendstate count: %u\n", e->blendstate_count);
491
492     read_dword(&ptr, &e->rasterizerstate_count);
493     TRACE("Rasterizerstate count: %u\n", e->rasterizerstate_count);
494
495     read_dword(&ptr, &e->samplerstate_count);
496     TRACE("Samplerstate count: %u\n", e->samplerstate_count);
497
498     read_dword(&ptr, &unknown);
499     FIXME("Unknown 4: %u\n", unknown);
500     read_dword(&ptr, &unknown);
501     FIXME("Unknown 5: %u\n", unknown);
502
503     /* Number of function calls in all passes? */
504     read_dword(&ptr, &unknown);
505     FIXME("Unknown 6: %u\n", unknown);
506     read_dword(&ptr, &unknown);
507     FIXME("Unknown 7: %u\n", unknown);
508
509     return parse_fx10_body(e, ptr, data_size - (ptr - data));
510 }
511
512 static HRESULT fx10_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
513 {
514     struct d3d10_effect *e = ctx;
515     char tag_str[5];
516
517     memcpy(tag_str, &tag, 4);
518     tag_str[4] = '\0';
519     TRACE("tag: %s\n", tag_str);
520
521     TRACE("chunk size: %#x\n", data_size);
522
523     switch(tag)
524     {
525         case TAG_FX10:
526             return parse_fx10(e, data, data_size);
527
528         default:
529             FIXME("Unhandled chunk %s\n", tag_str);
530             return S_OK;
531     }
532 }
533
534 HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T data_size)
535 {
536     return parse_dxbc(data, data_size, fx10_chunk_handler, This);
537 }
538
539 static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v)
540 {
541     TRACE("variable %p\n", v);
542
543     switch(v->type)
544     {
545         case D3D10_EVT_VERTEXSHADER:
546         case D3D10_EVT_PIXELSHADER:
547         case D3D10_EVT_GEOMETRYSHADER:
548             HeapFree(GetProcessHeap(), 0, ((struct d3d10_effect_shader_variable *)v->data)->input_signature);
549             break;
550
551         default:
552             break;
553     }
554     HeapFree(GetProcessHeap(), 0, v->data);
555 }
556
557 static HRESULT d3d10_effect_variable_apply(struct d3d10_effect_variable *v)
558 {
559     ID3D10Device *device = v->pass->technique->effect->device;
560
561     TRACE("variable %p, type %#x\n", v, v->type);
562
563     switch(v->type)
564     {
565         case D3D10_EVT_VERTEXSHADER:
566             ID3D10Device_VSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.vs);
567             return S_OK;
568
569         case D3D10_EVT_PIXELSHADER:
570             ID3D10Device_PSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.ps);
571             return S_OK;
572
573         case D3D10_EVT_GEOMETRYSHADER:
574             ID3D10Device_GSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.gs);
575             return S_OK;
576
577         default:
578             FIXME("Unhandled variable type %#x\n", v->type);
579             return E_FAIL;
580     }
581 }
582
583 static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p)
584 {
585     TRACE("pass %p\n", p);
586
587     HeapFree(GetProcessHeap(), 0, p->name);
588     if (p->variables)
589     {
590         unsigned int i;
591         for (i = 0; i < p->variable_count; ++i)
592         {
593             d3d10_effect_variable_destroy(&p->variables[i]);
594         }
595         HeapFree(GetProcessHeap(), 0, p->variables);
596     }
597 }
598
599 static void d3d10_effect_technique_destroy(struct d3d10_effect_technique *t)
600 {
601     TRACE("technique %p\n", t);
602
603     HeapFree(GetProcessHeap(), 0, t->name);
604     if (t->passes)
605     {
606         unsigned int i;
607         for (i = 0; i < t->pass_count; ++i)
608         {
609             d3d10_effect_pass_destroy(&t->passes[i]);
610         }
611         HeapFree(GetProcessHeap(), 0, t->passes);
612     }
613 }
614
615 /* IUnknown methods */
616
617 static HRESULT STDMETHODCALLTYPE d3d10_effect_QueryInterface(ID3D10Effect *iface, REFIID riid, void **object)
618 {
619     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
620
621     if (IsEqualGUID(riid, &IID_ID3D10Effect)
622             || IsEqualGUID(riid, &IID_IUnknown))
623     {
624         IUnknown_AddRef(iface);
625         *object = iface;
626         return S_OK;
627     }
628
629     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
630
631     *object = NULL;
632     return E_NOINTERFACE;
633 }
634
635 static ULONG STDMETHODCALLTYPE d3d10_effect_AddRef(ID3D10Effect *iface)
636 {
637     struct d3d10_effect *This = (struct d3d10_effect *)iface;
638     ULONG refcount = InterlockedIncrement(&This->refcount);
639
640     TRACE("%p increasing refcount to %u\n", This, refcount);
641
642     return refcount;
643 }
644
645 static ULONG STDMETHODCALLTYPE d3d10_effect_Release(ID3D10Effect *iface)
646 {
647     struct d3d10_effect *This = (struct d3d10_effect *)iface;
648     ULONG refcount = InterlockedDecrement(&This->refcount);
649
650     TRACE("%p decreasing refcount to %u\n", This, refcount);
651
652     if (!refcount)
653     {
654         if (This->techniques)
655         {
656             unsigned int i;
657             for (i = 0; i < This->technique_count; ++i)
658             {
659                 d3d10_effect_technique_destroy(&This->techniques[i]);
660             }
661             HeapFree(GetProcessHeap(), 0, This->techniques);
662         }
663         ID3D10Device_Release(This->device);
664         HeapFree(GetProcessHeap(), 0, This);
665     }
666
667     return refcount;
668 }
669
670 /* ID3D10Effect methods */
671
672 static BOOL STDMETHODCALLTYPE d3d10_effect_IsValid(ID3D10Effect *iface)
673 {
674     FIXME("iface %p stub!\n", iface);
675
676     return FALSE;
677 }
678
679 static BOOL STDMETHODCALLTYPE d3d10_effect_IsPool(ID3D10Effect *iface)
680 {
681     FIXME("iface %p stub!\n", iface);
682
683     return FALSE;
684 }
685
686 static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDevice(ID3D10Effect *iface, ID3D10Device **device)
687 {
688     struct d3d10_effect *This = (struct d3d10_effect *)iface;
689
690     TRACE("iface %p, device %p\n", iface, device);
691
692     ID3D10Device_AddRef(This->device);
693     *device = This->device;
694
695     return S_OK;
696 }
697
698 static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDesc(ID3D10Effect *iface, D3D10_EFFECT_DESC *desc)
699 {
700     FIXME("iface %p, desc %p stub!\n", iface, desc);
701
702     return E_NOTIMPL;
703 }
704
705 static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_GetConstantBufferByIndex(ID3D10Effect *iface,
706         UINT index)
707 {
708     FIXME("iface %p, index %u stub!\n", iface, index);
709
710     return NULL;
711 }
712
713 static struct ID3D10EffectConstantBuffer * STDMETHODCALLTYPE d3d10_effect_GetConstantBufferByName(ID3D10Effect *iface,
714         LPCSTR name)
715 {
716     FIXME("iface %p, name \"%s\" stub!\n", iface, name);
717
718     return NULL;
719 }
720
721 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_GetVariableByIndex(ID3D10Effect *iface, UINT index)
722 {
723     FIXME("iface %p, index %u stub!\n", iface, index);
724
725     return NULL;
726 }
727
728 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_GetVariableByName(ID3D10Effect *iface, LPCSTR name)
729 {
730     FIXME("iface %p, name \"%s\" stub!\n", iface, name);
731
732     return NULL;
733 }
734
735 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_GetVariableBySemantic(ID3D10Effect *iface,
736         LPCSTR semantic)
737 {
738     FIXME("iface %p, semantic \"%s\" stub!\n", iface, semantic);
739
740     return NULL;
741 }
742
743 static struct ID3D10EffectTechnique * STDMETHODCALLTYPE d3d10_effect_GetTechniqueByIndex(ID3D10Effect *iface,
744         UINT index)
745 {
746     struct d3d10_effect *This = (struct d3d10_effect *)iface;
747     struct d3d10_effect_technique *t;
748
749     TRACE("iface %p, index %u\n", iface, index);
750
751     if (index >= This->technique_count)
752     {
753         WARN("Invalid index specified\n");
754         return NULL;
755     }
756
757     t = &This->techniques[index];
758
759     TRACE("Returning technique %p, \"%s\"\n", t, t->name);
760
761     return (ID3D10EffectTechnique *)t;
762 }
763
764 static struct ID3D10EffectTechnique * STDMETHODCALLTYPE d3d10_effect_GetTechniqueByName(ID3D10Effect *iface,
765         LPCSTR name)
766 {
767     struct d3d10_effect *This = (struct d3d10_effect *)iface;
768     unsigned int i;
769
770     TRACE("iface %p, name \"%s\"\n", iface, name);
771
772     for (i = 0; i < This->technique_count; ++i)
773     {
774         struct d3d10_effect_technique *t = &This->techniques[i];
775         if (!strcmp(t->name, name))
776         {
777             TRACE("Returning technique %p\n", t);
778             return (ID3D10EffectTechnique *)t;
779         }
780     }
781
782     return NULL;
783 }
784
785 static HRESULT STDMETHODCALLTYPE d3d10_effect_Optimize(ID3D10Effect *iface)
786 {
787     FIXME("iface %p stub!\n", iface);
788
789     return E_NOTIMPL;
790 }
791
792 static BOOL STDMETHODCALLTYPE d3d10_effect_IsOptimized(ID3D10Effect *iface)
793 {
794     FIXME("iface %p stub!\n", iface);
795
796     return FALSE;
797 }
798
799 const struct ID3D10EffectVtbl d3d10_effect_vtbl =
800 {
801     /* IUnknown methods */
802     d3d10_effect_QueryInterface,
803     d3d10_effect_AddRef,
804     d3d10_effect_Release,
805     /* ID3D10Effect methods */
806     d3d10_effect_IsValid,
807     d3d10_effect_IsPool,
808     d3d10_effect_GetDevice,
809     d3d10_effect_GetDesc,
810     d3d10_effect_GetConstantBufferByIndex,
811     d3d10_effect_GetConstantBufferByName,
812     d3d10_effect_GetVariableByIndex,
813     d3d10_effect_GetVariableByName,
814     d3d10_effect_GetVariableBySemantic,
815     d3d10_effect_GetTechniqueByIndex,
816     d3d10_effect_GetTechniqueByName,
817     d3d10_effect_Optimize,
818     d3d10_effect_IsOptimized,
819 };
820
821 /* ID3D10EffectTechnique methods */
822
823 static BOOL STDMETHODCALLTYPE d3d10_effect_technique_IsValid(ID3D10EffectTechnique *iface)
824 {
825     FIXME("iface %p stub!\n", iface);
826
827     return FALSE;
828 }
829
830 static HRESULT STDMETHODCALLTYPE d3d10_effect_technique_GetDesc(ID3D10EffectTechnique *iface,
831         D3D10_TECHNIQUE_DESC *desc)
832 {
833     struct d3d10_effect_technique *This = (struct d3d10_effect_technique *)iface;
834
835     TRACE("iface %p, desc %p\n", iface, desc);
836
837     desc->Name = This->name;
838     desc->Passes = This->pass_count;
839     WARN("Annotations not implemented\n");
840     desc->Annotations = 0;
841
842     return S_OK;
843 }
844
845 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_technique_GetAnnotationByIndex(
846         ID3D10EffectTechnique *iface, UINT index)
847 {
848     FIXME("iface %p, index %u stub!\n", iface, index);
849
850     return NULL;
851 }
852
853 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_technique_GetAnnotationByName(
854         ID3D10EffectTechnique *iface, LPCSTR name)
855 {
856     FIXME("iface %p, name \"%s\" stub!\n", iface, name);
857
858     return NULL;
859 }
860
861 static struct ID3D10EffectPass * STDMETHODCALLTYPE d3d10_effect_technique_GetPassByIndex(ID3D10EffectTechnique *iface,
862         UINT index)
863 {
864     struct d3d10_effect_technique *This = (struct d3d10_effect_technique *)iface;
865     struct d3d10_effect_pass *p;
866
867     TRACE("iface %p, index %u\n", iface, index);
868
869     if (index >= This->pass_count)
870     {
871         WARN("Invalid index specified\n");
872         return NULL;
873     }
874
875     p = &This->passes[index];
876
877     TRACE("Returning pass %p, \"%s\"\n", p, p->name);
878
879     return (ID3D10EffectPass *)p;
880 }
881
882 static struct ID3D10EffectPass * STDMETHODCALLTYPE d3d10_effect_technique_GetPassByName(ID3D10EffectTechnique *iface,
883         LPCSTR name)
884 {
885     struct d3d10_effect_technique *This = (struct d3d10_effect_technique *)iface;
886     unsigned int i;
887
888     TRACE("iface %p, name \"%s\"\n", iface, name);
889
890     for (i = 0; i < This->pass_count; ++i)
891     {
892         struct d3d10_effect_pass *p = &This->passes[i];
893         if (!strcmp(p->name, name))
894         {
895             TRACE("Returning pass %p\n", p);
896             return (ID3D10EffectPass *)p;
897         }
898     }
899
900     return NULL;
901 }
902
903 static HRESULT STDMETHODCALLTYPE d3d10_effect_technique_ComputeStateBlockMask(ID3D10EffectTechnique *iface,
904         D3D10_STATE_BLOCK_MASK *mask)
905 {
906     FIXME("iface %p,mask %p stub!\n", iface, mask);
907
908     return E_NOTIMPL;
909 }
910
911 static const struct ID3D10EffectTechniqueVtbl d3d10_effect_technique_vtbl =
912 {
913     /* ID3D10EffectTechnique methods */
914     d3d10_effect_technique_IsValid,
915     d3d10_effect_technique_GetDesc,
916     d3d10_effect_technique_GetAnnotationByIndex,
917     d3d10_effect_technique_GetAnnotationByName,
918     d3d10_effect_technique_GetPassByIndex,
919     d3d10_effect_technique_GetPassByName,
920     d3d10_effect_technique_ComputeStateBlockMask,
921 };
922
923 /* ID3D10EffectPass methods */
924
925 static BOOL STDMETHODCALLTYPE d3d10_effect_pass_IsValid(ID3D10EffectPass *iface)
926 {
927     FIXME("iface %p stub!\n", iface);
928
929     return FALSE;
930 }
931
932 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *iface, D3D10_PASS_DESC *desc)
933 {
934     struct d3d10_effect_pass *This = (struct d3d10_effect_pass *)iface;
935     unsigned int i;
936
937     FIXME("iface %p, desc %p partial stub!\n", iface, desc);
938
939     memset(desc, 0, sizeof(*desc));
940     desc->Name = This->name;
941     for (i = 0; i < This->variable_count; ++i)
942     {
943         struct d3d10_effect_variable *v = &This->variables[i];
944         if (v->type == D3D10_EVT_VERTEXSHADER)
945         {
946             struct d3d10_effect_shader_variable *s = v->data;
947             desc->pIAInputSignature = (BYTE *)s->input_signature;
948             desc->IAInputSignatureSize = s->input_signature_size;
949             break;
950         }
951     }
952
953     return S_OK;
954 }
955
956 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10EffectPass *iface,
957         D3D10_PASS_SHADER_DESC *desc)
958 {
959     FIXME("iface %p, desc %p stub!\n", iface, desc);
960
961     return E_NOTIMPL;
962 }
963
964 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10EffectPass *iface,
965         D3D10_PASS_SHADER_DESC *desc)
966 {
967     FIXME("iface %p, desc %p stub!\n", iface, desc);
968
969     return E_NOTIMPL;
970 }
971
972 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetPixelShaderDesc(ID3D10EffectPass *iface,
973         D3D10_PASS_SHADER_DESC *desc)
974 {
975     FIXME("iface %p, desc %p stub!\n", iface, desc);
976
977     return E_NOTIMPL;
978 }
979
980 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_pass_GetAnnotationByIndex(ID3D10EffectPass *iface,
981         UINT index)
982 {
983     FIXME("iface %p, index %u stub!\n", iface, index);
984
985     return NULL;
986 }
987
988 static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_pass_GetAnnotationByName(ID3D10EffectPass *iface,
989         LPCSTR name)
990 {
991     FIXME("iface %p, name \"%s\" stub!\n", iface, name);
992
993     return NULL;
994 }
995
996 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags)
997 {
998     struct d3d10_effect_pass *This = (struct d3d10_effect_pass *)iface;
999     HRESULT hr = S_OK;
1000     unsigned int i;
1001
1002     TRACE("iface %p, flags %#x\n", iface, flags);
1003
1004     if (flags) FIXME("Ignoring flags (%#x)\n", flags);
1005
1006     for (i = 0; i < This->variable_count; ++i)
1007     {
1008         hr = d3d10_effect_variable_apply(&This->variables[i]);
1009         if (FAILED(hr)) break;
1010     }
1011
1012     return hr;
1013 }
1014
1015 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_ComputeStateBlockMask(ID3D10EffectPass *iface,
1016         D3D10_STATE_BLOCK_MASK *mask)
1017 {
1018     FIXME("iface %p, mask %p stub!\n", iface, mask);
1019
1020     return E_NOTIMPL;
1021 }
1022
1023 static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl =
1024 {
1025     /* ID3D10EffectPass methods */
1026     d3d10_effect_pass_IsValid,
1027     d3d10_effect_pass_GetDesc,
1028     d3d10_effect_pass_GetVertexShaderDesc,
1029     d3d10_effect_pass_GetGeometryShaderDesc,
1030     d3d10_effect_pass_GetPixelShaderDesc,
1031     d3d10_effect_pass_GetAnnotationByIndex,
1032     d3d10_effect_pass_GetAnnotationByName,
1033     d3d10_effect_pass_Apply,
1034     d3d10_effect_pass_ComputeStateBlockMask,
1035 };