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