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
22 #include "wine/port.h"
24 #include "d3dcompiler_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
28 static void free_signature(struct d3dcompiler_shader_signature *sig)
30 TRACE("Free signature %p\n", sig);
32 HeapFree(GetProcessHeap(), 0, sig->elements);
33 HeapFree(GetProcessHeap(), 0, sig->string_data);
36 static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref)
38 TRACE("Cleanup %p\n", ref);
42 free_signature(ref->isgn);
43 HeapFree(GetProcessHeap(), 0, ref->isgn);
48 free_signature(ref->osgn);
49 HeapFree(GetProcessHeap(), 0, ref->osgn);
54 free_signature(ref->pcsg);
55 HeapFree(GetProcessHeap(), 0, ref->pcsg);
59 static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
61 return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
64 /* IUnknown methods */
66 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
68 TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
70 if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection)
71 || IsEqualGUID(riid, &IID_IUnknown))
73 IUnknown_AddRef(iface);
78 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
84 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
86 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
87 ULONG refcount = InterlockedIncrement(&This->refcount);
89 TRACE("%p increasing refcount to %u\n", This, refcount);
94 static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
96 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
97 ULONG refcount = InterlockedDecrement(&This->refcount);
99 TRACE("%p decreasing refcount to %u\n", This, refcount);
103 reflection_cleanup(This);
104 HeapFree(GetProcessHeap(), 0, This);
110 /* ID3D11ShaderReflection methods */
112 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
114 FIXME("iface %p, desc %p stub!\n", iface, desc);
119 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
120 ID3D11ShaderReflection *iface, UINT index)
122 FIXME("iface %p, index %u stub!\n", iface, index);
127 static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
128 ID3D11ShaderReflection *iface, LPCSTR name)
130 FIXME("iface %p, name \"%s\" stub!\n", iface, name);
135 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
136 ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
138 FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc);
143 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
144 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
146 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
148 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
150 if (!desc || !This->isgn || index >= This->isgn->element_count)
152 WARN("Invalid argument specified\n");
156 *desc = This->isgn->elements[index];
161 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
162 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
164 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
166 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
168 if (!desc || !This->osgn || index >= This->osgn->element_count)
170 WARN("Invalid argument specified\n");
174 *desc = This->osgn->elements[index];
179 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
180 ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
182 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
184 TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
186 if (!desc || !This->pcsg || index >= This->pcsg->element_count)
188 WARN("Invalid argument specified\n");
192 *desc = This->pcsg->elements[index];
197 static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
198 ID3D11ShaderReflection *iface, LPCSTR name)
200 FIXME("iface %p, name %s stub!\n", iface, name);
205 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
206 ID3D11ShaderReflection *iface, LPCSTR name, D3D11_SHADER_INPUT_BIND_DESC *desc)
208 FIXME("iface %p, name %s, desc %p stub!\n", iface, name, desc);
213 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
214 ID3D11ShaderReflection *iface)
216 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
218 TRACE("iface %p\n", iface);
220 return This->mov_instruction_count;
223 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
224 ID3D11ShaderReflection *iface)
226 FIXME("iface %p stub!\n", iface);
231 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
232 ID3D11ShaderReflection *iface)
234 struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
236 TRACE("iface %p\n", iface);
238 return This->conversion_instruction_count;
241 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
242 ID3D11ShaderReflection *iface)
244 FIXME("iface %p stub!\n", iface);
249 static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
250 ID3D11ShaderReflection *iface)
252 FIXME("iface %p stub!\n", iface);
257 static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
258 ID3D11ShaderReflection *iface)
260 FIXME("iface %p stub!\n", iface);
265 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
266 ID3D11ShaderReflection *iface)
268 FIXME("iface %p stub!\n", iface);
273 static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
274 ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
276 FIXME("iface %p, level %p stub!\n", iface, level);
281 static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize(
282 ID3D11ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez)
284 FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez);
289 const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
291 /* IUnknown methods */
292 d3dcompiler_shader_reflection_QueryInterface,
293 d3dcompiler_shader_reflection_AddRef,
294 d3dcompiler_shader_reflection_Release,
295 /* ID3D11ShaderReflection methods */
296 d3dcompiler_shader_reflection_GetDesc,
297 d3dcompiler_shader_reflection_GetConstantBufferByIndex,
298 d3dcompiler_shader_reflection_GetConstantBufferByName,
299 d3dcompiler_shader_reflection_GetResourceBindingDesc,
300 d3dcompiler_shader_reflection_GetInputParameterDesc,
301 d3dcompiler_shader_reflection_GetOutputParameterDesc,
302 d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
303 d3dcompiler_shader_reflection_GetVariableByName,
304 d3dcompiler_shader_reflection_GetResourceBindingDescByName,
305 d3dcompiler_shader_reflection_GetMovInstructionCount,
306 d3dcompiler_shader_reflection_GetMovcInstructionCount,
307 d3dcompiler_shader_reflection_GetConversionInstructionCount,
308 d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
309 d3dcompiler_shader_reflection_GetGSInputPrimitive,
310 d3dcompiler_shader_reflection_IsSampleFrequencyShader,
311 d3dcompiler_shader_reflection_GetNumInterfaceSlots,
312 d3dcompiler_shader_reflection_GetMinFeatureLevel,
313 d3dcompiler_shader_reflection_GetThreadGroupSize,
316 static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, DWORD data_size)
318 const char *ptr = data;
319 DWORD size = data_size >> 2;
321 TRACE("Size %u\n", size);
323 read_dword(&ptr, &r->instruction_count);
324 TRACE("InstructionCount: %u\n", r->instruction_count);
326 read_dword(&ptr, &r->temp_register_count);
327 TRACE("TempRegisterCount: %u\n", r->temp_register_count);
329 skip_dword_unknown(&ptr, 1);
331 read_dword(&ptr, &r->dcl_count);
332 TRACE("DclCount: %u\n", r->dcl_count);
334 read_dword(&ptr, &r->float_instruction_count);
335 TRACE("FloatInstructionCount: %u\n", r->float_instruction_count);
337 read_dword(&ptr, &r->int_instruction_count);
338 TRACE("IntInstructionCount: %u\n", r->int_instruction_count);
340 read_dword(&ptr, &r->uint_instruction_count);
341 TRACE("UintInstructionCount: %u\n", r->uint_instruction_count);
343 read_dword(&ptr, &r->static_flow_control_count);
344 TRACE("StaticFlowControlCount: %u\n", r->static_flow_control_count);
346 read_dword(&ptr, &r->dynamic_flow_control_count);
347 TRACE("DynamicFlowControlCount: %u\n", r->dynamic_flow_control_count);
349 skip_dword_unknown(&ptr, 1);
351 read_dword(&ptr, &r->temp_array_count);
352 TRACE("TempArrayCount: %u\n", r->temp_array_count);
354 read_dword(&ptr, &r->array_instruction_count);
355 TRACE("ArrayInstructionCount: %u\n", r->array_instruction_count);
357 read_dword(&ptr, &r->cut_instruction_count);
358 TRACE("CutInstructionCount: %u\n", r->cut_instruction_count);
360 read_dword(&ptr, &r->emit_instruction_count);
361 TRACE("EmitInstructionCount: %u\n", r->emit_instruction_count);
363 read_dword(&ptr, &r->texture_normal_instructions);
364 TRACE("TextureNormalInstructions: %u\n", r->texture_normal_instructions);
366 read_dword(&ptr, &r->texture_load_instructions);
367 TRACE("TextureLoadInstructions: %u\n", r->texture_load_instructions);
369 read_dword(&ptr, &r->texture_comp_instructions);
370 TRACE("TextureCompInstructions: %u\n", r->texture_comp_instructions);
372 read_dword(&ptr, &r->texture_bias_instructions);
373 TRACE("TextureBiasInstructions: %u\n", r->texture_bias_instructions);
375 read_dword(&ptr, &r->texture_gradient_instructions);
376 TRACE("TextureGradientInstructions: %u\n", r->texture_gradient_instructions);
378 read_dword(&ptr, &r->mov_instruction_count);
379 TRACE("MovInstructionCount: %u\n", r->mov_instruction_count);
381 skip_dword_unknown(&ptr, 1);
383 read_dword(&ptr, &r->conversion_instruction_count);
384 TRACE("ConversionInstructionCount: %u\n", r->conversion_instruction_count);
386 skip_dword_unknown(&ptr, 1);
388 read_dword(&ptr, &r->input_primitive);
389 TRACE("InputPrimitive: %x\n", r->input_primitive);
391 read_dword(&ptr, &r->gs_output_topology);
392 TRACE("GSOutputTopology: %x\n", r->gs_output_topology);
394 read_dword(&ptr, &r->gs_max_output_vertex_count);
395 TRACE("GSMaxOutputVertexCount: %u\n", r->gs_max_output_vertex_count);
397 skip_dword_unknown(&ptr, 3);
400 if (size == 29) return S_OK;
402 skip_dword_unknown(&ptr, 1);
404 read_dword(&ptr, &r->c_control_points);
405 TRACE("cControlPoints: %u\n", r->c_control_points);
407 read_dword(&ptr, &r->hs_output_primitive);
408 TRACE("HSOutputPrimitive: %x\n", r->hs_output_primitive);
410 read_dword(&ptr, &r->hs_prtitioning);
411 TRACE("HSPartitioning: %x\n", r->hs_prtitioning);
413 read_dword(&ptr, &r->tessellator_domain);
414 TRACE("TessellatorDomain: %x\n", r->tessellator_domain);
416 skip_dword_unknown(&ptr, 3);
419 if (size == 37) return S_OK;
421 FIXME("Unhandled size %u\n", size);
426 HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, const char *data, DWORD data_size)
428 D3D11_SIGNATURE_PARAMETER_DESC *d;
429 unsigned int string_data_offset;
430 unsigned int string_data_size;
431 const char *ptr = data;
436 read_dword(&ptr, &count);
437 TRACE("%u elements\n", count);
439 skip_dword_unknown(&ptr, 1);
441 d = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*d));
444 ERR("Failed to allocate signature memory.\n");
445 return E_OUTOFMEMORY;
448 /* 2 DWORDs for the header, 6 for each element. */
449 string_data_offset = 2 * sizeof(DWORD) + count * 6 * sizeof(DWORD);
450 string_data_size = data_size - string_data_offset;
451 string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size);
454 ERR("Failed to allocate string data memory.\n");
455 HeapFree(GetProcessHeap(), 0, d);
456 return E_OUTOFMEMORY;
458 memcpy(string_data, data + string_data_offset, string_data_size);
460 for (i = 0; i < count; ++i)
465 /* todo: Parse stream in shaderblobs v5 (dx11) */
468 read_dword(&ptr, &name_offset);
469 d[i].SemanticName = string_data + (name_offset - string_data_offset);
470 read_dword(&ptr, &d[i].SemanticIndex);
471 read_dword(&ptr, &d[i].SystemValueType);
472 read_dword(&ptr, &d[i].ComponentType);
473 read_dword(&ptr, &d[i].Register);
474 read_dword(&ptr, &mask);
475 d[i].ReadWriteMask = (mask >> 8) & 0xff;
476 d[i].Mask = mask & 0xff;
478 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
479 "type %u, register idx: %u, use_mask %#x, input_mask %#x, stream %u\n",
480 debugstr_a(d[i].SemanticName), d[i].SemanticIndex, d[i].SystemValueType,
481 d[i].ComponentType, d[i].Register, d[i].Mask, d[i].ReadWriteMask, d[i].Stream);
485 s->element_count = count;
486 s->string_data = string_data;
491 HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection,
492 const void *data, SIZE_T data_size)
494 struct dxbc src_dxbc;
498 reflection->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
499 reflection->refcount = 1;
501 hr = dxbc_parse(data, data_size, &src_dxbc);
504 WARN("Failed to parse reflection\n");
508 for (i = 0; i < src_dxbc.count; ++i)
510 struct dxbc_section *section = &src_dxbc.sections[i];
512 switch (section->tag)
515 hr = d3dcompiler_parse_stat(reflection, section->data, section->data_size);
518 WARN("Failed to parse section STAT.\n");
524 reflection->isgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->isgn));
525 if (!reflection->isgn)
527 ERR("Failed to allocate ISGN memory.\n");
532 hr = d3dcompiler_parse_signature(reflection->isgn, section->data, section->data_size);
535 WARN("Failed to parse section ISGN.\n");
541 reflection->osgn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->osgn));
542 if (!reflection->osgn)
544 ERR("Failed to allocate OSGN memory.\n");
549 hr = d3dcompiler_parse_signature(reflection->osgn, section->data, section->data_size);
552 WARN("Failed to parse section OSGN.\n");
558 reflection->pcsg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*reflection->pcsg));
559 if (!reflection->pcsg)
561 ERR("Failed to allocate PCSG memory.\n");
566 hr = d3dcompiler_parse_signature(reflection->pcsg, section->data, section->data_size);
569 WARN("Failed to parse section PCSG.\n");
575 FIXME("Unhandled section %s!\n", debugstr_an((const char *)§ion->tag, 4));
580 dxbc_destroy(&src_dxbc);
585 reflection_cleanup(reflection);
586 dxbc_destroy(&src_dxbc);