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