cards: Fix description of cdtTerm.
[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 static BOOL copy_name(const char *ptr, char **name)
29 {
30     size_t name_len;
31
32     if (!ptr) return TRUE;
33
34     name_len = strlen(ptr) + 1;
35     if (name_len == 1)
36     {
37         return TRUE;
38     }
39
40     *name = HeapAlloc(GetProcessHeap(), 0, name_len);
41     if (!*name)
42     {
43         ERR("Failed to allocate name memory.\n");
44         return FALSE;
45     }
46
47     memcpy(*name, ptr, name_len);
48
49     return TRUE;
50 }
51
52 static void free_signature(struct d3dcompiler_shader_signature *sig)
53 {
54     TRACE("Free signature %p\n", sig);
55
56     HeapFree(GetProcessHeap(), 0, sig->elements);
57     HeapFree(GetProcessHeap(), 0, sig->string_data);
58 }
59
60 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref)
61 {
62     TRACE("Cleanup %p\n", ref);
63
64     if (ref->isgn)
65     {
66         free_signature(ref->isgn);
67         HeapFree(GetProcessHeap(), 0, ref->isgn);
68     }
69
70     if (ref->osgn)
71     {
72         free_signature(ref->osgn);
73         HeapFree(GetProcessHeap(), 0, ref->osgn);
74     }
75
76     if (ref->pcsg)
77     {
78         free_signature(ref->pcsg);
79         HeapFree(GetProcessHeap(), 0, ref->pcsg);
80     }
81
82     HeapFree(GetProcessHeap(), 0, ref->creator);
83 }
84
85 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
86 {
87     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
88 }
89
90 /* IUnknown methods */
91
92 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
93 {
94     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
95
96     if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
97             || IsEqualGUID(riid, &IID_IUnknown))
98     {
99         IUnknown_AddRef(iface);
100         *object = iface;
101         return S_OK;
102     }
103
104     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
105
106     *object = NULL;
107     return E_NOINTERFACE;
108 }
109
110 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
111 {
112     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
113     ULONG refcount = InterlockedIncrement(&This->refcount);
114
115     TRACE("%p increasing refcount to %u\n", This, refcount);
116
117     return refcount;
118 }
119
120 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
121 {
122     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
123     ULONG refcount = InterlockedDecrement(&This->refcount);
124
125     TRACE("%p decreasing refcount to %u\n", This, refcount);
126
127     if (!refcount)
128     {
129         reflection_cleanup(This);
130         HeapFree(GetProcessHeap(), 0, This);
131     }
132
133     return refcount;
134 }
135
136 /* ID3D11ShaderReflection methods */
137
138 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
139 {
140     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
141
142     FIXME("iface %p, desc %p partial stub!\n", iface, desc);
143
144     if (!desc)
145     {
146         WARN("Invalid argument specified\n");
147         return E_FAIL;
148     }
149
150     desc->Version = This->version;
151     desc->Creator = This->creator;
152     desc->Flags = This->flags;
153     desc->ConstantBuffers = This->constant_buffer_count;
154     desc->BoundResources = This->bound_resource_count;
155     desc->InputParameters = This->isgn ? This->isgn->element_count : 0;
156     desc->OutputParameters = This->osgn ? This->osgn->element_count : 0;
157     desc->InstructionCount = This->instruction_count;
158     desc->TempRegisterCount = This->temp_register_count;
159     desc->TempArrayCount = This->temp_array_count;
160     desc->DefCount = 0;
161     desc->DclCount = This->dcl_count;
162     desc->TextureNormalInstructions = This->texture_normal_instructions;
163     desc->TextureLoadInstructions = This->texture_load_instructions;
164     desc->TextureCompInstructions = This->texture_comp_instructions;
165     desc->TextureBiasInstructions = This->texture_bias_instructions;
166     desc->TextureGradientInstructions = This->texture_gradient_instructions;
167     desc->FloatInstructionCount = This->float_instruction_count;
168     desc->IntInstructionCount = This->int_instruction_count;
169     desc->UintInstructionCount = This->uint_instruction_count;
170     desc->StaticFlowControlCount = This->static_flow_control_count;
171     desc->DynamicFlowControlCount = This->dynamic_flow_control_count;
172     desc->MacroInstructionCount = 0;
173     desc->ArrayInstructionCount = This->array_instruction_count;
174     desc->CutInstructionCount = This->cut_instruction_count;
175     desc->EmitInstructionCount = This->emit_instruction_count;
176     desc->GSOutputTopology = This->gs_output_topology;
177     desc->GSMaxOutputVertexCount = This->gs_max_output_vertex_count;
178     desc->InputPrimitive = This->input_primitive;
179     desc->PatchConstantParameters = This->pcsg ? This->pcsg->element_count : 0;
180     desc->cGSInstanceCount = 0;
181     desc->cControlPoints = This->c_control_points;
182     desc->HSOutputPrimitive = This->hs_output_primitive;
183     desc->HSPartitioning = This->hs_prtitioning;
184     desc->TessellatorDomain = This->tessellator_domain;
185     desc->cBarrierInstructions = 0;
186     desc->cInterlockedInstructions = 0;
187     desc->cTextureStoreInstructions = 0;
188
189     return S_OK;
190 }
191
192 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
193         ID3D11ShaderReflection *iface, UINT index)
194 {
195     FIXME("iface %p, index %u stub!\n", iface, index);
196
197     return NULL;
198 }
199
200 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
201         ID3D11ShaderReflection *iface, LPCSTR name)
202 {
203     FIXME("iface %p, name \"%s\" stub!\n", iface, name);
204
205     return NULL;
206 }
207
208 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
209         ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
210 {
211     FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc);
212
213     return E_NOTIMPL;
214 }
215
216 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
217         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
218 {
219     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
220
221     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
222
223     if (!desc || !This->isgn || index >= This->isgn->element_count)
224     {
225         WARN("Invalid argument specified\n");
226         return E_INVALIDARG;
227     }
228
229     *desc = This->isgn->elements[index];
230
231     return S_OK;
232 }
233
234 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
235         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
236 {
237     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
238
239     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
240
241     if (!desc || !This->osgn || index >= This->osgn->element_count)
242     {
243         WARN("Invalid argument specified\n");
244         return E_INVALIDARG;
245     }
246
247     *desc = This->osgn->elements[index];
248
249     return S_OK;
250 }
251
252 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
253         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
254 {
255     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
256
257     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
258
259     if (!desc || !This->pcsg || index >= This->pcsg->element_count)
260     {
261         WARN("Invalid argument specified\n");
262         return E_INVALIDARG;
263     }
264
265     *desc = This->pcsg->elements[index];
266
267     return S_OK;
268 }
269
270 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
271         ID3D11ShaderReflection *iface, LPCSTR name)
272 {
273     FIXME("iface %p, name %s stub!\n", iface, name);
274
275     return NULL;
276 }
277
278 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
279         ID3D11ShaderReflection *iface, LPCSTR name, D3D11_SHADER_INPUT_BIND_DESC *desc)
280 {
281     FIXME("iface %p, name %s, desc %p stub!\n", iface, name, desc);
282
283     return E_NOTIMPL;
284 }
285
286 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
287         ID3D11ShaderReflection *iface)
288 {
289     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
290
291     TRACE("iface %p\n", iface);
292
293     return This->mov_instruction_count;
294 }
295
296 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
297         ID3D11ShaderReflection *iface)
298 {
299     FIXME("iface %p stub!\n", iface);
300
301     return 0;
302 }
303
304 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
305         ID3D11ShaderReflection *iface)
306 {
307     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
308
309     TRACE("iface %p\n", iface);
310
311     return This->conversion_instruction_count;
312 }
313
314 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
315         ID3D11ShaderReflection *iface)
316 {
317     FIXME("iface %p stub!\n", iface);
318
319     return 0;
320 }
321
322 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
323         ID3D11ShaderReflection *iface)
324 {
325     FIXME("iface %p stub!\n", iface);
326
327     return 0;
328 }
329
330 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
331         ID3D11ShaderReflection *iface)
332 {
333     FIXME("iface %p stub!\n", iface);
334
335     return 0;
336 }
337
338 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
339         ID3D11ShaderReflection *iface)
340 {
341     FIXME("iface %p stub!\n", iface);
342
343     return 0;
344 }
345
346 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
347         ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
348 {
349     FIXME("iface %p, level %p stub!\n", iface, level);
350
351     return E_NOTIMPL;
352 }
353
354 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize(
355         ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez)
356 {
357     FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez);
358
359     return 0;
360 }
361
362 const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
363 {
364     /* IUnknown methods */
365     d3dcompiler_shader_reflection_QueryInterface,
366     d3dcompiler_shader_reflection_AddRef,
367     d3dcompiler_shader_reflection_Release,
368     /* ID3D11ShaderReflection methods */
369     d3dcompiler_shader_reflection_GetDesc,
370     d3dcompiler_shader_reflection_GetConstantBufferByIndex,
371     d3dcompiler_shader_reflection_GetConstantBufferByName,
372     d3dcompiler_shader_reflection_GetResourceBindingDesc,
373     d3dcompiler_shader_reflection_GetInputParameterDesc,
374     d3dcompiler_shader_reflection_GetOutputParameterDesc,
375     d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
376     d3dcompiler_shader_reflection_GetVariableByName,
377     d3dcompiler_shader_reflection_GetResourceBindingDescByName,
378     d3dcompiler_shader_reflection_GetMovInstructionCount,
379     d3dcompiler_shader_reflection_GetMovcInstructionCount,
380     d3dcompiler_shader_reflection_GetConversionInstructionCount,
381     d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
382     d3dcompiler_shader_reflection_GetGSInputPrimitive,
383     d3dcompiler_shader_reflection_IsSampleFrequencyShader,
384     d3dcompiler_shader_reflection_GetNumInterfaceSlots,
385     d3dcompiler_shader_reflection_GetMinFeatureLevel,
386     d3dcompiler_shader_reflection_GetThreadGroupSize,
387 };
388
389 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
390 {
391     const char *ptr = data;
392     DWORD size = data_size >> 2;
393
394     TRACE("Size %u\n", size);
395
396     read_dword(&ptr, &r->instruction_count);
397     TRACE("InstructionCount: %u\n", r->instruction_count);
398
399     read_dword(&ptr, &r->temp_register_count);
400     TRACE("TempRegisterCount: %u\n", r->temp_register_count);
401
402     skip_dword_unknown(&ptr, 1);
403
404     read_dword(&ptr, &r->dcl_count);
405     TRACE("DclCount: %u\n", r->dcl_count);
406
407     read_dword(&ptr, &r->float_instruction_count);
408     TRACE("FloatInstructionCount: %u\n", r->float_instruction_count);
409
410     read_dword(&ptr, &r->int_instruction_count);
411     TRACE("IntInstructionCount: %u\n", r->int_instruction_count);
412
413     read_dword(&ptr, &r->uint_instruction_count);
414     TRACE("UintInstructionCount: %u\n", r->uint_instruction_count);
415
416     read_dword(&ptr, &r->static_flow_control_count);
417     TRACE("StaticFlowControlCount: %u\n", r->static_flow_control_count);
418
419     read_dword(&ptr, &r->dynamic_flow_control_count);
420     TRACE("DynamicFlowControlCount: %u\n", r->dynamic_flow_control_count);
421
422     skip_dword_unknown(&ptr, 1);
423
424     read_dword(&ptr, &r->temp_array_count);
425     TRACE("TempArrayCount: %u\n", r->temp_array_count);
426
427     read_dword(&ptr, &r->array_instruction_count);
428     TRACE("ArrayInstructionCount: %u\n", r->array_instruction_count);
429
430     read_dword(&ptr, &r->cut_instruction_count);
431     TRACE("CutInstructionCount: %u\n", r->cut_instruction_count);
432
433     read_dword(&ptr, &r->emit_instruction_count);
434     TRACE("EmitInstructionCount: %u\n", r->emit_instruction_count);
435
436     read_dword(&ptr, &r->texture_normal_instructions);
437     TRACE("TextureNormalInstructions: %u\n", r->texture_normal_instructions);
438
439     read_dword(&ptr, &r->texture_load_instructions);
440     TRACE("TextureLoadInstructions: %u\n", r->texture_load_instructions);
441
442     read_dword(&ptr, &r->texture_comp_instructions);
443     TRACE("TextureCompInstructions: %u\n", r->texture_comp_instructions);
444
445     read_dword(&ptr, &r->texture_bias_instructions);
446     TRACE("TextureBiasInstructions: %u\n", r->texture_bias_instructions);
447
448     read_dword(&ptr, &r->texture_gradient_instructions);
449     TRACE("TextureGradientInstructions: %u\n", r->texture_gradient_instructions);
450
451     read_dword(&ptr, &r->mov_instruction_count);
452     TRACE("MovInstructionCount: %u\n", r->mov_instruction_count);
453
454     skip_dword_unknown(&ptr, 1);
455
456     read_dword(&ptr, &r->conversion_instruction_count);
457     TRACE("ConversionInstructionCount: %u\n", r->conversion_instruction_count);
458
459     skip_dword_unknown(&ptr, 1);
460
461     read_dword(&ptr, &r->input_primitive);
462     TRACE("InputPrimitive: %x\n", r->input_primitive);
463
464     read_dword(&ptr, &r->gs_output_topology);
465     TRACE("GSOutputTopology: %x\n", r->gs_output_topology);
466
467     read_dword(&ptr, &r->gs_max_output_vertex_count);
468     TRACE("GSMaxOutputVertexCount: %u\n", r->gs_max_output_vertex_count);
469
470     skip_dword_unknown(&ptr, 3);
471
472     /* dx10 stat size */
473     if (size == 29) return S_OK;
474
475     skip_dword_unknown(&ptr, 1);
476
477     read_dword(&ptr, &r->c_control_points);
478     TRACE("cControlPoints: %u\n", r->c_control_points);
479
480     read_dword(&ptr, &r->hs_output_primitive);
481     TRACE("HSOutputPrimitive: %x\n", r->hs_output_primitive);
482
483     read_dword(&ptr, &r->hs_prtitioning);
484     TRACE("HSPartitioning: %x\n", r->hs_prtitioning);
485
486     read_dword(&ptr, &r->tessellator_domain);
487     TRACE("TessellatorDomain: %x\n", r->tessellator_domain);
488
489     skip_dword_unknown(&ptr, 3);
490
491     /* dx11 stat size */
492     if (size == 37) return S_OK;
493
494     FIXME("Unhandled size %u\n", size);
495
496     return E_FAIL;
497 }
498
499 static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
500 {
501     const char *ptr = data;
502     DWORD size = data_size >> 2;
503     DWORD offset;
504
505     TRACE("Size %u\n", size);
506
507     read_dword(&ptr, &r->constant_buffer_count);
508     TRACE("Constant buffer count: %u\n", r->constant_buffer_count);
509
510     read_dword(&ptr, &offset);
511     TRACE("Constant buffer offset: %x\n", offset);
512
513     read_dword(&ptr, &r->bound_resource_count);
514     TRACE("Bound resource count: %u\n", r->bound_resource_count);
515
516     read_dword(&ptr, &offset);
517     TRACE("Bound resource offset: %x\n", offset);
518
519     skip_dword_unknown(&ptr, 1);
520
521     read_dword(&ptr, &r->flags);
522     TRACE("Flags: %u\n", r->flags);
523
524     read_dword(&ptr, &offset);
525     TRACE("Creator at offset %#x.\n", offset);
526
527     if (!copy_name(data + offset, &r->creator))
528     {
529         ERR("Failed to copy name.\n");
530         return E_OUTOFMEMORY;
531     }
532     TRACE("Creator: %s.\n", debugstr_a(r->creator));
533
534     /* todo: Parse D3D11_SHADER_INPUT_BIND_DESC Structure */
535
536     /* todo: Parse Constant buffers */
537
538     return S_OK;
539 }
540
541 HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, const char *data, DWORD data_size)
542 {
543     D3D11_SIGNATURE_PARAMETER_DESC *d;
544     unsigned int string_data_offset;
545     unsigned int string_data_size;
546     const char *ptr = data;
547     char *string_data;
548     unsigned int i;
549     DWORD count;
550
551     read_dword(&ptr, &count);
552     TRACE("%u elements\n", count);
553
554     skip_dword_unknown(&ptr, 1);
555
556     d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d));
557     if (!d)
558     {
559         ERR("Failed to allocate signature memory.\n");
560         return E_OUTOFMEMORY;
561     }
562
563     /* 2 DWORDs for the header, 6 for each element. */
564     string_data_offset = 2 * sizeof(DWORD) + count * 6 * sizeof(DWORD);
565     string_data_size = data_size - string_data_offset;
566     string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
567     if (!string_data)
568     {
569         ERR("Failed to allocate string data memory.\n");
570         HeapFree(GetProcessHeap(), 0, d);
571         return E_OUTOFMEMORY;
572     }
573     memcpy(string_data, data + string_data_offset, string_data_size);
574
575     for (i = 0; i < count; ++i)
576     {
577         UINT name_offset;
578         DWORD mask;
579
580         /* todo: Parse stream in shaderblobs v5 (dx11) */
581         d[i].Stream = 0;
582
583         read_dword(&ptr, &name_offset);
584         d[i].SemanticName = string_data + (name_offset - string_data_offset);
585         read_dword(&ptr, &d[i].SemanticIndex);
586         read_dword(&ptr, &d[i].SystemValueType);
587         read_dword(&ptr, &d[i].ComponentType);
588         read_dword(&ptr, &d[i].Register);
589         read_dword(&ptr, &mask);
590         d[i].ReadWriteMask = (mask >> 8) & 0xff;
591         d[i].Mask = mask & 0xff;
592
593         TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
594                 "type %u, register idx: %u, use_mask %#x, input_mask %#x, stream %u\n",
595                 debugstr_a(d[i].SemanticName), d[i].SemanticIndex, d[i].SystemValueType,
596                 d[i].ComponentType, d[i].Register, d[i].Mask, d[i].ReadWriteMask, d[i].Stream);
597     }
598
599     s->elements = d;
600     s->element_count = count;
601     s->string_data = string_data;
602
603     return S_OK;
604 }
605
606 static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
607 {
608     const char *ptr = data;
609
610     read_dword(&ptr, &r->version);
611     TRACE("Shader version: %u\n", r->version);
612
613     /* todo: Check if anything else is needed from the shdr or shex blob. */
614
615     return S_OK;
616 }
617
618 HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection,
619         const void *data, SIZE_T data_size)
620 {
621     struct dxbc src_dxbc;
622     HRESULT hr;
623     unsigned int i;
624
625     reflection->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
626     reflection->refcount = 1;
627
628     hr = dxbc_parse(data, data_size, &src_dxbc);
629     if (FAILED(hr))
630     {
631         WARN("Failed to parse reflection\n");
632         return hr;
633     }
634
635     for (i = 0; i < src_dxbc.count; ++i)
636     {
637         struct dxbc_section *section = &src_dxbc.sections[i];
638
639         switch (section->tag)
640         {
641             case TAG_STAT:
642                 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size);
643                 if (FAILED(hr))
644                 {
645                     WARN("Failed to parse section STAT.\n");
646                     goto err_out;
647                 }
648                 break;
649
650             case TAG_SHEX:
651             case TAG_SHDR:
652                 hr = d3dcompiler_parse_shdr(reflection, section->data, section->data_size);
653                 if (FAILED(hr))
654                 {
655                     WARN("Failed to parse SHDR section.\n");
656                     goto err_out;
657                 }
658                 break;
659
660             case TAG_RDEF:
661                 hr = d3dcompiler_parse_rdef(reflection, section->data, section->data_size);
662                 if (FAILED(hr))
663                 {
664                     WARN("Failed to parse RDEF section.\n");
665                     goto err_out;
666                 }
667                 break;
668
669             case TAG_ISGN:
670                 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn));
671                 if (!reflection->isgn)
672                 {
673                     ERR("Failed to allocate ISGN memory.\n");
674                     hr = E_OUTOFMEMORY;
675                     goto err_out;
676                 }
677
678                 hr = d3dcompiler_parse_signature(reflection->isgn, section->data, section->data_size);
679                 if (FAILED(hr))
680                 {
681                     WARN("Failed to parse section ISGN.\n");
682                     goto err_out;
683                 }
684                 break;
685
686             case TAG_OSGN:
687                 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn));
688                 if (!reflection->osgn)
689                 {
690                     ERR("Failed to allocate OSGN memory.\n");
691                     hr = E_OUTOFMEMORY;
692                     goto err_out;
693                 }
694
695                 hr = d3dcompiler_parse_signature(reflection->osgn, section->data, section->data_size);
696                 if (FAILED(hr))
697                 {
698                     WARN("Failed to parse section OSGN.\n");
699                     goto err_out;
700                 }
701                 break;
702
703             case TAG_PCSG:
704                 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg));
705                 if (!reflection->pcsg)
706                 {
707                     ERR("Failed to allocate PCSG memory.\n");
708                     hr = E_OUTOFMEMORY;
709                     goto err_out;
710                 }
711
712                 hr = d3dcompiler_parse_signature(reflection->pcsg, section->data, section->data_size);
713                 if (FAILED(hr))
714                 {
715                     WARN("Failed to parse section PCSG.\n");
716                     goto err_out;
717                 }
718                 break;
719
720             default:
721                 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
722                 break;
723         }
724     }
725
726     dxbc_destroy(&src_dxbc);
727
728     return hr;
729
730 err_out:
731     reflection_cleanup(reflection);
732     dxbc_destroy(&src_dxbc);
733
734     return hr;
735 }