Unlike previous vkd3d-utils interfaces, ID3D12ShaderReflection is rather more large and complex, and will probably end up needing several new individual scan interfaces from vkd3d-shader, which are themselves not exactly trivial to design.
Therefore, instead of implementing everything in vkd3d-shader and then hooking up the vkd3d-utils interfaces on top of that, this patch series copies the existing implementation of reflection and then begins the process of moving its implementation to vkd3d-shader.
The primary motivation here is to add reflection crosstests (primarily for the benefit of the HLSL compiler) without being blocked on API design. Part 2 of this patch series does this.
From: Zebediah Figura zfigura@codeweavers.com
--- Makefile.am | 2 + include/vkd3d_d3d12shader.idl | 306 ++++++++++++++++++++++++++++++++++ include/vkd3d_d3dcommon.idl | 72 ++++++++ 3 files changed, 380 insertions(+) create mode 100644 include/vkd3d_d3d12shader.idl
diff --git a/Makefile.am b/Makefile.am index bc648b631..ea8f57ffe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,6 +6,7 @@ AM_LDFLAGS = -no-undefined widl_headers = \ include/vkd3d_d3d12.h \ include/vkd3d_d3d12sdklayers.h \ + include/vkd3d_d3d12shader.h \ include/vkd3d_d3dcommon.h \ include/vkd3d_d3dx9shader.h \ include/vkd3d_dxgi.h \ @@ -21,6 +22,7 @@ vkd3d_public_headers = \ include/vkd3d.h \ include/vkd3d_d3d12.h \ include/vkd3d_d3d12sdklayers.h \ + include/vkd3d_d3d12shader.h \ include/vkd3d_d3d9types.h \ include/vkd3d_d3dcommon.h \ include/vkd3d_d3dcompiler.h \ diff --git a/include/vkd3d_d3d12shader.idl b/include/vkd3d_d3d12shader.idl new file mode 100644 index 000000000..ba42a9458 --- /dev/null +++ b/include/vkd3d_d3d12shader.idl @@ -0,0 +1,306 @@ +/* + * Copyright 2020 Paul Gofman for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "vkd3d_windows.h"; +import "vkd3d_d3dcommon.idl"; + +typedef enum D3D12_SHADER_VERSION_TYPE +{ + D3D12_SHVER_PIXEL_SHADER = 0x0, + D3D12_SHVER_VERTEX_SHADER = 0x1, + D3D12_SHVER_GEOMETRY_SHADER = 0x2, + D3D12_SHVER_HULL_SHADER = 0x3, + D3D12_SHVER_DOMAIN_SHADER = 0x4, + D3D12_SHVER_COMPUTE_SHADER = 0x5, + D3D12_SHVER_RESERVED0 = 0xfff0, +} D3D12_SHADER_VERSION_TYPE; + +typedef struct _D3D12_SHADER_DESC +{ + UINT Version; + const char *Creator; + UINT Flags; + UINT ConstantBuffers; + UINT BoundResources; + UINT InputParameters; + UINT OutputParameters; + UINT InstructionCount; + UINT TempRegisterCount; + UINT TempArrayCount; + UINT DefCount; + UINT DclCount; + UINT TextureNormalInstructions; + UINT TextureLoadInstructions; + UINT TextureCompInstructions; + UINT TextureBiasInstructions; + UINT TextureGradientInstructions; + UINT FloatInstructionCount; + UINT IntInstructionCount; + UINT UintInstructionCount; + UINT StaticFlowControlCount; + UINT DynamicFlowControlCount; + UINT MacroInstructionCount; + UINT ArrayInstructionCount; + UINT CutInstructionCount; + UINT EmitInstructionCount; + D3D_PRIMITIVE_TOPOLOGY GSOutputTopology; + UINT GSMaxOutputVertexCount; + D3D_PRIMITIVE InputPrimitive; + UINT PatchConstantParameters; + UINT cGSInstanceCount; + UINT cControlPoints; + D3D_TESSELLATOR_OUTPUT_PRIMITIVE HSOutputPrimitive; + D3D_TESSELLATOR_PARTITIONING HSPartitioning; + D3D_TESSELLATOR_DOMAIN TessellatorDomain; + UINT cBarrierInstructions; + UINT cInterlockedInstructions; + UINT cTextureStoreInstructions; +} D3D12_SHADER_DESC; + +typedef struct _D3D12_SHADER_VARIABLE_DESC +{ + const char *Name; + UINT StartOffset; + UINT Size; + UINT uFlags; + void *DefaultValue; + UINT StartTexture; + UINT TextureSize; + UINT StartSampler; + UINT SamplerSize; +} D3D12_SHADER_VARIABLE_DESC; + +typedef struct _D3D12_SHADER_TYPE_DESC +{ + D3D_SHADER_VARIABLE_CLASS Class; + D3D_SHADER_VARIABLE_TYPE Type; + UINT Rows; + UINT Columns; + UINT Elements; + UINT Members; + UINT Offset; + const char *Name; +} D3D12_SHADER_TYPE_DESC; + +typedef struct _D3D12_SHADER_BUFFER_DESC +{ + const char *Name; + D3D_CBUFFER_TYPE Type; + UINT Variables; + UINT Size; + UINT uFlags; +} D3D12_SHADER_BUFFER_DESC; + +typedef struct _D3D12_SHADER_INPUT_BIND_DESC +{ + const char *Name; + D3D_SHADER_INPUT_TYPE Type; + UINT BindPoint; + UINT BindCount; + UINT uFlags; + D3D_RESOURCE_RETURN_TYPE ReturnType; + D3D_SRV_DIMENSION Dimension; + UINT NumSamples; + UINT Space; + UINT uID; +} D3D12_SHADER_INPUT_BIND_DESC; + +typedef struct _D3D12_SIGNATURE_PARAMETER_DESC +{ + const char *SemanticName; + UINT SemanticIndex; + UINT Register; + D3D_NAME SystemValueType; + D3D_REGISTER_COMPONENT_TYPE ComponentType; + BYTE Mask; + BYTE ReadWriteMask; + UINT Stream; + D3D_MIN_PRECISION MinPrecision; +} D3D12_SIGNATURE_PARAMETER_DESC; + +typedef struct _D3D12_PARAMETER_DESC +{ + const char *Name; + const char *SemanticName; + D3D_SHADER_VARIABLE_TYPE Type; + D3D_SHADER_VARIABLE_CLASS Class; + UINT Rows; + UINT Columns; + D3D_INTERPOLATION_MODE InterpolationMode; + D3D_PARAMETER_FLAGS Flags; + UINT FirstInRegister; + UINT FirstInComponent; + UINT FirstOutRegister; + UINT FirstOutComponent; +} D3D12_PARAMETER_DESC; + +typedef struct _D3D12_FUNCTION_DESC +{ + UINT Version; + const char *Creator; + UINT Flags; + UINT ConstantBuffers; + UINT BoundResources; + UINT InstructionCount; + UINT TempRegisterCount; + UINT TempArrayCount; + UINT DefCount; + UINT DclCount; + UINT TextureNormalInstructions; + UINT TextureLoadInstructions; + UINT TextureCompInstructions; + UINT TextureBiasInstructions; + UINT TextureGradientInstructions; + UINT FloatInstructionCount; + UINT IntInstructionCount; + UINT UintInstructionCount; + UINT StaticFlowControlCount; + UINT DynamicFlowControlCount; + UINT MacroInstructionCount; + UINT ArrayInstructionCount; + UINT MovInstructionCount; + UINT MovcInstructionCount; + UINT ConversionInstructionCount; + UINT BitwiseInstructionCount; + D3D_FEATURE_LEVEL MinFeatureLevel; + UINT64 RequiredFeatureFlags; + const char *Name; + INT FunctionParameterCount; + BOOL HasReturn; + BOOL Has10Level9VertexShader; + BOOL Has10Level9PixelShader; +} D3D12_FUNCTION_DESC; + +typedef struct _D3D12_LIBRARY_DESC +{ + const char *Creator; + UINT Flags; + UINT FunctionCount; +} D3D12_LIBRARY_DESC; + +interface ID3D12ShaderReflectionConstantBuffer; + +[ + uuid(e913c351-783d-48ca-a1d1-4f306284ad56), + object, + local, +] +interface ID3D12ShaderReflectionType +{ + HRESULT GetDesc(D3D12_SHADER_TYPE_DESC *desc); + ID3D12ShaderReflectionType *GetMemberTypeByIndex(UINT index); + ID3D12ShaderReflectionType *GetMemberTypeByName(const char *name); + const char *GetMemberTypeName(UINT index); + HRESULT IsEqual(ID3D12ShaderReflectionType *type); + ID3D12ShaderReflectionType *GetSubType(); + ID3D12ShaderReflectionType *GetBaseClass(); + UINT GetNumInterfaces(); + ID3D12ShaderReflectionType *GetInterfaceByIndex(UINT index); + HRESULT IsOfType(ID3D12ShaderReflectionType *type); + HRESULT ImplementsInterface(ID3D12ShaderReflectionType *base); +} + +[ + uuid(8337a8a6-a216-444a-b2f4-314733a73aea), + object, + local, +] +interface ID3D12ShaderReflectionVariable +{ + HRESULT GetDesc(D3D12_SHADER_VARIABLE_DESC *desc); + ID3D12ShaderReflectionType *GetType(); + ID3D12ShaderReflectionConstantBuffer *GetBuffer(); + UINT GetInterfaceSlot(UINT index); +} + +[ + uuid(c59598b4-48b3-4869-b9b1-b1618b14a8b7), + object, + local, +] +interface ID3D12ShaderReflectionConstantBuffer +{ + HRESULT GetDesc(D3D12_SHADER_BUFFER_DESC *desc); + ID3D12ShaderReflectionVariable *GetVariableByIndex(UINT index); + ID3D12ShaderReflectionVariable *GetVariableByName(const char *name); +} + +[ + uuid(5a58797d-a72c-478d-8ba2-efc6b0efe88e), + object, + local, +] +interface ID3D12ShaderReflection : IUnknown +{ + HRESULT GetDesc(D3D12_SHADER_DESC *desc); + ID3D12ShaderReflectionConstantBuffer *GetConstantBufferByIndex(UINT index); + ID3D12ShaderReflectionConstantBuffer *GetConstantBufferByName(const char *name); + HRESULT GetResourceBindingDesc(UINT index, D3D12_SHADER_INPUT_BIND_DESC *desc); + HRESULT GetInputParameterDesc(UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc); + HRESULT GetOutputParameterDesc(UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc); + HRESULT GetPatchConstantParameterDesc(UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc); + ID3D12ShaderReflectionVariable *GetVariableByName(const char *name); + HRESULT GetResourceBindingDescByName(const char *name, D3D12_SHADER_INPUT_BIND_DESC *desc); + UINT GetMovInstructionCount(); + UINT GetMovcInstructionCount(); + UINT GetConversionInstructionCount(); + UINT GetBitwiseInstructionCount(); + D3D_PRIMITIVE GetGSInputPrimitive(); + BOOL IsSampleFrequencyShader(); + UINT GetNumInterfaceSlots(); + HRESULT GetMinFeatureLevel(D3D_FEATURE_LEVEL *level); + UINT GetThreadGroupSize(UINT *sizex, UINT *sizey, UINT *sizez); + UINT64 GetRequiresFlags(); +} + +[ + uuid(ec25f42d-7006-4f2b-b33e-02cc3375733f), + object, + local, +] +interface ID3D12FunctionParameterReflection +{ + HRESULT GetDesc(D3D12_PARAMETER_DESC *desc); +} + +[ + uuid(1108795c-2772-4ba9-b2a8-d464dc7e2799), + object, + local, +] +interface ID3D12FunctionReflection +{ + HRESULT GetDesc(D3D12_FUNCTION_DESC *desc); + ID3D12ShaderReflectionConstantBuffer *GetConstantBufferByIndex(UINT index); + ID3D12ShaderReflectionConstantBuffer *GetConstantBufferByName(const char *name); + HRESULT GetResourceBindingDesc(UINT index, D3D12_SHADER_INPUT_BIND_DESC *desc); + ID3D12ShaderReflectionVariable *GetVariableByName(const char *name); + HRESULT GetResourceBindingDescByName(const char *name, D3D12_SHADER_INPUT_BIND_DESC *desc); + ID3D12FunctionParameterReflection *GetFunctionParameter(INT index); +} + +[ + uuid(8e349d19-54db-4a56-9dc9-119d87bdb804), + object, + local, +] +interface ID3D12LibraryReflection : IUnknown +{ + HRESULT GetDesc(D3D12_LIBRARY_DESC *desc); + ID3D12FunctionReflection *GetFunctionByIndex(INT index); +} diff --git a/include/vkd3d_d3dcommon.idl b/include/vkd3d_d3dcommon.idl index ab5dd01f1..0b6fdebd7 100644 --- a/include/vkd3d_d3dcommon.idl +++ b/include/vkd3d_d3dcommon.idl @@ -353,6 +353,78 @@ typedef enum _D3D_SHADER_VARIABLE_TYPE D3D_SVT_FORCE_DWORD = 0x7fffffff, } D3D_SHADER_VARIABLE_TYPE;
+typedef enum D3D_TESSELLATOR_DOMAIN +{ + D3D_TESSELLATOR_DOMAIN_UNDEFINED, + D3D_TESSELLATOR_DOMAIN_ISOLINE, + D3D_TESSELLATOR_DOMAIN_TRI, + D3D_TESSELLATOR_DOMAIN_QUAD, + D3D11_TESSELLATOR_DOMAIN_UNDEFINED = 0, + D3D11_TESSELLATOR_DOMAIN_ISOLINE, + D3D11_TESSELLATOR_DOMAIN_TRI, + D3D11_TESSELLATOR_DOMAIN_QUAD, +} D3D_TESSELLATOR_DOMAIN; + +typedef enum D3D_TESSELLATOR_PARTITIONING +{ + D3D_TESSELLATOR_PARTITIONING_UNDEFINED, + D3D_TESSELLATOR_PARTITIONING_INTEGER, + D3D_TESSELLATOR_PARTITIONING_POW2, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, + D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = 0, + D3D11_TESSELLATOR_PARTITIONING_INTEGER, + D3D11_TESSELLATOR_PARTITIONING_POW2, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, +} D3D_TESSELLATOR_PARTITIONING; + +typedef enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE +{ + D3D_TESSELLATOR_OUTPUT_UNDEFINED, + D3D_TESSELLATOR_OUTPUT_POINT, + D3D_TESSELLATOR_OUTPUT_LINE, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW, + D3D11_TESSELLATOR_OUTPUT_UNDEFINED = 0, + D3D11_TESSELLATOR_OUTPUT_POINT, + D3D11_TESSELLATOR_OUTPUT_LINE, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW, +} D3D_TESSELLATOR_OUTPUT_PRIMITIVE; + +typedef enum D3D_MIN_PRECISION +{ + D3D_MIN_PRECISION_DEFAULT = 0, + D3D_MIN_PRECISION_FLOAT_16 = 1, + D3D_MIN_PRECISION_FLOAT_2_8 = 2, + D3D_MIN_PRECISION_RESERVED = 3, + D3D_MIN_PRECISION_SINT_16 = 4, + D3D_MIN_PRECISION_UINT_16 = 5, + D3D_MIN_PRECISION_ANY_16 = 0xf0, + D3D_MIN_PRECISION_ANY_10 = 0xf1, +} D3D_MIN_PRECISION; + +typedef enum _D3D_INTERPOLATION_MODE +{ + D3D_INTERPOLATION_UNDEFINED, + D3D_INTERPOLATION_CONSTANT, + D3D_INTERPOLATION_LINEAR, + D3D_INTERPOLATION_LINEAR_CENTROID, + D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE, + D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID, + D3D_INTERPOLATION_LINEAR_SAMPLE, + D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE, +} D3D_INTERPOLATION_MODE; + +typedef enum _D3D_PARAMETER_FLAGS +{ + D3D_PF_NONE, + D3D_PF_IN, + D3D_PF_OUT, + D3D_PF_FORCE_DWORD = 0x7fffffff, +} D3D_PARAMETER_FLAGS; + [ uuid(8ba5fb08-5195-40e2-ac58-0d989c3a0102), object,
From: Zebediah Figura zfigura@codeweavers.com
Imported from Wine. --- Makefile.am | 1 + include/vkd3d_utils.h | 1 + libs/vkd3d-common/blob.c | 1 + libs/vkd3d-utils/reflection.c | 1934 ++++++++++++++++++++++++++++++ libs/vkd3d-utils/vkd3d_utils.map | 1 + 5 files changed, 1938 insertions(+) create mode 100644 libs/vkd3d-utils/reflection.c
diff --git a/Makefile.am b/Makefile.am index ea8f57ffe..629fdb020 100644 --- a/Makefile.am +++ b/Makefile.am @@ -353,6 +353,7 @@ EXTRA_libvkd3d_la_DEPENDENCIES = $(srcdir)/libs/vkd3d/vkd3d.map endif
libvkd3d_utils_la_SOURCES = \ + libs/vkd3d-utils/reflection.c \ libs/vkd3d-utils/vkd3d_utils.map \ libs/vkd3d-utils/vkd3d_utils_main.c \ libs/vkd3d-utils/vkd3d_utils_private.h diff --git a/include/vkd3d_utils.h b/include/vkd3d_utils.h index 686ddf386..845894c22 100644 --- a/include/vkd3d_utils.h +++ b/include/vkd3d_utils.h @@ -86,6 +86,7 @@ VKD3D_UTILS_API HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob); VKD3D_UTILS_API HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages); +VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
/** * Set a callback to be called when vkd3d-utils outputs debug logging. diff --git a/libs/vkd3d-common/blob.c b/libs/vkd3d-common/blob.c index 0f6d5a5ee..59e9834d4 100644 --- a/libs/vkd3d-common/blob.c +++ b/libs/vkd3d-common/blob.c @@ -23,6 +23,7 @@ #include "vkd3d_blob.h" #include "vkd3d_debug.h" #include "vkd3d_memory.h" +#include "vkd3d_d3d12shader.h"
struct vkd3d_blob { diff --git a/libs/vkd3d-utils/reflection.c b/libs/vkd3d-utils/reflection.c new file mode 100644 index 000000000..2d23df11b --- /dev/null +++ b/libs/vkd3d-utils/reflection.c @@ -0,0 +1,1934 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2010 Rico Schüller + * + * reflection library is vkd3d_free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * reflection library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "vkd3d_utils_private.h" +#include <vkd3d_d3dcommon.h> +#include <vkd3d_d3d12shader.h> +#include "rbtree.h" + +enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE +{ + D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6 = 6, + D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7 = 7, +}; + +#define D3DCOMPILER_SHADER_TARGET_VERSION_MASK 0xffff +#define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK 0xffff0000 +#define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_SHIFT 16 + +#define D3DCOMPILER_SHDR_SHADER_TYPE_CS 0x4353 + +enum d3dcompiler_shader_type +{ + D3DCOMPILER_SHADER_TYPE_CS = 5, +}; + +struct d3dcompiler_shader_signature +{ + D3D12_SIGNATURE_PARAMETER_DESC *elements; + unsigned int element_count; + char *string_data; +}; + +struct d3dcompiler_shader_reflection_type +{ + ID3D12ShaderReflectionType ID3D12ShaderReflectionType_iface; + + uint32_t id; + struct rb_entry entry; + + struct d3dcompiler_shader_reflection *reflection; + + D3D12_SHADER_TYPE_DESC desc; + struct d3dcompiler_shader_reflection_type_member *members; + char *name; +}; + +struct d3dcompiler_shader_reflection_type_member +{ + char *name; + uint32_t offset; + struct d3dcompiler_shader_reflection_type *type; +}; + +struct d3dcompiler_shader_reflection_variable +{ + ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable_iface; + + struct d3dcompiler_shader_reflection_constant_buffer *constant_buffer; + struct d3dcompiler_shader_reflection_type *type; + + char *name; + UINT start_offset; + UINT size; + UINT flags; + void *default_value; +}; + +struct d3dcompiler_shader_reflection_constant_buffer +{ + ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer_iface; + + struct d3dcompiler_shader_reflection *reflection; + + char *name; + D3D_CBUFFER_TYPE type; + UINT variable_count; + UINT size; + UINT flags; + + struct d3dcompiler_shader_reflection_variable *variables; +}; + +enum D3DCOMPILER_REFLECTION_VERSION +{ + D3DCOMPILER_REFLECTION_VERSION_D3D10, + D3DCOMPILER_REFLECTION_VERSION_D3D11, + D3DCOMPILER_REFLECTION_VERSION_D3D12, +}; + +struct d3dcompiler_shader_reflection +{ + ID3D12ShaderReflection ID3D12ShaderReflection_iface; + LONG refcount; + + enum D3DCOMPILER_REFLECTION_VERSION interface_version; + + uint32_t target; + char *creator; + UINT flags; + UINT version; + UINT bound_resource_count; + UINT constant_buffer_count; + + UINT mov_instruction_count; + UINT conversion_instruction_count; + UINT instruction_count; + UINT emit_instruction_count; + D3D_PRIMITIVE_TOPOLOGY gs_output_topology; + UINT gs_max_output_vertex_count; + D3D_PRIMITIVE input_primitive; + UINT cut_instruction_count; + UINT def_count; + UINT dcl_count; + UINT static_flow_control_count; + UINT float_instruction_count; + UINT temp_register_count; + UINT int_instruction_count; + UINT uint_instruction_count; + UINT temp_array_count; + UINT array_instruction_count; + UINT texture_normal_instructions; + UINT texture_load_instructions; + UINT texture_comp_instructions; + UINT texture_bias_instructions; + UINT texture_gradient_instructions; + UINT dynamic_flow_control_count; + UINT macro_instruction_count; + UINT c_control_points; + D3D_TESSELLATOR_OUTPUT_PRIMITIVE hs_output_primitive; + D3D_TESSELLATOR_PARTITIONING hs_partitioning; + D3D_TESSELLATOR_DOMAIN tessellator_domain; + UINT thread_group_size_x; + 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; + struct rb_tree types; +}; + +static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, uint32_t offset); + +static const struct ID3D12ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl; +static const struct ID3D12ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl; +static const struct ID3D12ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl; + +static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer = +{ + {&d3dcompiler_shader_reflection_constant_buffer_vtbl}, +}; +static struct d3dcompiler_shader_reflection_type null_type = +{ + {&d3dcompiler_shader_reflection_type_vtbl}, +}; +static struct d3dcompiler_shader_reflection_variable null_variable = +{ + {&d3dcompiler_shader_reflection_variable_vtbl}, + &null_constant_buffer, + &null_type +}; + +static uint32_t read_u32(const char **ptr) +{ + uint32_t r; + + memcpy(&r, *ptr, sizeof(r)); + *ptr += sizeof(r); + return r; +} + +static void skip_u32_unknown(const char **ptr, unsigned int count) +{ + uint32_t u32; + + FIXME("Skipping %u unknown u32s:\n", count); + for (unsigned int i = 0; i < count; ++i) + { + u32 = read_u32(ptr); + FIXME("\t0x%08x\n", u32); + } +} + +static BOOL copy_name(const char *ptr, char **name) +{ + if (!ptr || !ptr[0]) + return TRUE; + + *name = vkd3d_strdup(ptr); + if (!*name) + { + ERR("Failed to allocate name memory.\n"); + return FALSE; + } + + return TRUE; +} + +static BOOL copy_value(const char *ptr, void **value, uint32_t size) +{ + if (!ptr || !size) + return TRUE; + + *value = vkd3d_malloc(size); + if (!*value) + { + ERR("Failed to allocate value memory.\n"); + return FALSE; + } + + memcpy(*value, ptr, size); + + return TRUE; +} + +static int d3dcompiler_shader_reflection_type_compare(const void *key, const struct rb_entry *entry) +{ + const struct d3dcompiler_shader_reflection_type *t = RB_ENTRY_VALUE(entry, const struct d3dcompiler_shader_reflection_type, entry); + const uint32_t *id = key; + + return *id - t->id; +} + +static void free_type_member(struct d3dcompiler_shader_reflection_type_member *member) +{ + if (member) + vkd3d_free(member->name); +} + +static void d3dcompiler_shader_reflection_type_destroy(struct rb_entry *entry, void *context) +{ + struct d3dcompiler_shader_reflection_type *t = RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry); + + TRACE("reflection type %p.\n", t); + + if (t->members) + { + for (unsigned int i = 0; i < t->desc.Members; ++i) + free_type_member(&t->members[i]); + vkd3d_free(t->members); + } + + vkd3d_free(t->name); + vkd3d_free(t); +} + +static void free_signature(struct d3dcompiler_shader_signature *sig) +{ + TRACE("Free signature %p.\n", sig); + + vkd3d_free(sig->elements); + vkd3d_free(sig->string_data); +} + +static void free_variable(struct d3dcompiler_shader_reflection_variable *var) +{ + if (var) + { + vkd3d_free(var->name); + vkd3d_free(var->default_value); + } +} + +static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb) +{ + if (cb->variables) + { + for (unsigned int i = 0; i < cb->variable_count; ++i) + free_variable(&cb->variables[i]); + vkd3d_free(cb->variables); + } + + vkd3d_free(cb->name); +} + +static void reflection_cleanup(struct d3dcompiler_shader_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); + } + + if (ref->constant_buffers) + { + for (unsigned int i = 0; i < ref->constant_buffer_count; ++i) + free_constant_buffer(&ref->constant_buffers[i]); + } + + rb_destroy(&ref->types, d3dcompiler_shader_reflection_type_destroy, NULL); + vkd3d_free(ref->constant_buffers); + vkd3d_free(ref->bound_resources); + vkd3d_free(ref->resource_string); + vkd3d_free(ref->creator); +} + +static struct d3dcompiler_shader_reflection *impl_from_ID3D12ShaderReflection(ID3D12ShaderReflection *iface) +{ + return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D12ShaderReflection_iface); +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D12ShaderReflection *iface, REFIID iid, void **object) +{ + TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_ID3D12ShaderReflection)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(iid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D12ShaderReflection *iface) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + ULONG refcount = InterlockedIncrement(&reflection->refcount); + + TRACE("%p increasing refcount to %u.\n", reflection, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D12ShaderReflection *iface) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + ULONG refcount = InterlockedDecrement(&reflection->refcount); + + TRACE("%p decreasing refcount to %u.\n", reflection, refcount); + + if (!refcount) + { + reflection_cleanup(reflection); + vkd3d_free(reflection); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D12ShaderReflection *iface, D3D12_SHADER_DESC *desc) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + FIXME("iface %p, desc %p partial stub!\n", iface, desc); + + if (!desc) + { + WARN("Invalid argument specified.\n"); + return E_FAIL; + } + + desc->Version = reflection->version; + desc->Creator = reflection->creator; + 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->InstructionCount = reflection->instruction_count; + desc->TempRegisterCount = reflection->temp_register_count; + desc->TempArrayCount = reflection->temp_array_count; + desc->DefCount = reflection->def_count; + desc->DclCount = reflection->dcl_count; + desc->TextureNormalInstructions = reflection->texture_normal_instructions; + desc->TextureLoadInstructions = reflection->texture_load_instructions; + desc->TextureCompInstructions = reflection->texture_comp_instructions; + desc->TextureBiasInstructions = reflection->texture_bias_instructions; + desc->TextureGradientInstructions = reflection->texture_gradient_instructions; + desc->FloatInstructionCount = reflection->float_instruction_count; + desc->IntInstructionCount = reflection->int_instruction_count; + desc->UintInstructionCount = reflection->uint_instruction_count; + desc->StaticFlowControlCount = reflection->static_flow_control_count; + desc->DynamicFlowControlCount = reflection->dynamic_flow_control_count; + desc->MacroInstructionCount = reflection->macro_instruction_count; + desc->ArrayInstructionCount = reflection->array_instruction_count; + desc->CutInstructionCount = reflection->cut_instruction_count; + desc->EmitInstructionCount = reflection->emit_instruction_count; + 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->cGSInstanceCount = 0; + desc->cControlPoints = reflection->c_control_points; + desc->HSOutputPrimitive = reflection->hs_output_primitive; + desc->HSPartitioning = reflection->hs_partitioning; + desc->TessellatorDomain = reflection->tessellator_domain; + desc->cBarrierInstructions = 0; + desc->cInterlockedInstructions = 0; + desc->cTextureStoreInstructions = 0; + + return S_OK; +} + +static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex( + ID3D12ShaderReflection *iface, UINT index) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= reflection->constant_buffer_count) + { + WARN("Invalid argument specified.\n"); + return &null_constant_buffer.ID3D12ShaderReflectionConstantBuffer_iface; + } + + return &reflection->constant_buffers[index].ID3D12ShaderReflectionConstantBuffer_iface; +} + +static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName( + ID3D12ShaderReflection *iface, const char *name) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid argument specified.\n"); + return &null_constant_buffer.ID3D12ShaderReflectionConstantBuffer_iface; + } + + for (unsigned int i = 0; i < reflection->constant_buffer_count; ++i) + { + struct d3dcompiler_shader_reflection_constant_buffer *d = &reflection->constant_buffers[i]; + + if (!strcmp(d->name, name)) + { + TRACE("Returning ID3D12ShaderReflectionConstantBuffer %p.\n", d); + return &d->ID3D12ShaderReflectionConstantBuffer_iface; + } + } + + WARN("Invalid name specified.\n"); + + return &null_constant_buffer.ID3D12ShaderReflectionConstantBuffer_iface; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SHADER_INPUT_BIND_DESC *desc) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (!desc || index >= reflection->bound_resource_count) + { + WARN("Invalid argument specified.\n"); + return E_INVALIDARG; + } + + memcpy(desc, &reflection->bound_resources[index], + reflection->interface_version == D3DCOMPILER_REFLECTION_VERSION_D3D12 + ? sizeof(D3D12_SHADER_INPUT_BIND_DESC) : sizeof(D3D12_SHADER_INPUT_BIND_DESC)); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (!desc || !reflection->isgn || index >= reflection->isgn->element_count) + { + WARN("Invalid argument specified.\n"); + return E_INVALIDARG; + } + + *desc = reflection->isgn->elements[index]; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3dcompiler_shader_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; + } + + *desc = reflection->osgn->elements[index]; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + 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; +} + +static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName( + ID3D12ShaderReflection *iface, const char *name) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid name specified.\n"); + return &null_variable.ID3D12ShaderReflectionVariable_iface; + } + + for (unsigned int i = 0; i < reflection->constant_buffer_count; ++i) + { + struct d3dcompiler_shader_reflection_constant_buffer *cb = &reflection->constant_buffers[i]; + + for (unsigned int k = 0; k < cb->variable_count; ++k) + { + struct d3dcompiler_shader_reflection_variable *v = &cb->variables[k]; + + if (!strcmp(v->name, name)) + { + TRACE("Returning ID3D12ShaderReflectionVariable %p.\n", v); + return &v->ID3D12ShaderReflectionVariable_iface; + } + } + } + + WARN("Invalid name specified.\n"); + + return &null_variable.ID3D12ShaderReflectionVariable_iface; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName( + ID3D12ShaderReflection *iface, const char *name, D3D12_SHADER_INPUT_BIND_DESC *desc) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, name %s, desc %p.\n", iface, debugstr_a(name), desc); + + if (!desc || !name) + { + WARN("Invalid argument specified.\n"); + return E_INVALIDARG; + } + + for (unsigned int i = 0; i < reflection->bound_resource_count; ++i) + { + D3D12_SHADER_INPUT_BIND_DESC *d = &reflection->bound_resources[i]; + + if (!strcmp(d->Name, name)) + { + TRACE("Returning D3D12_SHADER_INPUT_BIND_DESC %p.\n", d); + memcpy(desc, d, reflection->interface_version == D3DCOMPILER_REFLECTION_VERSION_D3D12 + ? sizeof(D3D12_SHADER_INPUT_BIND_DESC) : sizeof(D3D12_SHADER_INPUT_BIND_DESC)); + return S_OK; + } + } + + WARN("Invalid name specified.\n"); + + return E_INVALIDARG; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount( + ID3D12ShaderReflection *iface) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p.\n", iface); + + return reflection->mov_instruction_count; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount( + ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount( + ID3D12ShaderReflection *iface) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p.\n", iface); + + return reflection->conversion_instruction_count; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount( + ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive( + ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader( + ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots( + ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel( + ID3D12ShaderReflection *iface, D3D_FEATURE_LEVEL *level) +{ + FIXME("iface %p, level %p stub!\n", iface, level); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize( + ID3D12ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez) +{ + struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, sizex %p, sizey %p, sizez %p.\n", iface, sizex, sizey, sizez); + + if (!sizex || !sizey || !sizez) + { + WARN("Invalid argument specified.\n"); + return E_INVALIDARG; + } + + *sizex = reflection->thread_group_size_x; + *sizey = reflection->thread_group_size_y; + *sizez = reflection->thread_group_size_z; + + return *sizex * *sizey * *sizez; +} + +static UINT64 STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetRequiresFlags( + ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static const struct ID3D12ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl = +{ + d3dcompiler_shader_reflection_QueryInterface, + d3dcompiler_shader_reflection_AddRef, + d3dcompiler_shader_reflection_Release, + d3dcompiler_shader_reflection_GetDesc, + d3dcompiler_shader_reflection_GetConstantBufferByIndex, + d3dcompiler_shader_reflection_GetConstantBufferByName, + d3dcompiler_shader_reflection_GetResourceBindingDesc, + d3dcompiler_shader_reflection_GetInputParameterDesc, + d3dcompiler_shader_reflection_GetOutputParameterDesc, + d3dcompiler_shader_reflection_GetPatchConstantParameterDesc, + d3dcompiler_shader_reflection_GetVariableByName, + d3dcompiler_shader_reflection_GetResourceBindingDescByName, + d3dcompiler_shader_reflection_GetMovInstructionCount, + d3dcompiler_shader_reflection_GetMovcInstructionCount, + d3dcompiler_shader_reflection_GetConversionInstructionCount, + d3dcompiler_shader_reflection_GetBitwiseInstructionCount, + d3dcompiler_shader_reflection_GetGSInputPrimitive, + d3dcompiler_shader_reflection_IsSampleFrequencyShader, + d3dcompiler_shader_reflection_GetNumInterfaceSlots, + d3dcompiler_shader_reflection_GetMinFeatureLevel, + d3dcompiler_shader_reflection_GetThreadGroupSize, + d3dcompiler_shader_reflection_GetRequiresFlags, +}; + +static struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D12ShaderReflectionConstantBuffer *iface) +{ + return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D12ShaderReflectionConstantBuffer_iface); +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc( + ID3D12ShaderReflectionConstantBuffer *iface, D3D12_SHADER_BUFFER_DESC *desc) +{ + struct d3dcompiler_shader_reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (cb == &null_constant_buffer) + { + WARN("Null constant buffer specified.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified.\n"); + return E_FAIL; + } + + desc->Name = cb->name; + desc->Type = cb->type; + desc->Variables = cb->variable_count; + desc->Size = cb->size; + desc->uFlags = cb->flags; + + return S_OK; +} + +static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex( + ID3D12ShaderReflectionConstantBuffer *iface, UINT index) +{ + struct d3dcompiler_shader_reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= cb->variable_count) + { + WARN("Invalid index specified.\n"); + return &null_variable.ID3D12ShaderReflectionVariable_iface; + } + + return &cb->variables[index].ID3D12ShaderReflectionVariable_iface; +} + +static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName( + ID3D12ShaderReflectionConstantBuffer *iface, const char *name) +{ + struct d3dcompiler_shader_reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid argument specified.\n"); + return &null_variable.ID3D12ShaderReflectionVariable_iface; + } + + for (unsigned int i = 0; i < cb->variable_count; ++i) + { + struct d3dcompiler_shader_reflection_variable *v = &cb->variables[i]; + + if (!strcmp(v->name, name)) + { + TRACE("Returning ID3D12ShaderReflectionVariable %p.\n", v); + return &v->ID3D12ShaderReflectionVariable_iface; + } + } + + WARN("Invalid name specified.\n"); + + return &null_variable.ID3D12ShaderReflectionVariable_iface; +} + +static const struct ID3D12ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl = +{ + d3dcompiler_shader_reflection_constant_buffer_GetDesc, + d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex, + d3dcompiler_shader_reflection_constant_buffer_GetVariableByName, +}; + +static struct d3dcompiler_shader_reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D12ShaderReflectionVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_variable, ID3D12ShaderReflectionVariable_iface); +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc( + ID3D12ShaderReflectionVariable *iface, D3D12_SHADER_VARIABLE_DESC *desc) +{ + struct d3dcompiler_shader_reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (variable == &null_variable) + { + WARN("Null variable specified.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified.\n"); + return E_FAIL; + } + + desc->Name = variable->name; + desc->StartOffset = variable->start_offset; + desc->Size = variable->size; + desc->uFlags = variable->flags; + desc->DefaultValue = variable->default_value; + + /* TODO test and set proper values for texture. */ + desc->StartTexture = 0xffffffff; + desc->TextureSize = 0; + desc->StartSampler = 0xffffffff; + desc->SamplerSize = 0; + + return S_OK; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType( + ID3D12ShaderReflectionVariable *iface) +{ + struct d3dcompiler_shader_reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface); + + TRACE("iface %p.\n", iface); + + return &variable->type->ID3D12ShaderReflectionType_iface; +} + +static ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer( + ID3D12ShaderReflectionVariable *iface) +{ + struct d3dcompiler_shader_reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface); + + TRACE("iface %p.\n", iface); + + return &variable->constant_buffer->ID3D12ShaderReflectionConstantBuffer_iface; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot( + ID3D12ShaderReflectionVariable *iface, UINT index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return 0; +} + +static const struct ID3D12ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl = +{ + d3dcompiler_shader_reflection_variable_GetDesc, + d3dcompiler_shader_reflection_variable_GetType, + d3dcompiler_shader_reflection_variable_GetBuffer, + d3dcompiler_shader_reflection_variable_GetInterfaceSlot, +}; + +static struct d3dcompiler_shader_reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D12ShaderReflectionType *iface) +{ + return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_type, ID3D12ShaderReflectionType_iface); +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc( + ID3D12ShaderReflectionType *iface, D3D12_SHADER_TYPE_DESC *desc) +{ + struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (variable == &null_type) + { + WARN("Null type specified.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("Invalid argument specified.\n"); + return E_FAIL; + } + + *desc = variable->desc; + + return S_OK; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByIndex( + ID3D12ShaderReflectionType *iface, UINT index) +{ + struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= variable->desc.Members) + { + WARN("Invalid index specified.\n"); + return &null_type.ID3D12ShaderReflectionType_iface; + } + + return &variable->members[index].type->ID3D12ShaderReflectionType_iface; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByName( + ID3D12ShaderReflectionType *iface, const char *name) +{ + struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); + + if (!name) + { + WARN("Invalid argument specified.\n"); + return &null_type.ID3D12ShaderReflectionType_iface; + } + + for (unsigned int i = 0; i < variable->desc.Members; ++i) + { + struct d3dcompiler_shader_reflection_type_member *member = &variable->members[i]; + + if (!strcmp(member->name, name)) + { + TRACE("Returning ID3D12ShaderReflectionType %p.\n", member->type); + return &member->type->ID3D12ShaderReflectionType_iface; + } + } + + WARN("Invalid name specified.\n"); + + return &null_type.ID3D12ShaderReflectionType_iface; +} + +static const char * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeName( + ID3D12ShaderReflectionType *iface, UINT index) +{ + struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (variable == &null_type) + { + WARN("Null type specified.\n"); + return "$Invalid"; + } + + if (index >= variable->desc.Members) + { + WARN("Invalid index specified.\n"); + return NULL; + } + + return variable->members[index].name; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual( + ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *type) +{ + struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + + TRACE("iface %p, type %p.\n", iface, type); + + if (variable == &null_type) + { + WARN("Null type specified.\n"); + return E_FAIL; + } + + if (iface == type) + return S_OK; + + return S_FALSE; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetSubType( + ID3D12ShaderReflectionType *iface) +{ + FIXME("iface %p stub!\n", iface); + + return NULL; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetBaseClass( + ID3D12ShaderReflectionType *iface) +{ + FIXME("iface %p stub!\n", iface); + + return NULL; +} + +static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterfaces( + ID3D12ShaderReflectionType *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetInterfaceByIndex( + ID3D12ShaderReflectionType *iface, UINT index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType( + ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *type) +{ + FIXME("iface %p, type %p stub!\n", iface, type); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsInterface( + ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *base) +{ + FIXME("iface %p, base %p stub!\n", iface, base); + + return E_NOTIMPL; +} + +static const struct ID3D12ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl = +{ + d3dcompiler_shader_reflection_type_GetDesc, + d3dcompiler_shader_reflection_type_GetMemberTypeByIndex, + d3dcompiler_shader_reflection_type_GetMemberTypeByName, + d3dcompiler_shader_reflection_type_GetMemberTypeName, + d3dcompiler_shader_reflection_type_IsEqual, + d3dcompiler_shader_reflection_type_GetSubType, + d3dcompiler_shader_reflection_type_GetBaseClass, + d3dcompiler_shader_reflection_type_GetNumInterfaces, + d3dcompiler_shader_reflection_type_GetInterfaceByIndex, + d3dcompiler_shader_reflection_type_IsOfType, + d3dcompiler_shader_reflection_type_ImplementsInterface, +}; + +static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size) +{ + const char *ptr = data; + size_t size = data_size >> 2; + + TRACE("Size %zu.\n", size); + + r->instruction_count = read_u32(&ptr); + TRACE("InstructionCount: %u.\n", r->instruction_count); + + r->temp_register_count = read_u32(&ptr); + TRACE("TempRegisterCount: %u.\n", r->temp_register_count); + + r->def_count = read_u32(&ptr); + TRACE("DefCount: %u.\n", r->def_count); + + r->dcl_count = read_u32(&ptr); + TRACE("DclCount: %u.\n", r->dcl_count); + + r->float_instruction_count = read_u32(&ptr); + TRACE("FloatInstructionCount: %u.\n", r->float_instruction_count); + + r->int_instruction_count = read_u32(&ptr); + TRACE("IntInstructionCount: %u.\n", r->int_instruction_count); + + r->uint_instruction_count = read_u32(&ptr); + TRACE("UintInstructionCount: %u.\n", r->uint_instruction_count); + + r->static_flow_control_count = read_u32(&ptr); + TRACE("StaticFlowControlCount: %u.\n", r->static_flow_control_count); + + r->dynamic_flow_control_count = read_u32(&ptr); + TRACE("DynamicFlowControlCount: %u.\n", r->dynamic_flow_control_count); + + r->macro_instruction_count = read_u32(&ptr); + TRACE("MacroInstructionCount: %u.\n", r->macro_instruction_count); + + r->temp_array_count = read_u32(&ptr); + TRACE("TempArrayCount: %u.\n", r->temp_array_count); + + r->array_instruction_count = read_u32(&ptr); + TRACE("ArrayInstructionCount: %u.\n", r->array_instruction_count); + + r->cut_instruction_count = read_u32(&ptr); + TRACE("CutInstructionCount: %u.\n", r->cut_instruction_count); + + r->emit_instruction_count = read_u32(&ptr); + TRACE("EmitInstructionCount: %u.\n", r->emit_instruction_count); + + r->texture_normal_instructions = read_u32(&ptr); + TRACE("TextureNormalInstructions: %u.\n", r->texture_normal_instructions); + + r->texture_load_instructions = read_u32(&ptr); + TRACE("TextureLoadInstructions: %u.\n", r->texture_load_instructions); + + r->texture_comp_instructions = read_u32(&ptr); + TRACE("TextureCompInstructions: %u.\n", r->texture_comp_instructions); + + r->texture_bias_instructions = read_u32(&ptr); + TRACE("TextureBiasInstructions: %u.\n", r->texture_bias_instructions); + + r->texture_gradient_instructions = read_u32(&ptr); + TRACE("TextureGradientInstructions: %u.\n", r->texture_gradient_instructions); + + r->mov_instruction_count = read_u32(&ptr); + TRACE("MovInstructionCount: %u.\n", r->mov_instruction_count); + + skip_u32_unknown(&ptr, 1); + + r->conversion_instruction_count = read_u32(&ptr); + TRACE("ConversionInstructionCount: %u.\n", r->conversion_instruction_count); + + skip_u32_unknown(&ptr, 1); + + r->input_primitive = read_u32(&ptr); + TRACE("InputPrimitive: %x.\n", r->input_primitive); + + r->gs_output_topology = read_u32(&ptr); + TRACE("GSOutputTopology: %x.\n", r->gs_output_topology); + + r->gs_max_output_vertex_count = read_u32(&ptr); + TRACE("GSMaxOutputVertexCount: %u.\n", r->gs_max_output_vertex_count); + + skip_u32_unknown(&ptr, 2); + + /* old dx10 stat size */ + if (size == 28) + return S_OK; + + skip_u32_unknown(&ptr, 1); + + /* dx10 stat size */ + if (size == 29) + return S_OK; + + skip_u32_unknown(&ptr, 1); + + r->c_control_points = read_u32(&ptr); + TRACE("cControlPoints: %u.\n", r->c_control_points); + + r->hs_output_primitive = read_u32(&ptr); + TRACE("HSOutputPrimitive: %x.\n", r->hs_output_primitive); + + r->hs_partitioning = read_u32(&ptr); + TRACE("HSPartitioning: %x.\n", r->hs_partitioning); + + r->tessellator_domain = read_u32(&ptr); + TRACE("TessellatorDomain: %x.\n", r->tessellator_domain); + + skip_u32_unknown(&ptr, 3); + + /* dx11 stat size */ + if (size == 37) + return S_OK; + + FIXME("Unhandled size %zu.\n", size); + + return E_FAIL; +} + +static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflection *ref, + struct d3dcompiler_shader_reflection_type_member *member, const char *data, const char **ptr) +{ + uint32_t offset; + + offset = read_u32(ptr); + if (!copy_name(data + offset, &member->name)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Member name: %s.\n", debugstr_a(member->name)); + + offset = read_u32(ptr); + TRACE("Member type offset: %x.\n", offset); + + member->type = get_reflection_type(ref, data, offset); + if (!member->type) + { + ERR("Failed to get member type\n"); + vkd3d_free(member->name); + return E_FAIL; + } + + member->offset = read_u32(ptr); + TRACE("Member offset %x.\n", member->offset); + + return S_OK; +} + +static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type *type, const char *data, uint32_t offset) +{ + struct d3dcompiler_shader_reflection_type_member *members = NULL; + const char *ptr = data + offset; + D3D12_SHADER_TYPE_DESC *desc; + uint32_t member_offset; + uint32_t temp; + HRESULT hr; + + desc = &type->desc; + + temp = read_u32(&ptr); + desc->Class = temp & 0xffff; + desc->Type = temp >> 16; + TRACE("Class %#x, Type %#x.\n", desc->Class, desc->Type); + + temp = read_u32(&ptr); + desc->Rows = temp & 0xffff; + desc->Columns = temp >> 16; + TRACE("Rows %u, Columns %u.\n", desc->Rows, desc->Columns); + + temp = read_u32(&ptr); + desc->Elements = temp & 0xffff; + desc->Members = temp >> 16; + TRACE("Elements %u, Members %u.\n", desc->Elements, desc->Members); + + member_offset = read_u32(&ptr); + TRACE("Member Offset %u.\n", member_offset); + + if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) + skip_u32_unknown(&ptr, 4); + + if (desc->Members) + { + const char *ptr2 = data + member_offset; + + members = vkd3d_calloc(desc->Members, sizeof(*members)); + if (!members) + { + ERR("Failed to allocate type memory.\n"); + return E_OUTOFMEMORY; + } + + for (unsigned int i = 0; i < desc->Members; ++i) + { + hr = d3dcompiler_parse_type_members(type->reflection, &members[i], data, &ptr2); + if (hr != S_OK) + { + FIXME("Failed to parse type members.\n"); + goto err_out; + } + } + } + + if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) + { + offset = read_u32(&ptr); + if (!copy_name(data + offset, &type->name)) + { + ERR("Failed to copy name.\n"); + vkd3d_free(members); + return E_OUTOFMEMORY; + } + desc->Name = type->name; + TRACE("Type name: %s.\n", debugstr_a(type->name)); + } + + type->members = members; + + return S_OK; + +err_out: + for (unsigned int i = 0; i < desc->Members; ++i) + free_type_member(&members[i]); + vkd3d_free(members); + return hr; +} + +static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, uint32_t offset) +{ + struct d3dcompiler_shader_reflection_type *type; + struct rb_entry *entry; + HRESULT hr; + + entry = rb_get(&reflection->types, &offset); + if (entry) + { + TRACE("Returning existing type.\n"); + return RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry); + } + + type = vkd3d_calloc(1, sizeof(*type)); + if (!type) + return NULL; + + type->ID3D12ShaderReflectionType_iface.lpVtbl = &d3dcompiler_shader_reflection_type_vtbl; + type->id = offset; + type->reflection = reflection; + + hr = d3dcompiler_parse_type(type, data, offset); + if (FAILED(hr)) + { + ERR("Failed to parse type info, hr %#x.\n", hr); + vkd3d_free(type); + return NULL; + } + + if (rb_put(&reflection->types, &offset, &type->entry) == -1) + { + ERR("Failed to insert type entry.\n"); + vkd3d_free(type); + return NULL; + } + + return type; +} + +static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb, + const char *data, size_t data_size, const char *ptr) +{ + struct d3dcompiler_shader_reflection_variable *variables; + HRESULT hr; + + variables = vkd3d_calloc(cb->variable_count, sizeof(*variables)); + if (!variables) + { + ERR("Failed to allocate variables memory.\n"); + return E_OUTOFMEMORY; + } + + for (unsigned int i = 0; i < cb->variable_count; i++) + { + struct d3dcompiler_shader_reflection_variable *v = &variables[i]; + uint32_t offset; + + v->ID3D12ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl; + v->constant_buffer = cb; + + offset = read_u32(&ptr); + if (!copy_name(data + offset, &v->name)) + { + ERR("Failed to copy name.\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + TRACE("Variable name: %s.\n", debugstr_a(v->name)); + + v->start_offset = read_u32(&ptr); + TRACE("Variable offset: %u.\n", v->start_offset); + + v->size = read_u32(&ptr); + TRACE("Variable size: %u.\n", v->size); + + v->flags = read_u32(&ptr); + TRACE("Variable flags: %u.\n", v->flags); + + offset = read_u32(&ptr); + TRACE("Variable type offset: %x.\n", offset); + v->type = get_reflection_type(cb->reflection, data, offset); + if (!v->type) + { + ERR("Failed to get type.\n"); + hr = E_FAIL; + goto err_out; + } + + offset = read_u32(&ptr); + TRACE("Variable default value offset: %x.\n", offset); + if (!copy_value(data + offset, &v->default_value, offset ? v->size : 0)) + { + ERR("Failed to copy name.\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + if ((cb->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) + skip_u32_unknown(&ptr, 4); + } + + cb->variables = variables; + + return S_OK; + +err_out: + for (unsigned int i = 0; i < cb->variable_count; i++) + { + free_variable(&variables[i]); + } + vkd3d_free(variables); + return hr; +} + +static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size) +{ + struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL; + uint32_t offset, cbuffer_offset, resource_offset, creator_offset; + D3D12_SHADER_INPUT_BIND_DESC *bound_resources = NULL; + unsigned int string_data_offset, string_data_size; + char *string_data = NULL, *creator = NULL; + size_t size = data_size >> 2; + uint32_t target_version; + const char *ptr = data; + HRESULT hr; + + TRACE("Size %zu.\n", size); + + r->constant_buffer_count = read_u32(&ptr); + TRACE("Constant buffer count: %u.\n", r->constant_buffer_count); + + cbuffer_offset = read_u32(&ptr); + TRACE("Constant buffer offset: %#x.\n", cbuffer_offset); + + r->bound_resource_count = read_u32(&ptr); + TRACE("Bound resource count: %u.\n", r->bound_resource_count); + + resource_offset = read_u32(&ptr); + TRACE("Bound resource offset: %#x.\n", resource_offset); + + r->target = read_u32(&ptr); + TRACE("Target: %#x.\n", r->target); + + target_version = r->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK; + + r->flags = read_u32(&ptr); + TRACE("Flags: %u.\n", r->flags); + + creator_offset = read_u32(&ptr); + TRACE("Creator at offset %#x.\n", creator_offset); + + if (!copy_name(data + creator_offset, &creator)) + { + ERR("Failed to copy name.\n"); + return E_OUTOFMEMORY; + } + TRACE("Creator: %s.\n", debugstr_a(creator)); + + /* todo: Parse RD11 */ + if (target_version >= 0x500) + { + skip_u32_unknown(&ptr, 8); + } + + if (r->bound_resource_count) + { + /* 8 for each bind desc */ + string_data_offset = resource_offset + r->bound_resource_count * 8 * sizeof(uint32_t); + string_data_size = (cbuffer_offset ? cbuffer_offset : creator_offset) - string_data_offset; + + string_data = vkd3d_malloc(string_data_size); + if (!string_data) + { + ERR("Failed to allocate string data memory.\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + memcpy(string_data, data + string_data_offset, string_data_size); + + bound_resources = vkd3d_calloc(r->bound_resource_count, sizeof(*bound_resources)); + if (!bound_resources) + { + ERR("Failed to allocate resources memory.\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + ptr = data + resource_offset; + for (unsigned int i = 0; i < r->bound_resource_count; i++) + { + D3D12_SHADER_INPUT_BIND_DESC *desc = &bound_resources[i]; + + offset = read_u32(&ptr); + desc->Name = string_data + (offset - string_data_offset); + TRACE("Input bind Name: %s.\n", debugstr_a(desc->Name)); + + desc->Type = read_u32(&ptr); + TRACE("Input bind Type: %#x.\n", desc->Type); + + desc->ReturnType = read_u32(&ptr); + TRACE("Input bind ReturnType: %#x.\n", desc->ReturnType); + + desc->Dimension = read_u32(&ptr); + TRACE("Input bind Dimension: %#x.\n", desc->Dimension); + + desc->NumSamples = read_u32(&ptr); + TRACE("Input bind NumSamples: %u.\n", desc->NumSamples); + + desc->BindPoint = read_u32(&ptr); + TRACE("Input bind BindPoint: %u.\n", desc->BindPoint); + + desc->BindCount = read_u32(&ptr); + TRACE("Input bind BindCount: %u.\n", desc->BindCount); + + desc->uFlags = read_u32(&ptr); + TRACE("Input bind uFlags: %u.\n", desc->uFlags); + + if (target_version >= 0x501) + { + desc->Space = read_u32(&ptr); + TRACE("Input bind Space %u.\n", desc->Space); + desc->uID = read_u32(&ptr); + TRACE("Input bind uID %u.\n", desc->uID); + } + else + { + desc->uID = desc->BindPoint; + } + } + } + + if (r->constant_buffer_count) + { + constant_buffers = vkd3d_calloc(r->constant_buffer_count, sizeof(*constant_buffers)); + if (!constant_buffers) + { + ERR("Failed to allocate constant buffer memory.\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + ptr = data + cbuffer_offset; + for (unsigned int i = 0; i < r->constant_buffer_count; i++) + { + struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i]; + + cb->ID3D12ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl; + cb->reflection = r; + + offset = read_u32(&ptr); + if (!copy_name(data + offset, &cb->name)) + { + ERR("Failed to copy name.\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + TRACE("Name: %s.\n", debugstr_a(cb->name)); + + cb->variable_count = read_u32(&ptr); + TRACE("Variable count: %u.\n", cb->variable_count); + + offset = read_u32(&ptr); + TRACE("Variable offset: %x.\n", offset); + + hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset); + if (hr != S_OK) + { + FIXME("Failed to parse variables.\n"); + goto err_out; + } + + cb->size = read_u32(&ptr); + TRACE("Cbuffer size: %u.\n", cb->size); + + cb->flags = read_u32(&ptr); + TRACE("Cbuffer flags: %u.\n", cb->flags); + + cb->type = read_u32(&ptr); + TRACE("Cbuffer type: %#x.\n", cb->type); + } + } + + r->creator = creator; + r->resource_string = string_data; + r->bound_resources = bound_resources; + r->constant_buffers = constant_buffers; + + return S_OK; + +err_out: + for (unsigned int i = 0; i < r->constant_buffer_count; ++i) + free_constant_buffer(&constant_buffers[i]); + vkd3d_free(constant_buffers); + vkd3d_free(bound_resources); + vkd3d_free(string_data); + vkd3d_free(creator); + + 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; + 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 = 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 %08x!\n", section->tag); + element_size = D3DCOMPILER_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 == D3DCOMPILER_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) + +enum sm4_opcode +{ + SM5_OP_DCL_THREAD_GROUP = 0x9b, +}; + +static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size) +{ + uint32_t opcode_token, opcode; + uint32_t size, shader_type; + const char *ptr = data; + const uint32_t *u_ptr; + unsigned int len; + + r->version = read_u32(&ptr); + TRACE("Shader version: %u.\n", r->version); + + shader_type = (r->version & D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK) + >> D3DCOMPILER_SHADER_TARGET_SHADERTYPE_SHIFT; + + if (shader_type != D3DCOMPILER_SHADER_TYPE_CS) + { + /* TODO: Check if anything else is needed from the SHDR or SHEX blob. */ + return S_OK; + } + + size = read_u32(&ptr); + TRACE("size %u.\n", size); + if (size * sizeof(uint32_t) != data_size || size < 2) + { + WARN("Invalid size %u.\n", size); + return E_FAIL; + } + size -= 2; + u_ptr = (uint32_t *)ptr; + while (size) + { + opcode_token = *u_ptr; + opcode = opcode_token & SM4_OPCODE_MASK; + len = (opcode_token & SM4_INSTRUCTION_LENGTH_MASK) >> SM4_INSTRUCTION_LENGTH_SHIFT; + if (!len) + { + if (size < 2) + { + WARN("End of byte-code, failed to read length token.\n"); + return E_FAIL; + } + len = u_ptr[1]; + } + if (!len || size < len) + { + WARN("Invalid instruction length %u, size %u.\n", len, size); + return E_FAIL; + } + if (opcode == SM5_OP_DCL_THREAD_GROUP) + { + if (len != 4) + { + WARN("Invalid dcl_thread_group opcode length %u.\n", len); + return E_FAIL; + } + r->thread_group_size_x = u_ptr[1]; + r->thread_group_size_y = u_ptr[2]; + r->thread_group_size_z = u_ptr[3]; + TRACE("Found dcl_thread_group %u, %u, %u.\n", + r->thread_group_size_x, r->thread_group_size_y, r->thread_group_size_z); + } + size -= len; + u_ptr += len; + } + return S_OK; +} + +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_dxbc_desc src_dxbc_desc; + HRESULT hr = S_OK; + int ret; + + rb_init(&reflection->types, d3dcompiler_shader_reflection_type_compare); + + if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0) + { + WARN("Failed to parse reflection, ret %d.\n", ret); + return E_FAIL; + } + + for (unsigned int i = 0; i < src_dxbc_desc.section_count; ++i) + { + const struct vkd3d_shader_dxbc_section_desc *section = &src_dxbc_desc.sections[i]; + + switch (section->tag) + { + case TAG_RDEF: + hr = d3dcompiler_parse_rdef(reflection, section->data.code, section->data.size); + if (FAILED(hr)) + { + WARN("Failed to parse RDEF section.\n"); + goto err_out; + } + 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 = 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 = vkd3d_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 = vkd3d_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: + case TAG_SHDR: + hr = d3dcompiler_parse_shdr(reflection, section->data.code, section->data.size); + if (FAILED(hr)) + { + WARN("Failed to parse SHDR section.\n"); + goto err_out; + } + break; + + case TAG_STAT: + hr = d3dcompiler_parse_stat(reflection, section->data.code, section->data.size); + if (FAILED(hr)) + { + WARN("Failed to parse section STAT.\n"); + goto err_out; + } + break; + + default: + FIXME("Unhandled section %08x!\n", section->tag); + break; + } + } + + vkd3d_shader_free_dxbc(&src_dxbc_desc); + + return hr; + +err_out: + reflection_cleanup(reflection); + vkd3d_shader_free_dxbc(&src_dxbc_desc); + + return hr; +} + +HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflector) +{ + struct d3dcompiler_shader_reflection *object; + const uint32_t *temp = data; + HRESULT hr; + + TRACE("data %p, data_size %zu, iid %s, blob %p.\n", data, data_size, debugstr_guid(iid), reflector); + + if (!data || data_size < 32) + { + WARN("Invalid argument supplied.\n"); + return D3DERR_INVALIDCALL; + } + + if (temp[6] != data_size) + { + WARN("Wrong size supplied.\n"); + return D3DERR_INVALIDCALL; + } + + if (!IsEqualGUID(iid, &IID_ID3D12ShaderReflection)) + { + WARN("Invalid iid %s.\n", debugstr_guid(iid)); + return E_INVALIDARG; + } + + if (!(object = vkd3d_calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID3D12ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl; + object->refcount = 1; + object->interface_version = IsEqualGUID(iid, &IID_ID3D12ShaderReflection) + ? D3DCOMPILER_REFLECTION_VERSION_D3D12 : D3DCOMPILER_REFLECTION_VERSION_D3D11; + + if (FAILED(hr = d3dcompiler_shader_reflection_init(object, data, data_size))) + { + vkd3d_free(object); + return hr; + } + + *reflector = object; + TRACE("Created ID3D12ShaderReflection %p.\n", object); + return S_OK; +} diff --git a/libs/vkd3d-utils/vkd3d_utils.map b/libs/vkd3d-utils/vkd3d_utils.map index 8cf102dde..8dad9cc3a 100644 --- a/libs/vkd3d-utils/vkd3d_utils.map +++ b/libs/vkd3d-utils/vkd3d_utils.map @@ -17,6 +17,7 @@ global: D3DGetInputSignatureBlob; D3DGetOutputSignatureBlob; D3DPreprocess; + D3DReflect; D3DStripShader; vkd3d_create_event; vkd3d_destroy_event;
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-utils/reflection.c | 444 +++++++++++++++++----------------- 1 file changed, 222 insertions(+), 222 deletions(-)
diff --git a/libs/vkd3d-utils/reflection.c b/libs/vkd3d-utils/reflection.c index 2d23df11b..1796a8428 100644 --- a/libs/vkd3d-utils/reflection.c +++ b/libs/vkd3d-utils/reflection.c @@ -22,57 +22,57 @@ #include <vkd3d_d3d12shader.h> #include "rbtree.h"
-enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE +enum signature_element_size { - D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6 = 6, - D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7 = 7, + SIGNATURE_ELEMENT_SIZE6 = 6, + SIGNATURE_ELEMENT_SIZE7 = 7, };
-#define D3DCOMPILER_SHADER_TARGET_VERSION_MASK 0xffff -#define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK 0xffff0000 -#define D3DCOMPILER_SHADER_TARGET_SHADERTYPE_SHIFT 16 +#define SHADER_TARGET_VERSION_MASK 0xffff +#define SHADER_TARGET_SHADERTYPE_MASK 0xffff0000 +#define SHADER_TARGET_SHADERTYPE_SHIFT 16
-#define D3DCOMPILER_SHDR_SHADER_TYPE_CS 0x4353 +#define SHDR_SHADER_TYPE_CS 0x4353
-enum d3dcompiler_shader_type +enum shader_type { - D3DCOMPILER_SHADER_TYPE_CS = 5, + SHADER_TYPE_CS = 5, };
-struct d3dcompiler_shader_signature +struct shader_signature { D3D12_SIGNATURE_PARAMETER_DESC *elements; unsigned int element_count; char *string_data; };
-struct d3dcompiler_shader_reflection_type +struct reflection_type { ID3D12ShaderReflectionType ID3D12ShaderReflectionType_iface;
uint32_t id; struct rb_entry entry;
- struct d3dcompiler_shader_reflection *reflection; + struct reflection *reflection;
D3D12_SHADER_TYPE_DESC desc; - struct d3dcompiler_shader_reflection_type_member *members; + struct reflection_type_member *members; char *name; };
-struct d3dcompiler_shader_reflection_type_member +struct reflection_type_member { char *name; uint32_t offset; - struct d3dcompiler_shader_reflection_type *type; + struct reflection_type *type; };
-struct d3dcompiler_shader_reflection_variable +struct reflection_variable { ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable_iface;
- struct d3dcompiler_shader_reflection_constant_buffer *constant_buffer; - struct d3dcompiler_shader_reflection_type *type; + struct reflection_constant_buffer *constant_buffer; + struct reflection_type *type;
char *name; UINT start_offset; @@ -81,11 +81,11 @@ struct d3dcompiler_shader_reflection_variable void *default_value; };
-struct d3dcompiler_shader_reflection_constant_buffer +struct reflection_constant_buffer { ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer_iface;
- struct d3dcompiler_shader_reflection *reflection; + struct reflection *reflection;
char *name; D3D_CBUFFER_TYPE type; @@ -93,22 +93,22 @@ struct d3dcompiler_shader_reflection_constant_buffer UINT size; UINT flags;
- struct d3dcompiler_shader_reflection_variable *variables; + struct reflection_variable *variables; };
-enum D3DCOMPILER_REFLECTION_VERSION +enum REFLECTION_VERSION { - D3DCOMPILER_REFLECTION_VERSION_D3D10, - D3DCOMPILER_REFLECTION_VERSION_D3D11, - D3DCOMPILER_REFLECTION_VERSION_D3D12, + REFLECTION_VERSION_D3D10, + REFLECTION_VERSION_D3D11, + REFLECTION_VERSION_D3D12, };
-struct d3dcompiler_shader_reflection +struct reflection { ID3D12ShaderReflection ID3D12ShaderReflection_iface; LONG refcount;
- enum D3DCOMPILER_REFLECTION_VERSION interface_version; + enum REFLECTION_VERSION interface_version;
uint32_t target; char *creator; @@ -149,32 +149,32 @@ 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; + struct shader_signature *isgn; + struct shader_signature *osgn; + struct shader_signature *pcsg; char *resource_string; D3D12_SHADER_INPUT_BIND_DESC *bound_resources; - struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers; + struct reflection_constant_buffer *constant_buffers; struct rb_tree types; };
-static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, uint32_t offset); +static struct reflection_type *get_reflection_type(struct reflection *reflection, const char *data, uint32_t offset);
-static const struct ID3D12ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl; -static const struct ID3D12ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl; -static const struct ID3D12ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl; +static const struct ID3D12ShaderReflectionConstantBufferVtbl reflection_constant_buffer_vtbl; +static const struct ID3D12ShaderReflectionVariableVtbl reflection_variable_vtbl; +static const struct ID3D12ShaderReflectionTypeVtbl reflection_type_vtbl;
-static struct d3dcompiler_shader_reflection_constant_buffer null_constant_buffer = +static struct reflection_constant_buffer null_constant_buffer = { - {&d3dcompiler_shader_reflection_constant_buffer_vtbl}, + {&reflection_constant_buffer_vtbl}, }; -static struct d3dcompiler_shader_reflection_type null_type = +static struct reflection_type null_type = { - {&d3dcompiler_shader_reflection_type_vtbl}, + {&reflection_type_vtbl}, }; -static struct d3dcompiler_shader_reflection_variable null_variable = +static struct reflection_variable null_variable = { - {&d3dcompiler_shader_reflection_variable_vtbl}, + {&reflection_variable_vtbl}, &null_constant_buffer, &null_type }; @@ -232,23 +232,23 @@ static BOOL copy_value(const char *ptr, void **value, uint32_t size) return TRUE; }
-static int d3dcompiler_shader_reflection_type_compare(const void *key, const struct rb_entry *entry) +static int reflection_type_compare(const void *key, const struct rb_entry *entry) { - const struct d3dcompiler_shader_reflection_type *t = RB_ENTRY_VALUE(entry, const struct d3dcompiler_shader_reflection_type, entry); + const struct reflection_type *t = RB_ENTRY_VALUE(entry, const struct reflection_type, entry); const uint32_t *id = key;
return *id - t->id; }
-static void free_type_member(struct d3dcompiler_shader_reflection_type_member *member) +static void free_type_member(struct reflection_type_member *member) { if (member) vkd3d_free(member->name); }
-static void d3dcompiler_shader_reflection_type_destroy(struct rb_entry *entry, void *context) +static void reflection_type_destroy(struct rb_entry *entry, void *context) { - struct d3dcompiler_shader_reflection_type *t = RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry); + struct reflection_type *t = RB_ENTRY_VALUE(entry, struct reflection_type, entry);
TRACE("reflection type %p.\n", t);
@@ -263,7 +263,7 @@ static void d3dcompiler_shader_reflection_type_destroy(struct rb_entry *entry, v vkd3d_free(t); }
-static void free_signature(struct d3dcompiler_shader_signature *sig) +static void free_signature(struct shader_signature *sig) { TRACE("Free signature %p.\n", sig);
@@ -271,7 +271,7 @@ static void free_signature(struct d3dcompiler_shader_signature *sig) vkd3d_free(sig->string_data); }
-static void free_variable(struct d3dcompiler_shader_reflection_variable *var) +static void free_variable(struct reflection_variable *var) { if (var) { @@ -280,7 +280,7 @@ static void free_variable(struct d3dcompiler_shader_reflection_variable *var) } }
-static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_buffer *cb) +static void free_constant_buffer(struct reflection_constant_buffer *cb) { if (cb->variables) { @@ -292,7 +292,7 @@ static void free_constant_buffer(struct d3dcompiler_shader_reflection_constant_b vkd3d_free(cb->name); }
-static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref) +static void reflection_cleanup(struct reflection *ref) { TRACE("Cleanup %p.\n", ref);
@@ -320,19 +320,19 @@ static void reflection_cleanup(struct d3dcompiler_shader_reflection *ref) free_constant_buffer(&ref->constant_buffers[i]); }
- rb_destroy(&ref->types, d3dcompiler_shader_reflection_type_destroy, NULL); + rb_destroy(&ref->types, reflection_type_destroy, NULL); vkd3d_free(ref->constant_buffers); vkd3d_free(ref->bound_resources); vkd3d_free(ref->resource_string); vkd3d_free(ref->creator); }
-static struct d3dcompiler_shader_reflection *impl_from_ID3D12ShaderReflection(ID3D12ShaderReflection *iface) +static struct reflection *impl_from_ID3D12ShaderReflection(ID3D12ShaderReflection *iface) { - return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D12ShaderReflection_iface); + return CONTAINING_RECORD(iface, struct reflection, ID3D12ShaderReflection_iface); }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D12ShaderReflection *iface, REFIID iid, void **object) +static HRESULT STDMETHODCALLTYPE reflection_QueryInterface(ID3D12ShaderReflection *iface, REFIID iid, void **object) { TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
@@ -349,9 +349,9 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D12ShaderReflection *iface) +static ULONG STDMETHODCALLTYPE reflection_AddRef(ID3D12ShaderReflection *iface) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface); ULONG refcount = InterlockedIncrement(&reflection->refcount);
TRACE("%p increasing refcount to %u.\n", reflection, refcount); @@ -359,9 +359,9 @@ static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_AddRef(ID3D12Shader return refcount; }
-static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D12ShaderReflection *iface) +static ULONG STDMETHODCALLTYPE reflection_Release(ID3D12ShaderReflection *iface) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface); ULONG refcount = InterlockedDecrement(&reflection->refcount);
TRACE("%p decreasing refcount to %u.\n", reflection, refcount); @@ -375,9 +375,9 @@ static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D12Shade return refcount; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D12ShaderReflection *iface, D3D12_SHADER_DESC *desc) +static HRESULT STDMETHODCALLTYPE reflection_GetDesc(ID3D12ShaderReflection *iface, D3D12_SHADER_DESC *desc) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
FIXME("iface %p, desc %p partial stub!\n", iface, desc);
@@ -429,10 +429,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D12Sha return S_OK; }
-static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex( +static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE reflection_GetConstantBufferByIndex( ID3D12ShaderReflection *iface, UINT index) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, index %u.\n", iface, index);
@@ -445,10 +445,10 @@ static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompil return &reflection->constant_buffers[index].ID3D12ShaderReflectionConstantBuffer_iface; }
-static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName( +static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE reflection_GetConstantBufferByName( ID3D12ShaderReflection *iface, const char *name) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
@@ -460,7 +460,7 @@ static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompil
for (unsigned int i = 0; i < reflection->constant_buffer_count; ++i) { - struct d3dcompiler_shader_reflection_constant_buffer *d = &reflection->constant_buffers[i]; + struct reflection_constant_buffer *d = &reflection->constant_buffers[i];
if (!strcmp(d->name, name)) { @@ -474,10 +474,10 @@ static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompil return &null_constant_buffer.ID3D12ShaderReflectionConstantBuffer_iface; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc( +static HRESULT STDMETHODCALLTYPE reflection_GetResourceBindingDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SHADER_INPUT_BIND_DESC *desc) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
@@ -488,16 +488,16 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindin }
memcpy(desc, &reflection->bound_resources[index], - reflection->interface_version == D3DCOMPILER_REFLECTION_VERSION_D3D12 + reflection->interface_version == REFLECTION_VERSION_D3D12 ? sizeof(D3D12_SHADER_INPUT_BIND_DESC) : sizeof(D3D12_SHADER_INPUT_BIND_DESC));
return S_OK; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc( +static HRESULT STDMETHODCALLTYPE reflection_GetInputParameterDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
@@ -512,10 +512,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameter return S_OK; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc( +static HRESULT STDMETHODCALLTYPE reflection_GetOutputParameterDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
@@ -530,10 +530,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParamete return S_OK; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc( +static HRESULT STDMETHODCALLTYPE reflection_GetPatchConstantParameterDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, index %u, desc %p.\n", iface, index, desc);
@@ -548,10 +548,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantP return S_OK; }
-static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName( +static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE reflection_GetVariableByName( ID3D12ShaderReflection *iface, const char *name) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
@@ -563,11 +563,11 @@ static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_sha
for (unsigned int i = 0; i < reflection->constant_buffer_count; ++i) { - struct d3dcompiler_shader_reflection_constant_buffer *cb = &reflection->constant_buffers[i]; + struct reflection_constant_buffer *cb = &reflection->constant_buffers[i];
for (unsigned int k = 0; k < cb->variable_count; ++k) { - struct d3dcompiler_shader_reflection_variable *v = &cb->variables[k]; + struct reflection_variable *v = &cb->variables[k];
if (!strcmp(v->name, name)) { @@ -582,10 +582,10 @@ static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_sha return &null_variable.ID3D12ShaderReflectionVariable_iface; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName( +static HRESULT STDMETHODCALLTYPE reflection_GetResourceBindingDescByName( ID3D12ShaderReflection *iface, const char *name, D3D12_SHADER_INPUT_BIND_DESC *desc) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, name %s, desc %p.\n", iface, debugstr_a(name), desc);
@@ -602,7 +602,7 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindin if (!strcmp(d->Name, name)) { TRACE("Returning D3D12_SHADER_INPUT_BIND_DESC %p.\n", d); - memcpy(desc, d, reflection->interface_version == D3DCOMPILER_REFLECTION_VERSION_D3D12 + memcpy(desc, d, reflection->interface_version == REFLECTION_VERSION_D3D12 ? sizeof(D3D12_SHADER_INPUT_BIND_DESC) : sizeof(D3D12_SHADER_INPUT_BIND_DESC)); return S_OK; } @@ -613,17 +613,17 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindin return E_INVALIDARG; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount( +static UINT STDMETHODCALLTYPE reflection_GetMovInstructionCount( ID3D12ShaderReflection *iface) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p.\n", iface);
return reflection->mov_instruction_count; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount( +static UINT STDMETHODCALLTYPE reflection_GetMovcInstructionCount( ID3D12ShaderReflection *iface) { FIXME("iface %p stub!\n", iface); @@ -631,17 +631,17 @@ static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCo return 0; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount( +static UINT STDMETHODCALLTYPE reflection_GetConversionInstructionCount( ID3D12ShaderReflection *iface) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p.\n", iface);
return reflection->conversion_instruction_count; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount( +static UINT STDMETHODCALLTYPE reflection_GetBitwiseInstructionCount( ID3D12ShaderReflection *iface) { FIXME("iface %p stub!\n", iface); @@ -649,7 +649,7 @@ static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructio return 0; }
-static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive( +static D3D_PRIMITIVE STDMETHODCALLTYPE reflection_GetGSInputPrimitive( ID3D12ShaderReflection *iface) { FIXME("iface %p stub!\n", iface); @@ -657,7 +657,7 @@ static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputP return 0; }
-static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader( +static BOOL STDMETHODCALLTYPE reflection_IsSampleFrequencyShader( ID3D12ShaderReflection *iface) { FIXME("iface %p stub!\n", iface); @@ -665,7 +665,7 @@ static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencySha return FALSE; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots( +static UINT STDMETHODCALLTYPE reflection_GetNumInterfaceSlots( ID3D12ShaderReflection *iface) { FIXME("iface %p stub!\n", iface); @@ -673,7 +673,7 @@ static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots return 0; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel( +static HRESULT STDMETHODCALLTYPE reflection_GetMinFeatureLevel( ID3D12ShaderReflection *iface, D3D_FEATURE_LEVEL *level) { FIXME("iface %p, level %p stub!\n", iface, level); @@ -681,10 +681,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLeve return E_NOTIMPL; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize( +static UINT STDMETHODCALLTYPE reflection_GetThreadGroupSize( ID3D12ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez) { - struct d3dcompiler_shader_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + struct reflection *reflection = impl_from_ID3D12ShaderReflection(iface);
TRACE("iface %p, sizex %p, sizey %p, sizez %p.\n", iface, sizex, sizey, sizez);
@@ -701,7 +701,7 @@ static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetThreadGroupSize( return *sizex * *sizey * *sizez; }
-static UINT64 STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetRequiresFlags( +static UINT64 STDMETHODCALLTYPE reflection_GetRequiresFlags( ID3D12ShaderReflection *iface) { FIXME("iface %p stub!\n", iface); @@ -709,41 +709,41 @@ static UINT64 STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetRequiresFlags( return 0; }
-static const struct ID3D12ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl = -{ - d3dcompiler_shader_reflection_QueryInterface, - d3dcompiler_shader_reflection_AddRef, - d3dcompiler_shader_reflection_Release, - d3dcompiler_shader_reflection_GetDesc, - d3dcompiler_shader_reflection_GetConstantBufferByIndex, - d3dcompiler_shader_reflection_GetConstantBufferByName, - d3dcompiler_shader_reflection_GetResourceBindingDesc, - d3dcompiler_shader_reflection_GetInputParameterDesc, - d3dcompiler_shader_reflection_GetOutputParameterDesc, - d3dcompiler_shader_reflection_GetPatchConstantParameterDesc, - d3dcompiler_shader_reflection_GetVariableByName, - d3dcompiler_shader_reflection_GetResourceBindingDescByName, - d3dcompiler_shader_reflection_GetMovInstructionCount, - d3dcompiler_shader_reflection_GetMovcInstructionCount, - d3dcompiler_shader_reflection_GetConversionInstructionCount, - d3dcompiler_shader_reflection_GetBitwiseInstructionCount, - d3dcompiler_shader_reflection_GetGSInputPrimitive, - d3dcompiler_shader_reflection_IsSampleFrequencyShader, - d3dcompiler_shader_reflection_GetNumInterfaceSlots, - d3dcompiler_shader_reflection_GetMinFeatureLevel, - d3dcompiler_shader_reflection_GetThreadGroupSize, - d3dcompiler_shader_reflection_GetRequiresFlags, +static const struct ID3D12ShaderReflectionVtbl reflection_vtbl = +{ + reflection_QueryInterface, + reflection_AddRef, + reflection_Release, + reflection_GetDesc, + reflection_GetConstantBufferByIndex, + reflection_GetConstantBufferByName, + reflection_GetResourceBindingDesc, + reflection_GetInputParameterDesc, + reflection_GetOutputParameterDesc, + reflection_GetPatchConstantParameterDesc, + reflection_GetVariableByName, + reflection_GetResourceBindingDescByName, + reflection_GetMovInstructionCount, + reflection_GetMovcInstructionCount, + reflection_GetConversionInstructionCount, + reflection_GetBitwiseInstructionCount, + reflection_GetGSInputPrimitive, + reflection_IsSampleFrequencyShader, + reflection_GetNumInterfaceSlots, + reflection_GetMinFeatureLevel, + reflection_GetThreadGroupSize, + reflection_GetRequiresFlags, };
-static struct d3dcompiler_shader_reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D12ShaderReflectionConstantBuffer *iface) +static struct reflection_constant_buffer *impl_from_ID3D11ShaderReflectionConstantBuffer(ID3D12ShaderReflectionConstantBuffer *iface) { - return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_constant_buffer, ID3D12ShaderReflectionConstantBuffer_iface); + return CONTAINING_RECORD(iface, struct reflection_constant_buffer, ID3D12ShaderReflectionConstantBuffer_iface); }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetDesc( +static HRESULT STDMETHODCALLTYPE reflection_constant_buffer_GetDesc( ID3D12ShaderReflectionConstantBuffer *iface, D3D12_SHADER_BUFFER_DESC *desc) { - struct d3dcompiler_shader_reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); + struct reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
TRACE("iface %p, desc %p.\n", iface, desc);
@@ -768,10 +768,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_G return S_OK; }
-static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex( +static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE reflection_constant_buffer_GetVariableByIndex( ID3D12ShaderReflectionConstantBuffer *iface, UINT index) { - struct d3dcompiler_shader_reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); + struct reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
TRACE("iface %p, index %u.\n", iface, index);
@@ -784,10 +784,10 @@ static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_ref return &cb->variables[index].ID3D12ShaderReflectionVariable_iface; }
-static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_constant_buffer_GetVariableByName( +static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE reflection_constant_buffer_GetVariableByName( ID3D12ShaderReflectionConstantBuffer *iface, const char *name) { - struct d3dcompiler_shader_reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface); + struct reflection_constant_buffer *cb = impl_from_ID3D11ShaderReflectionConstantBuffer(iface);
TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
@@ -799,7 +799,7 @@ static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_ref
for (unsigned int i = 0; i < cb->variable_count; ++i) { - struct d3dcompiler_shader_reflection_variable *v = &cb->variables[i]; + struct reflection_variable *v = &cb->variables[i];
if (!strcmp(v->name, name)) { @@ -813,22 +813,22 @@ static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_ref return &null_variable.ID3D12ShaderReflectionVariable_iface; }
-static const struct ID3D12ShaderReflectionConstantBufferVtbl d3dcompiler_shader_reflection_constant_buffer_vtbl = +static const struct ID3D12ShaderReflectionConstantBufferVtbl reflection_constant_buffer_vtbl = { - d3dcompiler_shader_reflection_constant_buffer_GetDesc, - d3dcompiler_shader_reflection_constant_buffer_GetVariableByIndex, - d3dcompiler_shader_reflection_constant_buffer_GetVariableByName, + reflection_constant_buffer_GetDesc, + reflection_constant_buffer_GetVariableByIndex, + reflection_constant_buffer_GetVariableByName, };
-static struct d3dcompiler_shader_reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D12ShaderReflectionVariable *iface) +static struct reflection_variable *impl_from_ID3D11ShaderReflectionVariable(ID3D12ShaderReflectionVariable *iface) { - return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_variable, ID3D12ShaderReflectionVariable_iface); + return CONTAINING_RECORD(iface, struct reflection_variable, ID3D12ShaderReflectionVariable_iface); }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc( +static HRESULT STDMETHODCALLTYPE reflection_variable_GetDesc( ID3D12ShaderReflectionVariable *iface, D3D12_SHADER_VARIABLE_DESC *desc) { - struct d3dcompiler_shader_reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface); + struct reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface);
TRACE("iface %p, desc %p.\n", iface, desc);
@@ -859,27 +859,27 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetDesc( return S_OK; }
-static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetType( +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE reflection_variable_GetType( ID3D12ShaderReflectionVariable *iface) { - struct d3dcompiler_shader_reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface); + struct reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface);
TRACE("iface %p.\n", iface);
return &variable->type->ID3D12ShaderReflectionType_iface; }
-static ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetBuffer( +static ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE reflection_variable_GetBuffer( ID3D12ShaderReflectionVariable *iface) { - struct d3dcompiler_shader_reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface); + struct reflection_variable *variable = impl_from_ID3D11ShaderReflectionVariable(iface);
TRACE("iface %p.\n", iface);
return &variable->constant_buffer->ID3D12ShaderReflectionConstantBuffer_iface; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfaceSlot( +static UINT STDMETHODCALLTYPE reflection_variable_GetInterfaceSlot( ID3D12ShaderReflectionVariable *iface, UINT index) { FIXME("iface %p, index %u stub!\n", iface, index); @@ -887,23 +887,23 @@ static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_variable_GetInterfac return 0; }
-static const struct ID3D12ShaderReflectionVariableVtbl d3dcompiler_shader_reflection_variable_vtbl = +static const struct ID3D12ShaderReflectionVariableVtbl reflection_variable_vtbl = { - d3dcompiler_shader_reflection_variable_GetDesc, - d3dcompiler_shader_reflection_variable_GetType, - d3dcompiler_shader_reflection_variable_GetBuffer, - d3dcompiler_shader_reflection_variable_GetInterfaceSlot, + reflection_variable_GetDesc, + reflection_variable_GetType, + reflection_variable_GetBuffer, + reflection_variable_GetInterfaceSlot, };
-static struct d3dcompiler_shader_reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D12ShaderReflectionType *iface) +static struct reflection_type *impl_from_ID3D11ShaderReflectionType(ID3D12ShaderReflectionType *iface) { - return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection_type, ID3D12ShaderReflectionType_iface); + return CONTAINING_RECORD(iface, struct reflection_type, ID3D12ShaderReflectionType_iface); }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc( +static HRESULT STDMETHODCALLTYPE reflection_type_GetDesc( ID3D12ShaderReflectionType *iface, D3D12_SHADER_TYPE_DESC *desc) { - struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + struct reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface);
TRACE("iface %p, desc %p.\n", iface, desc);
@@ -924,10 +924,10 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetDesc( return S_OK; }
-static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByIndex( +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE reflection_type_GetMemberTypeByIndex( ID3D12ShaderReflectionType *iface, UINT index) { - struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + struct reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface);
TRACE("iface %p, index %u.\n", iface, index);
@@ -940,10 +940,10 @@ static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflect return &variable->members[index].type->ID3D12ShaderReflectionType_iface; }
-static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeByName( +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE reflection_type_GetMemberTypeByName( ID3D12ShaderReflectionType *iface, const char *name) { - struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + struct reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface);
TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
@@ -955,7 +955,7 @@ static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflect
for (unsigned int i = 0; i < variable->desc.Members; ++i) { - struct d3dcompiler_shader_reflection_type_member *member = &variable->members[i]; + struct reflection_type_member *member = &variable->members[i];
if (!strcmp(member->name, name)) { @@ -969,10 +969,10 @@ static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflect return &null_type.ID3D12ShaderReflectionType_iface; }
-static const char * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemberTypeName( +static const char * STDMETHODCALLTYPE reflection_type_GetMemberTypeName( ID3D12ShaderReflectionType *iface, UINT index) { - struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + struct reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface);
TRACE("iface %p, index %u.\n", iface, index);
@@ -991,10 +991,10 @@ static const char * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetMemb return variable->members[index].name; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual( +static HRESULT STDMETHODCALLTYPE reflection_type_IsEqual( ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *type) { - struct d3dcompiler_shader_reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface); + struct reflection_type *variable = impl_from_ID3D11ShaderReflectionType(iface);
TRACE("iface %p, type %p.\n", iface, type);
@@ -1010,7 +1010,7 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsEqual( return S_FALSE; }
-static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetSubType( +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE reflection_type_GetSubType( ID3D12ShaderReflectionType *iface) { FIXME("iface %p stub!\n", iface); @@ -1018,7 +1018,7 @@ static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflect return NULL; }
-static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetBaseClass( +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE reflection_type_GetBaseClass( ID3D12ShaderReflectionType *iface) { FIXME("iface %p stub!\n", iface); @@ -1026,7 +1026,7 @@ static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflect return NULL; }
-static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterfaces( +static UINT STDMETHODCALLTYPE reflection_type_GetNumInterfaces( ID3D12ShaderReflectionType *iface) { FIXME("iface %p stub!\n", iface); @@ -1034,7 +1034,7 @@ static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetNumInterface return 0; }
-static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_GetInterfaceByIndex( +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE reflection_type_GetInterfaceByIndex( ID3D12ShaderReflectionType *iface, UINT index) { FIXME("iface %p, index %u stub!\n", iface, index); @@ -1042,7 +1042,7 @@ static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3dcompiler_shader_reflect return NULL; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType( +static HRESULT STDMETHODCALLTYPE reflection_type_IsOfType( ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *type) { FIXME("iface %p, type %p stub!\n", iface, type); @@ -1050,7 +1050,7 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_IsOfType( return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsInterface( +static HRESULT STDMETHODCALLTYPE reflection_type_ImplementsInterface( ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *base) { FIXME("iface %p, base %p stub!\n", iface, base); @@ -1058,22 +1058,22 @@ static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_type_ImplementsIn return E_NOTIMPL; }
-static const struct ID3D12ShaderReflectionTypeVtbl d3dcompiler_shader_reflection_type_vtbl = +static const struct ID3D12ShaderReflectionTypeVtbl reflection_type_vtbl = { - d3dcompiler_shader_reflection_type_GetDesc, - d3dcompiler_shader_reflection_type_GetMemberTypeByIndex, - d3dcompiler_shader_reflection_type_GetMemberTypeByName, - d3dcompiler_shader_reflection_type_GetMemberTypeName, - d3dcompiler_shader_reflection_type_IsEqual, - d3dcompiler_shader_reflection_type_GetSubType, - d3dcompiler_shader_reflection_type_GetBaseClass, - d3dcompiler_shader_reflection_type_GetNumInterfaces, - d3dcompiler_shader_reflection_type_GetInterfaceByIndex, - d3dcompiler_shader_reflection_type_IsOfType, - d3dcompiler_shader_reflection_type_ImplementsInterface, + reflection_type_GetDesc, + reflection_type_GetMemberTypeByIndex, + reflection_type_GetMemberTypeByName, + reflection_type_GetMemberTypeName, + reflection_type_IsEqual, + reflection_type_GetSubType, + reflection_type_GetBaseClass, + reflection_type_GetNumInterfaces, + reflection_type_GetInterfaceByIndex, + reflection_type_IsOfType, + reflection_type_ImplementsInterface, };
-static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size) +static HRESULT parse_stat(struct reflection *r, const char *data, size_t data_size) { const char *ptr = data; size_t size = data_size >> 2; @@ -1193,8 +1193,8 @@ static HRESULT d3dcompiler_parse_stat(struct d3dcompiler_shader_reflection *r, c return E_FAIL; }
-static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflection *ref, - struct d3dcompiler_shader_reflection_type_member *member, const char *data, const char **ptr) +static HRESULT parse_type_members(struct reflection *ref, + struct reflection_type_member *member, const char *data, const char **ptr) { uint32_t offset;
@@ -1223,9 +1223,9 @@ static HRESULT d3dcompiler_parse_type_members(struct d3dcompiler_shader_reflecti return S_OK; }
-static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type *type, const char *data, uint32_t offset) +static HRESULT parse_type(struct reflection_type *type, const char *data, uint32_t offset) { - struct d3dcompiler_shader_reflection_type_member *members = NULL; + struct reflection_type_member *members = NULL; const char *ptr = data + offset; D3D12_SHADER_TYPE_DESC *desc; uint32_t member_offset; @@ -1252,7 +1252,7 @@ static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type member_offset = read_u32(&ptr); TRACE("Member Offset %u.\n", member_offset);
- if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) + if ((type->reflection->target & SHADER_TARGET_VERSION_MASK) >= 0x500) skip_u32_unknown(&ptr, 4);
if (desc->Members) @@ -1268,7 +1268,7 @@ static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type
for (unsigned int i = 0; i < desc->Members; ++i) { - hr = d3dcompiler_parse_type_members(type->reflection, &members[i], data, &ptr2); + hr = parse_type_members(type->reflection, &members[i], data, &ptr2); if (hr != S_OK) { FIXME("Failed to parse type members.\n"); @@ -1277,7 +1277,7 @@ static HRESULT d3dcompiler_parse_type(struct d3dcompiler_shader_reflection_type } }
- if ((type->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) + if ((type->reflection->target & SHADER_TARGET_VERSION_MASK) >= 0x500) { offset = read_u32(&ptr); if (!copy_name(data + offset, &type->name)) @@ -1301,9 +1301,9 @@ err_out: return hr; }
-static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3dcompiler_shader_reflection *reflection, const char *data, uint32_t offset) +static struct reflection_type *get_reflection_type(struct reflection *reflection, const char *data, uint32_t offset) { - struct d3dcompiler_shader_reflection_type *type; + struct reflection_type *type; struct rb_entry *entry; HRESULT hr;
@@ -1311,18 +1311,18 @@ static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3d if (entry) { TRACE("Returning existing type.\n"); - return RB_ENTRY_VALUE(entry, struct d3dcompiler_shader_reflection_type, entry); + return RB_ENTRY_VALUE(entry, struct reflection_type, entry); }
type = vkd3d_calloc(1, sizeof(*type)); if (!type) return NULL;
- type->ID3D12ShaderReflectionType_iface.lpVtbl = &d3dcompiler_shader_reflection_type_vtbl; + type->ID3D12ShaderReflectionType_iface.lpVtbl = &reflection_type_vtbl; type->id = offset; type->reflection = reflection;
- hr = d3dcompiler_parse_type(type, data, offset); + hr = parse_type(type, data, offset); if (FAILED(hr)) { ERR("Failed to parse type info, hr %#x.\n", hr); @@ -1340,10 +1340,10 @@ static struct d3dcompiler_shader_reflection_type *get_reflection_type(struct d3d return type; }
-static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_constant_buffer *cb, +static HRESULT parse_variables(struct reflection_constant_buffer *cb, const char *data, size_t data_size, const char *ptr) { - struct d3dcompiler_shader_reflection_variable *variables; + struct reflection_variable *variables; HRESULT hr;
variables = vkd3d_calloc(cb->variable_count, sizeof(*variables)); @@ -1355,10 +1355,10 @@ static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_
for (unsigned int i = 0; i < cb->variable_count; i++) { - struct d3dcompiler_shader_reflection_variable *v = &variables[i]; + struct reflection_variable *v = &variables[i]; uint32_t offset;
- v->ID3D12ShaderReflectionVariable_iface.lpVtbl = &d3dcompiler_shader_reflection_variable_vtbl; + v->ID3D12ShaderReflectionVariable_iface.lpVtbl = &reflection_variable_vtbl; v->constant_buffer = cb;
offset = read_u32(&ptr); @@ -1398,7 +1398,7 @@ static HRESULT d3dcompiler_parse_variables(struct d3dcompiler_shader_reflection_ goto err_out; }
- if ((cb->reflection->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK) >= 0x500) + if ((cb->reflection->target & SHADER_TARGET_VERSION_MASK) >= 0x500) skip_u32_unknown(&ptr, 4); }
@@ -1415,9 +1415,9 @@ err_out: return hr; }
-static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size) +static HRESULT parse_rdef(struct reflection *r, const char *data, size_t data_size) { - struct d3dcompiler_shader_reflection_constant_buffer *constant_buffers = NULL; + struct reflection_constant_buffer *constant_buffers = NULL; uint32_t offset, cbuffer_offset, resource_offset, creator_offset; D3D12_SHADER_INPUT_BIND_DESC *bound_resources = NULL; unsigned int string_data_offset, string_data_size; @@ -1444,7 +1444,7 @@ static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, c r->target = read_u32(&ptr); TRACE("Target: %#x.\n", r->target);
- target_version = r->target & D3DCOMPILER_SHADER_TARGET_VERSION_MASK; + target_version = r->target & SHADER_TARGET_VERSION_MASK;
r->flags = read_u32(&ptr); TRACE("Flags: %u.\n", r->flags); @@ -1545,9 +1545,9 @@ static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, c ptr = data + cbuffer_offset; for (unsigned int i = 0; i < r->constant_buffer_count; i++) { - struct d3dcompiler_shader_reflection_constant_buffer *cb = &constant_buffers[i]; + struct reflection_constant_buffer *cb = &constant_buffers[i];
- cb->ID3D12ShaderReflectionConstantBuffer_iface.lpVtbl = &d3dcompiler_shader_reflection_constant_buffer_vtbl; + cb->ID3D12ShaderReflectionConstantBuffer_iface.lpVtbl = &reflection_constant_buffer_vtbl; cb->reflection = r;
offset = read_u32(&ptr); @@ -1565,7 +1565,7 @@ static HRESULT d3dcompiler_parse_rdef(struct d3dcompiler_shader_reflection *r, c offset = read_u32(&ptr); TRACE("Variable offset: %x.\n", offset);
- hr = d3dcompiler_parse_variables(cb, data, data_size, data + offset); + hr = parse_variables(cb, data, data_size, data + offset); if (hr != S_OK) { FIXME("Failed to parse variables.\n"); @@ -1601,10 +1601,10 @@ err_out: return hr; }
-static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *s, +static HRESULT parse_signature(struct shader_signature *s, const struct vkd3d_shader_dxbc_section_desc *section) { - enum D3DCOMPILER_SIGNATURE_ELEMENT_SIZE element_size; + enum signature_element_size element_size; const char *ptr = section->data.code; D3D12_SIGNATURE_PARAMETER_DESC *d; unsigned int string_data_offset; @@ -1615,18 +1615,18 @@ static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature * switch (section->tag) { case TAG_OSG5: - element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7; + element_size = SIGNATURE_ELEMENT_SIZE7; break;
case TAG_ISGN: case TAG_OSGN: case TAG_PCSG: - element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6; + element_size = SIGNATURE_ELEMENT_SIZE6; break;
default: FIXME("Unhandled section %08x!\n", section->tag); - element_size = D3DCOMPILER_SIGNATURE_ELEMENT_SIZE6; + element_size = SIGNATURE_ELEMENT_SIZE6; break; }
@@ -1661,7 +1661,7 @@ static HRESULT d3dcompiler_parse_signature(struct d3dcompiler_shader_signature *
/* FIXME */ d[i].MinPrecision = D3D_MIN_PRECISION_DEFAULT; - if (element_size == D3DCOMPILER_SIGNATURE_ELEMENT_SIZE7) + if (element_size == SIGNATURE_ELEMENT_SIZE7) d[i].Stream = read_u32(&ptr);
name_offset = read_u32(&ptr); @@ -1702,7 +1702,7 @@ enum sm4_opcode SM5_OP_DCL_THREAD_GROUP = 0x9b, };
-static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, const char *data, size_t data_size) +static HRESULT parse_shdr(struct reflection *r, const char *data, size_t data_size) { uint32_t opcode_token, opcode; uint32_t size, shader_type; @@ -1713,10 +1713,10 @@ static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, c r->version = read_u32(&ptr); TRACE("Shader version: %u.\n", r->version);
- shader_type = (r->version & D3DCOMPILER_SHADER_TARGET_SHADERTYPE_MASK) - >> D3DCOMPILER_SHADER_TARGET_SHADERTYPE_SHIFT; + shader_type = (r->version & SHADER_TARGET_SHADERTYPE_MASK) + >> SHADER_TARGET_SHADERTYPE_SHIFT;
- if (shader_type != D3DCOMPILER_SHADER_TYPE_CS) + if (shader_type != SHADER_TYPE_CS) { /* TODO: Check if anything else is needed from the SHDR or SHEX blob. */ return S_OK; @@ -1769,7 +1769,7 @@ static HRESULT d3dcompiler_parse_shdr(struct d3dcompiler_shader_reflection *r, c return S_OK; }
-static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_reflection *reflection, +static HRESULT reflection_init(struct reflection *reflection, const void *data, SIZE_T data_size) { const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size}; @@ -1777,7 +1777,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl HRESULT hr = S_OK; int ret;
- rb_init(&reflection->types, d3dcompiler_shader_reflection_type_compare); + rb_init(&reflection->types, reflection_type_compare);
if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0) { @@ -1792,7 +1792,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl switch (section->tag) { case TAG_RDEF: - hr = d3dcompiler_parse_rdef(reflection, section->data.code, section->data.size); + hr = parse_rdef(reflection, section->data.code, section->data.size); if (FAILED(hr)) { WARN("Failed to parse RDEF section.\n"); @@ -1809,7 +1809,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl goto err_out; }
- hr = d3dcompiler_parse_signature(reflection->isgn, section); + hr = parse_signature(reflection->isgn, section); if (FAILED(hr)) { WARN("Failed to parse section ISGN.\n"); @@ -1827,7 +1827,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl goto err_out; }
- hr = d3dcompiler_parse_signature(reflection->osgn, section); + hr = parse_signature(reflection->osgn, section); if (FAILED(hr)) { WARN("Failed to parse section OSGN.\n"); @@ -1844,7 +1844,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl goto err_out; }
- hr = d3dcompiler_parse_signature(reflection->pcsg, section); + hr = parse_signature(reflection->pcsg, section); if (FAILED(hr)) { WARN("Failed to parse section PCSG.\n"); @@ -1854,7 +1854,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl
case TAG_SHEX: case TAG_SHDR: - hr = d3dcompiler_parse_shdr(reflection, section->data.code, section->data.size); + hr = parse_shdr(reflection, section->data.code, section->data.size); if (FAILED(hr)) { WARN("Failed to parse SHDR section.\n"); @@ -1863,7 +1863,7 @@ static HRESULT d3dcompiler_shader_reflection_init(struct d3dcompiler_shader_refl break;
case TAG_STAT: - hr = d3dcompiler_parse_stat(reflection, section->data.code, section->data.size); + hr = parse_stat(reflection, section->data.code, section->data.size); if (FAILED(hr)) { WARN("Failed to parse section STAT.\n"); @@ -1890,7 +1890,7 @@ err_out:
HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflector) { - struct d3dcompiler_shader_reflection *object; + struct reflection *object; const uint32_t *temp = data; HRESULT hr;
@@ -1917,12 +1917,12 @@ HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void * if (!(object = vkd3d_calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- object->ID3D12ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl; + object->ID3D12ShaderReflection_iface.lpVtbl = &reflection_vtbl; object->refcount = 1; object->interface_version = IsEqualGUID(iid, &IID_ID3D12ShaderReflection) - ? D3DCOMPILER_REFLECTION_VERSION_D3D12 : D3DCOMPILER_REFLECTION_VERSION_D3D11; + ? REFLECTION_VERSION_D3D12 : REFLECTION_VERSION_D3D11;
- if (FAILED(hr = d3dcompiler_shader_reflection_init(object, data, data_size))) + if (FAILED(hr = reflection_init(object, data, data_size))) { vkd3d_free(object); return hr;
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:
From: Zebediah Figura zfigura@codeweavers.com
--- tests/vkd3d_shader_api.c | 59 +++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 10 deletions(-)
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c index 018506a45..00dcd2248 100644 --- a/tests/vkd3d_shader_api.c +++ b/tests/vkd3d_shader_api.c @@ -441,6 +441,7 @@ static void test_scan_signatures(void) struct vkd3d_shader_scan_signature_info signature_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO}; struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO}; struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; + struct vkd3d_shader_compile_option options[1]; struct vkd3d_shader_code dxbc; size_t i, j; int rc; @@ -496,6 +497,11 @@ static void test_scan_signatures(void) {"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf}, };
+ static const struct vkd3d_shader_signature_element vs2_legacy_outputs[] = + { + {"SV_Position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf}, + }; + static const char vs3_source[] = "void main(\n" " in float4 c : position,\n" @@ -656,6 +662,27 @@ static void test_scan_signatures(void) {"VFACE", 0, 0, VKD3D_SHADER_SV_IS_FRONT_FACE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0x1, 0x1}, };
+ static const char ps5_source[] = + "void main(\n" + " inout float4 a : color2,\n" + " inout float b : depth,\n" + " in float4 c : position)\n" + "{\n" + "}"; + + static const struct vkd3d_shader_signature_element ps5_inputs[] = + { + {"color", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf}, + {"depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0x1, 0x1}, + {"SV_Position", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf}, + }; + + static const struct vkd3d_shader_signature_element ps5_outputs[] = + { + {"SV_Target", 2, 0, VKD3D_SHADER_SV_TARGET, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf}, + {"SV_Depth", 0, 0, VKD3D_SHADER_SV_DEPTH, VKD3D_SHADER_COMPONENT_FLOAT, ~0u, 0x1, 0x1}, + }; + static const char cs1_source[] = "[numthreads(1, 1, 1)]\n" "void main(\n" @@ -670,6 +697,7 @@ static void test_scan_signatures(void) const char *source; bool sm4; const char *profile; + bool compat; const struct vkd3d_shader_signature_element *inputs; size_t input_count; const struct vkd3d_shader_signature_element *outputs; @@ -679,16 +707,20 @@ static void test_scan_signatures(void) } tests[] = { - {vs1_source, true, "vs_4_0", vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)}, - {vs2_source, true, "vs_4_0", vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)}, - {vs3_source, false, "vs_1_1", vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)}, - {vs3_source, false, "vs_2_0", vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)}, - {vs4_source, false, "vs_3_0", vs4_inputs, ARRAY_SIZE(vs4_inputs), vs4_outputs, ARRAY_SIZE(vs4_outputs)}, - {ps1_source, true, "ps_4_0", ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)}, - {ps2_source, false, "ps_1_1", ps2_inputs, ARRAY_SIZE(ps2_inputs), ps2_outputs, ARRAY_SIZE(ps2_outputs)}, - {ps3_source, false, "ps_2_0", ps3_inputs, ARRAY_SIZE(ps3_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)}, - {ps4_source, false, "ps_3_0", ps4_inputs, ARRAY_SIZE(ps4_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)}, - {cs1_source, true, "cs_5_0", NULL, 0, NULL, 0}, + {vs1_source, true, "vs_4_0", false, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)}, + {vs1_source, true, "vs_4_0", true, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)}, + {vs2_source, true, "vs_4_0", false, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)}, + {vs2_source, true, "vs_4_0", true, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_legacy_outputs, ARRAY_SIZE(vs2_legacy_outputs)}, + {ps1_source, true, "ps_4_0", false, ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)}, + {ps5_source, true, "ps_4_0", true, ps5_inputs, ARRAY_SIZE(ps5_inputs), ps5_outputs, ARRAY_SIZE(ps5_outputs)}, + {cs1_source, true, "cs_5_0", false, NULL, 0, NULL, 0}, + + {vs3_source, false, "vs_1_1", false, vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)}, + {vs3_source, false, "vs_2_0", false, vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)}, + {vs4_source, false, "vs_3_0", false, vs4_inputs, ARRAY_SIZE(vs4_inputs), vs4_outputs, ARRAY_SIZE(vs4_outputs)}, + {ps2_source, false, "ps_1_1", false, ps2_inputs, ARRAY_SIZE(ps2_inputs), ps2_outputs, ARRAY_SIZE(ps2_outputs)}, + {ps3_source, false, "ps_2_0", false, ps3_inputs, ARRAY_SIZE(ps3_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)}, + {ps4_source, false, "ps_3_0", false, ps4_inputs, ARRAY_SIZE(ps4_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)}, };
for (i = 0; i < ARRAY_SIZE(tests); ++i) @@ -700,6 +732,13 @@ static void test_scan_signatures(void) compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; compile_info.target_type = tests[i].sm4 ? VKD3D_SHADER_TARGET_DXBC_TPF : VKD3D_SHADER_TARGET_D3D_BYTECODE; compile_info.log_level = VKD3D_SHADER_LOG_INFO; + compile_info.options = options; + compile_info.option_count = 1; + + options[0].name = VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY; + options[0].value = 0; + if (tests[i].compat) + options[0].value = VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
compile_info.next = &hlsl_info; hlsl_info.profile = tests[i].profile;
From: Zebediah Figura zfigura@codeweavers.com
Ported from Wine. --- tests/hlsl_d3d12.c | 198 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+)
diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index 51010b9f5..a8e4fc9f3 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -19,6 +19,7 @@ #include "config.h" #include "d3d12_crosstest.h" #include "vkd3d_common.h" +#include "vkd3d_d3d12shader.h"
#ifndef D3DERR_INVALIDCALL #define D3DERR_INVALIDCALL 0x8876086c @@ -1316,6 +1317,202 @@ static void test_get_blob_part(void) ok(!refcount, "Got refcount %u.\n", refcount); }
+static void check_signature_element(const D3D12_SIGNATURE_PARAMETER_DESC *desc, + const D3D12_SIGNATURE_PARAMETER_DESC *expect) +{ + ok(!strcmp(desc->SemanticName, expect->SemanticName), "Got name "%s".\n", desc->SemanticName); + ok(desc->SemanticIndex == expect->SemanticIndex, "Got index %u.\n", desc->SemanticIndex); + ok(desc->Register == expect->Register, "Got register %u.\n", desc->Register); + ok(desc->SystemValueType == expect->SystemValueType, "Got sysval %u.\n", desc->SystemValueType); + ok(desc->ComponentType == expect->ComponentType, "Got data type %u.\n", desc->ComponentType); + ok(desc->Mask == expect->Mask, "Got mask %#x.\n", desc->Mask); + todo_if(desc->ReadWriteMask != expect->ReadWriteMask) + ok(desc->ReadWriteMask == expect->ReadWriteMask, "Got used mask %#x.\n", desc->ReadWriteMask); + ok(desc->Stream == expect->Stream, "Got stream %u.\n", desc->Stream); +} + +static void test_signature_reflection(void) +{ + D3D12_SIGNATURE_PARAMETER_DESC desc; + ID3D12ShaderReflection *reflection; + D3D12_SHADER_DESC shader_desc; + ID3D10Blob *code = NULL; + ULONG refcount; + HRESULT hr; + + static const char vs1_source[] = + "void main(\n" + " in float4 a : apple,\n" + " out float4 b : banana2,\n" + " inout float4 c : color,\n" + " inout float4 d : depth,\n" + " inout float4 e : sv_position,\n" + " in uint3 f : fruit,\n" + " inout bool2 g : grape,\n" + " in int h : honeydew,\n" + " in uint i : sv_vertexid)\n" + "{\n" + " b.yw = a.xz;\n" + "}"; + + static const D3D12_SIGNATURE_PARAMETER_DESC vs1_inputs[] = + { + {"apple", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x5}, + {"color", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf}, + {"depth", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf}, + {"sv_position", 0, 3, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf}, + {"fruit", 0, 4, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x7}, + {"grape", 0, 5, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x3, 0x3}, + {"honeydew", 0, 6, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_SINT32, 0x1}, + {"sv_vertexid", 0, 7, D3D_NAME_VERTEX_ID, D3D_REGISTER_COMPONENT_UINT32, 0x1}, + }; + + static const D3D12_SIGNATURE_PARAMETER_DESC vs1_outputs[] = + { + {"banana", 2, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x5}, + {"color", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + {"depth", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + {"sv_position", 0, 3, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + {"grape", 0, 4, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x3, 0xc}, + }; + + static const char vs2_source[] = + "void main(inout float4 pos : position)\n" + "{\n" + "}"; + + static const D3D12_SIGNATURE_PARAMETER_DESC vs2_inputs[] = + { + {"position", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf}, + }; + + static const D3D12_SIGNATURE_PARAMETER_DESC vs2_outputs[] = + { + {"position", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + }; + + static const D3D12_SIGNATURE_PARAMETER_DESC vs2_legacy_outputs[] = + { + {"SV_Position", 0, 0, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + }; + + static const char ps1_source[] = + "void main(\n" + " in float2 a : apple,\n" + " out float4 b : sv_target2,\n" + " out float c : sv_depth,\n" + " in float4 d : position,\n" + " in float4 e : sv_position)\n" + "{\n" + " b = d;\n" + " c = 0;\n" + "}"; + + static const D3D12_SIGNATURE_PARAMETER_DESC ps1_inputs[] = + { + {"apple", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x3}, + {"position", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf}, + {"sv_position", 0, 2, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + }; + + static const D3D12_SIGNATURE_PARAMETER_DESC ps1_outputs[] = + { + {"sv_target", 2, 2, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + {"sv_depth", 0, ~0u, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe}, + }; + + static const char ps2_source[] = + "void main(\n" + " inout float4 a : color2,\n" + " inout float b : depth,\n" + " in float4 c : position)\n" + "{\n" + "}"; + + static const D3D12_SIGNATURE_PARAMETER_DESC ps2_inputs[] = + { + {"color", 2, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf}, + {"depth", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0x1}, + {"SV_Position", 0, 2, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + }; + + static const D3D12_SIGNATURE_PARAMETER_DESC ps2_outputs[] = + { + {"SV_Target", 2, 2, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0xf}, + {"SV_Depth", 0, ~0u, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe}, + }; + + static const char cs1_source[] = + "[numthreads(1, 1, 1)]\n" + "void main(in uint a : sv_dispatchthreadid)\n" + "{\n" + "}"; + + static const struct + { + const char *source; + const char *target; + bool compat; + const D3D12_SIGNATURE_PARAMETER_DESC *inputs; + unsigned int input_count; + const D3D12_SIGNATURE_PARAMETER_DESC *outputs; + unsigned int output_count; + } + tests[] = + { + {vs1_source, "vs_4_0", false, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)}, + {vs1_source, "vs_4_0", true, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)}, + {vs2_source, "vs_4_0", false, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)}, + {vs2_source, "vs_4_0", true, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_legacy_outputs, ARRAY_SIZE(vs2_legacy_outputs)}, + {ps1_source, "ps_4_0", false, ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)}, + {ps2_source, "ps_4_0", true, ps2_inputs, ARRAY_SIZE(ps2_inputs), ps2_outputs, ARRAY_SIZE(ps2_outputs)}, + {cs1_source, "cs_5_0", false, NULL, 0, NULL, 0}, + }; + + for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) + { + vkd3d_test_push_context("Test %u", i); + + code = compile_shader_flags(tests[i].source, tests[i].target, + tests[i].compat ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0); + + hr = D3DReflect(ID3D10Blob_GetBufferPointer(code), ID3D10Blob_GetBufferSize(code), + &IID_ID3D12ShaderReflection, (void **)&reflection); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + hr = reflection->lpVtbl->GetDesc(reflection, &shader_desc); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(shader_desc.InputParameters == tests[i].input_count, + "Got %u input parameters.\n", shader_desc.InputParameters); + ok(shader_desc.OutputParameters == tests[i].output_count, + "Got %u output parameters.\n", shader_desc.OutputParameters); + + for (unsigned int j = 0; j < shader_desc.InputParameters; ++j) + { + vkd3d_test_push_context("Input %u", j); + hr = reflection->lpVtbl->GetInputParameterDesc(reflection, j, &desc); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + check_signature_element(&desc, &tests[i].inputs[j]); + vkd3d_test_pop_context(); + } + + for (unsigned int j = 0; j < shader_desc.OutputParameters; ++j) + { + vkd3d_test_push_context("Output %u", j); + hr = reflection->lpVtbl->GetOutputParameterDesc(reflection, j, &desc); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + check_signature_element(&desc, &tests[i].outputs[j]); + vkd3d_test_pop_context(); + } + + ID3D10Blob_Release(code); + refcount = reflection->lpVtbl->Release(reflection); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + + vkd3d_test_pop_context(); + } +} + START_TEST(hlsl_d3d12) { parse_args(argc, argv); @@ -1326,4 +1523,5 @@ START_TEST(hlsl_d3d12) run_test(test_thread_id); run_test(test_create_blob); run_test(test_get_blob_part); + run_test(test_signature_reflection); }
Unlike previous vkd3d-utils interfaces, ID3D12ShaderReflection is rather more large and complex, and will probably end up needing several new individual scan interfaces from vkd3d-shader, which are themselves not exactly trivial to design.
Therefore, instead of implementing everything in vkd3d-shader and then hooking up the vkd3d-utils interfaces on top of that, this patch series copies the existing implementation of reflection and then begins the process of moving its implementation to vkd3d-shader.
The primary motivation here is to add reflection crosstests (primarily for the benefit of the HLSL compiler) without being blocked on API design. Part 2 of this patch series does this.
Are we going to need much more than input and output signatures from D3DReflect()? If not, it seems a fair bit easier to just add some helpers which use either vkd3d_shader_scan() or D3DReflect() for that to d3d12_crosstest.h.
Also, note that this currently fails on the CI.
Are we going to need much more than input and output signatures from D3DReflect()? If not, it seems a fair bit easier to just add some helpers which use either vkd3d_shader_scan() or D3DReflect() for that to d3d12_crosstest.h.
I would like to be able to test signatures, constant buffers, and resources. (That's most of ID3D12ShaderReflection; the other part is basically the STAT chunk, which we currently don't even output.) Signatures is vkd3d_shader_scan_signature_info; resources should be vkd3d_shader_scan_descriptor_info1 (plus I think a couple of extra patches I have). The hard part is constant buffers; I've basically tried to design the interface several times and always been put off by how complex it gets. Still, perhaps the best thing to do is figure it out now anyway...