wined3d: Introduce helper function to get shader type from byte code.
[wine.git] / dlls / d3dcompiler_43 / reflection.c
blob5a59c64f94d40f1a420750d3311298ce86fefab6
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 "config.h"
22 #include "wine/port.h"
24 #include "d3dcompiler_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
28 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE
30 D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6 = 6,
31 D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7 = 7,
34 #define D3DCOMPILER_SHADER_TARGET_VERSION_MASK 0xffff
35 #define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK 0xffff0000
37 struct d3dcompiler_shader_signature
39 D3D11_SIGNATURE_PARAMETER_DESC *elements;
40 UINT element_count;
41 char *string_data;
44 struct d3dcompiler_shader_reflection_type
46 ID3D11ShaderReflectionType ID3D11ShaderReflectionType_iface;
48 DWORD id;
49 struct wine_rb_entry entry;
51 struct d3dcompiler_shader_reflection *reflection;
53 D3D11_SHADER_TYPE_DESC desc;
54 struct d3dcompiler_shader_reflection_type_member *members;
57 struct d3dcompiler_shader_reflection_type_member
59 char *name;
60 DWORD offset;
61 struct d3dcompiler_shader_reflection_type *type;
64 struct d3dcompiler_shader_reflection_variable
66 ID3D11ShaderReflectionVariable ID3D11ShaderReflectionVariable_iface;
68 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffer;
69 struct d3dcompiler_shader_reflection_type *type;
71 char *name;
72 UINT start_offset;
73 UINT size;
74 UINT flags;
75 void *default_value;
78 struct d3dcompiler_shader_reflection_constant_buffer
80 ID3D11ShaderReflectionConstantBuffer ID3D11ShaderReflectionConstantBuffer_iface;
82 struct d3dcompiler_shader_reflection *reflection;
84 char *name;
85 D3D_CBUFFER_TYPE type;
86 UINT variable_count;
87 UINT size;
88 UINT flags;
90 struct d3dcompiler_shader_reflection_variable *variables;
93 /* ID3D11ShaderReflection */
94 struct d3dcompiler_shader_reflection
96 ID3D11ShaderReflection ID3D11ShaderReflection_iface;
97 LONG refcount;
99 DWORD target;
100 char *creator;
101 UINT flags;
102 UINT version;
103 UINT bound_resource_count;
104 UINT constant_buffer_count;
106 UINT mov_instruction_count;
107 UINT conversion_instruction_count;
108 UINT instruction_count;
109 UINT emit_instruction_count;
110 D3D_PRIMITIVE_TOPOLOGY gs_output_topology;
111 UINT gs_max_output_vertex_count;
112 D3D_PRIMITIVE input_primitive;
113 UINT cut_instruction_count;
114 UINT dcl_count;
115 UINT static_flow_control_count;
116 UINT float_instruction_count;
117 UINT temp_register_count;
118 UINT int_instruction_count;
119 UINT uint_instruction_count;
120 UINT temp_array_count;
121 UINT array_instruction_count;
122 UINT texture_normal_instructions;
123 UINT texture_load_instructions;
124 UINT texture_comp_instructions;
125 UINT texture_bias_instructions;
126 UINT texture_gradient_instructions;
127 UINT dynamic_flow_control_count;
128 UINT c_control_points;
129 D3D_TESSELLATOR_OUTPUT_PRIMITIVE hs_output_primitive;
130 D3D_TESSELLATOR_PARTITIONING hs_prtitioning;
131 D3D_TESSELLATOR_DOMAIN tessellator_domain;
133 struct d3dcompiler_shader_signature *isgn;
134 struct d3dcompiler_shader_signature *osgn;
135 struct d3dcompiler_shader_signature *pcsg;
136 char *resource_string;
137 D3D11_SHADER_INPUT_BIND_DESC *bound_resources;
138 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers;
139 struct wine_rb_tree types;
142 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, DWORD offset);
144 static const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl;
145 static const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl;
146 static const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl;
148 /* null objects - needed for invalid calls */
149 static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer = {{&d3dcompiler_shader_reflection_constant_buffer_vtbl}};
150 static struct d3dcompiler_shader_reflection_type null_type = {{&d3dcompiler_shader_reflection_type_vtbl}};
151 static struct d3dcompiler_shader_reflection_variable null_variable = {{&d3dcompiler_shader_reflection_variable_vtbl},
152 &null_constant_buffer, &null_type};
154 static BOOL copy_name(const char *ptr, char **name)
156 size_t name_len;
158 if (!ptr) return TRUE;
160 name_len = strlen(ptr) + 1;
161 if (name_len == 1)
163 return TRUE;
166 *name = HeapAlloc(GetProcessHeap(), 0, name_len);
167 if (!*name)
169 ERR("Failed to allocate name memory.\n");
170 return FALSE;
173 memcpy(*name, ptr, name_len);
175 return TRUE;
178 static BOOL copy_value(const char *ptr, void **value, DWORD size)
180 if (!ptr || !size) return TRUE;
182 *value = HeapAlloc(GetProcessHeap(), 0, size);
183 if (!*value)
185 ERR("Failed to allocate value memory.\n");
186 return FALSE;
189 memcpy(*value, ptr, size);
191 return TRUE;
194 static int d3dcompiler_shader_reflection_type_compare(const void *key, const struct wine_rb_entry *entry)
196 const struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, const struct d3dcompiler_shader_reflection_type, entry);
197 const DWORD *id = key;
199 return *id - t->id;
202 static void free_type_member(struct d3dcompiler_shader_reflection_type_member *member)
204 if (member)
206 HeapFree(GetProcessHeap(), 0, member->name);
210 static void d3dcompiler_shader_reflection_type_destroy(struct wine_rb_entry *entry, void *context)
212 struct d3dcompiler_shader_reflection_type *t = WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry);
213 unsigned int i;
215 TRACE("reflection type %p.\n", t);
217 if (t->members)
219 for (i = 0; i < t->desc.Members; ++i)
221 free_type_member(&t->members[i]);
223 HeapFree(GetProcessHeap(), 0, t->members);
226 HeapFree(GetProcessHeap(), 0, t);
229 static void free_signature(struct d3dcompiler_shader_signature *sig)
231 TRACE("Free signature %p\n", sig);
233 HeapFree(GetProcessHeap(), 0, sig->elements);
234 HeapFree(GetProcessHeap(), 0, sig->string_data);
237 static void free_variable(struct d3dcompiler_shader_reflection_variable *var)
239 if (var)
241 HeapFree(GetProcessHeap(), 0, var->name);
242 HeapFree(GetProcessHeap(), 0, var->default_value);
246 static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb)
248 if (cb->variables)
250 unsigned int i;
252 for (i = 0; i < cb->variable_count; ++i)
254 free_variable(&cb->variables[i]);
256 HeapFree(GetProcessHeap(), 0, cb->variables);
259 HeapFree(GetProcessHeap(), 0, cb->name);
262 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref)
264 TRACE("Cleanup %p\n", ref);
266 if (ref->isgn)
268 free_signature(ref->isgn);
269 HeapFree(GetProcessHeap(), 0, ref->isgn);
272 if (ref->osgn)
274 free_signature(ref->osgn);
275 HeapFree(GetProcessHeap(), 0, ref->osgn);
278 if (ref->pcsg)
280 free_signature(ref->pcsg);
281 HeapFree(GetProcessHeap(), 0, ref->pcsg);
284 if (ref->constant_buffers)
286 unsigned int i;
288 for (i = 0; i < ref->constant_buffer_count; ++i)
290 free_constant_buffer(&ref->constant_buffers[i]);
294 wine_rb_destroy(&ref->types, d3dcompiler_shader_reflection_type_destroy, NULL);
295 HeapFree(GetProcessHeap(), 0, ref->constant_buffers);
296 HeapFree(GetProcessHeap(), 0, ref->bound_resources);
297 HeapFree(GetProcessHeap(), 0, ref->resource_string);
298 HeapFree(GetProcessHeap(), 0, ref->creator);
301 /* IUnknown methods */
303 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
305 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
308 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
310 TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
312 if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
313 || IsEqualGUID(riid, &IID_IUnknown))
315 IUnknown_AddRef(iface);
316 *object = iface;
317 return S_OK;
320 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
322 *object = NULL;
323 return E_NOINTERFACE;
326 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
328 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
329 ULONG refcount = InterlockedIncrement(&This->refcount);
331 TRACE("%p increasing refcount to %u\n", This, refcount);
333 return refcount;
336 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
338 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
339 ULONG refcount = InterlockedDecrement(&This->refcount);
341 TRACE("%p decreasing refcount to %u\n", This, refcount);
343 if (!refcount)
345 reflection_cleanup(This);
346 HeapFree(GetProcessHeap(), 0, This);
349 return refcount;
352 /* ID3D11ShaderReflection methods */
354 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
356 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
358 FIXME("iface %p, desc %p partial stub!\n", iface, desc);
360 if (!desc)
362 WARN("Invalid argument specified\n");
363 return E_FAIL;
366 desc->Version = This->version;
367 desc->Creator = This->creator;
368 desc->Flags = This->flags;
369 desc->ConstantBuffers = This->constant_buffer_count;
370 desc->BoundResources = This->bound_resource_count;
371 desc->InputParameters = This->isgn ? This->isgn->element_count : 0;
372 desc->OutputParameters = This->osgn ? This->osgn->element_count : 0;
373 desc->InstructionCount = This->instruction_count;
374 desc->TempRegisterCount = This->temp_register_count;
375 desc->TempArrayCount = This->temp_array_count;
376 desc->DefCount = 0;
377 desc->DclCount = This->dcl_count;
378 desc->TextureNormalInstructions = This->texture_normal_instructions;
379 desc->TextureLoadInstructions = This->texture_load_instructions;
380 desc->TextureCompInstructions = This->texture_comp_instructions;
381 desc->TextureBiasInstructions = This->texture_bias_instructions;
382 desc->TextureGradientInstructions = This->texture_gradient_instructions;
383 desc->FloatInstructionCount = This->float_instruction_count;
384 desc->IntInstructionCount = This->int_instruction_count;
385 desc->UintInstructionCount = This->uint_instruction_count;
386 desc->StaticFlowControlCount = This->static_flow_control_count;
387 desc->DynamicFlowControlCount = This->dynamic_flow_control_count;
388 desc->MacroInstructionCount = 0;
389 desc->ArrayInstructionCount = This->array_instruction_count;
390 desc->CutInstructionCount = This->cut_instruction_count;
391 desc->EmitInstructionCount = This->emit_instruction_count;
392 desc->GSOutputTopology = This->gs_output_topology;
393 desc->GSMaxOutputVertexCount = This->gs_max_output_vertex_count;
394 desc->InputPrimitive = This->input_primitive;
395 desc->PatchConstantParameters = This->pcsg ? This->pcsg->element_count : 0;
396 desc->cGSInstanceCount = 0;
397 desc->cControlPoints = This->c_control_points;
398 desc->HSOutputPrimitive = This->hs_output_primitive;
399 desc->HSPartitioning = This->hs_prtitioning;
400 desc->TessellatorDomain = This->tessellator_domain;
401 desc->cBarrierInstructions = 0;
402 desc->cInterlockedInstructions = 0;
403 desc->cTextureStoreInstructions = 0;
405 return S_OK;
408 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
409 ID3D11ShaderReflection *iface, UINT index)
411 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
413 TRACE("iface %p, index %u\n", iface, index);
415 if (index >= This->constant_buffer_count)
417 WARN("Invalid argument specified\n");
418 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
421 return &This->constant_buffers[index].ID3D11ShaderReflectionConstantBuffer_iface;
424 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
425 ID3D11ShaderReflection *iface, const char *name)
427 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
428 unsigned int i;
430 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
432 if (!name)
434 WARN("Invalid argument specified\n");
435 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
438 for (i = 0; i < This->constant_buffer_count; ++i)
440 struct d3dcompiler_shader_reflection_constant_buffer *d = &This->constant_buffers[i];
442 if (!strcmp(d->name, name))
444 TRACE("Returning ID3D11ShaderReflectionConstantBuffer %p.\n", d);
445 return &d->ID3D11ShaderReflectionConstantBuffer_iface;
449 WARN("Invalid name specified\n");
451 return &null_constant_buffer.ID3D11ShaderReflectionConstantBuffer_iface;
454 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
455 ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
457 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
459 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
461 if (!desc || index >= This->bound_resource_count)
463 WARN("Invalid argument specified\n");
464 return E_INVALIDARG;
467 *desc = This->bound_resources[index];
469 return S_OK;
472 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
473 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
475 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
477 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
479 if (!desc || !This->isgn || index >= This->isgn->element_count)
481 WARN("Invalid argument specified\n");
482 return E_INVALIDARG;
485 *desc = This->isgn->elements[index];
487 return S_OK;
490 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
491 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
493 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
495 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
497 if (!desc || !This->osgn || index >= This->osgn->element_count)
499 WARN("Invalid argument specified\n");
500 return E_INVALIDARG;
503 *desc = This->osgn->elements[index];
505 return S_OK;
508 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
509 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
511 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
513 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
515 if (!desc || !This->pcsg || index >= This->pcsg->element_count)
517 WARN("Invalid argument specified\n");
518 return E_INVALIDARG;
521 *desc = This->pcsg->elements[index];
523 return S_OK;
526 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
527 ID3D11ShaderReflection *iface, const char *name)
529 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
530 unsigned int i, k;
532 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
534 if (!name)
536 WARN("Invalid name specified\n");
537 return &null_variable.ID3D11ShaderReflectionVariable_iface;
540 for (i = 0; i < This->constant_buffer_count; ++i)
542 struct d3dcompiler_shader_reflection_constant_buffer *cb = &This->constant_buffers[i];
544 for (k = 0; k < cb->variable_count; ++k)
546 struct d3dcompiler_shader_reflection_variable *v = &cb->variables[k];
548 if (!strcmp(v->name, name))
550 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v);
551 return &v->ID3D11ShaderReflectionVariable_iface;
556 WARN("Invalid name specified\n");
558 return &null_variable.ID3D11ShaderReflectionVariable_iface;
561 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
562 ID3D11ShaderReflection *iface, const char *name, D3D11_SHADER_INPUT_BIND_DESC *desc)
564 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
565 unsigned int i;
567 TRACE("iface %p, name %s, desc %p\n", iface, debugstr_a(name), desc);
569 if (!desc || !name)
571 WARN("Invalid argument specified\n");
572 return E_INVALIDARG;
575 for (i = 0; i < This->bound_resource_count; ++i)
577 D3D11_SHADER_INPUT_BIND_DESC *d = &This->bound_resources[i];
579 if (!strcmp(d->Name, name))
581 TRACE("Returning D3D11_SHADER_INPUT_BIND_DESC %p.\n", d);
582 *desc = *d;
583 return S_OK;
587 WARN("Invalid name specified\n");
589 return E_INVALIDARG;
592 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
593 ID3D11ShaderReflection *iface)
595 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
597 TRACE("iface %p\n", iface);
599 return This->mov_instruction_count;
602 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
603 ID3D11ShaderReflection *iface)
605 FIXME("iface %p stub!\n", iface);
607 return 0;
610 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
611 ID3D11ShaderReflection *iface)
613 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
615 TRACE("iface %p\n", iface);
617 return This->conversion_instruction_count;
620 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
621 ID3D11ShaderReflection *iface)
623 FIXME("iface %p stub!\n", iface);
625 return 0;
628 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
629 ID3D11ShaderReflection *iface)
631 FIXME("iface %p stub!\n", iface);
633 return 0;
636 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
637 ID3D11ShaderReflection *iface)
639 FIXME("iface %p stub!\n", iface);
641 return FALSE;
644 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
645 ID3D11ShaderReflection *iface)
647 FIXME("iface %p stub!\n", iface);
649 return 0;
652 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
653 ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
655 FIXME("iface %p, level %p stub!\n", iface, level);
657 return E_NOTIMPL;
660 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize(
661 ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez)
663 FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez);
665 return 0;
668 static const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
670 /* IUnknown methods */
671 d3dcompiler_shader_reflection_QueryInterface,
672 d3dcompiler_shader_reflection_AddRef,
673 d3dcompiler_shader_reflection_Release,
674 /* ID3D11ShaderReflection methods */
675 d3dcompiler_shader_reflection_GetDesc,
676 d3dcompiler_shader_reflection_GetConstantBufferByIndex,
677 d3dcompiler_shader_reflection_GetConstantBufferByName,
678 d3dcompiler_shader_reflection_GetResourceBindingDesc,
679 d3dcompiler_shader_reflection_GetInputParameterDesc,
680 d3dcompiler_shader_reflection_GetOutputParameterDesc,
681 d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
682 d3dcompiler_shader_reflection_GetVariableByName,
683 d3dcompiler_shader_reflection_GetResourceBindingDescByName,
684 d3dcompiler_shader_reflection_GetMovInstructionCount,
685 d3dcompiler_shader_reflection_GetMovcInstructionCount,
686 d3dcompiler_shader_reflection_GetConversionInstructionCount,
687 d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
688 d3dcompiler_shader_reflection_GetGSInputPrimitive,
689 d3dcompiler_shader_reflection_IsSampleFrequencyShader,
690 d3dcompiler_shader_reflection_GetNumInterfaceSlots,
691 d3dcompiler_shader_reflection_GetMinFeatureLevel,
692 d3dcompiler_shader_reflection_GetThreadGroupSize,
695 /* ID3D11ShaderReflectionConstantBuffer methods */
697 static inline struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D11ShaderReflectionConstantBuffer *iface)
699 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D11ShaderReflectionConstantBuffer_iface);
702 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc(
703 ID3D11ShaderReflectionConstantBuffer *iface, D3D11_SHADER_BUFFER_DESC *desc)
705 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
707 TRACE("iface %p, desc %p\n", iface, desc);
709 if (This == &null_constant_buffer)
711 WARN("Null constant buffer specified\n");
712 return E_FAIL;
715 if (!desc)
717 WARN("Invalid argument specified\n");
718 return E_FAIL;
721 desc->Name = This->name;
722 desc->Type = This->type;
723 desc->Variables = This->variable_count;
724 desc->Size = This->size;
725 desc->uFlags = This->flags;
727 return S_OK;
730 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex(
731 ID3D11ShaderReflectionConstantBuffer *iface, UINT index)
733 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
735 TRACE("iface %p, index %u\n", iface, index);
737 if (index >= This->variable_count)
739 WARN("Invalid index specified\n");
740 return &null_variable.ID3D11ShaderReflectionVariable_iface;
743 return &This->variables[index].ID3D11ShaderReflectionVariable_iface;
746 static ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName(
747 ID3D11ShaderReflectionConstantBuffer *iface, const char *name)
749 struct d3dcompiler_shader_reflection_constant_buffer *This = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
750 unsigned int i;
752 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
754 if (!name)
756 WARN("Invalid argument specified\n");
757 return &null_variable.ID3D11ShaderReflectionVariable_iface;
760 for (i = 0; i < This->variable_count; ++i)
762 struct d3dcompiler_shader_reflection_variable *v = &This->variables[i];
764 if (!strcmp(v->name, name))
766 TRACE("Returning ID3D11ShaderReflectionVariable %p.\n", v);
767 return &v->ID3D11ShaderReflectionVariable_iface;
771 WARN("Invalid name specified\n");
773 return &null_variable.ID3D11ShaderReflectionVariable_iface;
776 static const struct ID3D11ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl =
778 /* ID3D11ShaderReflectionConstantBuffer methods */
779 d3dcompiler_shader_reflection_constant_buffer_GetDesc,
780 d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex,
781 d3dcompiler_shader_reflection_constant_buffer_GetVariableByName,
784 /* ID3D11ShaderReflectionVariable methods */
786 static inline struct d3dcompiler_shader_reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D11ShaderReflectionVariable *iface)
788 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_variable, ID3D11ShaderReflectionVariable_iface);
791 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc(
792 ID3D11ShaderReflectionVariable *iface, D3D11_SHADER_VARIABLE_DESC *desc)
794 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
796 TRACE("iface %p, desc %p\n", iface, desc);
798 if (This == &null_variable)
800 WARN("Null variable specified\n");
801 return E_FAIL;
804 if (!desc)
806 WARN("Invalid argument specified\n");
807 return E_FAIL;
810 desc->Name = This->name;
811 desc->StartOffset = This->start_offset;
812 desc->Size = This->size;
813 desc->uFlags = This->flags;
814 desc->DefaultValue = This->default_value;
816 return S_OK;
819 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType(
820 ID3D11ShaderReflectionVariable *iface)
822 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
824 TRACE("iface %p\n", iface);
826 return &This->type->ID3D11ShaderReflectionType_iface;
829 static ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer(
830 ID3D11ShaderReflectionVariable *iface)
832 struct d3dcompiler_shader_reflection_variable *This = impl_from_ID3D11ShaderReflectionVariable(iface);
834 TRACE("iface %p\n", iface);
836 return &This->constant_buffer->ID3D11ShaderReflectionConstantBuffer_iface;
839 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot(
840 ID3D11ShaderReflectionVariable *iface, UINT index)
842 FIXME("iface %p, index %u stub!\n", iface, index);
844 return 0;
847 static const struct ID3D11ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl =
849 /* ID3D11ShaderReflectionVariable methods */
850 d3dcompiler_shader_reflection_variable_GetDesc,
851 d3dcompiler_shader_reflection_variable_GetType,
852 d3dcompiler_shader_reflection_variable_GetBuffer,
853 d3dcompiler_shader_reflection_variable_GetInterfaceSlot,
856 /* ID3D11ShaderReflectionType methods */
858 static inline struct d3dcompiler_shader_reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D11ShaderReflectionType *iface)
860 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_type, ID3D11ShaderReflectionType_iface);
863 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc(
864 ID3D11ShaderReflectionType *iface, D3D11_SHADER_TYPE_DESC *desc)
866 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
868 TRACE("iface %p, desc %p\n", iface, desc);
870 if (This == &null_type)
872 WARN("Null type specified\n");
873 return E_FAIL;
876 if (!desc)
878 WARN("Invalid argument specified\n");
879 return E_FAIL;
882 *desc = This->desc;
884 return S_OK;
887 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByIndex(
888 ID3D11ShaderReflectionType *iface, UINT index)
890 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
892 TRACE("iface %p, index %u\n", iface, index);
894 if (index >= This->desc.Members)
896 WARN("Invalid index specified\n");
897 return &null_type.ID3D11ShaderReflectionType_iface;
900 return &This->members[index].type->ID3D11ShaderReflectionType_iface;
903 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByName(
904 ID3D11ShaderReflectionType *iface, const char *name)
906 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
907 unsigned int i;
909 TRACE("iface %p, name %s\n", iface, debugstr_a(name));
911 if (!name)
913 WARN("Invalid argument specified\n");
914 return &null_type.ID3D11ShaderReflectionType_iface;
917 for (i = 0; i < This->desc.Members; ++i)
919 struct d3dcompiler_shader_reflection_type_member *member = &This->members[i];
921 if (!strcmp(member->name, name))
923 TRACE("Returning ID3D11ShaderReflectionType %p.\n", member->type);
924 return &member->type->ID3D11ShaderReflectionType_iface;
928 WARN("Invalid name specified\n");
930 return &null_type.ID3D11ShaderReflectionType_iface;
933 static const char * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeName(
934 ID3D11ShaderReflectionType *iface, UINT index)
936 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
938 TRACE("iface %p, index %u\n", iface, index);
940 if (This == &null_type)
942 WARN("Null type specified\n");
943 return "$Invalid";
946 if (index >= This->desc.Members)
948 WARN("Invalid index specified\n");
949 return NULL;
952 return This->members[index].name;
955 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual(
956 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type)
958 struct d3dcompiler_shader_reflection_type *This = impl_from_ID3D11ShaderReflectionType(iface);
960 TRACE("iface %p, type %p\n", iface, type);
962 if (This == &null_type)
964 WARN("Null type specified\n");
965 return E_FAIL;
968 if (iface == type)
969 return S_OK;
971 return S_FALSE;
974 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetSubType(
975 ID3D11ShaderReflectionType *iface)
977 FIXME("iface %p stub!\n", iface);
979 return NULL;
982 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetBaseClass(
983 ID3D11ShaderReflectionType *iface)
985 FIXME("iface %p stub!\n", iface);
987 return NULL;
990 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterfaces(
991 ID3D11ShaderReflectionType *iface)
993 FIXME("iface %p stub!\n", iface);
995 return 0;
998 static ID3D11ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetInterfaceByIndex(
999 ID3D11ShaderReflectionType *iface, UINT index)
1001 FIXME("iface %p, index %u stub!\n", iface, index);
1003 return NULL;
1006 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType(
1007 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *type)
1009 FIXME("iface %p, type %p stub!\n", iface, type);
1011 return E_NOTIMPL;
1014 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsInterface(
1015 ID3D11ShaderReflectionType *iface, ID3D11ShaderReflectionType *base)
1017 FIXME("iface %p, base %p stub!\n", iface, base);
1019 return E_NOTIMPL;
1022 static const struct ID3D11ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl =
1024 /* ID3D11ShaderReflectionType methods */
1025 d3dcompiler_shader_reflection_type_GetDesc,
1026 d3dcompiler_shader_reflection_type_GetMemberTypeByIndex,
1027 d3dcompiler_shader_reflection_type_GetMemberTypeByName,
1028 d3dcompiler_shader_reflection_type_GetMemberTypeName,
1029 d3dcompiler_shader_reflection_type_IsEqual,
1030 d3dcompiler_shader_reflection_type_GetSubType,
1031 d3dcompiler_shader_reflection_type_GetBaseClass,
1032 d3dcompiler_shader_reflection_type_GetNumInterfaces,
1033 d3dcompiler_shader_reflection_type_GetInterfaceByIndex,
1034 d3dcompiler_shader_reflection_type_IsOfType,
1035 d3dcompiler_shader_reflection_type_ImplementsInterface,
1038 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1040 const char *ptr = data;
1041 DWORD size = data_size >> 2;
1043 TRACE("Size %u\n", size);
1045 read_dword(&ptr, &r->instruction_count);
1046 TRACE("InstructionCount: %u\n", r->instruction_count);
1048 read_dword(&ptr, &r->temp_register_count);
1049 TRACE("TempRegisterCount: %u\n", r->temp_register_count);
1051 skip_dword_unknown(&ptr, 1);
1053 read_dword(&ptr, &r->dcl_count);
1054 TRACE("DclCount: %u\n", r->dcl_count);
1056 read_dword(&ptr, &r->float_instruction_count);
1057 TRACE("FloatInstructionCount: %u\n", r->float_instruction_count);
1059 read_dword(&ptr, &r->int_instruction_count);
1060 TRACE("IntInstructionCount: %u\n", r->int_instruction_count);
1062 read_dword(&ptr, &r->uint_instruction_count);
1063 TRACE("UintInstructionCount: %u\n", r->uint_instruction_count);
1065 read_dword(&ptr, &r->static_flow_control_count);
1066 TRACE("StaticFlowControlCount: %u\n", r->static_flow_control_count);
1068 read_dword(&ptr, &r->dynamic_flow_control_count);
1069 TRACE("DynamicFlowControlCount: %u\n", r->dynamic_flow_control_count);
1071 skip_dword_unknown(&ptr, 1);
1073 read_dword(&ptr, &r->temp_array_count);
1074 TRACE("TempArrayCount: %u\n", r->temp_array_count);
1076 read_dword(&ptr, &r->array_instruction_count);
1077 TRACE("ArrayInstructionCount: %u\n", r->array_instruction_count);
1079 read_dword(&ptr, &r->cut_instruction_count);
1080 TRACE("CutInstructionCount: %u\n", r->cut_instruction_count);
1082 read_dword(&ptr, &r->emit_instruction_count);
1083 TRACE("EmitInstructionCount: %u\n", r->emit_instruction_count);
1085 read_dword(&ptr, &r->texture_normal_instructions);
1086 TRACE("TextureNormalInstructions: %u\n", r->texture_normal_instructions);
1088 read_dword(&ptr, &r->texture_load_instructions);
1089 TRACE("TextureLoadInstructions: %u\n", r->texture_load_instructions);
1091 read_dword(&ptr, &r->texture_comp_instructions);
1092 TRACE("TextureCompInstructions: %u\n", r->texture_comp_instructions);
1094 read_dword(&ptr, &r->texture_bias_instructions);
1095 TRACE("TextureBiasInstructions: %u\n", r->texture_bias_instructions);
1097 read_dword(&ptr, &r->texture_gradient_instructions);
1098 TRACE("TextureGradientInstructions: %u\n", r->texture_gradient_instructions);
1100 read_dword(&ptr, &r->mov_instruction_count);
1101 TRACE("MovInstructionCount: %u\n", r->mov_instruction_count);
1103 skip_dword_unknown(&ptr, 1);
1105 read_dword(&ptr, &r->conversion_instruction_count);
1106 TRACE("ConversionInstructionCount: %u\n", r->conversion_instruction_count);
1108 skip_dword_unknown(&ptr, 1);
1110 read_dword(&ptr, &r->input_primitive);
1111 TRACE("InputPrimitive: %x\n", r->input_primitive);
1113 read_dword(&ptr, &r->gs_output_topology);
1114 TRACE("GSOutputTopology: %x\n", r->gs_output_topology);
1116 read_dword(&ptr, &r->gs_max_output_vertex_count);
1117 TRACE("GSMaxOutputVertexCount: %u\n", r->gs_max_output_vertex_count);
1119 skip_dword_unknown(&ptr, 3);
1121 /* dx10 stat size */
1122 if (size == 29) return S_OK;
1124 skip_dword_unknown(&ptr, 1);
1126 read_dword(&ptr, &r->c_control_points);
1127 TRACE("cControlPoints: %u\n", r->c_control_points);
1129 read_dword(&ptr, &r->hs_output_primitive);
1130 TRACE("HSOutputPrimitive: %x\n", r->hs_output_primitive);
1132 read_dword(&ptr, &r->hs_prtitioning);
1133 TRACE("HSPartitioning: %x\n", r->hs_prtitioning);
1135 read_dword(&ptr, &r->tessellator_domain);
1136 TRACE("TessellatorDomain: %x\n", r->tessellator_domain);
1138 skip_dword_unknown(&ptr, 3);
1140 /* dx11 stat size */
1141 if (size == 37) return S_OK;
1143 FIXME("Unhandled size %u\n", size);
1145 return E_FAIL;
1148 static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflection *ref,
1149 struct d3dcompiler_shader_reflection_type_member *member, const char *data, const char **ptr)
1151 DWORD offset;
1153 read_dword(ptr, &offset);
1154 if (!copy_name(data + offset, &member->name))
1156 ERR("Failed to copy name.\n");
1157 return E_OUTOFMEMORY;
1159 TRACE("Member name: %s.\n", debugstr_a(member->name));
1161 read_dword(ptr, &offset);
1162 TRACE("Member type offset: %x\n", offset);
1164 member->type = get_reflection_type(ref, data, offset);
1165 if (!member->type)
1167 ERR("Failed to get member type\n");
1168 HeapFree(GetProcessHeap(), 0, member->name);
1169 return E_FAIL;
1172 read_dword(ptr, &member->offset);
1173 TRACE("Member offset %x\n", member->offset);
1175 return S_OK;
1178 static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type *type, const char *data, DWORD offset)
1180 const char *ptr = data + offset;
1181 DWORD temp;
1182 D3D11_SHADER_TYPE_DESC *desc;
1183 unsigned int i;
1184 struct d3dcompiler_shader_reflection_type_member *members = NULL;
1185 HRESULT hr;
1186 DWORD member_offset;
1188 desc = &type->desc;
1190 read_dword(&ptr, &temp);
1191 desc->Class = temp & 0xffff;
1192 desc->Type = temp >> 16;
1193 TRACE("Class %s, Type %s\n", debug_d3dcompiler_shader_variable_class(desc->Class),
1194 debug_d3dcompiler_shader_variable_type(desc->Type));
1196 read_dword(&ptr, &temp);
1197 desc->Rows = temp & 0xffff;
1198 desc->Columns = temp >> 16;
1199 TRACE("Rows %u, Columns %u\n", desc->Rows, desc->Columns);
1201 read_dword(&ptr, &temp);
1202 desc->Elements = temp & 0xffff;
1203 desc->Members = temp >> 16;
1204 TRACE("Elements %u, Members %u\n", desc->Elements, desc->Members);
1206 read_dword(&ptr, &member_offset);
1207 TRACE("Member Offset %u\n", member_offset);
1209 if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1210 skip_dword_unknown(&ptr, 4);
1212 if (desc->Members)
1214 const char *ptr2 = data + member_offset;
1216 members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*members) * desc->Members);
1217 if (!members)
1219 ERR("Failed to allocate type memory.\n");
1220 return E_OUTOFMEMORY;
1223 for (i = 0; i < desc->Members; ++i)
1225 hr = d3dcompiler_parse_type_members(type->reflection, &members[i], data, &ptr2);
1226 if (hr != S_OK)
1228 FIXME("Failed to parse type members.\n");
1229 goto err_out;
1234 type->members = members;
1236 return S_OK;
1238 err_out:
1239 for (i = 0; i < desc->Members; ++i)
1241 free_type_member(&members[i]);
1243 HeapFree(GetProcessHeap(), 0, members);
1244 return hr;
1247 static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, DWORD offset)
1249 struct d3dcompiler_shader_reflection_type *type;
1250 struct wine_rb_entry *entry;
1251 HRESULT hr;
1253 entry = wine_rb_get(&reflection->types, &offset);
1254 if (entry)
1256 TRACE("Returning existing type.\n");
1257 return WINE_RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry);
1260 type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*type));
1261 if (!type)
1262 return NULL;
1264 type->ID3D11ShaderReflectionType_iface.lpVtbl = &d3dcompiler_shader_reflection_type_vtbl;
1265 type->id = offset;
1266 type->reflection = reflection;
1268 hr = d3dcompiler_parse_type(type, data, offset);
1269 if (FAILED(hr))
1271 ERR("Failed to parse type info, hr %#x.\n", hr);
1272 HeapFree(GetProcessHeap(), 0, type);
1273 return NULL;
1276 if (wine_rb_put(&reflection->types, &offset, &type->entry) == -1)
1278 ERR("Failed to insert type entry.\n");
1279 HeapFree(GetProcessHeap(), 0, type);
1280 return NULL;
1283 return type;
1286 static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb,
1287 const char *data, DWORD data_size, const char *ptr)
1289 struct d3dcompiler_shader_reflection_variable *variables;
1290 unsigned int i;
1291 HRESULT hr;
1293 variables = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb->variable_count * sizeof(*variables));
1294 if (!variables)
1296 ERR("Failed to allocate variables memory.\n");
1297 return E_OUTOFMEMORY;
1300 for (i = 0; i < cb->variable_count; i++)
1302 struct d3dcompiler_shader_reflection_variable *v = &variables[i];
1303 DWORD offset;
1305 v->ID3D11ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl;
1306 v->constant_buffer = cb;
1308 read_dword(&ptr, &offset);
1309 if (!copy_name(data + offset, &v->name))
1311 ERR("Failed to copy name.\n");
1312 hr = E_OUTOFMEMORY;
1313 goto err_out;
1315 TRACE("Variable name: %s.\n", debugstr_a(v->name));
1317 read_dword(&ptr, &v->start_offset);
1318 TRACE("Variable offset: %u\n", v->start_offset);
1320 read_dword(&ptr, &v->size);
1321 TRACE("Variable size: %u\n", v->size);
1323 read_dword(&ptr, &v->flags);
1324 TRACE("Variable flags: %u\n", v->flags);
1326 read_dword(&ptr, &offset);
1327 TRACE("Variable type offset: %x\n", offset);
1328 v->type = get_reflection_type(cb->reflection, data, offset);
1329 if (!v->type)
1331 ERR("Failed to get type.\n");
1332 hr = E_FAIL;
1333 goto err_out;
1336 read_dword(&ptr, &offset);
1337 TRACE("Variable default value offset: %x\n", offset);
1338 if (!copy_value(data + offset, &v->default_value, offset ? v->size : 0))
1340 ERR("Failed to copy name.\n");
1341 hr = E_OUTOFMEMORY;
1342 goto err_out;
1345 if ((cb->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1346 skip_dword_unknown(&ptr, 4);
1349 cb->variables = variables;
1351 return S_OK;
1353 err_out:
1354 for (i = 0; i < cb->variable_count; i++)
1356 free_variable(&variables[i]);
1358 HeapFree(GetProcessHeap(), 0, variables);
1359 return hr;
1362 static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1364 const char *ptr = data;
1365 DWORD size = data_size >> 2;
1366 DWORD offset, cbuffer_offset, resource_offset, creator_offset;
1367 unsigned int i, string_data_offset, string_data_size;
1368 char *string_data = NULL, *creator = NULL;
1369 D3D11_SHADER_INPUT_BIND_DESC *bound_resources = NULL;
1370 struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL;
1371 HRESULT hr;
1373 TRACE("Size %u\n", size);
1375 read_dword(&ptr, &r->constant_buffer_count);
1376 TRACE("Constant buffer count: %u\n", r->constant_buffer_count);
1378 read_dword(&ptr, &cbuffer_offset);
1379 TRACE("Constant buffer offset: %#x\n", cbuffer_offset);
1381 read_dword(&ptr, &r->bound_resource_count);
1382 TRACE("Bound resource count: %u\n", r->bound_resource_count);
1384 read_dword(&ptr, &resource_offset);
1385 TRACE("Bound resource offset: %#x\n", resource_offset);
1387 read_dword(&ptr, &r->target);
1388 TRACE("Target: %#x\n", r->target);
1390 read_dword(&ptr, &r->flags);
1391 TRACE("Flags: %u\n", r->flags);
1393 read_dword(&ptr, &creator_offset);
1394 TRACE("Creator at offset %#x.\n", creator_offset);
1396 if (!copy_name(data + creator_offset, &creator))
1398 ERR("Failed to copy name.\n");
1399 return E_OUTOFMEMORY;
1401 TRACE("Creator: %s.\n", debugstr_a(creator));
1403 /* todo: Parse RD11 */
1404 if ((r->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500)
1406 skip_dword_unknown(&ptr, 8);
1409 if (r->bound_resource_count)
1411 /* 8 for each bind desc */
1412 string_data_offset = resource_offset + r->bound_resource_count * 8 * sizeof(DWORD);
1413 string_data_size = (cbuffer_offset ? cbuffer_offset : creator_offset) - string_data_offset;
1415 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1416 if (!string_data)
1418 ERR("Failed to allocate string data memory.\n");
1419 hr = E_OUTOFMEMORY;
1420 goto err_out;
1422 memcpy(string_data, data + string_data_offset, string_data_size);
1424 bound_resources = HeapAlloc(GetProcessHeap(), 0, r->bound_resource_count * sizeof(*bound_resources));
1425 if (!bound_resources)
1427 ERR("Failed to allocate resources memory.\n");
1428 hr = E_OUTOFMEMORY;
1429 goto err_out;
1432 ptr = data + resource_offset;
1433 for (i = 0; i < r->bound_resource_count; i++)
1435 D3D11_SHADER_INPUT_BIND_DESC *desc = &bound_resources[i];
1437 read_dword(&ptr, &offset);
1438 desc->Name = string_data + (offset - string_data_offset);
1439 TRACE("Input bind Name: %s\n", debugstr_a(desc->Name));
1441 read_dword(&ptr, &desc->Type);
1442 TRACE("Input bind Type: %#x\n", desc->Type);
1444 read_dword(&ptr, &desc->ReturnType);
1445 TRACE("Input bind ReturnType: %#x\n", desc->ReturnType);
1447 read_dword(&ptr, &desc->Dimension);
1448 TRACE("Input bind Dimension: %#x\n", desc->Dimension);
1450 read_dword(&ptr, &desc->NumSamples);
1451 TRACE("Input bind NumSamples: %u\n", desc->NumSamples);
1453 read_dword(&ptr, &desc->BindPoint);
1454 TRACE("Input bind BindPoint: %u\n", desc->BindPoint);
1456 read_dword(&ptr, &desc->BindCount);
1457 TRACE("Input bind BindCount: %u\n", desc->BindCount);
1459 read_dword(&ptr, &desc->uFlags);
1460 TRACE("Input bind uFlags: %u\n", desc->uFlags);
1464 if (r->constant_buffer_count)
1466 constant_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, r->constant_buffer_count * sizeof(*constant_buffers));
1467 if (!constant_buffers)
1469 ERR("Failed to allocate constant buffer memory.\n");
1470 hr = E_OUTOFMEMORY;
1471 goto err_out;
1474 ptr = data + cbuffer_offset;
1475 for (i = 0; i < r->constant_buffer_count; i++)
1477 struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i];
1479 cb->ID3D11ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl;
1480 cb->reflection = r;
1482 read_dword(&ptr, &offset);
1483 if (!copy_name(data + offset, &cb->name))
1485 ERR("Failed to copy name.\n");
1486 hr = E_OUTOFMEMORY;
1487 goto err_out;
1489 TRACE("Name: %s.\n", debugstr_a(cb->name));
1491 read_dword(&ptr, &cb->variable_count);
1492 TRACE("Variable count: %u\n", cb->variable_count);
1494 read_dword(&ptr, &offset);
1495 TRACE("Variable offset: %x\n", offset);
1497 hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset);
1498 if (hr != S_OK)
1500 FIXME("Failed to parse variables.\n");
1501 goto err_out;
1504 read_dword(&ptr, &cb->size);
1505 TRACE("Cbuffer size: %u\n", cb->size);
1507 read_dword(&ptr, &cb->flags);
1508 TRACE("Cbuffer flags: %u\n", cb->flags);
1510 read_dword(&ptr, &cb->type);
1511 TRACE("Cbuffer type: %#x\n", cb->type);
1515 r->creator = creator;
1516 r->resource_string = string_data;
1517 r->bound_resources = bound_resources;
1518 r->constant_buffers = constant_buffers;
1520 return S_OK;
1522 err_out:
1523 for (i = 0; i < r->constant_buffer_count; ++i)
1525 free_constant_buffer(&constant_buffers[i]);
1527 HeapFree(GetProcessHeap(), 0, constant_buffers);
1528 HeapFree(GetProcessHeap(), 0, bound_resources);
1529 HeapFree(GetProcessHeap(), 0, string_data);
1530 HeapFree(GetProcessHeap(), 0, creator);
1532 return hr;
1535 static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, struct dxbc_section *section, DWORD target)
1537 D3D11_SIGNATURE_PARAMETER_DESC *d;
1538 unsigned int string_data_offset;
1539 unsigned int string_data_size;
1540 const char *ptr = section->data;
1541 char *string_data;
1542 unsigned int i;
1543 DWORD count;
1544 enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size;
1546 switch (section->tag)
1548 case TAG_OSG5:
1549 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7;
1550 break;
1552 case TAG_ISGN:
1553 case TAG_OSGN:
1554 case TAG_PCSG:
1555 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
1556 break;
1558 default:
1559 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1560 element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6;
1561 break;
1564 read_dword(&ptr, &count);
1565 TRACE("%u elements\n", count);
1567 skip_dword_unknown(&ptr, 1);
1569 d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d));
1570 if (!d)
1572 ERR("Failed to allocate signature memory.\n");
1573 return E_OUTOFMEMORY;
1576 /* 2 DWORDs for the header, element_size for each element. */
1577 string_data_offset = 2 * sizeof(DWORD) + count * element_size * sizeof(DWORD);
1578 string_data_size = section->data_size - string_data_offset;
1580 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
1581 if (!string_data)
1583 ERR("Failed to allocate string data memory.\n");
1584 HeapFree(GetProcessHeap(), 0, d);
1585 return E_OUTOFMEMORY;
1587 memcpy(string_data, section->data + string_data_offset, string_data_size);
1589 for (i = 0; i < count; ++i)
1591 UINT name_offset;
1592 DWORD mask;
1594 if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7)
1596 read_dword(&ptr, &d[i].Stream);
1598 else
1600 d[i].Stream = 0;
1603 read_dword(&ptr, &name_offset);
1604 d[i].SemanticName = string_data + (name_offset - string_data_offset);
1605 read_dword(&ptr, &d[i].SemanticIndex);
1606 read_dword(&ptr, &d[i].SystemValueType);
1607 read_dword(&ptr, &d[i].ComponentType);
1608 read_dword(&ptr, &d[i].Register);
1609 read_dword(&ptr, &mask);
1610 d[i].ReadWriteMask = (mask >> 8) & 0xff;
1611 d[i].Mask = mask & 0xff;
1613 /* pixel shaders have a special handling for SystemValueType in the output signature */
1614 if (((target & D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK) == 0xffff0000) && (section->tag == TAG_OSG5 || section->tag == TAG_OSGN))
1616 TRACE("Pixelshader output signature fixup.\n");
1618 if (d[i].Register == 0xffffffff)
1620 if (!strcasecmp(d[i].SemanticName, "sv_depth")) d[i].SystemValueType = D3D_NAME_DEPTH;
1621 if (!strcasecmp(d[i].SemanticName, "sv_coverage")) d[i].SystemValueType = D3D_NAME_COVERAGE;
1622 if (!strcasecmp(d[i].SemanticName, "sv_depthgreaterequal")) d[i].SystemValueType = D3D_NAME_DEPTH_GREATER_EQUAL;
1623 if (!strcasecmp(d[i].SemanticName, "sv_depthlessequal")) d[i].SystemValueType = D3D_NAME_DEPTH_LESS_EQUAL;
1625 else
1627 d[i].SystemValueType = D3D_NAME_TARGET;
1631 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
1632 "type %u, register idx: %u, use_mask %#x, input_mask %#x, stream %u\n",
1633 debugstr_a(d[i].SemanticName), d[i].SemanticIndex, d[i].SystemValueType,
1634 d[i].ComponentType, d[i].Register, d[i].Mask, d[i].ReadWriteMask, d[i].Stream);
1637 s->elements = d;
1638 s->element_count = count;
1639 s->string_data = string_data;
1641 return S_OK;
1644 static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
1646 const char *ptr = data;
1648 read_dword(&ptr, &r->version);
1649 TRACE("Shader version: %u\n", r->version);
1651 /* todo: Check if anything else is needed from the shdr or shex blob. */
1653 return S_OK;
1656 static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection,
1657 const void *data, SIZE_T data_size)
1659 struct dxbc src_dxbc;
1660 HRESULT hr;
1661 unsigned int i;
1663 reflection->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
1664 reflection->refcount = 1;
1666 wine_rb_init(&reflection->types, d3dcompiler_shader_reflection_type_compare);
1668 hr = dxbc_parse(data, data_size, &src_dxbc);
1669 if (FAILED(hr))
1671 WARN("Failed to parse reflection\n");
1672 return hr;
1675 for (i = 0; i < src_dxbc.count; ++i)
1677 struct dxbc_section *section = &src_dxbc.sections[i];
1679 switch (section->tag)
1681 case TAG_RDEF:
1682 hr = d3dcompiler_parse_rdef(reflection, section->data, section->data_size);
1683 if (FAILED(hr))
1685 WARN("Failed to parse RDEF section.\n");
1686 goto err_out;
1688 break;
1690 case TAG_ISGN:
1691 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn));
1692 if (!reflection->isgn)
1694 ERR("Failed to allocate ISGN memory.\n");
1695 hr = E_OUTOFMEMORY;
1696 goto err_out;
1699 hr = d3dcompiler_parse_signature(reflection->isgn, section, reflection->target);
1700 if (FAILED(hr))
1702 WARN("Failed to parse section ISGN.\n");
1703 goto err_out;
1705 break;
1707 case TAG_OSG5:
1708 case TAG_OSGN:
1709 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn));
1710 if (!reflection->osgn)
1712 ERR("Failed to allocate OSGN memory.\n");
1713 hr = E_OUTOFMEMORY;
1714 goto err_out;
1717 hr = d3dcompiler_parse_signature(reflection->osgn, section, reflection->target);
1718 if (FAILED(hr))
1720 WARN("Failed to parse section OSGN.\n");
1721 goto err_out;
1723 break;
1725 case TAG_PCSG:
1726 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg));
1727 if (!reflection->pcsg)
1729 ERR("Failed to allocate PCSG memory.\n");
1730 hr = E_OUTOFMEMORY;
1731 goto err_out;
1734 hr = d3dcompiler_parse_signature(reflection->pcsg, section, reflection->target);
1735 if (FAILED(hr))
1737 WARN("Failed to parse section PCSG.\n");
1738 goto err_out;
1740 break;
1742 case TAG_SHEX:
1743 case TAG_SHDR:
1744 hr = d3dcompiler_parse_shdr(reflection, section->data, section->data_size);
1745 if (FAILED(hr))
1747 WARN("Failed to parse SHDR section.\n");
1748 goto err_out;
1750 break;
1752 case TAG_STAT:
1753 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size);
1754 if (FAILED(hr))
1756 WARN("Failed to parse section STAT.\n");
1757 goto err_out;
1759 break;
1761 default:
1762 FIXME("Unhandled section %s!\n", debugstr_an((const char *)&section->tag, 4));
1763 break;
1767 dxbc_destroy(&src_dxbc);
1769 return hr;
1771 err_out:
1772 reflection_cleanup(reflection);
1773 dxbc_destroy(&src_dxbc);
1775 return hr;
1778 HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID riid, void **reflector)
1780 struct d3dcompiler_shader_reflection *object;
1781 HRESULT hr;
1782 const DWORD *temp = data;
1784 TRACE("data %p, data_size %lu, riid %s, blob %p\n", data, data_size, debugstr_guid(riid), reflector);
1786 if (!data || data_size < 32)
1788 WARN("Invalid argument supplied.\n");
1789 return D3DERR_INVALIDCALL;
1792 if (temp[6] != data_size)
1794 WARN("Wrong size supplied.\n");
1795 return E_FAIL;
1798 if (!IsEqualGUID(riid, &IID_ID3D11ShaderReflection))
1800 WARN("Wrong riid %s, accept only %s!\n", debugstr_guid(riid), debugstr_guid(&IID_ID3D11ShaderReflection));
1801 return E_NOINTERFACE;
1804 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1805 if (!object)
1806 return E_OUTOFMEMORY;
1808 hr = d3dcompiler_shader_reflection_init(object, data, data_size);
1809 if (FAILED(hr))
1811 WARN("Failed to initialize shader reflection\n");
1812 HeapFree(GetProcessHeap(), 0, object);
1813 return hr;
1816 *reflector = object;
1818 TRACE("Created ID3D11ShaderReflection %p\n", object);
1820 return S_OK;