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