From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-utils/reflection.c | 253 +++++++--------------------------- 1 file changed, 47 insertions(+), 206 deletions(-)
diff --git a/libs/vkd3d-utils/reflection.c b/libs/vkd3d-utils/reflection.c index 1796a8428..1c537ab26 100644 --- a/libs/vkd3d-utils/reflection.c +++ b/libs/vkd3d-utils/reflection.c @@ -22,12 +22,6 @@ #include <vkd3d_d3d12shader.h> #include "rbtree.h"
-enum signature_element_size -{ - SIGNATURE_ELEMENT_SIZE6 = 6, - SIGNATURE_ELEMENT_SIZE7 = 7, -}; - #define SHADER_TARGET_VERSION_MASK 0xffff #define SHADER_TARGET_SHADERTYPE_MASK 0xffff0000 #define SHADER_TARGET_SHADERTYPE_SHIFT 16 @@ -36,16 +30,10 @@ enum signature_element_size
enum shader_type { + SHADER_TYPE_HS = 3, SHADER_TYPE_CS = 5, };
-struct shader_signature -{ - D3D12_SIGNATURE_PARAMETER_DESC *elements; - unsigned int element_count; - char *string_data; -}; - struct reflection_type { ID3D12ShaderReflectionType ID3D12ShaderReflectionType_iface; @@ -110,6 +98,8 @@ struct reflection
enum REFLECTION_VERSION interface_version;
+ struct vkd3d_shader_scan_signature_info signature_info; + uint32_t target; char *creator; UINT flags; @@ -149,9 +139,6 @@ struct reflection UINT thread_group_size_y; UINT thread_group_size_z;
- struct shader_signature *isgn; - struct shader_signature *osgn; - struct shader_signature *pcsg; char *resource_string; D3D12_SHADER_INPUT_BIND_DESC *bound_resources; struct reflection_constant_buffer *constant_buffers; @@ -263,14 +250,6 @@ static void reflection_type_destroy(struct rb_entry *entry, void *context) vkd3d_free(t); }
-static void free_signature(struct shader_signature *sig) -{ - TRACE("Free signature %p.\n", sig); - - vkd3d_free(sig->elements); - vkd3d_free(sig->string_data); -} - static void free_variable(struct reflection_variable *var) { if (var) @@ -296,23 +275,7 @@ static void reflection_cleanup(struct reflection *ref) { TRACE("Cleanup %p.\n", ref);
- if (ref->isgn) - { - free_signature(ref->isgn); - vkd3d_free(ref->isgn); - } - - if (ref->osgn) - { - free_signature(ref->osgn); - vkd3d_free(ref->osgn); - } - - if (ref->pcsg) - { - free_signature(ref->pcsg); - vkd3d_free(ref->pcsg); - } + vkd3d_shader_free_scan_signature_info(&ref->signature_info);
if (ref->constant_buffers) { @@ -392,8 +355,8 @@ static HRESULT STDMETHODCALLTYPE reflection_GetDesc(ID3D12ShaderReflection *ifac desc->Flags = reflection->flags; desc->ConstantBuffers = reflection->constant_buffer_count; desc->BoundResources = reflection->bound_resource_count; - desc->InputParameters = reflection->isgn ? reflection->isgn->element_count : 0; - desc->OutputParameters = reflection->osgn ? reflection->osgn->element_count : 0; + desc->InputParameters = reflection->signature_info.input.element_count; + desc->OutputParameters = reflection->signature_info.output.element_count; desc->InstructionCount = reflection->instruction_count; desc->TempRegisterCount = reflection->temp_register_count; desc->TempArrayCount = reflection->temp_array_count; @@ -416,7 +379,7 @@ static HRESULT STDMETHODCALLTYPE reflection_GetDesc(ID3D12ShaderReflection *ifac desc->GSOutputTopology = reflection->gs_output_topology; desc->GSMaxOutputVertexCount = reflection->gs_max_output_vertex_count; desc->InputPrimitive = reflection->input_primitive; - desc->PatchConstantParameters = reflection->pcsg ? reflection->pcsg->element_count : 0; + desc->PatchConstantParameters = reflection->signature_info.patch_constant.element_count; desc->cGSInstanceCount = 0; desc->cControlPoints = reflection->c_control_points; desc->HSOutputPrimitive = reflection->hs_output_primitive; @@ -494,58 +457,60 @@ static HRESULT STDMETHODCALLTYPE reflection_GetResourceBindingDesc( return S_OK; }
-static HRESULT STDMETHODCALLTYPE reflection_GetInputParameterDesc( - ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +static HRESULT get_signature_parameter(const struct vkd3d_shader_signature *signature, + unsigned int index, D3D12_SIGNATURE_PARAMETER_DESC *desc, bool output) { - struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface); - - TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + const struct vkd3d_shader_signature_element *e;
- if (!desc || !reflection->isgn || index >= reflection->isgn->element_count) + if (!desc || index >= signature->element_count) { WARN("Invalid argument specified.\n"); return E_INVALIDARG; } + e = &signature->elements[index];
- *desc = reflection->isgn->elements[index]; + desc->SemanticName = e->semantic_name; + desc->SemanticIndex = e->semantic_index; + desc->Register = e->register_index; + desc->SystemValueType = (D3D_NAME)e->sysval_semantic; + desc->ComponentType = (D3D_REGISTER_COMPONENT_TYPE)e->component_type; + desc->Mask = e->mask; + desc->ReadWriteMask = output ? (e->mask & ~e->used_mask) : e->used_mask; + desc->Stream = e->stream_index; + desc->MinPrecision = (D3D_MIN_PRECISION)e->min_precision;
return S_OK; }
-static HRESULT STDMETHODCALLTYPE reflection_GetOutputParameterDesc( +static HRESULT STDMETHODCALLTYPE reflection_GetInputParameterDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) { struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
- if (!desc || !reflection->osgn || index >= reflection->osgn->element_count) - { - WARN("Invalid argument specified.\n"); - return E_INVALIDARG; - } + return get_signature_parameter(&reflection->signature_info.input, index, desc, false); +}
- *desc = reflection->osgn->elements[index]; +static HRESULT STDMETHODCALLTYPE reflection_GetOutputParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
- return S_OK; + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + return get_signature_parameter(&reflection->signature_info.output, index, desc, true); }
static HRESULT STDMETHODCALLTYPE reflection_GetPatchConstantParameterDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) { struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + enum shader_type type = (reflection->version & SHADER_TARGET_SHADERTYPE_MASK) >> SHADER_TARGET_SHADERTYPE_SHIFT;
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
- if (!desc || !reflection->pcsg || index >= reflection->pcsg->element_count) - { - WARN("Invalid argument specified.\n"); - return E_INVALIDARG; - } - - *desc = reflection->pcsg->elements[index]; - - return S_OK; + return get_signature_parameter(&reflection->signature_info.patch_constant, index, desc, type == SHADER_TYPE_HS); }
static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE reflection_GetVariableByName( @@ -1601,98 +1566,6 @@ err_out: return hr; }
-static HRESULT parse_signature(struct shader_signature *s, - const struct vkd3d_shader_dxbc_section_desc *section) -{ - enum signature_element_size element_size; - const char *ptr = section->data.code; - D3D12_SIGNATURE_PARAMETER_DESC *d; - unsigned int string_data_offset; - unsigned int string_data_size; - unsigned int count; - char *string_data; - - switch (section->tag) - { - case TAG_OSG5: - element_size = SIGNATURE_ELEMENT_SIZE7; - break; - - case TAG_ISGN: - case TAG_OSGN: - case TAG_PCSG: - element_size = SIGNATURE_ELEMENT_SIZE6; - break; - - default: - FIXME("Unhandled section %08x!\n", section->tag); - element_size = SIGNATURE_ELEMENT_SIZE6; - break; - } - - count = read_u32(&ptr); - TRACE("%u elements.\n", count); - - skip_u32_unknown(&ptr, 1); - - d = vkd3d_calloc(count, sizeof(*d)); - if (!d) - { - ERR("Failed to allocate signature memory.\n"); - return E_OUTOFMEMORY; - } - - /* 2 u32s for the header, element_size for each element. */ - string_data_offset = 2 * sizeof(uint32_t) + count * element_size * sizeof(uint32_t); - string_data_size = section->data.size - string_data_offset; - - string_data = vkd3d_malloc(string_data_size); - if (!string_data) - { - ERR("Failed to allocate string data memory.\n"); - vkd3d_free(d); - return E_OUTOFMEMORY; - } - memcpy(string_data, (const char *)section->data.code + string_data_offset, string_data_size); - - for (unsigned int i = 0; i < count; ++i) - { - uint32_t name_offset, mask; - - /* FIXME */ - d[i].MinPrecision = D3D_MIN_PRECISION_DEFAULT; - if (element_size == SIGNATURE_ELEMENT_SIZE7) - d[i].Stream = read_u32(&ptr); - - name_offset = read_u32(&ptr); - d[i].SemanticName = string_data + (name_offset - string_data_offset); - d[i].SemanticIndex = read_u32(&ptr); - d[i].SystemValueType = read_u32(&ptr); - d[i].ComponentType = read_u32(&ptr); - d[i].Register = read_u32(&ptr); - mask = read_u32(&ptr); - d[i].ReadWriteMask = (mask >> 8) & 0xff; - d[i].Mask = mask & 0xff; - - if (!ascii_strcasecmp(d[i].SemanticName, "sv_depth")) - d[i].SystemValueType = D3D_NAME_DEPTH; - else if (!ascii_strcasecmp(d[i].SemanticName, "sv_coverage")) - d[i].SystemValueType = D3D_NAME_COVERAGE; - else if (!ascii_strcasecmp(d[i].SemanticName, "sv_depthgreaterequal")) - d[i].SystemValueType = D3D_NAME_DEPTH_GREATER_EQUAL; - else if (!ascii_strcasecmp(d[i].SemanticName, "sv_depthlessequal")) - d[i].SystemValueType = D3D_NAME_DEPTH_LESS_EQUAL; - else if (!ascii_strcasecmp(d[i].SemanticName, "sv_target")) - d[i].SystemValueType = D3D_NAME_TARGET; - } - - s->elements = d; - s->element_count = count; - s->string_data = string_data; - - return S_OK; -} - #define SM4_OPCODE_MASK 0xff #define SM4_INSTRUCTION_LENGTH_SHIFT 24 #define SM4_INSTRUCTION_LENGTH_MASK (0x1fu << SM4_INSTRUCTION_LENGTH_SHIFT) @@ -1772,11 +1645,25 @@ static HRESULT parse_shdr(struct reflection *r, const char *data, size_t data_si static HRESULT reflection_init(struct reflection *reflection, const void *data, SIZE_T data_size) { + struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size}; struct vkd3d_shader_dxbc_desc src_dxbc_desc; HRESULT hr = S_OK; int ret;
+ info.source = src_dxbc; + info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; + info.target_type = VKD3D_SHADER_TARGET_NONE; + + info.next = &reflection->signature_info; + reflection->signature_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO; + + if ((ret = vkd3d_shader_scan(&info, NULL))) + { + WARN("Failed to scan, ret %d.\n", ret); + return hresult_from_vkd3d_result(ret); + } + rb_init(&reflection->types, reflection_type_compare);
if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0) @@ -1801,55 +1688,9 @@ static HRESULT reflection_init(struct reflection *reflection, break;
case TAG_ISGN: - reflection->isgn = vkd3d_calloc(1, sizeof(*reflection->isgn)); - if (!reflection->isgn) - { - ERR("Failed to allocate ISGN memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } - - hr = parse_signature(reflection->isgn, section); - if (FAILED(hr)) - { - WARN("Failed to parse section ISGN.\n"); - goto err_out; - } - break; - case TAG_OSG5: case TAG_OSGN: - reflection->osgn = vkd3d_calloc(1, sizeof(*reflection->osgn)); - if (!reflection->osgn) - { - ERR("Failed to allocate OSGN memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } - - hr = parse_signature(reflection->osgn, section); - if (FAILED(hr)) - { - WARN("Failed to parse section OSGN.\n"); - goto err_out; - } - break; - case TAG_PCSG: - reflection->pcsg = vkd3d_calloc(1, sizeof(*reflection->pcsg)); - if (!reflection->pcsg) - { - ERR("Failed to allocate PCSG memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } - - hr = parse_signature(reflection->pcsg, section); - if (FAILED(hr)) - { - WARN("Failed to parse section PCSG.\n"); - goto err_out; - } break;
case TAG_SHEX: