From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-utils/reflection.c | 118 ++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-utils/reflection.c b/libs/vkd3d-utils/reflection.c index 38b26afb4..c1fdf200f 100644 --- a/libs/vkd3d-utils/reflection.c +++ b/libs/vkd3d-utils/reflection.c @@ -22,10 +22,19 @@ #include <vkd3d_d3dcommon.h> #include <vkd3d_d3d12shader.h>
+struct d3d12_variable +{ + ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable_iface; + const struct vkd3d_shader_d3d_variable *variable; + struct d3d12_buffer *buffer; +}; + struct d3d12_buffer { ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer_iface; const struct vkd3d_shader_d3d_buffer *buffer; + + struct d3d12_variable *variables; };
struct d3d12_reflection @@ -40,6 +49,80 @@ struct d3d12_reflection };
static struct d3d12_buffer null_buffer; +static struct d3d12_variable null_variable; + +static struct d3d12_variable *impl_from_ID3D12ShaderReflectionVariable(ID3D12ShaderReflectionVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d12_variable, ID3D12ShaderReflectionVariable_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d12_variable_GetDesc( + ID3D12ShaderReflectionVariable *iface, D3D12_SHADER_VARIABLE_DESC *desc) +{ + struct d3d12_variable *variable = impl_from_ID3D12ShaderReflectionVariable(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (variable == &null_variable) + { + WARN("Null variable, returning E_FAIL.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("NULL pointer, returning E_FAIL.\n"); + return E_FAIL; + } + + desc->Name = variable->variable->name; + desc->StartOffset = variable->variable->offset; + desc->Size = variable->variable->size; + desc->uFlags = variable->variable->flags; + desc->DefaultValue = (void *)variable->variable->default_value; + desc->StartTexture = variable->variable->resource_binding; + desc->TextureSize = variable->variable->resource_count; + desc->StartSampler = variable->variable->sampler_binding; + desc->SamplerSize = variable->variable->sampler_count; + + return S_OK; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_variable_GetType( + ID3D12ShaderReflectionVariable *iface) +{ + FIXME("iface %p, stub!\n", iface); + + return NULL; +} + +static ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d12_variable_GetBuffer( + ID3D12ShaderReflectionVariable *iface) +{ + struct d3d12_variable *variable = impl_from_ID3D12ShaderReflectionVariable(iface); + + TRACE("iface %p.\n", iface); + + return &variable->buffer->ID3D12ShaderReflectionConstantBuffer_iface; +} + +static UINT STDMETHODCALLTYPE d3d12_variable_GetInterfaceSlot( + ID3D12ShaderReflectionVariable *iface, UINT index) +{ + FIXME("iface %p, index %u, stub!\n", iface, index); + + return 0; +} + +static const struct ID3D12ShaderReflectionVariableVtbl d3d12_variable_vtbl = +{ + d3d12_variable_GetDesc, + d3d12_variable_GetType, + d3d12_variable_GetBuffer, + d3d12_variable_GetInterfaceSlot, +}; + +static struct d3d12_variable null_variable = {{&d3d12_variable_vtbl}};
static struct d3d12_buffer *impl_from_ID3D12ShaderReflectionConstantBuffer(ID3D12ShaderReflectionConstantBuffer *iface) { @@ -76,9 +159,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_buffer_GetDesc( static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3d12_buffer_GetVariableByIndex( ID3D12ShaderReflectionConstantBuffer *iface, UINT index) { - FIXME("iface %p, index %u, stub!\n", iface, index); + struct d3d12_buffer *buffer = impl_from_ID3D12ShaderReflectionConstantBuffer(iface);
- return NULL; + TRACE("iface %p, index %u.\n", iface, index); + + if (index > buffer->buffer->variable_count) + { + WARN("Invalid index %u.\n", index); + return &null_variable.ID3D12ShaderReflectionVariable_iface; + } + + return &buffer->variables[index].ID3D12ShaderReflectionVariable_iface; }
static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3d12_buffer_GetVariableByName( @@ -367,10 +458,26 @@ static const struct ID3D12ShaderReflectionVtbl d3d12_reflection_vtbl = d3d12_reflection_GetRequiresFlags, };
-static void d3d12_buffer_init(struct d3d12_buffer *buffer, const struct vkd3d_shader_d3d_buffer *vkd3d_buffer) +static void d3d12_variable_init(struct d3d12_variable *variable, + struct d3d12_buffer *buffer, const struct vkd3d_shader_d3d_variable *vkd3d_variable) +{ + variable->ID3D12ShaderReflectionVariable_iface.lpVtbl = &d3d12_variable_vtbl; + variable->buffer = buffer; + variable->variable = vkd3d_variable; +} + +static bool d3d12_buffer_init(struct d3d12_buffer *buffer, const struct vkd3d_shader_d3d_buffer *vkd3d_buffer) { buffer->ID3D12ShaderReflectionConstantBuffer_iface.lpVtbl = &d3d12_buffer_vtbl; buffer->buffer = vkd3d_buffer; + + if (!(buffer->variables = vkd3d_calloc(vkd3d_buffer->variable_count, sizeof(*buffer->variables)))) + return false; + + for (uint32_t i = 0; i < vkd3d_buffer->variable_count; ++i) + d3d12_variable_init(&buffer->variables[i], buffer, &vkd3d_buffer->variables[i]); + + return true; }
static HRESULT d3d12_reflection_init(struct d3d12_reflection *reflection, const void *data, size_t data_size) @@ -398,7 +505,10 @@ static HRESULT d3d12_reflection_init(struct d3d12_reflection *reflection, const return E_OUTOFMEMORY;
for (uint32_t i = 0; i < reflection->buffer_info.buffer_count; ++i) - d3d12_buffer_init(&reflection->buffers[i], &reflection->buffer_info.buffers[i]); + { + if (!d3d12_buffer_init(&reflection->buffers[i], &reflection->buffer_info.buffers[i])) + return E_OUTOFMEMORY; + }
return S_OK; }