mshtml: Add support for get/put mousemove event.
[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 const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl;
35
36 /* null objects - needed for invalid calls */
37 static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer = {{&d3dcompiler_shader_reflection_constant_buffer_vtbl}};
38
39 static BOOL copy_name(const char *ptr, char **name)
40 {
41     size_t name_len;
42
43     if (!ptr) return TRUE;
44
45     name_len = strlen(ptr) + 1;
46     if (name_len == 1)
47     {
48         return TRUE;
49     }
50
51     *name = HeapAlloc(GetProcessHeap(), 0, name_len);
52     if (!*name)
53     {
54         ERR("Failed to allocate name memory.\n");
55         return FALSE;
56     }
57
58     memcpy(*name, ptr, name_len);
59
60     return TRUE;
61 }
62
63 static BOOL copy_value(const char *ptr, void **value, DWORD size)
64 {
65     if (!ptr || !size) return TRUE;
66
67     *value = HeapAlloc(GetProcessHeap(), 0, size);
68     if (!*value)
69     {
70         ERR("Failed to allocate vlaue memory.\n");
71         return FALSE;
72     }
73
74     memcpy(*value, ptr, size);
75
76     return TRUE;
77 }
78
79 static void free_signature(struct d3dcompiler_shader_signature *sig)
80 {
81     TRACE("Free signature %p\n", sig);
82
83     HeapFree(GetProcessHeap(), 0, sig->elements);
84     HeapFree(GetProcessHeap(), 0, sig->string_data);
85 }
86
87 static void free_variable(struct d3dcompiler_shader_reflection_variable *var)
88 {
89     if (var)
90     {
91         HeapFree(GetProcessHeap(), 0, var->name);
92         HeapFree(GetProcessHeap(), 0, var->default_value);
93     }
94 }
95
96 static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb)
97 {
98     if (cb->variables)
99     {
100         unsigned int i;
101
102         for (i = 0; i < cb->variable_count; ++i)
103         {
104             free_variable(&cb->variables[i]);
105         }
106         HeapFree(GetProcessHeap(), 0, cb->variables);
107     }
108
109     HeapFree(GetProcessHeap(), 0, cb->name);
110 }
111
112 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref)
113 {
114     TRACE("Cleanup %p\n", ref);
115
116     if (ref->isgn)
117     {
118         free_signature(ref->isgn);
119         HeapFree(GetProcessHeap(), 0, ref->isgn);
120     }
121
122     if (ref->osgn)
123     {
124         free_signature(ref->osgn);
125         HeapFree(GetProcessHeap(), 0, ref->osgn);
126     }
127
128     if (ref->pcsg)
129     {
130         free_signature(ref->pcsg);
131         HeapFree(GetProcessHeap(), 0, ref->pcsg);
132     }
133
134     if (ref->constant_buffers)
135     {
136         unsigned int i;
137
138         for (i = 0; i < ref->constant_buffer_count; ++i)
139         {
140             free_constant_buffer(&ref->constant_buffers[i]);
141         }
142     }
143
144     HeapFree(GetProcessHeap(), 0, ref->constant_buffers);
145     HeapFree(GetProcessHeap(), 0, ref->bound_resources);
146     HeapFree(GetProcessHeap(), 0, ref->resource_string);
147     HeapFree(GetProcessHeap(), 0, ref->creator);
148 }
149
150 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
151 {
152     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
153 }
154
155 /* IUnknown methods */
156
157 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
158 {
159     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
160
161     if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
162             || IsEqualGUID(riid, &IID_IUnknown))
163     {
164         IUnknown_AddRef(iface);
165         *object = iface;
166         return S_OK;
167     }
168
169     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
170
171     *object = NULL;
172     return E_NOINTERFACE;
173 }
174
175 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
176 {
177     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
178     ULONG refcount = InterlockedIncrement(&This->refcount);
179
180     TRACE("%p increasing refcount to %u\n", This, refcount);
181
182     return refcount;
183 }
184
185 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
186 {
187     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
188     ULONG refcount = InterlockedDecrement(&This->refcount);
189
190     TRACE("%p decreasing refcount to %u\n", This, refcount);
191
192     if (!refcount)
193     {
194         reflection_cleanup(This);
195         HeapFree(GetProcessHeap(), 0, This);
196     }
197
198     return refcount;
199 }
200
201 /* ID3D11ShaderReflection methods */
202
203 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
204 {
205     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
206
207     FIXME("iface %p, desc %p partial stub!\n", iface, desc);
208
209     if (!desc)
210     {
211         WARN("Invalid argument specified\n");
212         return E_FAIL;
213     }
214
215     desc->Version = This->version;
216     desc->Creator = This->creator;
217     desc->Flags = This->flags;
218     desc->ConstantBuffers = This->constant_buffer_count;
219     desc->BoundResources = This->bound_resource_count;
220     desc->InputParameters = This->isgn ? This->isgn->element_count : 0;
221     desc->OutputParameters = This->osgn ? This->osgn->element_count : 0;
222     desc->InstructionCount = This->instruction_count;
223     desc->TempRegisterCount = This->temp_register_count;
224     desc->TempArrayCount = This->temp_array_count;
225     desc->DefCount = 0;
226     desc->DclCount = This->dcl_count;
227     desc->TextureNormalInstructions = This->texture_normal_instructions;
228     desc->TextureLoadInstructions = This->texture_load_instructions;
229     desc->TextureCompInstructions = This->texture_comp_instructions;
230     desc->TextureBiasInstructions = This->texture_bias_instructions;
231     desc->TextureGradientInstructions = This->texture_gradient_instructions;
232     desc->FloatInstructionCount = This->float_instruction_count;
233     desc->IntInstructionCount = This->int_instruction_count;
234     desc->UintInstructionCount = This->uint_instruction_count;
235     desc->StaticFlowControlCount = This->static_flow_control_count;
236     desc->DynamicFlowControlCount = This->dynamic_flow_control_count;
237     desc->MacroInstructionCount = 0;
238     desc->ArrayInstructionCount = This->array_instruction_count;
239     desc->CutInstructionCount = This->cut_instruction_count;
240     desc->EmitInstructionCount = This->emit_instruction_count;
241     desc->GSOutputTopology = This->gs_output_topology;
242     desc->GSMaxOutputVertexCount = This->gs_max_output_vertex_count;
243     desc->InputPrimitive = This->input_primitive;
244     desc->PatchConstantParameters = This->pcsg ? This->pcsg->element_count : 0;
245     desc->cGSInstanceCount = 0;
246     desc->cControlPoints = This->c_control_points;
247     desc->HSOutputPrimitive = This->hs_output_primitive;
248     desc->HSPartitioning = This->hs_prtitioning;
249     desc->TessellatorDomain = This->tessellator_domain;
250     desc->cBarrierInstructions = 0;
251     desc->cInterlockedInstructions = 0;
252     desc->cTextureStoreInstructions = 0;
253
254     return S_OK;
255 }
256
257 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
258         ID3D11ShaderReflection *iface, UINT index)
259 {
260     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
261
262     TRACE("iface %p, index %u\n", iface, index);
263
264     if (index >= This->constant_buffer_count)
265     {
266         WARN("Invalid argument specified\n");
267         return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
268     }
269
270     return &This->constant_buffers[index].ID3D11ShaderReflectionConstantBuffer_iface;
271 }
272
273 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
274         ID3D11ShaderReflection *iface, LPCSTR name)
275 {
276     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
277     unsigned int i;
278
279     TRACE("iface %p, name %s\n", iface, debugstr_a(name));
280
281     if (!name)
282     {
283         WARN("Invalid argument specified\n");
284         return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
285     }
286
287     for (i = 0; i < This->constant_buffer_count; ++i)
288     {
289         struct d3dcompiler_shader_reflection_constant_buffer *d = &This->constant_buffers[i];
290
291         if (!strcmp(d->name, name))
292         {
293             TRACE("Returning ID3D11ShaderReflectionConstantBuffer %p.\n", d);
294             return &d->ID3D11ShaderReflectionConstantBuffer_iface;
295         }
296     }
297
298     WARN("Invalid name specified\n");
299
300     return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
301 }
302
303 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
304         ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
305 {
306     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
307
308     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
309
310     if (!desc || index >= This->bound_resource_count)
311     {
312         WARN("Invalid argument specified\n");
313         return E_INVALIDARG;
314     }
315
316     *desc = This->bound_resources[index];
317
318     return S_OK;
319 }
320
321 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
322         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
323 {
324     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
325
326     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
327
328     if (!desc || !This->isgn || index >= This->isgn->element_count)
329     {
330         WARN("Invalid argument specified\n");
331         return E_INVALIDARG;
332     }
333
334     *desc = This->isgn->elements[index];
335
336     return S_OK;
337 }
338
339 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
340         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
341 {
342     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
343
344     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
345
346     if (!desc || !This->osgn || index >= This->osgn->element_count)
347     {
348         WARN("Invalid argument specified\n");
349         return E_INVALIDARG;
350     }
351
352     *desc = This->osgn->elements[index];
353
354     return S_OK;
355 }
356
357 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
358         ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
359 {
360     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
361
362     TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
363
364     if (!desc || !This->pcsg || index >= This->pcsg->element_count)
365     {
366         WARN("Invalid argument specified\n");
367         return E_INVALIDARG;
368     }
369
370     *desc = This->pcsg->elements[index];
371
372     return S_OK;
373 }
374
375 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
376         ID3D11ShaderReflection *iface, LPCSTR name)
377 {
378     FIXME("iface %p, name %s stub!\n", iface, name);
379
380     return NULL;
381 }
382
383 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
384         ID3D11ShaderReflection *iface, LPCSTR name, D3D11_SHADER_INPUT_BIND_DESC *desc)
385 {
386     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
387     unsigned int i;
388
389     TRACE("iface %p, name %s, desc %p\n", iface, debugstr_a(name), desc);
390
391     if (!desc || !name)
392     {
393         WARN("Invalid argument specified\n");
394         return E_INVALIDARG;
395     }
396
397     for (i = 0; i < This->bound_resource_count; ++i)
398     {
399         D3D11_SHADER_INPUT_BIND_DESC *d = &This->bound_resources[i];
400
401         if (!strcmp(d->Name, name))
402         {
403             TRACE("Returning D3D11_SHADER_INPUT_BIND_DESC %p.\n", d);
404             *desc = *d;
405             return S_OK;
406         }
407     }
408
409     WARN("Invalid name specified\n");
410
411     return E_INVALIDARG;
412 }
413
414 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
415         ID3D11ShaderReflection *iface)
416 {
417     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
418
419     TRACE("iface %p\n", iface);
420
421     return This->mov_instruction_count;
422 }
423
424 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
425         ID3D11ShaderReflection *iface)
426 {
427     FIXME("iface %p stub!\n", iface);
428
429     return 0;
430 }
431
432 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
433         ID3D11ShaderReflection *iface)
434 {
435     struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
436
437     TRACE("iface %p\n", iface);
438
439     return This->conversion_instruction_count;
440 }
441
442 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
443         ID3D11ShaderReflection *iface)
444 {
445     FIXME("iface %p stub!\n", iface);
446
447     return 0;
448 }
449
450 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
451         ID3D11ShaderReflection *iface)
452 {
453     FIXME("iface %p stub!\n", iface);
454
455     return 0;
456 }
457
458 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
459         ID3D11ShaderReflection *iface)
460 {
461     FIXME("iface %p stub!\n", iface);
462
463     return 0;
464 }
465
466 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
467         ID3D11ShaderReflection *iface)
468 {
469     FIXME("iface %p stub!\n", iface);
470
471     return 0;
472 }
473
474 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
475         ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
476 {
477     FIXME("iface %p, level %p stub!\n", iface, level);
478
479     return E_NOTIMPL;
480 }
481
482 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize(
483         ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez)
484 {
485     FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez);
486
487     return 0;
488 }
489
490 const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
491 {
492     /* IUnknown methods */
493     d3dcompiler_shader_reflection_QueryInterface,
494     d3dcompiler_shader_reflection_AddRef,
495     d3dcompiler_shader_reflection_Release,
496     /* ID3D11ShaderReflection methods */
497     d3dcompiler_shader_reflection_GetDesc,
498     d3dcompiler_shader_reflection_GetConstantBufferByIndex,
499     d3dcompiler_shader_reflection_GetConstantBufferByName,
500     d3dcompiler_shader_reflection_GetResourceBindingDesc,
501     d3dcompiler_shader_reflection_GetInputParameterDesc,
502     d3dcompiler_shader_reflection_GetOutputParameterDesc,
503     d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
504     d3dcompiler_shader_reflection_GetVariableByName,
505     d3dcompiler_shader_reflection_GetResourceBindingDescByName,
506     d3dcompiler_shader_reflection_GetMovInstructionCount,
507     d3dcompiler_shader_reflection_GetMovcInstructionCount,
508     d3dcompiler_shader_reflection_GetConversionInstructionCount,
509     d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
510     d3dcompiler_shader_reflection_GetGSInputPrimitive,
511     d3dcompiler_shader_reflection_IsSampleFrequencyShader,
512     d3dcompiler_shader_reflection_GetNumInterfaceSlots,
513     d3dcompiler_shader_reflection_GetMinFeatureLevel,
514     d3dcompiler_shader_reflection_GetThreadGroupSize,
515 };
516
517 /* ID3D11ShaderReflectionConstantBuffer methods */
518
519 static inline struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D11ShaderReflectionConstantBuffer *iface)
520 {
521     return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D11ShaderReflectionConstantBuffer_iface);
522 }
523
524 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc(
525         ID3D11ShaderReflectionConstantBuffer *iface, D3D11_SHADER_BUFFER_DESC *desc)
526 {
527     struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
528
529     TRACE("iface %p, desc %p\n", iface, desc);
530
531     if (This == &null_constant_buffer)
532     {
533         WARN("Null constant buffer specified\n");
534         return E_FAIL;
535     }
536
537     if (!desc)
538     {
539         WARN("Invalid argument specified\n");
540         return E_FAIL;
541     }
542
543     desc->Name = This->name;
544     desc->Type = This->type;
545     desc->Variables = This->variable_count;
546     desc->Size = This->size;
547     desc->uFlags = This->flags;
548
549     return S_OK;
550 }
551
552 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex(
553         ID3D11ShaderReflectionConstantBuffer *iface, UINT index)
554 {
555     FIXME("iface %p, index %u stub!\n", iface, index);
556
557     return NULL;
558 }
559
560 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName(
561         ID3D11ShaderReflectionConstantBuffer *iface, LPCSTR name)
562 {
563     FIXME("iface %p, name %s stub!\n", iface, name);
564
565     return NULL;
566 }
567
568 const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl =
569 {
570     /* ID3D11ShaderReflectionConstantBuffer methods */
571     d3dcompiler_shader_reflection_constant_buffer_GetDesc,
572     d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex,
573     d3dcompiler_shader_reflection_constant_buffer_GetVariableByName,
574 };
575
576 /* ID3D11ShaderReflectionVariable methods */
577
578 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc(
579         ID3D11ShaderReflectionVariable *iface, D3D11_SHADER_VARIABLE_DESC *desc)
580 {
581     FIXME("iface %p, desc %p stub!\n", iface, desc);
582
583     return E_NOTIMPL;
584 }
585
586 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType(
587         ID3D11ShaderReflectionVariable *iface)
588 {
589     FIXME("iface %p stub!\n", iface);
590
591     return NULL;
592 }
593
594 static ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer(
595         ID3D11ShaderReflectionVariable *iface)
596 {
597     FIXME("iface %p stub!\n", iface);
598
599     return NULL;
600 }
601
602 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot(
603         ID3D11ShaderReflectionVariable *iface, UINT index)
604 {
605     FIXME("iface %p, index %u stub!\n", iface, index);
606
607     return 0;
608 }
609
610 const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl =
611 {
612     /* ID3D11ShaderReflectionVariable methods */
613     d3dcompiler_shader_reflection_variable_GetDesc,
614     d3dcompiler_shader_reflection_variable_GetType,
615     d3dcompiler_shader_reflection_variable_GetBuffer,
616     d3dcompiler_shader_reflection_variable_GetInterfaceSlot,
617 };
618
619 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
620 {
621     const char *ptr = data;
622     DWORD size = data_size >> 2;
623
624     TRACE("Size %u\n", size);
625
626     read_dword(&ptr, &r->instruction_count);
627     TRACE("InstructionCount: %u\n", r->instruction_count);
628
629     read_dword(&ptr, &r->temp_register_count);
630     TRACE("TempRegisterCount: %u\n", r->temp_register_count);
631
632     skip_dword_unknown(&ptr, 1);
633
634     read_dword(&ptr, &r->dcl_count);
635     TRACE("DclCount: %u\n", r->dcl_count);
636
637     read_dword(&ptr, &r->float_instruction_count);
638     TRACE("FloatInstructionCount: %u\n", r->float_instruction_count);
639
640     read_dword(&ptr, &r->int_instruction_count);
641     TRACE("IntInstructionCount: %u\n", r->int_instruction_count);
642
643     read_dword(&ptr, &r->uint_instruction_count);
644     TRACE("UintInstructionCount: %u\n", r->uint_instruction_count);
645
646     read_dword(&ptr, &r->static_flow_control_count);
647     TRACE("StaticFlowControlCount: %u\n", r->static_flow_control_count);
648
649     read_dword(&ptr, &r->dynamic_flow_control_count);
650     TRACE("DynamicFlowControlCount: %u\n", r->dynamic_flow_control_count);
651
652     skip_dword_unknown(&ptr, 1);
653
654     read_dword(&ptr, &r->temp_array_count);
655     TRACE("TempArrayCount: %u\n", r->temp_array_count);
656
657     read_dword(&ptr, &r->array_instruction_count);
658     TRACE("ArrayInstructionCount: %u\n", r->array_instruction_count);
659
660     read_dword(&ptr, &r->cut_instruction_count);
661     TRACE("CutInstructionCount: %u\n", r->cut_instruction_count);
662
663     read_dword(&ptr, &r->emit_instruction_count);
664     TRACE("EmitInstructionCount: %u\n", r->emit_instruction_count);
665
666     read_dword(&ptr, &r->texture_normal_instructions);
667     TRACE("TextureNormalInstructions: %u\n", r->texture_normal_instructions);
668
669     read_dword(&ptr, &r->texture_load_instructions);
670     TRACE("TextureLoadInstructions: %u\n", r->texture_load_instructions);
671
672     read_dword(&ptr, &r->texture_comp_instructions);
673     TRACE("TextureCompInstructions: %u\n", r->texture_comp_instructions);
674
675     read_dword(&ptr, &r->texture_bias_instructions);
676     TRACE("TextureBiasInstructions: %u\n", r->texture_bias_instructions);
677
678     read_dword(&ptr, &r->texture_gradient_instructions);
679     TRACE("TextureGradientInstructions: %u\n", r->texture_gradient_instructions);
680
681     read_dword(&ptr, &r->mov_instruction_count);
682     TRACE("MovInstructionCount: %u\n", r->mov_instruction_count);
683
684     skip_dword_unknown(&ptr, 1);
685
686     read_dword(&ptr, &r->conversion_instruction_count);
687     TRACE("ConversionInstructionCount: %u\n", r->conversion_instruction_count);
688
689     skip_dword_unknown(&ptr, 1);
690
691     read_dword(&ptr, &r->input_primitive);
692     TRACE("InputPrimitive: %x\n", r->input_primitive);
693
694     read_dword(&ptr, &r->gs_output_topology);
695     TRACE("GSOutputTopology: %x\n", r->gs_output_topology);
696
697     read_dword(&ptr, &r->gs_max_output_vertex_count);
698     TRACE("GSMaxOutputVertexCount: %u\n", r->gs_max_output_vertex_count);
699
700     skip_dword_unknown(&ptr, 3);
701
702     /* dx10 stat size */
703     if (size == 29) return S_OK;
704
705     skip_dword_unknown(&ptr, 1);
706
707     read_dword(&ptr, &r->c_control_points);
708     TRACE("cControlPoints: %u\n", r->c_control_points);
709
710     read_dword(&ptr, &r->hs_output_primitive);
711     TRACE("HSOutputPrimitive: %x\n", r->hs_output_primitive);
712
713     read_dword(&ptr, &r->hs_prtitioning);
714     TRACE("HSPartitioning: %x\n", r->hs_prtitioning);
715
716     read_dword(&ptr, &r->tessellator_domain);
717     TRACE("TessellatorDomain: %x\n", r->tessellator_domain);
718
719     skip_dword_unknown(&ptr, 3);
720
721     /* dx11 stat size */
722     if (size == 37) return S_OK;
723
724     FIXME("Unhandled size %u\n", size);
725
726     return E_FAIL;
727 }
728
729 static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb,
730         const char *data, DWORD data_size, const char *ptr)
731 {
732     struct d3dcompiler_shader_reflection_variable *variables;
733     unsigned int i;
734     HRESULT hr;
735
736     variables = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb->variable_count * sizeof(*variables));
737     if (!variables)
738     {
739         ERR("Failed to allocate variables memory.\n");
740         return E_OUTOFMEMORY;
741     }
742
743     for (i = 0; i < cb->variable_count; i++)
744     {
745         struct d3dcompiler_shader_reflection_variable *v = &variables[i];
746         DWORD offset;
747
748         v->ID3D11ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl;
749
750         read_dword(&ptr, &offset);
751         if (!copy_name(data + offset, &v->name))
752         {
753             ERR("Failed to copy name.\n");
754             hr = E_OUTOFMEMORY;
755             goto err_out;
756         }
757         TRACE("Variable name: %s.\n", debugstr_a(v->name));
758
759         read_dword(&ptr, &v->start_offset);
760         TRACE("Variable offset: %u\n", v->start_offset);
761
762         read_dword(&ptr, &v->size);
763         TRACE("Variable size: %u\n", v->size);
764
765         read_dword(&ptr, &v->flags);
766         TRACE("Variable flags: %u\n", v->flags);
767
768         /* todo: Parse types */
769         read_dword(&ptr, &offset);
770         FIXME("Variable type offset: %x\n", offset);
771
772         read_dword(&ptr, &offset);
773         TRACE("Variable default value offset: %x\n", offset);
774         if (!copy_value(data + offset, &v->default_value, offset ? v->size : 0))
775         {
776             ERR("Failed to copy name.\n");
777             hr = E_OUTOFMEMORY;
778             goto err_out;
779         }
780
781         if ((cb->reflection->target & 0xffff) >= 0x500)
782             skip_dword_unknown(&ptr, 4);
783     }
784
785     cb->variables = variables;
786
787     return S_OK;
788
789 err_out:
790     for (i = 0; i < cb->variable_count; i++)
791     {
792         free_variable(&variables[i]);
793     }
794     HeapFree(GetProcessHeap(), 0, variables);
795     return hr;
796 }
797
798 static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
799 {
800     const char *ptr = data;
801     DWORD size = data_size >> 2;
802     DWORD offset, cbuffer_offset, resource_offset, creator_offset;
803     unsigned int i, string_data_offset, string_data_size;
804     char *string_data = NULL, *creator = NULL;
805     D3D11_SHADER_INPUT_BIND_DESC *bound_resources = NULL;
806     struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL;
807     HRESULT hr;
808
809     TRACE("Size %u\n", size);
810
811     read_dword(&ptr, &r->constant_buffer_count);
812     TRACE("Constant buffer count: %u\n", r->constant_buffer_count);
813
814     read_dword(&ptr, &cbuffer_offset);
815     TRACE("Constant buffer offset: %#x\n", cbuffer_offset);
816
817     read_dword(&ptr, &r->bound_resource_count);
818     TRACE("Bound resource count: %u\n", r->bound_resource_count);
819
820     read_dword(&ptr, &resource_offset);
821     TRACE("Bound resource offset: %#x\n", resource_offset);
822
823     read_dword(&ptr, &r->target);
824     TRACE("Target: %#x\n", r->target);
825
826     read_dword(&ptr, &r->flags);
827     TRACE("Flags: %u\n", r->flags);
828
829     read_dword(&ptr, &creator_offset);
830     TRACE("Creator at offset %#x.\n", creator_offset);
831
832     if (!copy_name(data + creator_offset, &creator))
833     {
834         ERR("Failed to copy name.\n");
835         return E_OUTOFMEMORY;
836     }
837     TRACE("Creator: %s.\n", debugstr_a(creator));
838
839     /* todo: Parse RD11 */
840     if ((r->target & 0x0000ffff) >= 0x500)
841     {
842         skip_dword_unknown(&ptr, 8);
843     }
844
845     if (r->bound_resource_count)
846     {
847         /* 8 for each bind desc */
848         string_data_offset = resource_offset + r->bound_resource_count * 8 * sizeof(DWORD);
849         string_data_size = (cbuffer_offset ? cbuffer_offset : creator_offset) - string_data_offset;
850
851         string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
852         if (!string_data)
853         {
854             ERR("Failed to allocate string data memory.\n");
855             hr = E_OUTOFMEMORY;
856             goto err_out;
857         }
858         memcpy(string_data, data + string_data_offset, string_data_size);
859
860         bound_resources = HeapAlloc(GetProcessHeap(), 0, r->bound_resource_count * sizeof(*bound_resources));
861         if (!bound_resources)
862         {
863             ERR("Failed to allocate resources memory.\n");
864             hr = E_OUTOFMEMORY;
865             goto err_out;
866         }
867
868         ptr = data + resource_offset;
869         for (i = 0; i < r->bound_resource_count; i++)
870         {
871             D3D11_SHADER_INPUT_BIND_DESC *desc = &bound_resources[i];
872
873             read_dword(&ptr, &offset);
874             desc->Name = string_data + (offset - string_data_offset);
875             TRACE("Input bind Name: %s\n", debugstr_a(desc->Name));
876
877             read_dword(&ptr, &desc->Type);
878             TRACE("Input bind Type: %#x\n", desc->Type);
879
880             read_dword(&ptr, &desc->ReturnType);
881             TRACE("Input bind ReturnType: %#x\n", desc->ReturnType);
882
883             read_dword(&ptr, &desc->Dimension);
884             TRACE("Input bind Dimension: %#x\n", desc->Dimension);
885
886             read_dword(&ptr, &desc->NumSamples);
887             TRACE("Input bind NumSamples: %u\n", desc->NumSamples);
888
889             read_dword(&ptr, &desc->BindPoint);
890             TRACE("Input bind BindPoint: %u\n", desc->BindPoint);
891
892             read_dword(&ptr, &desc->BindCount);
893             TRACE("Input bind BindCount: %u\n", desc->BindCount);
894
895             read_dword(&ptr, &desc->uFlags);
896             TRACE("Input bind uFlags: %u\n", desc->uFlags);
897         }
898     }
899
900     if (r->constant_buffer_count)
901     {
902         constant_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, r->constant_buffer_count * sizeof(*constant_buffers));
903         if (!constant_buffers)
904         {
905             ERR("Failed to allocate constant buffer memory.\n");
906             hr = E_OUTOFMEMORY;
907             goto err_out;
908         }
909
910         ptr = data + cbuffer_offset;
911         for (i = 0; i < r->constant_buffer_count; i++)
912         {
913             struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i];
914
915             cb->ID3D11ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl;
916             cb->reflection = r;
917
918             read_dword(&ptr, &offset);
919             if (!copy_name(data + offset, &cb->name))
920             {
921                 ERR("Failed to copy name.\n");
922                 hr = E_OUTOFMEMORY;
923                 goto err_out;
924             }
925             TRACE("Name: %s.\n", debugstr_a(cb->name));
926
927             read_dword(&ptr, &cb->variable_count);
928             TRACE("Variable count: %u\n", cb->variable_count);
929
930             read_dword(&ptr, &offset);
931             TRACE("Variable offset: %x\n", offset);
932
933             hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset);
934             if (hr != S_OK)
935             {
936                 FIXME("Failed to parse variables.");
937                 goto err_out;
938             }
939
940             read_dword(&ptr, &cb->size);
941             TRACE("Cbuffer size: %u\n", cb->size);
942
943             read_dword(&ptr, &cb->flags);
944             TRACE("Cbuffer flags: %u\n", cb->flags);
945
946             read_dword(&ptr, &cb->type);
947             TRACE("Cbuffer type: %#x\n", cb->type);
948         }
949     }
950
951     r->creator = creator;
952     r->resource_string = string_data;
953     r->bound_resources = bound_resources;
954     r->constant_buffers = constant_buffers;
955
956     return S_OK;
957
958 err_out:
959     for (i = 0; i < r->constant_buffer_count; ++i)
960     {
961         free_constant_buffer(&constant_buffers[i]);
962     }
963     HeapFree(GetProcessHeap(), 0, constant_buffers);
964     HeapFree(GetProcessHeap(), 0, bound_resources);
965     HeapFree(GetProcessHeap(), 0, string_data);
966     HeapFree(GetProcessHeap(), 0, creator);
967
968     return hr;
969 }
970
971 HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, struct dxbc_section *section)
972 {
973     D3D11_SIGNATURE_PARAMETER_DESC *d;
974     unsigned int string_data_offset;
975     unsigned int string_data_size;
976     const char *ptr = section->data;
977     char *string_data;
978     unsigned int i;
979     DWORD count;
980     enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size;
981
982     switch (section->tag)
983     {
984         case TAG_OSG5:
985             element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7;
986             break;
987
988         case TAG_ISGN:
989         case TAG_OSGN:
990         case TAG_PCSG:
991             element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
992             break;
993
994         default:
995             FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
996             element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
997             break;
998     }
999
1000     read_dword(&ptr, &count);
1001     TRACE("%u elements\n", count);
1002
1003     skip_dword_unknown(&ptr, 1);
1004
1005     d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d));
1006     if (!d)
1007     {
1008         ERR("Failed to allocate signature memory.\n");
1009         return E_OUTOFMEMORY;
1010     }
1011
1012     /* 2 DWORDs for the header, element_size for each element. */
1013     string_data_offset = 2 * sizeof(DWORD) + count * element_size * sizeof(DWORD);
1014     string_data_size = section->data_size - string_data_offset;
1015
1016     string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1017     if (!string_data)
1018     {
1019         ERR("Failed to allocate string data memory.\n");
1020         HeapFree(GetProcessHeap(), 0, d);
1021         return E_OUTOFMEMORY;
1022     }
1023     memcpy(string_data, section->data + string_data_offset, string_data_size);
1024
1025     for (i = 0; i < count; ++i)
1026     {
1027         UINT name_offset;
1028         DWORD mask;
1029
1030         if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7)
1031         {
1032             read_dword(&ptr, &d[i].Stream);
1033         }
1034         else
1035         {
1036             d[i].Stream = 0;
1037         }
1038
1039         read_dword(&ptr, &name_offset);
1040         d[i].SemanticName = string_data + (name_offset - string_data_offset);
1041         read_dword(&ptr, &d[i].SemanticIndex);
1042         read_dword(&ptr, &d[i].SystemValueType);
1043         read_dword(&ptr, &d[i].ComponentType);
1044         read_dword(&ptr, &d[i].Register);
1045         read_dword(&ptr, &mask);
1046         d[i].ReadWriteMask = (mask >> 8) & 0xff;
1047         d[i].Mask = mask & 0xff;
1048
1049         TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
1050                 "type %u, register idx: %u, use_mask %#x, input_mask %#x, stream %u\n",
1051                 debugstr_a(d[i].SemanticName), d[i].SemanticIndex, d[i].SystemValueType,
1052                 d[i].ComponentType, d[i].Register, d[i].Mask, d[i].ReadWriteMask, d[i].Stream);
1053     }
1054
1055     s->elements = d;
1056     s->element_count = count;
1057     s->string_data = string_data;
1058
1059     return S_OK;
1060 }
1061
1062 static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1063 {
1064     const char *ptr = data;
1065
1066     read_dword(&ptr, &r->version);
1067     TRACE("Shader version: %u\n", r->version);
1068
1069     /* todo: Check if anything else is needed from the shdr or shex blob. */
1070
1071     return S_OK;
1072 }
1073
1074 HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection,
1075         const void *data, SIZE_T data_size)
1076 {
1077     struct dxbc src_dxbc;
1078     HRESULT hr;
1079     unsigned int i;
1080
1081     reflection->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
1082     reflection->refcount = 1;
1083
1084     hr = dxbc_parse(data, data_size, &src_dxbc);
1085     if (FAILED(hr))
1086     {
1087         WARN("Failed to parse reflection\n");
1088         return hr;
1089     }
1090
1091     for (i = 0; i < src_dxbc.count; ++i)
1092     {
1093         struct dxbc_section *section = &src_dxbc.sections[i];
1094
1095         switch (section->tag)
1096         {
1097             case TAG_STAT:
1098                 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size);
1099                 if (FAILED(hr))
1100                 {
1101                     WARN("Failed to parse section STAT.\n");
1102                     goto err_out;
1103                 }
1104                 break;
1105
1106             case TAG_SHEX:
1107             case TAG_SHDR:
1108                 hr = d3dcompiler_parse_shdr(reflection, section->data, section->data_size);
1109                 if (FAILED(hr))
1110                 {
1111                     WARN("Failed to parse SHDR section.\n");
1112                     goto err_out;
1113                 }
1114                 break;
1115
1116             case TAG_RDEF:
1117                 hr = d3dcompiler_parse_rdef(reflection, section->data, section->data_size);
1118                 if (FAILED(hr))
1119                 {
1120                     WARN("Failed to parse RDEF section.\n");
1121                     goto err_out;
1122                 }
1123                 break;
1124
1125             case TAG_ISGN:
1126                 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn));
1127                 if (!reflection->isgn)
1128                 {
1129                     ERR("Failed to allocate ISGN memory.\n");
1130                     hr = E_OUTOFMEMORY;
1131                     goto err_out;
1132                 }
1133
1134                 hr = d3dcompiler_parse_signature(reflection->isgn, section);
1135                 if (FAILED(hr))
1136                 {
1137                     WARN("Failed to parse section ISGN.\n");
1138                     goto err_out;
1139                 }
1140                 break;
1141
1142             case TAG_OSG5:
1143             case TAG_OSGN:
1144                 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn));
1145                 if (!reflection->osgn)
1146                 {
1147                     ERR("Failed to allocate OSGN memory.\n");
1148                     hr = E_OUTOFMEMORY;
1149                     goto err_out;
1150                 }
1151
1152                 hr = d3dcompiler_parse_signature(reflection->osgn, section);
1153                 if (FAILED(hr))
1154                 {
1155                     WARN("Failed to parse section OSGN.\n");
1156                     goto err_out;
1157                 }
1158                 break;
1159
1160             case TAG_PCSG:
1161                 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg));
1162                 if (!reflection->pcsg)
1163                 {
1164                     ERR("Failed to allocate PCSG memory.\n");
1165                     hr = E_OUTOFMEMORY;
1166                     goto err_out;
1167                 }
1168
1169                 hr = d3dcompiler_parse_signature(reflection->pcsg, section);
1170                 if (FAILED(hr))
1171                 {
1172                     WARN("Failed to parse section PCSG.\n");
1173                     goto err_out;
1174                 }
1175                 break;
1176
1177             default:
1178                 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1179                 break;
1180         }
1181     }
1182
1183     dxbc_destroy(&src_dxbc);
1184
1185     return hr;
1186
1187 err_out:
1188     reflection_cleanup(reflection);
1189     dxbc_destroy(&src_dxbc);
1190
1191     return hr;
1192 }