From: Henri Verbeet <hverbeet@locutus.nl> --- dlls/d3dcompiler_43/reflection.c | 268 +++++++------------------------ dlls/wined3d/wined3d.spec | 1 + 2 files changed, 57 insertions(+), 212 deletions(-) diff --git a/dlls/d3dcompiler_43/reflection.c b/dlls/d3dcompiler_43/reflection.c index 21b367f5002..c720d28e7e4 100644 --- a/dlls/d3dcompiler_43/reflection.c +++ b/dlls/d3dcompiler_43/reflection.c @@ -59,13 +59,6 @@ enum d3dcompiler_shader_type D3DCOMPILER_SHADER_TYPE_CS = 5, }; -struct d3dcompiler_shader_signature -{ - D3D11_SIGNATURE_PARAMETER_DESC *elements; - unsigned int element_count; - char *string_data; -}; - struct d3dcompiler_shader_reflection_type { ID3D11ShaderReflectionType ID3D11ShaderReflectionType_iface; @@ -131,6 +124,8 @@ struct d3dcompiler_shader_reflection enum D3DCOMPILER_REFLECTION_VERSION interface_version; + struct vkd3d_shader_scan_signature_info signature_info; + uint32_t target; char *creator; UINT flags; @@ -170,9 +165,6 @@ struct d3dcompiler_shader_reflection UINT thread_group_size_y; UINT thread_group_size_z; - struct d3dcompiler_shader_signature *isgn; - struct d3dcompiler_shader_signature *osgn; - struct d3dcompiler_shader_signature *pcsg; char *resource_string; D3D12_SHADER_INPUT_BIND_DESC *bound_resources; struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers; @@ -267,14 +259,6 @@ static void d3dcompiler_shader_reflection_type_destroy(struct wine_rb_entry *ent free(t); } -static void free_signature(struct d3dcompiler_shader_signature *sig) -{ - TRACE("Free signature %p\n", sig); - - free(sig->elements); - free(sig->string_data); -} - static void free_variable(struct d3dcompiler_shader_reflection_variable *var) { if (var) @@ -304,24 +288,6 @@ static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref) { TRACE("Cleanup %p\n", ref); - if (ref->isgn) - { - free_signature(ref->isgn); - free(ref->isgn); - } - - if (ref->osgn) - { - free_signature(ref->osgn); - free(ref->osgn); - } - - if (ref->pcsg) - { - free_signature(ref->pcsg); - free(ref->pcsg); - } - if (ref->constant_buffers) { unsigned int i; @@ -337,6 +303,8 @@ static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref) free(ref->bound_resources); free(ref->resource_string); free(ref->creator); + + vkd3d_shader_free_scan_signature_info(&ref->signature_info); } /* IUnknown methods */ @@ -410,8 +378,8 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11Sha 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; @@ -435,7 +403,7 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11Sha desc->GSMaxOutputVertexCount = reflection->gs_max_output_vertex_count; #if D3D_COMPILER_VERSION 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; @@ -515,40 +483,53 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindin return S_OK; } -static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc( - ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) +static HRESULT get_signature_parameter(const struct vkd3d_shader_signature *signature, + unsigned int index, D3D11_SIGNATURE_PARAMETER_DESC *desc, bool output) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(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"); + 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 ? (0xf ^ e->used_mask) : e->used_mask; +#if D3D_COMPILER_VERSION + desc->Stream = e->stream_index; +#endif +#if D3D_COMPILER_VERSION >= 46 + desc->MinPrecision = (D3D_MIN_PRECISION)e->min_precision; +#endif return S_OK; } -static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc( +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc( ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) { struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface); - TRACE("iface %p, index %u, desc %p\n", iface, index, desc); + 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 d3dcompiler_shader_reflection_GetOutputParameterDesc( + ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(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); } #if D3D_COMPILER_VERSION @@ -556,18 +537,11 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantP ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) { struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D11ShaderReflection(iface); + bool output = ((reflection->version & 0xffff0000) >> 16) == D3D12_SHVER_HULL_SHADER; - TRACE("iface %p, index %u, desc %p\n", iface, index, desc); + 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, output); } static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName( @@ -1670,104 +1644,6 @@ err_out: return hr; } -static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, - const struct vkd3d_shader_dxbc_section_desc *section) -{ - enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size; - const char *ptr = section->data.code; - D3D11_SIGNATURE_PARAMETER_DESC *d; - unsigned int string_data_offset; - unsigned int string_data_size; - unsigned int i, count; - char *string_data; - - switch (section->tag) - { - case TAG_OSG5: - element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7; - break; - - case TAG_ISGN: - case TAG_OSGN: - case TAG_PCSG: - element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6; - break; - - default: - FIXME("Unhandled section %s!\n", debugstr_fourcc(section->tag)); - element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6; - break; - } - - count = read_u32(&ptr); - TRACE("%u elements\n", count); - - skip_u32_unknown(&ptr, 1); - - d = 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 = malloc(string_data_size); - if (!string_data) - { - ERR("Failed to allocate string data memory.\n"); - free(d); - return E_OUTOFMEMORY; - } - memcpy(string_data, (const char *)section->data.code + string_data_offset, string_data_size); - - for (i = 0; i < count; ++i) - { - uint32_t name_offset, mask; - -#if D3D_COMPILER_VERSION >= 46 - /* FIXME */ - d[i].MinPrecision = D3D_MIN_PRECISION_DEFAULT; -#endif -#if D3D_COMPILER_VERSION - if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7) - { - d[i].Stream = read_u32(&ptr); - } -#endif - - 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 (!stricmp(d[i].SemanticName, "sv_depth")) - d[i].SystemValueType = D3D_NAME_DEPTH; - else if (!stricmp(d[i].SemanticName, "sv_coverage")) - d[i].SystemValueType = D3D_NAME_COVERAGE; - else if (!stricmp(d[i].SemanticName, "sv_depthgreaterequal")) - d[i].SystemValueType = D3D_NAME_DEPTH_GREATER_EQUAL; - else if (!stricmp(d[i].SemanticName, "sv_depthlessequal")) - d[i].SystemValueType = D3D_NAME_DEPTH_LESS_EQUAL; - else if (!stricmp(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) @@ -1847,17 +1723,31 @@ static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, c static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection, const void *data, SIZE_T data_size) { - const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size}; + struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; struct vkd3d_shader_dxbc_desc src_dxbc_desc; HRESULT hr = S_OK; unsigned int i; int ret; + compile_info.next = &reflection->signature_info; + compile_info.source.code = data; + compile_info.source.size = data_size; + compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; + + reflection->signature_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO; + + if ((ret = vkd3d_shader_scan(&compile_info, NULL)) < 0) + { + WARN("Failed to scan shader, ret %d.\n", ret); + return E_FAIL; + } + wine_rb_init(&reflection->types, d3dcompiler_shader_reflection_type_compare); - if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0) + if ((ret = vkd3d_shader_parse_dxbc(&compile_info.source, 0, &src_dxbc_desc, NULL)) < 0) { WARN("Failed to parse reflection, ret %d.\n", ret); + vkd3d_shader_free_scan_signature_info(&reflection->signature_info); return E_FAIL; } @@ -1877,55 +1767,9 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl break; case TAG_ISGN: - reflection->isgn = calloc(1, sizeof(*reflection->isgn)); - if (!reflection->isgn) - { - ERR("Failed to allocate ISGN memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } - - hr = d3dcompiler_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 = calloc(1, sizeof(*reflection->osgn)); - if (!reflection->osgn) - { - ERR("Failed to allocate OSGN memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } - - hr = d3dcompiler_parse_signature(reflection->osgn, section); - if (FAILED(hr)) - { - WARN("Failed to parse section OSGN.\n"); - goto err_out; - } - break; - case TAG_PCSG: - reflection->pcsg = calloc(1, sizeof(*reflection->pcsg)); - if (!reflection->pcsg) - { - ERR("Failed to allocate PCSG memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } - - hr = d3dcompiler_parse_signature(reflection->pcsg, section); - if (FAILED(hr)) - { - WARN("Failed to parse section PCSG.\n"); - goto err_out; - } break; case TAG_SHEX: diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index e08dd089521..735957c8777 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -388,6 +388,7 @@ @ cdecl vkd3d_shader_free_messages(ptr) @ cdecl vkd3d_shader_free_root_signature(ptr) @ cdecl vkd3d_shader_free_scan_descriptor_info(ptr) +@ cdecl vkd3d_shader_free_scan_signature_info(ptr) @ cdecl vkd3d_shader_free_shader_code(ptr) @ cdecl vkd3d_shader_free_shader_signature(ptr) @ cdecl vkd3d_shader_get_supported_source_types(ptr) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11070