kernel32/tests/pipe: Enable compilation with long types.
[wine.git] / dlls / d3dcompiler_43 / reflection.c
blob91cc20cdded71da9e588e688214ba347c7672263
1 /*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
3 * Copyright 2010 Rico Schüller
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.
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.
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
21 #include "initguid.h"
22 #include "d3dcompiler_private.h"
23 #include "d3d10.h"
25 #if !D3D_COMPILER_VERSION
26 #define ID3D11ShaderReflection ID3D10ShaderReflection
27 #define ID3D11ShaderReflectionVtbl ID3D10ShaderReflectionVtbl
28 #define ID3D11ShaderReflectionConstantBuffer ID3D10ShaderReflectionConstantBuffer
29 #define ID3D11ShaderReflectionConstantBufferVtbl ID3D10ShaderReflectionConstantBufferVtbl
30 #define ID3D11ShaderReflectionType ID3D10ShaderReflectionType
31 #define ID3D11ShaderReflectionTypeVtbl ID3D10ShaderReflectionTypeVtbl
32 #define ID3D11ShaderReflectionVariable ID3D10ShaderReflectionVariable
33 #define ID3D11ShaderReflectionVariableVtbl ID3D10ShaderReflectionVariableVtbl
34 #define IID_ID3D11ShaderReflection IID_ID3D10ShaderReflection
35 #define D3D11_SHADER_BUFFER_DESC D3D10_SHADER_BUFFER_DESC
36 #define D3D11_SHADER_DESC D3D10_SHADER_DESC
37 #define D3D11_SHADER_INPUT_BIND_DESC D3D10_SHADER_INPUT_BIND_DESC
38 #define D3D11_SHADER_TYPE_DESC D3D10_SHADER_TYPE_DESC
39 #define D3D11_SHADER_VARIABLE_DESC D3D10_SHADER_VARIABLE_DESC
40 #define D3D11_SIGNATURE_PARAMETER_DESC D3D10_SIGNATURE_PARAMETER_DESC
41 #endif
43 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
45 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE
47 D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6 = 6,
48 D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7 = 7,
51 #define D3DCOMPILER_SHADER_TARGET_VERSION_MASK 0xffff
52 #define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK 0xffff0000
54 struct d3dcompiler_shader_signature
56 D3D11_SIGNATURE_PARAMETER_DESC *elements;
57 unsigned int element_count;
58 char *string_data;
61 struct d3dcompiler_shader_reflection_type
63 ID3D11ShaderReflectionType ID3D11ShaderReflectionType_iface;
65 uint32_t id;
66 struct wine_rb_entry entry;
68 struct d3dcompiler_shader_reflection *reflection;
70 D3D11_SHADER_TYPE_DESC desc;
71 struct d3dcompiler_shader_reflection_type_member *members;
72 char *name;
75 struct d3dcompiler_shader_reflection_type_member
77 char *name;
78 uint32_t offset;
79 struct d3dcompiler_shader_reflection_type *type;
82 struct d3dcompiler_shader_reflection_variable
84 ID3D11ShaderReflectionVariable ID3D11ShaderReflectionVariable_iface;
86 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffer;
87 struct d3dcompiler_shader_reflection_type *type;
89 char *name;
90 UINT start_offset;
91 UINT size;
92 UINT flags;
93 void *default_value;
96 struct d3dcompiler_shader_reflection_constant_buffer
98 ID3D11ShaderReflectionConstantBuffer ID3D11ShaderReflectionConstantBuffer_iface;
100 struct d3dcompiler_shader_reflection *reflection;
102 char *name;
103 D3D_CBUFFER_TYPE type;
104 UINT variable_count;
105 UINT size;
106 UINT flags;
108 struct d3dcompiler_shader_reflection_variable *variables;
111 enum D3DCOMPILER_REFLECTION_VERSION
113 D3DCOMPILER_REFLECTION_VERSION_D3D10,
114 D3DCOMPILER_REFLECTION_VERSION_D3D11,
115 D3DCOMPILER_REFLECTION_VERSION_D3D12,
118 /* ID3D11ShaderReflection */
119 struct d3dcompiler_shader_reflection
121 ID3D11ShaderReflection ID3D11ShaderReflection_iface;
122 LONG refcount;
124 enum D3DCOMPILER_REFLECTION_VERSION interface_version;
126 uint32_t target;
127 char *creator;
128 UINT flags;
129 UINT version;
130 UINT bound_resource_count;
131 UINT constant_buffer_count;
133 UINT mov_instruction_count;
134 UINT conversion_instruction_count;
135 UINT instruction_count;
136 UINT emit_instruction_count;
137 D3D_PRIMITIVE_TOPOLOGY gs_output_topology;
138 UINT gs_max_output_vertex_count;
139 D3D_PRIMITIVE input_primitive;
140 UINT cut_instruction_count;
141 UINT def_count;
142 UINT dcl_count;
143 UINT static_flow_control_count;
144 UINT float_instruction_count;
145 UINT temp_register_count;
146 UINT int_instruction_count;
147 UINT uint_instruction_count;
148 UINT temp_array_count;
149 UINT array_instruction_count;
150 UINT texture_normal_instructions;
151 UINT texture_load_instructions;
152 UINT texture_comp_instructions;
153 UINT texture_bias_instructions;
154 UINT texture_gradient_instructions;
155 UINT dynamic_flow_control_count;
156 UINT macro_instruction_count;
157 UINT c_control_points;
158 D3D_TESSELLATOR_OUTPUT_PRIMITIVE hs_output_primitive;
159 D3D_TESSELLATOR_PARTITIONING hs_partitioning;
160 D3D_TESSELLATOR_DOMAIN tessellator_domain;
162 struct d3dcompiler_shader_signature *isgn;
163 struct d3dcompiler_shader_signature *osgn;
164 struct d3dcompiler_shader_signature *pcsg;
165 char *resource_string;
166 D3D12_SHADER_INPUT_BIND_DESC *bound_resources;
167 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers;
168 struct wine_rb_tree types;
171 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, uint32_t offset);
173 static const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl;
174 static const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl;
175 static const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl;
177 /* null objects - needed for invalid calls */
178 static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer =
180 {&d3dcompiler_shader_reflection_constant_buffer_vtbl},
182 static struct d3dcompiler_shader_reflection_type null_type =
184 {&d3dcompiler_shader_reflection_type_vtbl},
186 static struct d3dcompiler_shader_reflection_variable null_variable =
188 {&d3dcompiler_shader_reflection_variable_vtbl},
189 &null_constant_buffer,
190 &null_type
193 static BOOL copy_name(const char *ptr, char **name)
195 size_t name_len;
197 if (!ptr) return TRUE;
199 name_len = strlen(ptr) + 1;
200 if (name_len == 1)
202 return TRUE;
205 *name = HeapAlloc(GetProcessHeap(), 0, name_len);
206 if (!*name)
208 ERR("Failed to allocate name memory.\n");
209 return FALSE;
212 memcpy(*name, ptr, name_len);
214 return TRUE;
217 static BOOL copy_value(const char *ptr, void **value, uint32_t size)
219 if (!ptr || !size) return TRUE;
221 *value = HeapAlloc(GetProcessHeap(), 0, size);
222 if (!*value)
224 ERR("Failed to allocate value memory.\n");
225 return FALSE;
228 memcpy(*value, ptr, size);
230 return TRUE;
233 static int d3dcompiler_shader_reflection_type_compare(const void *key, const struct wine_rb_entry *entry)
235 const struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, const struct d3dcompiler_shader_reflection_type, entry);
236 const uint32_t *id = key;
238 return *id - t->id;
241 static void free_type_member(struct d3dcompiler_shader_reflection_type_member *member)
243 if (member)
245 HeapFree(GetProcessHeap(), 0, member->name);
249 static void d3dcompiler_shader_reflection_type_destroy(struct wine_rb_entry *entry, void *context)
251 struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry);
252 unsigned int i;
254 TRACE("reflection type %p.\n", t);
256 if (t->members)
258 for (i = 0; i < t->desc.Members; ++i)
260 free_type_member(&t->members[i]);
262 HeapFree(GetProcessHeap(), 0, t->members);
265 heap_free(t->name);
266 HeapFree(GetProcessHeap(), 0, t);
269 static void free_signature(struct d3dcompiler_shader_signature *sig)
271 TRACE("Free signature %p\n", sig);
273 HeapFree(GetProcessHeap(), 0, sig->elements);
274 HeapFree(GetProcessHeap(), 0, sig->string_data);
277 static void free_variable(struct d3dcompiler_shader_reflection_variable *var)
279 if (var)
281 HeapFree(GetProcessHeap(), 0, var->name);
282 HeapFree(GetProcessHeap(), 0, var->default_value);
286 static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb)
288 if (cb->variables)
290 unsigned int i;
292 for (i = 0; i < cb->variable_count; ++i)
294 free_variable(&cb->variables[i]);
296 HeapFree(GetProcessHeap(), 0, cb->variables);
299 HeapFree(GetProcessHeap(), 0, cb->name);
302 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref)
304 TRACE("Cleanup %p\n", ref);
306 if (ref->isgn)
308 free_signature(ref->isgn);
309 HeapFree(GetProcessHeap(), 0, ref->isgn);
312 if (ref->osgn)
314 free_signature(ref->osgn);
315 HeapFree(GetProcessHeap(), 0, ref->osgn);
318 if (ref->pcsg)
320 free_signature(ref->pcsg);
321 HeapFree(GetProcessHeap(), 0, ref->pcsg);
324 if (ref->constant_buffers)
326 unsigned int i;
328 for (i = 0; i < ref->constant_buffer_count; ++i)
330 free_constant_buffer(&ref->constant_buffers[i]);
334 wine_rb_destroy(&ref->types, d3dcompiler_shader_reflection_type_destroy, NULL);
335 HeapFree(GetProcessHeap(), 0, ref->constant_buffers);
336 HeapFree(GetProcessHeap(), 0, ref->bound_resources);
337 HeapFree(GetProcessHeap(), 0, ref->resource_string);
338 HeapFree(GetProcessHeap(), 0, ref->creator);
341 /* IUnknown methods */
343 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
345 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
348 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
350 TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
352 if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
353 || IsEqualGUID(riid, &IID_IUnknown)
354 || (D3D_COMPILER_VERSION >= 47 && IsEqualGUID(riid, &IID_ID3D12ShaderReflection)))
356 IUnknown_AddRef(iface);
357 *object = iface;
358 return S_OK;
361 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
363 *object = NULL;
364 return E_NOINTERFACE;
367 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
369 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
370 ULONG refcount = InterlockedIncrement(&This->refcount);
372 TRACE("%p increasing refcount to %lu.\n", This, refcount);
374 return refcount;
377 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
379 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
380 ULONG refcount = InterlockedDecrement(&This->refcount);
382 TRACE("%p decreasing refcount to %lu.\n", This, refcount);
384 if (!refcount)
386 reflection_cleanup(This);
387 HeapFree(GetProcessHeap(), 0, This);
390 return refcount;
393 /* ID3D11ShaderReflection methods */
395 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
397 struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface);
399 FIXME("iface %p, desc %p partial stub!\n", iface, desc);
401 if (!desc)
403 WARN("Invalid argument specified\n");
404 return E_FAIL;
407 desc->Version = reflection->version;
408 desc->Creator = reflection->creator;
409 desc->Flags = reflection->flags;
410 desc->ConstantBuffers = reflection->constant_buffer_count;
411 desc->BoundResources = reflection->bound_resource_count;
412 desc->InputParameters = reflection->isgn ? reflection->isgn->element_count : 0;
413 desc->OutputParameters = reflection->osgn ? reflection->osgn->element_count : 0;
414 desc->InstructionCount = reflection->instruction_count;
415 desc->TempRegisterCount = reflection->temp_register_count;
416 desc->TempArrayCount = reflection->temp_array_count;
417 desc->DefCount = reflection->def_count;
418 desc->DclCount = reflection->dcl_count;
419 desc->TextureNormalInstructions = reflection->texture_normal_instructions;
420 desc->TextureLoadInstructions = reflection->texture_load_instructions;
421 desc->TextureCompInstructions = reflection->texture_comp_instructions;
422 desc->TextureBiasInstructions = reflection->texture_bias_instructions;
423 desc->TextureGradientInstructions = reflection->texture_gradient_instructions;
424 desc->FloatInstructionCount = reflection->float_instruction_count;
425 desc->IntInstructionCount = reflection->int_instruction_count;
426 desc->UintInstructionCount = reflection->uint_instruction_count;
427 desc->StaticFlowControlCount = reflection->static_flow_control_count;
428 desc->DynamicFlowControlCount = reflection->dynamic_flow_control_count;
429 desc->MacroInstructionCount = reflection->macro_instruction_count;
430 desc->ArrayInstructionCount = reflection->array_instruction_count;
431 desc->CutInstructionCount = reflection->cut_instruction_count;
432 desc->EmitInstructionCount = reflection->emit_instruction_count;
433 desc->GSOutputTopology = reflection->gs_output_topology;
434 desc->GSMaxOutputVertexCount = reflection->gs_max_output_vertex_count;
435 #if D3D_COMPILER_VERSION
436 desc->InputPrimitive = reflection->input_primitive;
437 desc->PatchConstantParameters = reflection->pcsg ? reflection->pcsg->element_count : 0;
438 desc->cGSInstanceCount = 0;
439 desc->cControlPoints = reflection->c_control_points;
440 desc->HSOutputPrimitive = reflection->hs_output_primitive;
441 desc->HSPartitioning = reflection->hs_partitioning;
442 desc->TessellatorDomain = reflection->tessellator_domain;
443 desc->cBarrierInstructions = 0;
444 desc->cInterlockedInstructions = 0;
445 desc->cTextureStoreInstructions = 0;
446 #endif
448 return S_OK;
451 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
452 ID3D11ShaderReflection *iface, UINT index)
454 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
456 TRACE("iface %p, index %u\n", iface, index);
458 if (index >= This->constant_buffer_count)
460 WARN("Invalid argument specified\n");
461 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
464 return &This->constant_buffers[index].ID3D11ShaderReflectionConstantBuffer_iface;
467 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
468 ID3D11ShaderReflection *iface, const char *name)
470 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
471 unsigned int i;
473 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
475 if (!name)
477 WARN("Invalid argument specified\n");
478 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
481 for (i = 0; i < This->constant_buffer_count; ++i)
483 struct d3dcompiler_shader_reflection_constant_buffer *d = &This->constant_buffers[i];
485 if (!strcmp(d->name, name))
487 TRACE("Returning ID3D11ShaderReflectionConstantBuffer %p.\n", d);
488 return &d->ID3D11ShaderReflectionConstantBuffer_iface;
492 WARN("Invalid name specified\n");
494 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
497 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
498 ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
500 struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface);
502 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
504 if (!desc || index >= reflection->bound_resource_count)
506 WARN("Invalid argument specified\n");
507 return E_INVALIDARG;
510 memcpy(desc, &reflection->bound_resources[index],
511 reflection->interface_version == D3DCOMPILER_REFLECTION_VERSION_D3D12
512 ? sizeof(D3D12_SHADER_INPUT_BIND_DESC) : sizeof(D3D11_SHADER_INPUT_BIND_DESC));
514 return S_OK;
517 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
518 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
520 struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface);
522 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
524 if (!desc || !reflection->isgn || index >= reflection->isgn->element_count)
526 WARN("Invalid argument specified\n");
527 return E_INVALIDARG;
530 *desc = reflection->isgn->elements[index];
532 return S_OK;
535 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
536 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
538 struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface);
540 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
542 if (!desc || !reflection->osgn || index >= reflection->osgn->element_count)
544 WARN("Invalid argument specified\n");
545 return E_INVALIDARG;
548 *desc = reflection->osgn->elements[index];
550 return S_OK;
553 #if D3D_COMPILER_VERSION
554 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
555 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
557 struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface);
559 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
561 if (!desc || !reflection->pcsg || index >= reflection->pcsg->element_count)
563 WARN("Invalid argument specified\n");
564 return E_INVALIDARG;
567 *desc = reflection->pcsg->elements[index];
569 return S_OK;
572 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
573 ID3D11ShaderReflection *iface, const char *name)
575 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
576 unsigned int i, k;
578 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
580 if (!name)
582 WARN("Invalid name specified\n");
583 return &null_variable.ID3D11ShaderReflectionVariable_iface;
586 for (i = 0; i < This->constant_buffer_count; ++i)
588 struct d3dcompiler_shader_reflection_constant_buffer *cb = &This->constant_buffers[i];
590 for (k = 0; k < cb->variable_count; ++k)
592 struct d3dcompiler_shader_reflection_variable *v = &cb->variables[k];
594 if (!strcmp(v->name, name))
596 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v);
597 return &v->ID3D11ShaderReflectionVariable_iface;
602 WARN("Invalid name specified\n");
604 return &null_variable.ID3D11ShaderReflectionVariable_iface;
607 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
608 ID3D11ShaderReflection *iface, const char *name, D3D11_SHADER_INPUT_BIND_DESC *desc)
610 struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface);
611 unsigned int i;
613 TRACE("iface %p, name %s, desc %p\n", iface, debugstr_a(name), desc);
615 if (!desc || !name)
617 WARN("Invalid argument specified\n");
618 return E_INVALIDARG;
621 for (i = 0; i < reflection->bound_resource_count; ++i)
623 D3D12_SHADER_INPUT_BIND_DESC *d = &reflection->bound_resources[i];
625 if (!strcmp(d->Name, name))
627 TRACE("Returning D3D11_SHADER_INPUT_BIND_DESC %p.\n", d);
628 memcpy(desc, d, reflection->interface_version == D3DCOMPILER_REFLECTION_VERSION_D3D12
629 ? sizeof(D3D12_SHADER_INPUT_BIND_DESC) : sizeof(D3D11_SHADER_INPUT_BIND_DESC));
630 return S_OK;
634 WARN("Invalid name specified\n");
636 return E_INVALIDARG;
639 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
640 ID3D11ShaderReflection *iface)
642 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
644 TRACE("iface %p\n", iface);
646 return This->mov_instruction_count;
649 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
650 ID3D11ShaderReflection *iface)
652 FIXME("iface %p stub!\n", iface);
654 return 0;
657 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
658 ID3D11ShaderReflection *iface)
660 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
662 TRACE("iface %p\n", iface);
664 return This->conversion_instruction_count;
667 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
668 ID3D11ShaderReflection *iface)
670 FIXME("iface %p stub!\n", iface);
672 return 0;
675 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
676 ID3D11ShaderReflection *iface)
678 FIXME("iface %p stub!\n", iface);
680 return 0;
683 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
684 ID3D11ShaderReflection *iface)
686 FIXME("iface %p stub!\n", iface);
688 return FALSE;
691 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
692 ID3D11ShaderReflection *iface)
694 FIXME("iface %p stub!\n", iface);
696 return 0;
699 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
700 ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
702 FIXME("iface %p, level %p stub!\n", iface, level);
704 return E_NOTIMPL;
707 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize(
708 ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez)
710 FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez);
712 return 0;
715 static UINT64 STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetRequiresFlags(
716 ID3D11ShaderReflection *iface)
718 FIXME("iface %p stub!\n", iface);
720 return 0;
722 #endif
724 static const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
726 /* IUnknown methods */
727 d3dcompiler_shader_reflection_QueryInterface,
728 d3dcompiler_shader_reflection_AddRef,
729 d3dcompiler_shader_reflection_Release,
730 /* ID3D11ShaderReflection methods */
731 d3dcompiler_shader_reflection_GetDesc,
732 d3dcompiler_shader_reflection_GetConstantBufferByIndex,
733 d3dcompiler_shader_reflection_GetConstantBufferByName,
734 d3dcompiler_shader_reflection_GetResourceBindingDesc,
735 d3dcompiler_shader_reflection_GetInputParameterDesc,
736 d3dcompiler_shader_reflection_GetOutputParameterDesc,
737 #if D3D_COMPILER_VERSION
738 d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
739 d3dcompiler_shader_reflection_GetVariableByName,
740 d3dcompiler_shader_reflection_GetResourceBindingDescByName,
741 d3dcompiler_shader_reflection_GetMovInstructionCount,
742 d3dcompiler_shader_reflection_GetMovcInstructionCount,
743 d3dcompiler_shader_reflection_GetConversionInstructionCount,
744 d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
745 d3dcompiler_shader_reflection_GetGSInputPrimitive,
746 d3dcompiler_shader_reflection_IsSampleFrequencyShader,
747 d3dcompiler_shader_reflection_GetNumInterfaceSlots,
748 d3dcompiler_shader_reflection_GetMinFeatureLevel,
749 d3dcompiler_shader_reflection_GetThreadGroupSize,
750 d3dcompiler_shader_reflection_GetRequiresFlags,
751 #endif
754 /* ID3D11ShaderReflectionConstantBuffer methods */
756 static inline struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D11ShaderReflectionConstantBuffer *iface)
758 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D11ShaderReflectionConstantBuffer_iface);
761 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc(
762 ID3D11ShaderReflectionConstantBuffer *iface, D3D11_SHADER_BUFFER_DESC *desc)
764 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
766 TRACE("iface %p, desc %p\n", iface, desc);
768 if (This == &null_constant_buffer)
770 WARN("Null constant buffer specified\n");
771 return E_FAIL;
774 if (!desc)
776 WARN("Invalid argument specified\n");
777 return E_FAIL;
780 desc->Name = This->name;
781 desc->Type = This->type;
782 desc->Variables = This->variable_count;
783 desc->Size = This->size;
784 desc->uFlags = This->flags;
786 return S_OK;
789 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex(
790 ID3D11ShaderReflectionConstantBuffer *iface, UINT index)
792 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
794 TRACE("iface %p, index %u\n", iface, index);
796 if (index >= This->variable_count)
798 WARN("Invalid index specified\n");
799 return &null_variable.ID3D11ShaderReflectionVariable_iface;
802 return &This->variables[index].ID3D11ShaderReflectionVariable_iface;
805 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName(
806 ID3D11ShaderReflectionConstantBuffer *iface, const char *name)
808 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
809 unsigned int i;
811 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
813 if (!name)
815 WARN("Invalid argument specified\n");
816 return &null_variable.ID3D11ShaderReflectionVariable_iface;
819 for (i = 0; i < This->variable_count; ++i)
821 struct d3dcompiler_shader_reflection_variable *v = &This->variables[i];
823 if (!strcmp(v->name, name))
825 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v);
826 return &v->ID3D11ShaderReflectionVariable_iface;
830 WARN("Invalid name specified\n");
832 return &null_variable.ID3D11ShaderReflectionVariable_iface;
835 static const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl =
837 /* ID3D11ShaderReflectionConstantBuffer methods */
838 d3dcompiler_shader_reflection_constant_buffer_GetDesc,
839 d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex,
840 d3dcompiler_shader_reflection_constant_buffer_GetVariableByName,
843 /* ID3D11ShaderReflectionVariable methods */
845 static inline struct d3dcompiler_shader_reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D11ShaderReflectionVariable *iface)
847 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_variable, ID3D11ShaderReflectionVariable_iface);
850 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc(
851 ID3D11ShaderReflectionVariable *iface, D3D11_SHADER_VARIABLE_DESC *desc)
853 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
855 TRACE("iface %p, desc %p\n", iface, desc);
857 if (This == &null_variable)
859 WARN("Null variable specified\n");
860 return E_FAIL;
863 if (!desc)
865 WARN("Invalid argument specified\n");
866 return E_FAIL;
869 desc->Name = This->name;
870 desc->StartOffset = This->start_offset;
871 desc->Size = This->size;
872 desc->uFlags = This->flags;
873 desc->DefaultValue = This->default_value;
875 #if D3D_COMPILER_VERSION
876 /* TODO test and set proper values for texture. */
877 desc->StartTexture = 0xffffffff;
878 desc->TextureSize = 0;
879 desc->StartSampler = 0xffffffff;
880 desc->SamplerSize = 0;
881 #endif
883 return S_OK;
886 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType(
887 ID3D11ShaderReflectionVariable *iface)
889 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
891 TRACE("iface %p\n", iface);
893 return &This->type->ID3D11ShaderReflectionType_iface;
896 #if D3D_COMPILER_VERSION
897 static ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer(
898 ID3D11ShaderReflectionVariable *iface)
900 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
902 TRACE("iface %p\n", iface);
904 return &This->constant_buffer->ID3D11ShaderReflectionConstantBuffer_iface;
907 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot(
908 ID3D11ShaderReflectionVariable *iface, UINT index)
910 FIXME("iface %p, index %u stub!\n", iface, index);
912 return 0;
914 #endif
916 static const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl =
918 /* ID3D11ShaderReflectionVariable methods */
919 d3dcompiler_shader_reflection_variable_GetDesc,
920 d3dcompiler_shader_reflection_variable_GetType,
921 #if D3D_COMPILER_VERSION
922 d3dcompiler_shader_reflection_variable_GetBuffer,
923 d3dcompiler_shader_reflection_variable_GetInterfaceSlot,
924 #endif
927 /* ID3D11ShaderReflectionType methods */
929 static inline struct d3dcompiler_shader_reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D11ShaderReflectionType *iface)
931 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_type, ID3D11ShaderReflectionType_iface);
934 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc(
935 ID3D11ShaderReflectionType *iface, D3D11_SHADER_TYPE_DESC *desc)
937 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
939 TRACE("iface %p, desc %p\n", iface, desc);
941 if (This == &null_type)
943 WARN("Null type specified\n");
944 return E_FAIL;
947 if (!desc)
949 WARN("Invalid argument specified\n");
950 return E_FAIL;
953 *desc = This->desc;
955 return S_OK;
958 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByIndex(
959 ID3D11ShaderReflectionType *iface, UINT index)
961 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
963 TRACE("iface %p, index %u\n", iface, index);
965 if (index >= This->desc.Members)
967 WARN("Invalid index specified\n");
968 return &null_type.ID3D11ShaderReflectionType_iface;
971 return &This->members[index].type->ID3D11ShaderReflectionType_iface;
974 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByName(
975 ID3D11ShaderReflectionType *iface, const char *name)
977 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
978 unsigned int i;
980 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
982 if (!name)
984 WARN("Invalid argument specified\n");
985 return &null_type.ID3D11ShaderReflectionType_iface;
988 for (i = 0; i < This->desc.Members; ++i)
990 struct d3dcompiler_shader_reflection_type_member *member = &This->members[i];
992 if (!strcmp(member->name, name))
994 TRACE("Returning ID3D11ShaderReflectionType %p.\n", member->type);
995 return &member->type->ID3D11ShaderReflectionType_iface;
999 WARN("Invalid name specified\n");
1001 return &null_type.ID3D11ShaderReflectionType_iface;
1004 static const char * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeName(
1005 ID3D11ShaderReflectionType *iface, UINT index)
1007 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
1009 TRACE("iface %p, index %u\n", iface, index);
1011 if (This == &null_type)
1013 WARN("Null type specified\n");
1014 return "$Invalid";
1017 if (index >= This->desc.Members)
1019 WARN("Invalid index specified\n");
1020 return NULL;
1023 return This->members[index].name;
1026 #if D3D_COMPILER_VERSION
1027 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual(
1028 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type)
1030 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
1032 TRACE("iface %p, type %p\n", iface, type);
1034 if (This == &null_type)
1036 WARN("Null type specified\n");
1037 return E_FAIL;
1040 if (iface == type)
1041 return S_OK;
1043 return S_FALSE;
1046 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetSubType(
1047 ID3D11ShaderReflectionType *iface)
1049 FIXME("iface %p stub!\n", iface);
1051 return NULL;
1054 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetBaseClass(
1055 ID3D11ShaderReflectionType *iface)
1057 FIXME("iface %p stub!\n", iface);
1059 return NULL;
1062 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterfaces(
1063 ID3D11ShaderReflectionType *iface)
1065 FIXME("iface %p stub!\n", iface);
1067 return 0;
1070 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetInterfaceByIndex(
1071 ID3D11ShaderReflectionType *iface, UINT index)
1073 FIXME("iface %p, index %u stub!\n", iface, index);
1075 return NULL;
1078 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType(
1079 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type)
1081 FIXME("iface %p, type %p stub!\n", iface, type);
1083 return E_NOTIMPL;
1086 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsInterface(
1087 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *base)
1089 FIXME("iface %p, base %p stub!\n", iface, base);
1091 return E_NOTIMPL;
1093 #endif
1095 static const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl =
1097 /* ID3D11ShaderReflectionType methods */
1098 d3dcompiler_shader_reflection_type_GetDesc,
1099 d3dcompiler_shader_reflection_type_GetMemberTypeByIndex,
1100 d3dcompiler_shader_reflection_type_GetMemberTypeByName,
1101 d3dcompiler_shader_reflection_type_GetMemberTypeName,
1102 #if D3D_COMPILER_VERSION
1103 d3dcompiler_shader_reflection_type_IsEqual,
1104 d3dcompiler_shader_reflection_type_GetSubType,
1105 d3dcompiler_shader_reflection_type_GetBaseClass,
1106 d3dcompiler_shader_reflection_type_GetNumInterfaces,
1107 d3dcompiler_shader_reflection_type_GetInterfaceByIndex,
1108 d3dcompiler_shader_reflection_type_IsOfType,
1109 d3dcompiler_shader_reflection_type_ImplementsInterface,
1110 #endif
1113 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size)
1115 const char *ptr = data;
1116 size_t size = data_size >> 2;
1118 TRACE("Size %Iu.\n", size);
1120 r->instruction_count = read_u32(&ptr);
1121 TRACE("InstructionCount: %u.\n", r->instruction_count);
1123 r->temp_register_count = read_u32(&ptr);
1124 TRACE("TempRegisterCount: %u.\n", r->temp_register_count);
1126 r->def_count = read_u32(&ptr);
1127 TRACE("DefCount: %u.\n", r->def_count);
1129 r->dcl_count = read_u32(&ptr);
1130 TRACE("DclCount: %u.\n", r->dcl_count);
1132 r->float_instruction_count = read_u32(&ptr);
1133 TRACE("FloatInstructionCount: %u.\n", r->float_instruction_count);
1135 r->int_instruction_count = read_u32(&ptr);
1136 TRACE("IntInstructionCount: %u.\n", r->int_instruction_count);
1138 r->uint_instruction_count = read_u32(&ptr);
1139 TRACE("UintInstructionCount: %u.\n", r->uint_instruction_count);
1141 r->static_flow_control_count = read_u32(&ptr);
1142 TRACE("StaticFlowControlCount: %u.\n", r->static_flow_control_count);
1144 r->dynamic_flow_control_count = read_u32(&ptr);
1145 TRACE("DynamicFlowControlCount: %u.\n", r->dynamic_flow_control_count);
1147 r->macro_instruction_count = read_u32(&ptr);
1148 TRACE("MacroInstructionCount: %u.\n", r->macro_instruction_count);
1150 r->temp_array_count = read_u32(&ptr);
1151 TRACE("TempArrayCount: %u.\n", r->temp_array_count);
1153 r->array_instruction_count = read_u32(&ptr);
1154 TRACE("ArrayInstructionCount: %u.\n", r->array_instruction_count);
1156 r->cut_instruction_count = read_u32(&ptr);
1157 TRACE("CutInstructionCount: %u.\n", r->cut_instruction_count);
1159 r->emit_instruction_count = read_u32(&ptr);
1160 TRACE("EmitInstructionCount: %u.\n", r->emit_instruction_count);
1162 r->texture_normal_instructions = read_u32(&ptr);
1163 TRACE("TextureNormalInstructions: %u.\n", r->texture_normal_instructions);
1165 r->texture_load_instructions = read_u32(&ptr);
1166 TRACE("TextureLoadInstructions: %u.\n", r->texture_load_instructions);
1168 r->texture_comp_instructions = read_u32(&ptr);
1169 TRACE("TextureCompInstructions: %u.\n", r->texture_comp_instructions);
1171 r->texture_bias_instructions = read_u32(&ptr);
1172 TRACE("TextureBiasInstructions: %u.\n", r->texture_bias_instructions);
1174 r->texture_gradient_instructions = read_u32(&ptr);
1175 TRACE("TextureGradientInstructions: %u.\n", r->texture_gradient_instructions);
1177 r->mov_instruction_count = read_u32(&ptr);
1178 TRACE("MovInstructionCount: %u.\n", r->mov_instruction_count);
1180 skip_u32_unknown(&ptr, 1);
1182 r->conversion_instruction_count = read_u32(&ptr);
1183 TRACE("ConversionInstructionCount: %u.\n", r->conversion_instruction_count);
1185 skip_u32_unknown(&ptr, 1);
1187 r->input_primitive = read_u32(&ptr);
1188 TRACE("InputPrimitive: %x.\n", r->input_primitive);
1190 r->gs_output_topology = read_u32(&ptr);
1191 TRACE("GSOutputTopology: %x.\n", r->gs_output_topology);
1193 r->gs_max_output_vertex_count = read_u32(&ptr);
1194 TRACE("GSMaxOutputVertexCount: %u.\n", r->gs_max_output_vertex_count);
1196 skip_u32_unknown(&ptr, 2);
1198 /* old dx10 stat size */
1199 if (size == 28) return S_OK;
1201 skip_u32_unknown(&ptr, 1);
1203 /* dx10 stat size */
1204 if (size == 29) return S_OK;
1206 skip_u32_unknown(&ptr, 1);
1208 r->c_control_points = read_u32(&ptr);
1209 TRACE("cControlPoints: %u.\n", r->c_control_points);
1211 r->hs_output_primitive = read_u32(&ptr);
1212 TRACE("HSOutputPrimitive: %x.\n", r->hs_output_primitive);
1214 r->hs_partitioning = read_u32(&ptr);
1215 TRACE("HSPartitioning: %x.\n", r->hs_partitioning);
1217 r->tessellator_domain = read_u32(&ptr);
1218 TRACE("TessellatorDomain: %x.\n", r->tessellator_domain);
1220 skip_u32_unknown(&ptr, 3);
1222 /* dx11 stat size */
1223 if (size == 37) return S_OK;
1225 FIXME("Unhandled size %Iu.\n", size);
1227 return E_FAIL;
1230 static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflection *ref,
1231 struct d3dcompiler_shader_reflection_type_member *member, const char *data, const char **ptr)
1233 uint32_t offset;
1235 offset = read_u32(ptr);
1236 if (!copy_name(data + offset, &member->name))
1238 ERR("Failed to copy name.\n");
1239 return E_OUTOFMEMORY;
1241 TRACE("Member name: %s.\n", debugstr_a(member->name));
1243 offset = read_u32(ptr);
1244 TRACE("Member type offset: %x.\n", offset);
1246 member->type = get_reflection_type(ref, data, offset);
1247 if (!member->type)
1249 ERR("Failed to get member type\n");
1250 HeapFree(GetProcessHeap(), 0, member->name);
1251 return E_FAIL;
1254 member->offset = read_u32(ptr);
1255 TRACE("Member offset %x.\n", member->offset);
1257 return S_OK;
1260 static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type *type, const char *data, uint32_t offset)
1262 const char *ptr = data + offset;
1263 uint32_t temp;
1264 D3D11_SHADER_TYPE_DESC *desc;
1265 unsigned int i;
1266 struct d3dcompiler_shader_reflection_type_member *members = NULL;
1267 HRESULT hr;
1268 uint32_t member_offset;
1270 desc = &type->desc;
1272 temp = read_u32(&ptr);
1273 desc->Class = temp & 0xffff;
1274 desc->Type = temp >> 16;
1275 TRACE("Class %s, Type %s\n", debug_d3dcompiler_shader_variable_class(desc->Class),
1276 debug_d3dcompiler_shader_variable_type(desc->Type));
1278 temp = read_u32(&ptr);
1279 desc->Rows = temp & 0xffff;
1280 desc->Columns = temp >> 16;
1281 TRACE("Rows %u, Columns %u\n", desc->Rows, desc->Columns);
1283 temp = read_u32(&ptr);
1284 desc->Elements = temp & 0xffff;
1285 desc->Members = temp >> 16;
1286 TRACE("Elements %u, Members %u\n", desc->Elements, desc->Members);
1288 member_offset = read_u32(&ptr);
1289 TRACE("Member Offset %u.\n", member_offset);
1291 if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1292 skip_u32_unknown(&ptr, 4);
1294 if (desc->Members)
1296 const char *ptr2 = data + member_offset;
1298 members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*members) * desc->Members);
1299 if (!members)
1301 ERR("Failed to allocate type memory.\n");
1302 return E_OUTOFMEMORY;
1305 for (i = 0; i < desc->Members; ++i)
1307 hr = d3dcompiler_parse_type_members(type->reflection, &members[i], data, &ptr2);
1308 if (hr != S_OK)
1310 FIXME("Failed to parse type members.\n");
1311 goto err_out;
1316 #if D3D_COMPILER_VERSION
1317 if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1319 offset = read_u32(&ptr);
1320 if (!copy_name(data + offset, &type->name))
1322 ERR("Failed to copy name.\n");
1323 heap_free(members);
1324 return E_OUTOFMEMORY;
1326 desc->Name = type->name;
1327 TRACE("Type name: %s.\n", debugstr_a(type->name));
1329 #endif
1331 type->members = members;
1333 return S_OK;
1335 err_out:
1336 for (i = 0; i < desc->Members; ++i)
1338 free_type_member(&members[i]);
1340 HeapFree(GetProcessHeap(), 0, members);
1341 return hr;
1344 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, uint32_t offset)
1346 struct d3dcompiler_shader_reflection_type *type;
1347 struct wine_rb_entry *entry;
1348 HRESULT hr;
1350 entry = wine_rb_get(&reflection->types, &offset);
1351 if (entry)
1353 TRACE("Returning existing type.\n");
1354 return WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry);
1357 type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*type));
1358 if (!type)
1359 return NULL;
1361 type->ID3D11ShaderReflectionType_iface.lpVtbl = &d3dcompiler_shader_reflection_type_vtbl;
1362 type->id = offset;
1363 type->reflection = reflection;
1365 hr = d3dcompiler_parse_type(type, data, offset);
1366 if (FAILED(hr))
1368 ERR("Failed to parse type info, hr %#lx.\n", hr);
1369 HeapFree(GetProcessHeap(), 0, type);
1370 return NULL;
1373 if (wine_rb_put(&reflection->types, &offset, &type->entry) == -1)
1375 ERR("Failed to insert type entry.\n");
1376 HeapFree(GetProcessHeap(), 0, type);
1377 return NULL;
1380 return type;
1383 static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb,
1384 const char *data, size_t data_size, const char *ptr)
1386 struct d3dcompiler_shader_reflection_variable *variables;
1387 unsigned int i;
1388 HRESULT hr;
1390 variables = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb->variable_count * sizeof(*variables));
1391 if (!variables)
1393 ERR("Failed to allocate variables memory.\n");
1394 return E_OUTOFMEMORY;
1397 for (i = 0; i < cb->variable_count; i++)
1399 struct d3dcompiler_shader_reflection_variable *v = &variables[i];
1400 uint32_t offset;
1402 v->ID3D11ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl;
1403 v->constant_buffer = cb;
1405 offset = read_u32(&ptr);
1406 if (!copy_name(data + offset, &v->name))
1408 ERR("Failed to copy name.\n");
1409 hr = E_OUTOFMEMORY;
1410 goto err_out;
1412 TRACE("Variable name: %s.\n", debugstr_a(v->name));
1414 v->start_offset = read_u32(&ptr);
1415 TRACE("Variable offset: %u\n", v->start_offset);
1417 v->size = read_u32(&ptr);
1418 TRACE("Variable size: %u\n", v->size);
1420 v->flags = read_u32(&ptr);
1421 TRACE("Variable flags: %u\n", v->flags);
1423 offset = read_u32(&ptr);
1424 TRACE("Variable type offset: %x.\n", offset);
1425 v->type = get_reflection_type(cb->reflection, data, offset);
1426 if (!v->type)
1428 ERR("Failed to get type.\n");
1429 hr = E_FAIL;
1430 goto err_out;
1433 offset = read_u32(&ptr);
1434 TRACE("Variable default value offset: %x.\n", offset);
1435 if (!copy_value(data + offset, &v->default_value, offset ? v->size : 0))
1437 ERR("Failed to copy name.\n");
1438 hr = E_OUTOFMEMORY;
1439 goto err_out;
1442 if ((cb->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1443 skip_u32_unknown(&ptr, 4);
1446 cb->variables = variables;
1448 return S_OK;
1450 err_out:
1451 for (i = 0; i < cb->variable_count; i++)
1453 free_variable(&variables[i]);
1455 HeapFree(GetProcessHeap(), 0, variables);
1456 return hr;
1459 static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size)
1461 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL;
1462 uint32_t offset, cbuffer_offset, resource_offset, creator_offset;
1463 unsigned int i, string_data_offset, string_data_size;
1464 D3D12_SHADER_INPUT_BIND_DESC *bound_resources = NULL;
1465 char *string_data = NULL, *creator = NULL;
1466 size_t size = data_size >> 2;
1467 uint32_t target_version;
1468 const char *ptr = data;
1469 HRESULT hr;
1471 TRACE("Size %Iu.\n", size);
1473 r->constant_buffer_count = read_u32(&ptr);
1474 TRACE("Constant buffer count: %u.\n", r->constant_buffer_count);
1476 cbuffer_offset = read_u32(&ptr);
1477 TRACE("Constant buffer offset: %#x.\n", cbuffer_offset);
1479 r->bound_resource_count = read_u32(&ptr);
1480 TRACE("Bound resource count: %u.\n", r->bound_resource_count);
1482 resource_offset = read_u32(&ptr);
1483 TRACE("Bound resource offset: %#x.\n", resource_offset);
1485 r->target = read_u32(&ptr);
1486 TRACE("Target: %#x.\n", r->target);
1488 target_version = r->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK;
1490 #if D3D_COMPILER_VERSION < 47
1491 if (target_version >= 0x501)
1493 WARN("Target version %#x is not supported in d3dcompiler %u.\n", target_version, D3D_COMPILER_VERSION);
1494 return E_INVALIDARG;
1496 #endif
1498 r->flags = read_u32(&ptr);
1499 TRACE("Flags: %u.\n", r->flags);
1501 creator_offset = read_u32(&ptr);
1502 TRACE("Creator at offset %#x.\n", creator_offset);
1504 if (!copy_name(data + creator_offset, &creator))
1506 ERR("Failed to copy name.\n");
1507 return E_OUTOFMEMORY;
1509 TRACE("Creator: %s.\n", debugstr_a(creator));
1511 /* todo: Parse RD11 */
1512 if (target_version >= 0x500)
1514 skip_u32_unknown(&ptr, 8);
1517 if (r->bound_resource_count)
1519 /* 8 for each bind desc */
1520 string_data_offset = resource_offset + r->bound_resource_count * 8 * sizeof(uint32_t);
1521 string_data_size = (cbuffer_offset ? cbuffer_offset : creator_offset) - string_data_offset;
1523 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1524 if (!string_data)
1526 ERR("Failed to allocate string data memory.\n");
1527 hr = E_OUTOFMEMORY;
1528 goto err_out;
1530 memcpy(string_data, data + string_data_offset, string_data_size);
1532 bound_resources = HeapAlloc(GetProcessHeap(), 0, r->bound_resource_count * sizeof(*bound_resources));
1533 if (!bound_resources)
1535 ERR("Failed to allocate resources memory.\n");
1536 hr = E_OUTOFMEMORY;
1537 goto err_out;
1540 ptr = data + resource_offset;
1541 for (i = 0; i < r->bound_resource_count; i++)
1543 D3D12_SHADER_INPUT_BIND_DESC *desc = &bound_resources[i];
1545 offset = read_u32(&ptr);
1546 desc->Name = string_data + (offset - string_data_offset);
1547 TRACE("Input bind Name: %s.\n", debugstr_a(desc->Name));
1549 desc->Type = read_u32(&ptr);
1550 TRACE("Input bind Type: %#x.\n", desc->Type);
1552 desc->ReturnType = read_u32(&ptr);
1553 TRACE("Input bind ReturnType: %#x.\n", desc->ReturnType);
1555 desc->Dimension = read_u32(&ptr);
1556 TRACE("Input bind Dimension: %#x.\n", desc->Dimension);
1558 desc->NumSamples = read_u32(&ptr);
1559 TRACE("Input bind NumSamples: %u.\n", desc->NumSamples);
1561 desc->BindPoint = read_u32(&ptr);
1562 TRACE("Input bind BindPoint: %u.\n", desc->BindPoint);
1564 desc->BindCount = read_u32(&ptr);
1565 TRACE("Input bind BindCount: %u.\n", desc->BindCount);
1567 desc->uFlags = read_u32(&ptr);
1568 TRACE("Input bind uFlags: %u.\n", desc->uFlags);
1570 if (target_version >= 0x501)
1572 desc->Space = read_u32(&ptr);
1573 TRACE("Input bind Space %u.\n", desc->Space);
1574 desc->uID = read_u32(&ptr);
1575 TRACE("Input bind uID %u.\n", desc->uID);
1577 else
1579 desc->Space = 0;
1580 desc->uID = desc->BindPoint;
1585 if (r->constant_buffer_count)
1587 constant_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, r->constant_buffer_count * sizeof(*constant_buffers));
1588 if (!constant_buffers)
1590 ERR("Failed to allocate constant buffer memory.\n");
1591 hr = E_OUTOFMEMORY;
1592 goto err_out;
1595 ptr = data + cbuffer_offset;
1596 for (i = 0; i < r->constant_buffer_count; i++)
1598 struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i];
1600 cb->ID3D11ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl;
1601 cb->reflection = r;
1603 offset = read_u32(&ptr);
1604 if (!copy_name(data + offset, &cb->name))
1606 ERR("Failed to copy name.\n");
1607 hr = E_OUTOFMEMORY;
1608 goto err_out;
1610 TRACE("Name: %s.\n", debugstr_a(cb->name));
1612 cb->variable_count = read_u32(&ptr);
1613 TRACE("Variable count: %u.\n", cb->variable_count);
1615 offset = read_u32(&ptr);
1616 TRACE("Variable offset: %x.\n", offset);
1618 hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset);
1619 if (hr != S_OK)
1621 FIXME("Failed to parse variables.\n");
1622 goto err_out;
1625 cb->size = read_u32(&ptr);
1626 TRACE("Cbuffer size: %u.\n", cb->size);
1628 cb->flags = read_u32(&ptr);
1629 TRACE("Cbuffer flags: %u.\n", cb->flags);
1631 cb->type = read_u32(&ptr);
1632 TRACE("Cbuffer type: %#x.\n", cb->type);
1636 r->creator = creator;
1637 r->resource_string = string_data;
1638 r->bound_resources = bound_resources;
1639 r->constant_buffers = constant_buffers;
1641 return S_OK;
1643 err_out:
1644 for (i = 0; i < r->constant_buffer_count; ++i)
1646 free_constant_buffer(&constant_buffers[i]);
1648 HeapFree(GetProcessHeap(), 0, constant_buffers);
1649 HeapFree(GetProcessHeap(), 0, bound_resources);
1650 HeapFree(GetProcessHeap(), 0, string_data);
1651 HeapFree(GetProcessHeap(), 0, creator);
1653 return hr;
1656 static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, struct dxbc_section *section)
1658 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size;
1659 D3D11_SIGNATURE_PARAMETER_DESC *d;
1660 unsigned int string_data_offset;
1661 const char *ptr = section->data;
1662 unsigned int string_data_size;
1663 unsigned int i, count;
1664 char *string_data;
1666 switch (section->tag)
1668 case TAG_OSG5:
1669 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7;
1670 break;
1672 case TAG_ISGN:
1673 case TAG_OSGN:
1674 case TAG_PCSG:
1675 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
1676 break;
1678 default:
1679 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1680 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
1681 break;
1684 count = read_u32(&ptr);
1685 TRACE("%u elements\n", count);
1687 skip_u32_unknown(&ptr, 1);
1689 d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d));
1690 if (!d)
1692 ERR("Failed to allocate signature memory.\n");
1693 return E_OUTOFMEMORY;
1696 /* 2 u32s for the header, element_size for each element. */
1697 string_data_offset = 2 * sizeof(uint32_t) + count * element_size * sizeof(uint32_t);
1698 string_data_size = section->data_size - string_data_offset;
1700 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1701 if (!string_data)
1703 ERR("Failed to allocate string data memory.\n");
1704 HeapFree(GetProcessHeap(), 0, d);
1705 return E_OUTOFMEMORY;
1707 memcpy(string_data, section->data + string_data_offset, string_data_size);
1709 for (i = 0; i < count; ++i)
1711 uint32_t name_offset, mask;
1713 #if D3D_COMPILER_VERSION >= 46
1714 /* FIXME */
1715 d[i].MinPrecision = D3D_MIN_PRECISION_DEFAULT;
1716 #endif
1717 #if D3D_COMPILER_VERSION
1718 if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7)
1720 d[i].Stream = read_u32(&ptr);
1722 else
1724 d[i].Stream = 0;
1726 #endif
1728 name_offset = read_u32(&ptr);
1729 d[i].SemanticName = string_data + (name_offset - string_data_offset);
1730 d[i].SemanticIndex = read_u32(&ptr);
1731 d[i].SystemValueType = read_u32(&ptr);
1732 d[i].ComponentType = read_u32(&ptr);
1733 d[i].Register = read_u32(&ptr);
1734 mask = read_u32(&ptr);
1735 d[i].ReadWriteMask = (mask >> 8) & 0xff;
1736 d[i].Mask = mask & 0xff;
1738 if (!stricmp(d[i].SemanticName, "sv_depth"))
1739 d[i].SystemValueType = D3D_NAME_DEPTH;
1740 else if (!stricmp(d[i].SemanticName, "sv_coverage"))
1741 d[i].SystemValueType = D3D_NAME_COVERAGE;
1742 else if (!stricmp(d[i].SemanticName, "sv_depthgreaterequal"))
1743 d[i].SystemValueType = D3D_NAME_DEPTH_GREATER_EQUAL;
1744 else if (!stricmp(d[i].SemanticName, "sv_depthlessequal"))
1745 d[i].SystemValueType = D3D_NAME_DEPTH_LESS_EQUAL;
1746 else if (!stricmp(d[i].SemanticName, "sv_target"))
1747 d[i].SystemValueType = D3D_NAME_TARGET;
1750 s->elements = d;
1751 s->element_count = count;
1752 s->string_data = string_data;
1754 return S_OK;
1757 static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size)
1759 const char *ptr = data;
1761 r->version = read_u32(&ptr);
1762 TRACE("Shader version: %u\n", r->version);
1764 /* todo: Check if anything else is needed from the shdr or shex blob. */
1766 return S_OK;
1769 static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection,
1770 const void *data, SIZE_T data_size)
1772 struct dxbc src_dxbc;
1773 HRESULT hr;
1774 unsigned int i;
1776 wine_rb_init(&reflection->types, d3dcompiler_shader_reflection_type_compare);
1778 hr = dxbc_parse(data, data_size, &src_dxbc);
1779 if (FAILED(hr))
1781 WARN("Failed to parse reflection\n");
1782 return hr;
1785 for (i = 0; i < src_dxbc.count; ++i)
1787 struct dxbc_section *section = &src_dxbc.sections[i];
1789 switch (section->tag)
1791 case TAG_RDEF:
1792 hr = d3dcompiler_parse_rdef(reflection, section->data, section->data_size);
1793 if (FAILED(hr))
1795 WARN("Failed to parse RDEF section.\n");
1796 goto err_out;
1798 break;
1800 case TAG_ISGN:
1801 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn));
1802 if (!reflection->isgn)
1804 ERR("Failed to allocate ISGN memory.\n");
1805 hr = E_OUTOFMEMORY;
1806 goto err_out;
1809 hr = d3dcompiler_parse_signature(reflection->isgn, section);
1810 if (FAILED(hr))
1812 WARN("Failed to parse section ISGN.\n");
1813 goto err_out;
1815 break;
1817 case TAG_OSG5:
1818 case TAG_OSGN:
1819 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn));
1820 if (!reflection->osgn)
1822 ERR("Failed to allocate OSGN memory.\n");
1823 hr = E_OUTOFMEMORY;
1824 goto err_out;
1827 hr = d3dcompiler_parse_signature(reflection->osgn, section);
1828 if (FAILED(hr))
1830 WARN("Failed to parse section OSGN.\n");
1831 goto err_out;
1833 break;
1835 case TAG_PCSG:
1836 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg));
1837 if (!reflection->pcsg)
1839 ERR("Failed to allocate PCSG memory.\n");
1840 hr = E_OUTOFMEMORY;
1841 goto err_out;
1844 hr = d3dcompiler_parse_signature(reflection->pcsg, section);
1845 if (FAILED(hr))
1847 WARN("Failed to parse section PCSG.\n");
1848 goto err_out;
1850 break;
1852 case TAG_SHEX:
1853 case TAG_SHDR:
1854 hr = d3dcompiler_parse_shdr(reflection, section->data, section->data_size);
1855 if (FAILED(hr))
1857 WARN("Failed to parse SHDR section.\n");
1858 goto err_out;
1860 break;
1862 case TAG_STAT:
1863 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size);
1864 if (FAILED(hr))
1866 WARN("Failed to parse section STAT.\n");
1867 goto err_out;
1869 break;
1871 default:
1872 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1873 break;
1877 dxbc_destroy(&src_dxbc);
1879 return hr;
1881 err_out:
1882 reflection_cleanup(reflection);
1883 dxbc_destroy(&src_dxbc);
1885 return hr;
1888 /* d3d10 reflection methods. */
1889 #if !D3D_COMPILER_VERSION
1890 HRESULT WINAPI D3D10ReflectShader(const void *data, SIZE_T data_size, ID3D10ShaderReflection **reflector)
1892 struct d3dcompiler_shader_reflection *object;
1893 HRESULT hr;
1895 TRACE("data %p, data_size %Iu, reflector %p.\n", data, data_size, reflector);
1897 if (!(object = heap_alloc_zero(sizeof(*object))))
1899 ERR("Failed to allocate D3D10 shader reflection object memory.\n");
1900 return E_OUTOFMEMORY;
1903 object->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
1904 object->interface_version = D3DCOMPILER_REFLECTION_VERSION_D3D10;
1905 object->refcount = 1;
1907 hr = d3dcompiler_shader_reflection_init(object, data, data_size);
1908 if (FAILED(hr))
1910 WARN("Failed to initialize shader reflection.\n");
1911 HeapFree(GetProcessHeap(), 0, object);
1912 return hr;
1915 *reflector = (ID3D10ShaderReflection *)&object->ID3D11ShaderReflection_iface;
1917 TRACE("Created ID3D10ShaderReflection %p.\n", object);
1919 return S_OK;
1921 #else
1922 HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID riid, void **reflector)
1924 struct d3dcompiler_shader_reflection *object;
1925 const uint32_t *temp = data;
1926 HRESULT hr;
1928 TRACE("data %p, data_size %Iu, riid %s, blob %p.\n", data, data_size, debugstr_guid(riid), reflector);
1930 if (!data || data_size < 32)
1932 WARN("Invalid argument supplied.\n");
1933 return D3DERR_INVALIDCALL;
1936 if (temp[6] != data_size)
1938 WARN("Wrong size supplied.\n");
1939 #if D3D_COMPILER_VERSION >= 46
1940 return D3DERR_INVALIDCALL;
1941 #else
1942 return E_FAIL;
1943 #endif
1946 if (!IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
1947 && (D3D_COMPILER_VERSION < 47 || !IsEqualGUID(riid, &IID_ID3D12ShaderReflection)))
1949 WARN("Wrong riid %s, accept only %s!\n", debugstr_guid(riid), debugstr_guid(&IID_ID3D11ShaderReflection));
1950 #if D3D_COMPILER_VERSION >= 46
1951 return E_INVALIDARG;
1952 #else
1953 return E_NOINTERFACE;
1954 #endif
1957 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1958 if (!object)
1959 return E_OUTOFMEMORY;
1961 object->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
1962 object->refcount = 1;
1963 object->interface_version = IsEqualGUID(riid, &IID_ID3D12ShaderReflection)
1964 ? D3DCOMPILER_REFLECTION_VERSION_D3D12 : D3DCOMPILER_REFLECTION_VERSION_D3D11;
1966 hr = d3dcompiler_shader_reflection_init(object, data, data_size);
1967 if (FAILED(hr))
1969 WARN("Failed to initialize shader reflection\n");
1970 HeapFree(GetProcessHeap(), 0, object);
1971 return hr;
1974 *reflector = object;
1976 TRACE("Created ID3D11ShaderReflection %p\n", object);
1978 return S_OK;
1980 #endif