vkd3d-utils: Implement ID3D12ShaderReflection::GetResourceBindingDesc().

This commit is contained in:
Zebediah Figura 2024-05-02 23:43:38 -05:00 committed by Alexandre Julliard
parent 694d39ffe6
commit cefd6f9de6
Notes: Alexandre Julliard 2024-05-06 22:37:40 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/848
2 changed files with 85 additions and 6 deletions

View File

@ -61,6 +61,8 @@ struct d3d12_reflection
D3D12_SHADER_DESC desc;
struct d3d12_buffer *buffers;
D3D12_SHADER_INPUT_BIND_DESC *bindings;
};
static struct d3d12_buffer null_buffer;
@ -397,6 +399,10 @@ static ULONG STDMETHODCALLTYPE d3d12_reflection_Release(ID3D12ShaderReflection *
}
vkd3d_free(reflection->buffers);
for (UINT i = 0; i < reflection->desc.BoundResources; ++i)
vkd3d_free((void *)reflection->bindings[i].Name);
vkd3d_free(reflection->bindings);
vkd3d_shader_free_scan_signature_info(&reflection->signature_info);
free(reflection);
}
@ -444,9 +450,18 @@ static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d12_ref
static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetResourceBindingDesc(
ID3D12ShaderReflection *iface, UINT index, D3D12_SHADER_INPUT_BIND_DESC *desc)
{
FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc);
struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
return E_NOTIMPL;
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
if (index >= reflection->desc.BoundResources)
{
WARN("Invalid index %u.\n", index);
return E_INVALIDARG;
}
*desc = reflection->bindings[index];
return S_OK;
}
static HRESULT get_signature_parameter(const struct vkd3d_shader_signature *signature,
@ -730,6 +745,20 @@ struct rdef_field
uint32_t offset;
};
struct rdef_binding
{
uint32_t name_offset;
uint32_t type;
uint32_t resource_format;
uint32_t dimension;
uint32_t multisample_count;
uint32_t index;
uint32_t count;
uint32_t flags;
uint32_t space;
uint32_t id;
};
static HRESULT d3d12_type_init(struct d3d12_type *type, uint32_t type_offset, uint32_t type_size,
const struct vkd3d_shader_code *section, uint32_t field_offset)
{
@ -856,6 +885,7 @@ static HRESULT d3d12_buffer_init(struct d3d12_buffer *buffer, const struct rdef_
static HRESULT parse_rdef(struct d3d12_reflection *reflection, const struct vkd3d_shader_code *section)
{
uint32_t variable_size = offsetof(struct rdef_variable, resource_binding);
uint32_t binding_size = offsetof(struct rdef_binding, space);
uint32_t type_size = offsetof(struct rdef_type, unknown);
const struct rdef_header *header;
const struct rdef_rd11 *rd11;
@ -897,6 +927,14 @@ static HRESULT parse_rdef(struct d3d12_reflection *reflection, const struct vkd3
}
variable_size = rd11->variable_size;
if (rd11->binding_size != sizeof(struct rdef_binding)
&& rd11->binding_size != offsetof(struct rdef_binding, space))
{
FIXME("Unexpected binding size %#x.\n", rd11->binding_size);
return E_INVALIDARG;
}
binding_size = rd11->binding_size;
if (rd11->type_size != sizeof(struct rdef_type))
{
FIXME("Unexpected type size %#x.\n", rd11->type_size);
@ -931,6 +969,48 @@ static HRESULT parse_rdef(struct d3d12_reflection *reflection, const struct vkd3
}
}
reflection->desc.BoundResources = header->binding_count;
if (header->binding_count)
{
if (!(reflection->bindings = vkd3d_calloc(header->binding_count, sizeof(*reflection->bindings))))
return E_OUTOFMEMORY;
for (uint32_t i = 0; i < header->binding_count; ++i)
{
const struct rdef_binding *rdef_binding;
D3D12_SHADER_INPUT_BIND_DESC *binding;
char *name;
if (!(rdef_binding = get_data_ptr(section, header->bindings_offset + (i * binding_size), 1, binding_size)))
return E_INVALIDARG;
if (FAILED(hr = get_string(section, rdef_binding->name_offset, &name)))
return hr;
binding = &reflection->bindings[i];
binding->Name = name;
binding->Type = rdef_binding->type;
binding->BindPoint = rdef_binding->index;
binding->BindCount = rdef_binding->count;
binding->uFlags = rdef_binding->flags;
binding->ReturnType = rdef_binding->resource_format;
binding->Dimension = rdef_binding->dimension;
binding->NumSamples = rdef_binding->multisample_count;
if (binding_size == sizeof(*rdef_binding))
{
binding->Space = rdef_binding->space;
binding->uID = rdef_binding->id;
}
else
{
binding->Space = 0;
binding->uID = rdef_binding->index;
}
}
}
return S_OK;
}

View File

@ -1573,7 +1573,7 @@ static void test_reflection(void)
hr = ID3D12ShaderReflection_GetDesc(reflection, &shader_desc);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
ok(shader_desc.ConstantBuffers == tests[t].buffer_count, "Got %u buffers.\n", shader_desc.ConstantBuffers);
todo ok(shader_desc.BoundResources == tests[t].binding_count, "Got %u resources.\n", shader_desc.BoundResources);
ok(shader_desc.BoundResources == tests[t].binding_count, "Got %u resources.\n", shader_desc.BoundResources);
for (unsigned int i = 0; i < shader_desc.ConstantBuffers; ++i)
{
@ -1669,8 +1669,7 @@ static void test_reflection(void)
ok(binding_desc.Type == expect->Type, "Got type %#x.\n", binding_desc.Type);
ok(binding_desc.BindPoint == expect->BindPoint, "Got bind point %u.\n", binding_desc.BindPoint);
ok(binding_desc.BindCount == expect->BindCount, "Got bind count %u.\n", binding_desc.BindCount);
todo_if ((expect->uFlags & D3D_SIF_USERPACKED) && expect->Type != D3D_SIT_CBUFFER)
ok(binding_desc.uFlags == expect->uFlags, "Got flags %#x.\n", binding_desc.uFlags);
ok(binding_desc.uFlags == expect->uFlags, "Got flags %#x.\n", binding_desc.uFlags);
ok(binding_desc.ReturnType == expect->ReturnType, "Got return type %#x.\n", binding_desc.ReturnType);
ok(binding_desc.Dimension == expect->Dimension, "Got dimension %#x.\n", binding_desc.Dimension);
ok(binding_desc.NumSamples == expect->NumSamples, "Got multisample count %u.\n", binding_desc.NumSamples);
@ -1679,7 +1678,7 @@ static void test_reflection(void)
}
hr = ID3D12ShaderReflection_GetResourceBindingDesc(reflection, shader_desc.BoundResources, &binding_desc);
todo ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
ID3D10Blob_Release(code);
refcount = ID3D12ShaderReflection_Release(reflection);