dbghelp: Local variable used out of scope (Coverity).
[wine] / dlls / d3dcompiler_43 / reflection.c
1 /*
2  * Copyright 2009 Henri Verbeet for CodeWeavers
3  * Copyright 2010 Rico Schüller
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  *
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include "d3dcompiler_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
27
28 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE
29 {
30     D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6 = 6,
31     D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7 = 7,
32 };
33
34 #define D3DCOMPILER_SHADER_TARGET_VERSION_MASK 0xffff
35 #define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK 0xffff0000
36
37 struct d3dcompiler_shader_signature
38 {
39     D3D11_SIGNATURE_PARAMETER_DESC *elements;
40     UINT element_count;
41     char *string_data;
42 };
43
44 struct d3dcompiler_shader_reflection_type
45 {
46     ID3D11ShaderReflectionType ID3D11ShaderReflectionType_iface;
47
48     DWORD id;
49     struct wine_rb_entry entry;
50
51     struct d3dcompiler_shader_reflection *reflection;
52
53     D3D11_SHADER_TYPE_DESC desc;
54     struct d3dcompiler_shader_reflection_type_member *members;
55 };
56
57 struct d3dcompiler_shader_reflection_type_member
58 {
59     char *name;
60     DWORD offset;
61     struct d3dcompiler_shader_reflection_type *type;
62 };
63
64 struct d3dcompiler_shader_reflection_variable
65 {
66     ID3D11ShaderReflectionVariable ID3D11ShaderReflectionVariable_iface;
67
68     struct d3dcompiler_shader_reflection_constant_buffer *constant_buffer;
69     struct d3dcompiler_shader_reflection_type *type;
70
71     char *name;
72     UINT start_offset;
73     UINT size;
74     UINT flags;
75     LPVOID default_value;
76 };
77
78 struct d3dcompiler_shader_reflection_constant_buffer
79 {
80     ID3D11ShaderReflectionConstantBuffer ID3D11ShaderReflectionConstantBuffer_iface;
81
82     struct d3dcompiler_shader_reflection *reflection;
83
84     char *name;
85     D3D_CBUFFER_TYPE type;
86     UINT variable_count;
87     UINT size;
88     UINT flags;
89
90     struct d3dcompiler_shader_reflection_variable *variables;
91 };
92
93 /* ID3D11ShaderReflection */
94 struct d3dcompiler_shader_reflection
95 {
96     ID3D11ShaderReflection ID3D11ShaderReflection_iface;
97     LONG refcount;
98
99     DWORD target;
100     char *creator;
101     UINT flags;
102     UINT version;
103     UINT bound_resource_count;
104     UINT constant_buffer_count;
105
106     UINT mov_instruction_count;
107     UINT conversion_instruction_count;
108     UINT instruction_count;
109     UINT emit_instruction_count;
110     D3D_PRIMITIVE_TOPOLOGY gs_output_topology;
111     UINT gs_max_output_vertex_count;
112     D3D_PRIMITIVE input_primitive;
113     UINT cut_instruction_count;
114     UINT dcl_count;
115     UINT static_flow_control_count;
116     UINT float_instruction_count;
117     UINT temp_register_count;
118     UINT int_instruction_count;
119     UINT uint_instruction_count;
120     UINT temp_array_count;
121     UINT array_instruction_count;
122     UINT texture_normal_instructions;
123     UINT texture_load_instructions;
124     UINT texture_comp_instructions;
125     UINT texture_bias_instructions;
126     UINT texture_gradient_instructions;
127     UINT dynamic_flow_control_count;
128     UINT c_control_points;
129     D3D_TESSELLATOR_OUTPUT_PRIMITIVE hs_output_primitive;
130     D3D_TESSELLATOR_PARTITIONING hs_prtitioning;
131     D3D_TESSELLATOR_DOMAIN tessellator_domain;
132
133     struct d3dcompiler_shader_signature *isgn;
134     struct d3dcompiler_shader_signature *osgn;
135     struct d3dcompiler_shader_signature *pcsg;
136     char *resource_string;
137     D3D11_SHADER_INPUT_BIND_DESC *bound_resources;
138     struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers;
139     struct wine_rb_tree types;
140 };
141
142 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, DWORD offset);
143
144 const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl;
145 const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl;
146 const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl;
147
148 /* null objects - needed for invalid calls */
149 static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer = {{&d3dcompiler_shader_reflection_constant_buffer_vtbl}};
150 static struct d3dcompiler_shader_reflection_type null_type = {{&d3dcompiler_shader_reflection_type_vtbl}};
151 static struct d3dcompiler_shader_reflection_variable null_variable = {{&d3dcompiler_shader_reflection_variable_vtbl},
152     &null_constant_buffer, &null_type};
153
154 static BOOL copy_name(const char *ptr, char **name)
155 {
156     size_t name_len;
157
158     if (!ptr) return TRUE;
159
160     name_len = strlen(ptr) + 1;
161     if (name_len == 1)
162     {
163         return TRUE;
164     }
165
166     *name = HeapAlloc(GetProcessHeap(), 0, name_len);
167     if (!*name)
168     {
169         ERR("Failed to allocate name memory.\n");
170         return FALSE;
171     }
172
173     memcpy(*name, ptr, name_len);
174
175     return TRUE;
176 }
177
178 static BOOL copy_value(const char *ptr, void **value, DWORD size)
179 {
180     if (!ptr || !size) return TRUE;
181
182     *value = HeapAlloc(GetProcessHeap(), 0, size);
183     if (!*value)
184     {
185         ERR("Failed to allocate vlaue memory.\n");
186         return FALSE;
187     }
188
189     memcpy(*value, ptr, size);
190
191     return TRUE;
192 }
193
194 static void *d3dcompiler_rb_alloc(size_t size)
195 {
196     return HeapAlloc(GetProcessHeap(), 0, size);
197 }
198
199 static void *d3dcompiler_rb_realloc(void *ptr, size_t size)
200 {
201     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
202 }
203
204 static void d3dcompiler_rb_free(void *ptr)
205 {
206     HeapFree(GetProcessHeap(), 0, ptr);
207 }
208
209 static int d3dcompiler_shader_reflection_type_compare(const void *key, const struct wine_rb_entry *entry)
210 {
211     const struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, const struct d3dcompiler_shader_reflection_type, entry);
212     const DWORD *id = key;
213
214     return *id - t->id;
215 }
216
217 static void free_type_member(struct d3dcompiler_shader_reflection_type_member *member)
218 {
219     if (member)
220     {
221         HeapFree(GetProcessHeap(), 0, member->name);
222     }
223 }
224
225 static void d3dcompiler_shader_reflection_type_destroy(struct wine_rb_entry *entry, void *context)
226 {
227     struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry);
228     unsigned int i;
229
230     TRACE("reflection type %p.\n", t);
231
232     if (t->members)
233     {
234         for (i = 0; i < t->desc.Members; ++i)
235         {
236             free_type_member(&t->members[i]);
237         }
238     }
239
240     HeapFree(GetProcessHeap(), 0, t);
241 }
242
243 static const struct wine_rb_functions d3dcompiler_shader_reflection_type_rb_functions =
244 {
245     d3dcompiler_rb_alloc,
246     d3dcompiler_rb_realloc,
247     d3dcompiler_rb_free,
248     d3dcompiler_shader_reflection_type_compare,
249 };
250
251 static void free_signature(struct d3dcompiler_shader_signature *sig)
252 {
253     TRACE("Free signature %p\n", sig);
254
255     HeapFree(GetProcessHeap(), 0, sig->elements);
256     HeapFree(GetProcessHeap(), 0, sig->string_data);
257 }
258
259 static void free_variable(struct d3dcompiler_shader_reflection_variable *var)
260 {
261     if (var)
262     {
263         HeapFree(GetProcessHeap(), 0, var->name);
264         HeapFree(GetProcessHeap(), 0, var->default_value);
265     }
266 }
267
268 static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb)
269 {
270     if (cb->variables)
271     {
272         unsigned int i;
273
274         for (i = 0; i < cb->variable_count; ++i)
275         {
276             free_variable(&cb->variables[i]);
277         }
278         HeapFree(GetProcessHeap(), 0, cb->variables);
279     }
280
281     HeapFree(GetProcessHeap(), 0, cb->name);
282 }
283
284 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref)
285 {
286     TRACE("Cleanup %p\n", ref);
287
288     if (ref->isgn)
289     {
290         free_signature(ref->isgn);
291         HeapFree(GetProcessHeap(), 0, ref->isgn);
292     }
293
294     if (ref->osgn)
295     {
296         free_signature(ref->osgn);
297         HeapFree(GetProcessHeap(), 0, ref->osgn);
298     }
299
300     if (ref->pcsg)
301     {
302         free_signature(ref->pcsg);
303         HeapFree(GetProcessHeap(), 0, ref->pcsg);
304     }
305
306     if (ref->constant_buffers)
307     {
308         unsigned int i;
309
310         for (i = 0; i < ref->constant_buffer_count; ++i)
311         {
312             free_constant_buffer(&ref->constant_buffers[i]);
313         }
314     }
315
316     wine_rb_destroy(&ref->types, d3dcompiler_shader_reflection_type_destroy, NULL);
317     HeapFree(GetProcessHeap(), 0, ref->constant_buffers);
318     HeapFree(GetProcessHeap(), 0, ref->bound_resources);
319     HeapFree(GetProcessHeap(), 0, ref->resource_string);
320     HeapFree(GetProcessHeap(), 0, ref->creator);
321 }
322
323 /* IUnknown methods */
324
325 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
326 {
327     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
328 }
329
330 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
331 {
332     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
333
334     if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
335             || IsEqualGUID(riid, &IID_IUnknown))
336     {
337         IUnknown_AddRef(iface);
338         *object = iface;
339         return S_OK;
340     }
341
342     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
343
344     *object = NULL;
345     return E_NOINTERFACE;
346 }
347
348 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
349 {
350     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
351     ULONG refcount = InterlockedIncrement(&This->refcount);
352
353     TRACE("%p increasing refcount to %u\n", This, refcount);
354
355     return refcount;
356 }
357
358 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
359 {
360     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
361     ULONG refcount = InterlockedDecrement(&This->refcount);
362
363     TRACE("%p decreasing refcount to %u\n", This, refcount);
364
365     if (!refcount)
366     {
367         reflection_cleanup(This);
368         HeapFree(GetProcessHeap(), 0, This);
369     }
370
371     return refcount;
372 }
373
374 /* ID3D11ShaderReflection methods */
375
376 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
377 {
378     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
379
380     FIXME("iface %p, desc %p partial stub!\n", iface, desc);
381
382     if (!desc)
383     {
384         WARN("Invalid argument specified\n");
385         return E_FAIL;
386     }
387
388     desc->Version = This->version;
389     desc->Creator = This->creator;
390     desc->Flags = This->flags;
391     desc->ConstantBuffers = This->constant_buffer_count;
392     desc->BoundResources = This->bound_resource_count;
393     desc->InputParameters = This->isgn ? This->isgn->element_count : 0;
394     desc->OutputParameters = This->osgn ? This->osgn->element_count : 0;
395     desc->InstructionCount = This->instruction_count;
396     desc->TempRegisterCount = This->temp_register_count;
397     desc->TempArrayCount = This->temp_array_count;
398     desc->DefCount = 0;
399     desc->DclCount = This->dcl_count;
400     desc->TextureNormalInstructions = This->texture_normal_instructions;
401     desc->TextureLoadInstructions = This->texture_load_instructions;
402     desc->TextureCompInstructions = This->texture_comp_instructions;
403     desc->TextureBiasInstructions = This->texture_bias_instructions;
404     desc->TextureGradientInstructions = This->texture_gradient_instructions;
405     desc->FloatInstructionCount = This->float_instruction_count;
406     desc->IntInstructionCount = This->int_instruction_count;
407     desc->UintInstructionCount = This->uint_instruction_count;
408     desc->StaticFlowControlCount = This->static_flow_control_count;
409     desc->DynamicFlowControlCount = This->dynamic_flow_control_count;
410     desc->MacroInstructionCount = 0;
411     desc->ArrayInstructionCount = This->array_instruction_count;
412     desc->CutInstructionCount = This->cut_instruction_count;
413     desc->EmitInstructionCount = This->emit_instruction_count;
414     desc->GSOutputTopology = This->gs_output_topology;
415     desc->GSMaxOutputVertexCount = This->gs_max_output_vertex_count;
416     desc->InputPrimitive = This->input_primitive;
417     desc->PatchConstantParameters = This->pcsg ? This->pcsg->element_count : 0;
418     desc->cGSInstanceCount = 0;
419     desc->cControlPoints = This->c_control_points;
420     desc->HSOutputPrimitive = This->hs_output_primitive;
421     desc->HSPartitioning = This->hs_prtitioning;
422     desc->TessellatorDomain = This->tessellator_domain;
423     desc->cBarrierInstructions = 0;
424     desc->cInterlockedInstructions = 0;
425     desc->cTextureStoreInstructions = 0;
426
427     return S_OK;
428 }
429
430 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
431         ID3D11ShaderReflection *iface, UINT index)
432 {
433     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
434
435     TRACE("iface %p, index %u\n", iface, index);
436
437     if (index >= This->constant_buffer_count)
438     {
439         WARN("Invalid argument specified\n");
440         return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
441     }
442
443     return &This->constant_buffers[index].ID3D11ShaderReflectionConstantBuffer_iface;
444 }
445
446 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
447         ID3D11ShaderReflection *iface, LPCSTR name)
448 {
449     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
450     unsigned int i;
451
452     TRACE("iface %p, name %s\n", iface, debugstr_a(name));
453
454     if (!name)
455     {
456         WARN("Invalid argument specified\n");
457         return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
458     }
459
460     for (i = 0; i < This->constant_buffer_count; ++i)
461     {
462         struct d3dcompiler_shader_reflection_constant_buffer *d = &This->constant_buffers[i];
463
464         if (!strcmp(d->name, name))
465         {
466             TRACE("Returning ID3D11ShaderReflectionConstantBuffer %p.\n", d);
467             return &d->ID3D11ShaderReflectionConstantBuffer_iface;
468         }
469     }
470
471     WARN("Invalid name specified\n");
472
473     return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
474 }
475
476 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
477         ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
478 {
479     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
480
481     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
482
483     if (!desc || index >= This->bound_resource_count)
484     {
485         WARN("Invalid argument specified\n");
486         return E_INVALIDARG;
487     }
488
489     *desc = This->bound_resources[index];
490
491     return S_OK;
492 }
493
494 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
495         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
496 {
497     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
498
499     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
500
501     if (!desc || !This->isgn || index >= This->isgn->element_count)
502     {
503         WARN("Invalid argument specified\n");
504         return E_INVALIDARG;
505     }
506
507     *desc = This->isgn->elements[index];
508
509     return S_OK;
510 }
511
512 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
513         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
514 {
515     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
516
517     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
518
519     if (!desc || !This->osgn || index >= This->osgn->element_count)
520     {
521         WARN("Invalid argument specified\n");
522         return E_INVALIDARG;
523     }
524
525     *desc = This->osgn->elements[index];
526
527     return S_OK;
528 }
529
530 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
531         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
532 {
533     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
534
535     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
536
537     if (!desc || !This->pcsg || index >= This->pcsg->element_count)
538     {
539         WARN("Invalid argument specified\n");
540         return E_INVALIDARG;
541     }
542
543     *desc = This->pcsg->elements[index];
544
545     return S_OK;
546 }
547
548 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
549         ID3D11ShaderReflection *iface, LPCSTR name)
550 {
551     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
552     unsigned int i, k;
553
554     TRACE("iface %p, name %s\n", iface, debugstr_a(name));
555
556     if (!name)
557     {
558         WARN("Invalid name specified\n");
559         return &null_variable.ID3D11ShaderReflectionVariable_iface;
560     }
561
562     for (i = 0; i < This->constant_buffer_count; ++i)
563     {
564         struct d3dcompiler_shader_reflection_constant_buffer *cb = &This->constant_buffers[i];
565
566         for (k = 0; k < cb->variable_count; ++k)
567         {
568             struct d3dcompiler_shader_reflection_variable *v = &cb->variables[k];
569
570             if (!strcmp(v->name, name))
571             {
572                 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v);
573                 return &v->ID3D11ShaderReflectionVariable_iface;
574             }
575         }
576     }
577
578     WARN("Invalid name specified\n");
579
580     return &null_variable.ID3D11ShaderReflectionVariable_iface;
581 }
582
583 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
584         ID3D11ShaderReflection *iface, LPCSTR name, D3D11_SHADER_INPUT_BIND_DESC *desc)
585 {
586     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
587     unsigned int i;
588
589     TRACE("iface %p, name %s, desc %p\n", iface, debugstr_a(name), desc);
590
591     if (!desc || !name)
592     {
593         WARN("Invalid argument specified\n");
594         return E_INVALIDARG;
595     }
596
597     for (i = 0; i < This->bound_resource_count; ++i)
598     {
599         D3D11_SHADER_INPUT_BIND_DESC *d = &This->bound_resources[i];
600
601         if (!strcmp(d->Name, name))
602         {
603             TRACE("Returning D3D11_SHADER_INPUT_BIND_DESC %p.\n", d);
604             *desc = *d;
605             return S_OK;
606         }
607     }
608
609     WARN("Invalid name specified\n");
610
611     return E_INVALIDARG;
612 }
613
614 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
615         ID3D11ShaderReflection *iface)
616 {
617     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
618
619     TRACE("iface %p\n", iface);
620
621     return This->mov_instruction_count;
622 }
623
624 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
625         ID3D11ShaderReflection *iface)
626 {
627     FIXME("iface %p stub!\n", iface);
628
629     return 0;
630 }
631
632 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
633         ID3D11ShaderReflection *iface)
634 {
635     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
636
637     TRACE("iface %p\n", iface);
638
639     return This->conversion_instruction_count;
640 }
641
642 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
643         ID3D11ShaderReflection *iface)
644 {
645     FIXME("iface %p stub!\n", iface);
646
647     return 0;
648 }
649
650 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
651         ID3D11ShaderReflection *iface)
652 {
653     FIXME("iface %p stub!\n", iface);
654
655     return 0;
656 }
657
658 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
659         ID3D11ShaderReflection *iface)
660 {
661     FIXME("iface %p stub!\n", iface);
662
663     return 0;
664 }
665
666 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
667         ID3D11ShaderReflection *iface)
668 {
669     FIXME("iface %p stub!\n", iface);
670
671     return 0;
672 }
673
674 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
675         ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
676 {
677     FIXME("iface %p, level %p stub!\n", iface, level);
678
679     return E_NOTIMPL;
680 }
681
682 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize(
683         ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez)
684 {
685     FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez);
686
687     return 0;
688 }
689
690 const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
691 {
692     /* IUnknown methods */
693     d3dcompiler_shader_reflection_QueryInterface,
694     d3dcompiler_shader_reflection_AddRef,
695     d3dcompiler_shader_reflection_Release,
696     /* ID3D11ShaderReflection methods */
697     d3dcompiler_shader_reflection_GetDesc,
698     d3dcompiler_shader_reflection_GetConstantBufferByIndex,
699     d3dcompiler_shader_reflection_GetConstantBufferByName,
700     d3dcompiler_shader_reflection_GetResourceBindingDesc,
701     d3dcompiler_shader_reflection_GetInputParameterDesc,
702     d3dcompiler_shader_reflection_GetOutputParameterDesc,
703     d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
704     d3dcompiler_shader_reflection_GetVariableByName,
705     d3dcompiler_shader_reflection_GetResourceBindingDescByName,
706     d3dcompiler_shader_reflection_GetMovInstructionCount,
707     d3dcompiler_shader_reflection_GetMovcInstructionCount,
708     d3dcompiler_shader_reflection_GetConversionInstructionCount,
709     d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
710     d3dcompiler_shader_reflection_GetGSInputPrimitive,
711     d3dcompiler_shader_reflection_IsSampleFrequencyShader,
712     d3dcompiler_shader_reflection_GetNumInterfaceSlots,
713     d3dcompiler_shader_reflection_GetMinFeatureLevel,
714     d3dcompiler_shader_reflection_GetThreadGroupSize,
715 };
716
717 /* ID3D11ShaderReflectionConstantBuffer methods */
718
719 static inline struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D11ShaderReflectionConstantBuffer *iface)
720 {
721     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D11ShaderReflectionConstantBuffer_iface);
722 }
723
724 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc(
725         ID3D11ShaderReflectionConstantBuffer *iface, D3D11_SHADER_BUFFER_DESC *desc)
726 {
727     struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
728
729     TRACE("iface %p, desc %p\n", iface, desc);
730
731     if (This == &null_constant_buffer)
732     {
733         WARN("Null constant buffer specified\n");
734         return E_FAIL;
735     }
736
737     if (!desc)
738     {
739         WARN("Invalid argument specified\n");
740         return E_FAIL;
741     }
742
743     desc->Name = This->name;
744     desc->Type = This->type;
745     desc->Variables = This->variable_count;
746     desc->Size = This->size;
747     desc->uFlags = This->flags;
748
749     return S_OK;
750 }
751
752 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex(
753         ID3D11ShaderReflectionConstantBuffer *iface, UINT index)
754 {
755     struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
756
757     TRACE("iface %p, index %u\n", iface, index);
758
759     if (index >= This->variable_count)
760     {
761         WARN("Invalid index specified\n");
762         return &null_variable.ID3D11ShaderReflectionVariable_iface;
763     }
764
765     return &This->variables[index].ID3D11ShaderReflectionVariable_iface;
766 }
767
768 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName(
769         ID3D11ShaderReflectionConstantBuffer *iface, LPCSTR name)
770 {
771     struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
772     unsigned int i;
773
774     TRACE("iface %p, name %s\n", iface, debugstr_a(name));
775
776     if (!name)
777     {
778         WARN("Invalid argument specified\n");
779         return &null_variable.ID3D11ShaderReflectionVariable_iface;
780     }
781
782     for (i = 0; i < This->variable_count; ++i)
783     {
784         struct d3dcompiler_shader_reflection_variable *v = &This->variables[i];
785
786         if (!strcmp(v->name, name))
787         {
788             TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v);
789             return &v->ID3D11ShaderReflectionVariable_iface;
790         }
791     }
792
793     WARN("Invalid name specified\n");
794
795     return &null_variable.ID3D11ShaderReflectionVariable_iface;
796 }
797
798 const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl =
799 {
800     /* ID3D11ShaderReflectionConstantBuffer methods */
801     d3dcompiler_shader_reflection_constant_buffer_GetDesc,
802     d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex,
803     d3dcompiler_shader_reflection_constant_buffer_GetVariableByName,
804 };
805
806 /* ID3D11ShaderReflectionVariable methods */
807
808 static inline struct d3dcompiler_shader_reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D11ShaderReflectionVariable *iface)
809 {
810     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_variable, ID3D11ShaderReflectionVariable_iface);
811 }
812
813 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc(
814         ID3D11ShaderReflectionVariable *iface, D3D11_SHADER_VARIABLE_DESC *desc)
815 {
816     struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
817
818     TRACE("iface %p, desc %p\n", iface, desc);
819
820     if (This == &null_variable)
821     {
822         WARN("Null variable specified\n");
823         return E_FAIL;
824     }
825
826     if (!desc)
827     {
828         WARN("Invalid argument specified\n");
829         return E_FAIL;
830     }
831
832     desc->Name = This->name;
833     desc->StartOffset = This->start_offset;
834     desc->Size = This->size;
835     desc->uFlags = This->flags;
836     desc->DefaultValue = This->default_value;
837
838     return S_OK;
839 }
840
841 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType(
842         ID3D11ShaderReflectionVariable *iface)
843 {
844     struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
845
846     TRACE("iface %p\n", iface);
847
848     return &This->type->ID3D11ShaderReflectionType_iface;
849 }
850
851 static ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer(
852         ID3D11ShaderReflectionVariable *iface)
853 {
854     struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
855
856     TRACE("iface %p\n", iface);
857
858     return &This->constant_buffer->ID3D11ShaderReflectionConstantBuffer_iface;
859 }
860
861 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot(
862         ID3D11ShaderReflectionVariable *iface, UINT index)
863 {
864     FIXME("iface %p, index %u stub!\n", iface, index);
865
866     return 0;
867 }
868
869 const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl =
870 {
871     /* ID3D11ShaderReflectionVariable methods */
872     d3dcompiler_shader_reflection_variable_GetDesc,
873     d3dcompiler_shader_reflection_variable_GetType,
874     d3dcompiler_shader_reflection_variable_GetBuffer,
875     d3dcompiler_shader_reflection_variable_GetInterfaceSlot,
876 };
877
878 /* ID3D11ShaderReflectionType methods */
879
880 static inline struct d3dcompiler_shader_reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D11ShaderReflectionType *iface)
881 {
882     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_type, ID3D11ShaderReflectionType_iface);
883 }
884
885 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc(
886         ID3D11ShaderReflectionType *iface, D3D11_SHADER_TYPE_DESC *desc)
887 {
888     struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
889
890     TRACE("iface %p, desc %p\n", iface, desc);
891
892     if (This == &null_type)
893     {
894         WARN("Null type specified\n");
895         return E_FAIL;
896     }
897
898     if (!desc)
899     {
900         WARN("Invalid argument specified\n");
901         return E_FAIL;
902     }
903
904     *desc = This->desc;
905
906     return S_OK;
907 }
908
909 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByIndex(
910         ID3D11ShaderReflectionType *iface, UINT index)
911 {
912     struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
913
914     TRACE("iface %p, index %u\n", iface, index);
915
916     if (index >= This->desc.Members)
917     {
918         WARN("Invalid index specified\n");
919         return &null_type.ID3D11ShaderReflectionType_iface;
920     }
921
922     return &This->members[index].type->ID3D11ShaderReflectionType_iface;
923 }
924
925 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByName(
926         ID3D11ShaderReflectionType *iface, LPCSTR name)
927 {
928     struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
929     unsigned int i;
930
931     TRACE("iface %p, name %s\n", iface, debugstr_a(name));
932
933     if (!name)
934     {
935         WARN("Invalid argument specified\n");
936         return &null_type.ID3D11ShaderReflectionType_iface;
937     }
938
939     for (i = 0; i < This->desc.Members; ++i)
940     {
941         struct d3dcompiler_shader_reflection_type_member *member = &This->members[i];
942
943         if (!strcmp(member->name, name))
944         {
945             TRACE("Returning ID3D11ShaderReflectionType %p.\n", member->type);
946             return &member->type->ID3D11ShaderReflectionType_iface;
947         }
948     }
949
950     WARN("Invalid name specified\n");
951
952     return &null_type.ID3D11ShaderReflectionType_iface;
953 }
954
955 static LPCSTR STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeName(
956         ID3D11ShaderReflectionType *iface, UINT index)
957 {
958     struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
959
960     TRACE("iface %p, index %u\n", iface, index);
961
962     if (This == &null_type)
963     {
964         WARN("Null type specified\n");
965         return "$Invalid";
966     }
967
968     if (index >= This->desc.Members)
969     {
970         WARN("Invalid index specified\n");
971         return NULL;
972     }
973
974     return This->members[index].name;
975 }
976
977 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual(
978         ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type)
979 {
980     struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
981
982     TRACE("iface %p, type %p\n", iface, type);
983
984     if (This == &null_type)
985     {
986         WARN("Null type specified\n");
987         return E_FAIL;
988     }
989
990     if (iface == type)
991         return S_OK;
992
993     return S_FALSE;
994 }
995
996 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetSubType(
997         ID3D11ShaderReflectionType *iface)
998 {
999     FIXME("iface %p stub!\n", iface);
1000
1001     return NULL;
1002 }
1003
1004 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetBaseClass(
1005         ID3D11ShaderReflectionType *iface)
1006 {
1007     FIXME("iface %p stub!\n", iface);
1008
1009     return NULL;
1010 }
1011
1012 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterfaces(
1013         ID3D11ShaderReflectionType *iface)
1014 {
1015     FIXME("iface %p stub!\n", iface);
1016
1017     return 0;
1018 }
1019
1020 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetInterfaceByIndex(
1021         ID3D11ShaderReflectionType *iface, UINT index)
1022 {
1023     FIXME("iface %p, index %u stub!\n", iface, index);
1024
1025     return NULL;
1026 }
1027
1028 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType(
1029         ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type)
1030 {
1031     FIXME("iface %p, type %p stub!\n", iface, type);
1032
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsInterface(
1037         ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *base)
1038 {
1039     FIXME("iface %p, base %p stub!\n", iface, base);
1040
1041     return E_NOTIMPL;
1042 }
1043
1044 const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl =
1045 {
1046     /* ID3D11ShaderReflectionType methods */
1047     d3dcompiler_shader_reflection_type_GetDesc,
1048     d3dcompiler_shader_reflection_type_GetMemberTypeByIndex,
1049     d3dcompiler_shader_reflection_type_GetMemberTypeByName,
1050     d3dcompiler_shader_reflection_type_GetMemberTypeName,
1051     d3dcompiler_shader_reflection_type_IsEqual,
1052     d3dcompiler_shader_reflection_type_GetSubType,
1053     d3dcompiler_shader_reflection_type_GetBaseClass,
1054     d3dcompiler_shader_reflection_type_GetNumInterfaces,
1055     d3dcompiler_shader_reflection_type_GetInterfaceByIndex,
1056     d3dcompiler_shader_reflection_type_IsOfType,
1057     d3dcompiler_shader_reflection_type_ImplementsInterface,
1058 };
1059
1060 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1061 {
1062     const char *ptr = data;
1063     DWORD size = data_size >> 2;
1064
1065     TRACE("Size %u\n", size);
1066
1067     read_dword(&ptr, &r->instruction_count);
1068     TRACE("InstructionCount: %u\n", r->instruction_count);
1069
1070     read_dword(&ptr, &r->temp_register_count);
1071     TRACE("TempRegisterCount: %u\n", r->temp_register_count);
1072
1073     skip_dword_unknown(&ptr, 1);
1074
1075     read_dword(&ptr, &r->dcl_count);
1076     TRACE("DclCount: %u\n", r->dcl_count);
1077
1078     read_dword(&ptr, &r->float_instruction_count);
1079     TRACE("FloatInstructionCount: %u\n", r->float_instruction_count);
1080
1081     read_dword(&ptr, &r->int_instruction_count);
1082     TRACE("IntInstructionCount: %u\n", r->int_instruction_count);
1083
1084     read_dword(&ptr, &r->uint_instruction_count);
1085     TRACE("UintInstructionCount: %u\n", r->uint_instruction_count);
1086
1087     read_dword(&ptr, &r->static_flow_control_count);
1088     TRACE("StaticFlowControlCount: %u\n", r->static_flow_control_count);
1089
1090     read_dword(&ptr, &r->dynamic_flow_control_count);
1091     TRACE("DynamicFlowControlCount: %u\n", r->dynamic_flow_control_count);
1092
1093     skip_dword_unknown(&ptr, 1);
1094
1095     read_dword(&ptr, &r->temp_array_count);
1096     TRACE("TempArrayCount: %u\n", r->temp_array_count);
1097
1098     read_dword(&ptr, &r->array_instruction_count);
1099     TRACE("ArrayInstructionCount: %u\n", r->array_instruction_count);
1100
1101     read_dword(&ptr, &r->cut_instruction_count);
1102     TRACE("CutInstructionCount: %u\n", r->cut_instruction_count);
1103
1104     read_dword(&ptr, &r->emit_instruction_count);
1105     TRACE("EmitInstructionCount: %u\n", r->emit_instruction_count);
1106
1107     read_dword(&ptr, &r->texture_normal_instructions);
1108     TRACE("TextureNormalInstructions: %u\n", r->texture_normal_instructions);
1109
1110     read_dword(&ptr, &r->texture_load_instructions);
1111     TRACE("TextureLoadInstructions: %u\n", r->texture_load_instructions);
1112
1113     read_dword(&ptr, &r->texture_comp_instructions);
1114     TRACE("TextureCompInstructions: %u\n", r->texture_comp_instructions);
1115
1116     read_dword(&ptr, &r->texture_bias_instructions);
1117     TRACE("TextureBiasInstructions: %u\n", r->texture_bias_instructions);
1118
1119     read_dword(&ptr, &r->texture_gradient_instructions);
1120     TRACE("TextureGradientInstructions: %u\n", r->texture_gradient_instructions);
1121
1122     read_dword(&ptr, &r->mov_instruction_count);
1123     TRACE("MovInstructionCount: %u\n", r->mov_instruction_count);
1124
1125     skip_dword_unknown(&ptr, 1);
1126
1127     read_dword(&ptr, &r->conversion_instruction_count);
1128     TRACE("ConversionInstructionCount: %u\n", r->conversion_instruction_count);
1129
1130     skip_dword_unknown(&ptr, 1);
1131
1132     read_dword(&ptr, &r->input_primitive);
1133     TRACE("InputPrimitive: %x\n", r->input_primitive);
1134
1135     read_dword(&ptr, &r->gs_output_topology);
1136     TRACE("GSOutputTopology: %x\n", r->gs_output_topology);
1137
1138     read_dword(&ptr, &r->gs_max_output_vertex_count);
1139     TRACE("GSMaxOutputVertexCount: %u\n", r->gs_max_output_vertex_count);
1140
1141     skip_dword_unknown(&ptr, 3);
1142
1143     /* dx10 stat size */
1144     if (size == 29) return S_OK;
1145
1146     skip_dword_unknown(&ptr, 1);
1147
1148     read_dword(&ptr, &r->c_control_points);
1149     TRACE("cControlPoints: %u\n", r->c_control_points);
1150
1151     read_dword(&ptr, &r->hs_output_primitive);
1152     TRACE("HSOutputPrimitive: %x\n", r->hs_output_primitive);
1153
1154     read_dword(&ptr, &r->hs_prtitioning);
1155     TRACE("HSPartitioning: %x\n", r->hs_prtitioning);
1156
1157     read_dword(&ptr, &r->tessellator_domain);
1158     TRACE("TessellatorDomain: %x\n", r->tessellator_domain);
1159
1160     skip_dword_unknown(&ptr, 3);
1161
1162     /* dx11 stat size */
1163     if (size == 37) return S_OK;
1164
1165     FIXME("Unhandled size %u\n", size);
1166
1167     return E_FAIL;
1168 }
1169
1170 static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflection *ref,
1171         struct d3dcompiler_shader_reflection_type_member *member, const char *data, const char **ptr)
1172 {
1173     DWORD offset;
1174
1175     read_dword(ptr, &offset);
1176     if (!copy_name(data + offset, &member->name))
1177     {
1178         ERR("Failed to copy name.\n");
1179         return E_OUTOFMEMORY;
1180     }
1181     TRACE("Member name: %s.\n", debugstr_a(member->name));
1182
1183     read_dword(ptr, &offset);
1184     TRACE("Member type offset: %x\n", offset);
1185
1186     member->type = get_reflection_type(ref, data, offset);
1187     if (!member->type)
1188     {
1189         ERR("Failed to get member type\n");
1190         HeapFree(GetProcessHeap(), 0, member->name);
1191         return E_FAIL;
1192     }
1193
1194     read_dword(ptr, &member->offset);
1195     TRACE("Member offset %x\n", member->offset);
1196
1197     return S_OK;
1198 }
1199
1200 static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type *type, const char *data, DWORD offset)
1201 {
1202     const char *ptr = data + offset;
1203     DWORD temp;
1204     D3D11_SHADER_TYPE_DESC *desc;
1205     unsigned int i;
1206     struct d3dcompiler_shader_reflection_type_member *members;
1207     HRESULT hr;
1208     DWORD member_offset;
1209
1210     desc = &type->desc;
1211
1212     read_dword(&ptr, &temp);
1213     desc->Class = temp & 0xffff;
1214     desc->Type = temp >> 16;
1215     TRACE("Class %s, Type %s\n", debug_d3dcompiler_shader_variable_class(desc->Class),
1216             debug_d3dcompiler_shader_variable_type(desc->Type));
1217
1218     read_dword(&ptr, &temp);
1219     desc->Rows = temp & 0xffff;
1220     desc->Columns = temp >> 16;
1221     TRACE("Rows %u, Columns %u\n", desc->Rows, desc->Columns);
1222
1223     read_dword(&ptr, &temp);
1224     desc->Elements = temp & 0xffff;
1225     desc->Members = temp >> 16;
1226     TRACE("Elements %u, Members %u\n", desc->Elements, desc->Members);
1227
1228     read_dword(&ptr, &member_offset);
1229     TRACE("Member Offset %u\n", member_offset);
1230
1231     if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1232         skip_dword_unknown(&ptr, 4);
1233
1234     if (desc->Members)
1235     {
1236         const char *ptr2 = data + member_offset;
1237
1238         members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*members));
1239         if (!members)
1240         {
1241             ERR("Failed to allocate type memory.\n");
1242             return E_OUTOFMEMORY;
1243         }
1244
1245         for (i = 0; i < desc->Members; ++i)
1246         {
1247             hr = d3dcompiler_parse_type_members(type->reflection, &members[i], data, &ptr2);
1248             if (hr != S_OK)
1249             {
1250                 FIXME("Failed to parse type members.");
1251                 goto err_out;
1252             }
1253         }
1254     }
1255
1256     type->members = members;
1257
1258     return S_OK;
1259
1260 err_out:
1261     for (i = 0; i < desc->Members; ++i)
1262     {
1263         free_type_member(&members[i]);
1264     }
1265     HeapFree(GetProcessHeap(), 0, members);
1266     return hr;
1267 }
1268
1269 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, DWORD offset)
1270 {
1271     struct d3dcompiler_shader_reflection_type *type;
1272     struct wine_rb_entry *entry;
1273     HRESULT hr;
1274
1275     entry = wine_rb_get(&reflection->types, &offset);
1276     if (entry)
1277     {
1278         TRACE("Returning existing type.\n");
1279         return WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry);
1280     }
1281
1282     type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*type));
1283     if (!type)
1284     {
1285         ERR("Failed to allocate type memory.\n");
1286         return NULL;
1287     }
1288
1289     type->ID3D11ShaderReflectionType_iface.lpVtbl = &d3dcompiler_shader_reflection_type_vtbl;
1290     type->id = offset;
1291     type->reflection = reflection;
1292
1293     hr = d3dcompiler_parse_type(type, data, offset);
1294     if (FAILED(hr))
1295     {
1296         ERR("Failed to parse type info, hr %#x.\n", hr);
1297         HeapFree(GetProcessHeap(), 0, type);
1298         return NULL;
1299     }
1300
1301     if (wine_rb_put(&reflection->types, &offset, &type->entry) == -1)
1302     {
1303         ERR("Failed to insert type entry.\n");
1304         HeapFree(GetProcessHeap(), 0, type);
1305         return NULL;
1306     }
1307
1308     return type;
1309 }
1310
1311 static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb,
1312         const char *data, DWORD data_size, const char *ptr)
1313 {
1314     struct d3dcompiler_shader_reflection_variable *variables;
1315     unsigned int i;
1316     HRESULT hr;
1317
1318     variables = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb->variable_count * sizeof(*variables));
1319     if (!variables)
1320     {
1321         ERR("Failed to allocate variables memory.\n");
1322         return E_OUTOFMEMORY;
1323     }
1324
1325     for (i = 0; i < cb->variable_count; i++)
1326     {
1327         struct d3dcompiler_shader_reflection_variable *v = &variables[i];
1328         DWORD offset;
1329
1330         v->ID3D11ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl;
1331         v->constant_buffer = cb;
1332
1333         read_dword(&ptr, &offset);
1334         if (!copy_name(data + offset, &v->name))
1335         {
1336             ERR("Failed to copy name.\n");
1337             hr = E_OUTOFMEMORY;
1338             goto err_out;
1339         }
1340         TRACE("Variable name: %s.\n", debugstr_a(v->name));
1341
1342         read_dword(&ptr, &v->start_offset);
1343         TRACE("Variable offset: %u\n", v->start_offset);
1344
1345         read_dword(&ptr, &v->size);
1346         TRACE("Variable size: %u\n", v->size);
1347
1348         read_dword(&ptr, &v->flags);
1349         TRACE("Variable flags: %u\n", v->flags);
1350
1351         read_dword(&ptr, &offset);
1352         TRACE("Variable type offset: %x\n", offset);
1353         v->type = get_reflection_type(cb->reflection, data, offset);
1354         if (!v->type)
1355         {
1356             ERR("Failed to get type.\n");
1357             hr = E_FAIL;
1358             goto err_out;
1359         }
1360
1361         read_dword(&ptr, &offset);
1362         TRACE("Variable default value offset: %x\n", offset);
1363         if (!copy_value(data + offset, &v->default_value, offset ? v->size : 0))
1364         {
1365             ERR("Failed to copy name.\n");
1366             hr = E_OUTOFMEMORY;
1367             goto err_out;
1368         }
1369
1370         if ((cb->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1371             skip_dword_unknown(&ptr, 4);
1372     }
1373
1374     cb->variables = variables;
1375
1376     return S_OK;
1377
1378 err_out:
1379     for (i = 0; i < cb->variable_count; i++)
1380     {
1381         free_variable(&variables[i]);
1382     }
1383     HeapFree(GetProcessHeap(), 0, variables);
1384     return hr;
1385 }
1386
1387 static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1388 {
1389     const char *ptr = data;
1390     DWORD size = data_size >> 2;
1391     DWORD offset, cbuffer_offset, resource_offset, creator_offset;
1392     unsigned int i, string_data_offset, string_data_size;
1393     char *string_data = NULL, *creator = NULL;
1394     D3D11_SHADER_INPUT_BIND_DESC *bound_resources = NULL;
1395     struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL;
1396     HRESULT hr;
1397
1398     TRACE("Size %u\n", size);
1399
1400     read_dword(&ptr, &r->constant_buffer_count);
1401     TRACE("Constant buffer count: %u\n", r->constant_buffer_count);
1402
1403     read_dword(&ptr, &cbuffer_offset);
1404     TRACE("Constant buffer offset: %#x\n", cbuffer_offset);
1405
1406     read_dword(&ptr, &r->bound_resource_count);
1407     TRACE("Bound resource count: %u\n", r->bound_resource_count);
1408
1409     read_dword(&ptr, &resource_offset);
1410     TRACE("Bound resource offset: %#x\n", resource_offset);
1411
1412     read_dword(&ptr, &r->target);
1413     TRACE("Target: %#x\n", r->target);
1414
1415     read_dword(&ptr, &r->flags);
1416     TRACE("Flags: %u\n", r->flags);
1417
1418     read_dword(&ptr, &creator_offset);
1419     TRACE("Creator at offset %#x.\n", creator_offset);
1420
1421     if (!copy_name(data + creator_offset, &creator))
1422     {
1423         ERR("Failed to copy name.\n");
1424         return E_OUTOFMEMORY;
1425     }
1426     TRACE("Creator: %s.\n", debugstr_a(creator));
1427
1428     /* todo: Parse RD11 */
1429     if ((r->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1430     {
1431         skip_dword_unknown(&ptr, 8);
1432     }
1433
1434     if (r->bound_resource_count)
1435     {
1436         /* 8 for each bind desc */
1437         string_data_offset = resource_offset + r->bound_resource_count * 8 * sizeof(DWORD);
1438         string_data_size = (cbuffer_offset ? cbuffer_offset : creator_offset) - string_data_offset;
1439
1440         string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1441         if (!string_data)
1442         {
1443             ERR("Failed to allocate string data memory.\n");
1444             hr = E_OUTOFMEMORY;
1445             goto err_out;
1446         }
1447         memcpy(string_data, data + string_data_offset, string_data_size);
1448
1449         bound_resources = HeapAlloc(GetProcessHeap(), 0, r->bound_resource_count * sizeof(*bound_resources));
1450         if (!bound_resources)
1451         {
1452             ERR("Failed to allocate resources memory.\n");
1453             hr = E_OUTOFMEMORY;
1454             goto err_out;
1455         }
1456
1457         ptr = data + resource_offset;
1458         for (i = 0; i < r->bound_resource_count; i++)
1459         {
1460             D3D11_SHADER_INPUT_BIND_DESC *desc = &bound_resources[i];
1461
1462             read_dword(&ptr, &offset);
1463             desc->Name = string_data + (offset - string_data_offset);
1464             TRACE("Input bind Name: %s\n", debugstr_a(desc->Name));
1465
1466             read_dword(&ptr, &desc->Type);
1467             TRACE("Input bind Type: %#x\n", desc->Type);
1468
1469             read_dword(&ptr, &desc->ReturnType);
1470             TRACE("Input bind ReturnType: %#x\n", desc->ReturnType);
1471
1472             read_dword(&ptr, &desc->Dimension);
1473             TRACE("Input bind Dimension: %#x\n", desc->Dimension);
1474
1475             read_dword(&ptr, &desc->NumSamples);
1476             TRACE("Input bind NumSamples: %u\n", desc->NumSamples);
1477
1478             read_dword(&ptr, &desc->BindPoint);
1479             TRACE("Input bind BindPoint: %u\n", desc->BindPoint);
1480
1481             read_dword(&ptr, &desc->BindCount);
1482             TRACE("Input bind BindCount: %u\n", desc->BindCount);
1483
1484             read_dword(&ptr, &desc->uFlags);
1485             TRACE("Input bind uFlags: %u\n", desc->uFlags);
1486         }
1487     }
1488
1489     if (r->constant_buffer_count)
1490     {
1491         constant_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, r->constant_buffer_count * sizeof(*constant_buffers));
1492         if (!constant_buffers)
1493         {
1494             ERR("Failed to allocate constant buffer memory.\n");
1495             hr = E_OUTOFMEMORY;
1496             goto err_out;
1497         }
1498
1499         ptr = data + cbuffer_offset;
1500         for (i = 0; i < r->constant_buffer_count; i++)
1501         {
1502             struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i];
1503
1504             cb->ID3D11ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl;
1505             cb->reflection = r;
1506
1507             read_dword(&ptr, &offset);
1508             if (!copy_name(data + offset, &cb->name))
1509             {
1510                 ERR("Failed to copy name.\n");
1511                 hr = E_OUTOFMEMORY;
1512                 goto err_out;
1513             }
1514             TRACE("Name: %s.\n", debugstr_a(cb->name));
1515
1516             read_dword(&ptr, &cb->variable_count);
1517             TRACE("Variable count: %u\n", cb->variable_count);
1518
1519             read_dword(&ptr, &offset);
1520             TRACE("Variable offset: %x\n", offset);
1521
1522             hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset);
1523             if (hr != S_OK)
1524             {
1525                 FIXME("Failed to parse variables.");
1526                 goto err_out;
1527             }
1528
1529             read_dword(&ptr, &cb->size);
1530             TRACE("Cbuffer size: %u\n", cb->size);
1531
1532             read_dword(&ptr, &cb->flags);
1533             TRACE("Cbuffer flags: %u\n", cb->flags);
1534
1535             read_dword(&ptr, &cb->type);
1536             TRACE("Cbuffer type: %#x\n", cb->type);
1537         }
1538     }
1539
1540     r->creator = creator;
1541     r->resource_string = string_data;
1542     r->bound_resources = bound_resources;
1543     r->constant_buffers = constant_buffers;
1544
1545     return S_OK;
1546
1547 err_out:
1548     for (i = 0; i < r->constant_buffer_count; ++i)
1549     {
1550         free_constant_buffer(&constant_buffers[i]);
1551     }
1552     HeapFree(GetProcessHeap(), 0, constant_buffers);
1553     HeapFree(GetProcessHeap(), 0, bound_resources);
1554     HeapFree(GetProcessHeap(), 0, string_data);
1555     HeapFree(GetProcessHeap(), 0, creator);
1556
1557     return hr;
1558 }
1559
1560 static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, struct dxbc_section *section, DWORD target)
1561 {
1562     D3D11_SIGNATURE_PARAMETER_DESC *d;
1563     unsigned int string_data_offset;
1564     unsigned int string_data_size;
1565     const char *ptr = section->data;
1566     char *string_data;
1567     unsigned int i;
1568     DWORD count;
1569     enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size;
1570
1571     switch (section->tag)
1572     {
1573         case TAG_OSG5:
1574             element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7;
1575             break;
1576
1577         case TAG_ISGN:
1578         case TAG_OSGN:
1579         case TAG_PCSG:
1580             element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
1581             break;
1582
1583         default:
1584             FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1585             element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
1586             break;
1587     }
1588
1589     read_dword(&ptr, &count);
1590     TRACE("%u elements\n", count);
1591
1592     skip_dword_unknown(&ptr, 1);
1593
1594     d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d));
1595     if (!d)
1596     {
1597         ERR("Failed to allocate signature memory.\n");
1598         return E_OUTOFMEMORY;
1599     }
1600
1601     /* 2 DWORDs for the header, element_size for each element. */
1602     string_data_offset = 2 * sizeof(DWORD) + count * element_size * sizeof(DWORD);
1603     string_data_size = section->data_size - string_data_offset;
1604
1605     string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1606     if (!string_data)
1607     {
1608         ERR("Failed to allocate string data memory.\n");
1609         HeapFree(GetProcessHeap(), 0, d);
1610         return E_OUTOFMEMORY;
1611     }
1612     memcpy(string_data, section->data + string_data_offset, string_data_size);
1613
1614     for (i = 0; i < count; ++i)
1615     {
1616         UINT name_offset;
1617         DWORD mask;
1618
1619         if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7)
1620         {
1621             read_dword(&ptr, &d[i].Stream);
1622         }
1623         else
1624         {
1625             d[i].Stream = 0;
1626         }
1627
1628         read_dword(&ptr, &name_offset);
1629         d[i].SemanticName = string_data + (name_offset - string_data_offset);
1630         read_dword(&ptr, &d[i].SemanticIndex);
1631         read_dword(&ptr, &d[i].SystemValueType);
1632         read_dword(&ptr, &d[i].ComponentType);
1633         read_dword(&ptr, &d[i].Register);
1634         read_dword(&ptr, &mask);
1635         d[i].ReadWriteMask = (mask >> 8) & 0xff;
1636         d[i].Mask = mask & 0xff;
1637
1638         /* pixel shaders have a special handling for SystemValueType in the output signature */
1639         if (((target & D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK) == 0xffff0000) && (section->tag == TAG_OSG5 || section->tag == TAG_OSGN))
1640         {
1641             TRACE("Pixelshader output signature fixup.\n");
1642
1643             if (d[i].Register == 0xffffffff)
1644             {
1645                 if (!strcasecmp(d[i].SemanticName, "sv_depth")) d[i].SystemValueType = D3D_NAME_DEPTH;
1646                 if (!strcasecmp(d[i].SemanticName, "sv_coverage")) d[i].SystemValueType = D3D_NAME_COVERAGE;
1647                 if (!strcasecmp(d[i].SemanticName, "sv_depthgreaterequal")) d[i].SystemValueType = D3D_NAME_DEPTH_GREATER_EQUAL;
1648                 if (!strcasecmp(d[i].SemanticName, "sv_depthlessequal")) d[i].SystemValueType = D3D_NAME_DEPTH_LESS_EQUAL;
1649             }
1650             else
1651             {
1652                 d[i].SystemValueType = D3D_NAME_TARGET;
1653             }
1654         }
1655
1656         TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
1657                 "type %u, register idx: %u, use_mask %#x, input_mask %#x, stream %u\n",
1658                 debugstr_a(d[i].SemanticName), d[i].SemanticIndex, d[i].SystemValueType,
1659                 d[i].ComponentType, d[i].Register, d[i].Mask, d[i].ReadWriteMask, d[i].Stream);
1660     }
1661
1662     s->elements = d;
1663     s->element_count = count;
1664     s->string_data = string_data;
1665
1666     return S_OK;
1667 }
1668
1669 static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1670 {
1671     const char *ptr = data;
1672
1673     read_dword(&ptr, &r->version);
1674     TRACE("Shader version: %u\n", r->version);
1675
1676     /* todo: Check if anything else is needed from the shdr or shex blob. */
1677
1678     return S_OK;
1679 }
1680
1681 static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection,
1682         const void *data, SIZE_T data_size)
1683 {
1684     struct dxbc src_dxbc;
1685     HRESULT hr;
1686     unsigned int i;
1687
1688     reflection->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
1689     reflection->refcount = 1;
1690
1691     if (wine_rb_init(&reflection->types, &d3dcompiler_shader_reflection_type_rb_functions) == -1)
1692     {
1693         ERR("Failed to initialize type rbtree.\n");
1694         return E_FAIL;
1695     }
1696
1697     hr = dxbc_parse(data, data_size, &src_dxbc);
1698     if (FAILED(hr))
1699     {
1700         WARN("Failed to parse reflection\n");
1701         return hr;
1702     }
1703
1704     for (i = 0; i < src_dxbc.count; ++i)
1705     {
1706         struct dxbc_section *section = &src_dxbc.sections[i];
1707
1708         switch (section->tag)
1709         {
1710             case TAG_RDEF:
1711                 hr = d3dcompiler_parse_rdef(reflection, section->data, section->data_size);
1712                 if (FAILED(hr))
1713                 {
1714                     WARN("Failed to parse RDEF section.\n");
1715                     goto err_out;
1716                 }
1717                 break;
1718
1719             case TAG_ISGN:
1720                 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn));
1721                 if (!reflection->isgn)
1722                 {
1723                     ERR("Failed to allocate ISGN memory.\n");
1724                     hr = E_OUTOFMEMORY;
1725                     goto err_out;
1726                 }
1727
1728                 hr = d3dcompiler_parse_signature(reflection->isgn, section, reflection->target);
1729                 if (FAILED(hr))
1730                 {
1731                     WARN("Failed to parse section ISGN.\n");
1732                     goto err_out;
1733                 }
1734                 break;
1735
1736             case TAG_OSG5:
1737             case TAG_OSGN:
1738                 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn));
1739                 if (!reflection->osgn)
1740                 {
1741                     ERR("Failed to allocate OSGN memory.\n");
1742                     hr = E_OUTOFMEMORY;
1743                     goto err_out;
1744                 }
1745
1746                 hr = d3dcompiler_parse_signature(reflection->osgn, section, reflection->target);
1747                 if (FAILED(hr))
1748                 {
1749                     WARN("Failed to parse section OSGN.\n");
1750                     goto err_out;
1751                 }
1752                 break;
1753
1754             case TAG_PCSG:
1755                 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg));
1756                 if (!reflection->pcsg)
1757                 {
1758                     ERR("Failed to allocate PCSG memory.\n");
1759                     hr = E_OUTOFMEMORY;
1760                     goto err_out;
1761                 }
1762
1763                 hr = d3dcompiler_parse_signature(reflection->pcsg, section, reflection->target);
1764                 if (FAILED(hr))
1765                 {
1766                     WARN("Failed to parse section PCSG.\n");
1767                     goto err_out;
1768                 }
1769                 break;
1770
1771             case TAG_SHEX:
1772             case TAG_SHDR:
1773                 hr = d3dcompiler_parse_shdr(reflection, section->data, section->data_size);
1774                 if (FAILED(hr))
1775                 {
1776                     WARN("Failed to parse SHDR section.\n");
1777                     goto err_out;
1778                 }
1779                 break;
1780
1781             case TAG_STAT:
1782                 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size);
1783                 if (FAILED(hr))
1784                 {
1785                     WARN("Failed to parse section STAT.\n");
1786                     goto err_out;
1787                 }
1788                 break;
1789
1790             default:
1791                 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1792                 break;
1793         }
1794     }
1795
1796     dxbc_destroy(&src_dxbc);
1797
1798     return hr;
1799
1800 err_out:
1801     reflection_cleanup(reflection);
1802     dxbc_destroy(&src_dxbc);
1803
1804     return hr;
1805 }
1806
1807 HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID riid, void **reflector)
1808 {
1809     struct d3dcompiler_shader_reflection *object;
1810     HRESULT hr;
1811     const DWORD *temp = data;
1812
1813     TRACE("data %p, data_size %lu, riid %s, blob %p\n", data, data_size, debugstr_guid(riid), reflector);
1814
1815     if (!data || data_size < 32)
1816     {
1817         WARN("Invalid argument supplied.\n");
1818         return D3DERR_INVALIDCALL;
1819     }
1820
1821     if (temp[6] != data_size)
1822     {
1823         WARN("Wrong size supplied.\n");
1824         return E_FAIL;
1825     }
1826
1827     if (!IsEqualGUID(riid, &IID_ID3D11ShaderReflection))
1828     {
1829         WARN("Wrong riid %s, accept only %s!\n", debugstr_guid(riid), debugstr_guid(&IID_ID3D11ShaderReflection));
1830         return E_NOINTERFACE;
1831     }
1832
1833     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1834     if (!object)
1835     {
1836         ERR("Failed to allocate D3D compiler shader reflection object memory\n");
1837         return E_OUTOFMEMORY;
1838     }
1839
1840     hr = d3dcompiler_shader_reflection_init(object, data, data_size);
1841     if (FAILED(hr))
1842     {
1843         WARN("Failed to initialize shader reflection\n");
1844         HeapFree(GetProcessHeap(), 0, object);
1845         return hr;
1846     }
1847
1848     *reflector = object;
1849
1850     TRACE("Created ID3D11ShaderReflection %p\n", object);
1851
1852     return S_OK;
1853 }