From 36fca5207d6d73b57def9d19bf248f83b6503404 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Sat, 1 Nov 2025 13:36:10 -0700 Subject: [PATCH] Update for latest D3DX12 --- Common/d3dx12.h | 847 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 658 insertions(+), 189 deletions(-) diff --git a/Common/d3dx12.h b/Common/d3dx12.h index ea091244..f67a8ac1 100644 --- a/Common/d3dx12.h +++ b/Common/d3dx12.h @@ -4365,6 +4365,88 @@ struct CD3DX12_PIPELINE_STATE_STREAM5_PARSE_HELPER : public ID3DX12PipelineParse }; #endif // D3D12_SDK_VERSION >= 610 +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618) +struct CD3DX12_PIPELINE_STATE_STREAM6_PARSE_HELPER : public ID3DX12PipelineParserCallbacks +{ + CD3DX12_PIPELINE_STATE_STREAM6 PipelineStream; + CD3DX12_PIPELINE_STATE_STREAM6_PARSE_HELPER() noexcept + : SeenDSS(false), + SeenMS(false), + SeenTopology(false) + { + // Adjust defaults to account for absent members. + PipelineStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + + // Depth disabled if no DSV format specified. + static_cast(PipelineStream.DepthStencilState).DepthEnable = false; + } + + // ID3DX12PipelineParserCallbacks + void FlagsCb(D3D12_PIPELINE_STATE_FLAGS Flags) override { PipelineStream.Flags = Flags; } + void NodeMaskCb(UINT NodeMask) override { PipelineStream.NodeMask = NodeMask; } + void RootSignatureCb(ID3D12RootSignature* pRootSignature) override { PipelineStream.pRootSignature = pRootSignature; } + void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC& InputLayout) override { PipelineStream.InputLayout = InputLayout; } + void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) override { PipelineStream.IBStripCutValue = IBStripCutValue; } + void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType) override + { + PipelineStream.PrimitiveTopologyType = PrimitiveTopologyType; + SeenTopology = true; + } + void VSCb(const D3D12_SHADER_BYTECODE& VS) override { PipelineStream.VS = VS; } + void GSCb(const D3D12_SHADER_BYTECODE& GS) override { PipelineStream.GS = GS; } + void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC& StreamOutput) override { PipelineStream.StreamOutput = StreamOutput; } + void HSCb(const D3D12_SHADER_BYTECODE& HS) override { PipelineStream.HS = HS; } + void DSCb(const D3D12_SHADER_BYTECODE& DS) override { PipelineStream.DS = DS; } + void PSCb(const D3D12_SHADER_BYTECODE& PS) override { PipelineStream.PS = PS; } + void CSCb(const D3D12_SHADER_BYTECODE& CS) override { PipelineStream.CS = CS; } + void ASCb(const D3D12_SHADER_BYTECODE& AS) override { PipelineStream.AS = AS; } + void MSCb(const D3D12_SHADER_BYTECODE& MS) override { PipelineStream.MS = MS; SeenMS = true; } + void BlendStateCb(const D3D12_BLEND_DESC& BlendState) override { PipelineStream.BlendState = CD3DX12_BLEND_DESC(BlendState); } + void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC2(DepthStencilState); + SeenDSS = true; + } + void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC2(DepthStencilState); + SeenDSS = true; + } + void DepthStencilState2Cb(const D3D12_DEPTH_STENCIL_DESC2& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC2(DepthStencilState); + SeenDSS = true; + } + void DSVFormatCb(DXGI_FORMAT DSVFormat) override { PipelineStream.DSVFormat = DSVFormat; } + void RasterizerStateCb(const D3D12_RASTERIZER_DESC& RasterizerState) override { PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC2(RasterizerState); } + void RasterizerState1Cb(const D3D12_RASTERIZER_DESC1& RasterizerState) override { PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC2(RasterizerState); } + void RasterizerState2Cb(const D3D12_RASTERIZER_DESC2& RasterizerState) override { PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC2(RasterizerState); } + void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY& RTVFormats) override { PipelineStream.RTVFormats = RTVFormats; } + void SampleDescCb(const DXGI_SAMPLE_DESC& SampleDesc) override { PipelineStream.SampleDesc = SampleDesc; } + void SampleMaskCb(UINT SampleMask) override { PipelineStream.SampleMask = SampleMask; } + void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC& ViewInstancingDesc) override { PipelineStream.ViewInstancingDesc = CD3DX12_VIEW_INSTANCING_DESC(ViewInstancingDesc); } + void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE& CachedPSO) override { PipelineStream.CachedPSO = CachedPSO; } + void FinalizeCb() override + { + if (!SeenDSS && PipelineStream.DSVFormat != DXGI_FORMAT_UNKNOWN) + { + // Re-enable depth for the default state. + static_cast(PipelineStream.DepthStencilState).DepthEnable = true; + } + if (!SeenTopology && SeenMS) + { + PipelineStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED; + } + } + void SerializedRootSignatureCb(const D3D12_SERIALIZED_ROOT_SIGNATURE_DESC& SerializedRootSignature) override { PipelineStream.SerializedRootSignature = CD3DX12_SERIALIZED_ROOT_SIGNATURE_DESC(SerializedRootSignature); } + +private: + bool SeenDSS; + bool SeenMS; + bool SeenTopology; +}; +#endif // D3D12_SDK_VERSION >= 618 + struct CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER : public ID3DX12PipelineParserCallbacks { CD3DX12_PIPELINE_STATE_STREAM1 PipelineStream; @@ -4591,6 +4673,12 @@ inline HRESULT D3DX12ParsePipelineStream(const D3D12_PIPELINE_STATE_STREAM_DESC& pCallbacks->ViewInstancingCb(*reinterpret_cast(pStream)); SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM1::ViewInstancingDesc); break; +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618) + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SERIALIZED_ROOT_SIGNATURE: + pCallbacks->SerializedRootSignatureCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM6::SerializedRootSignature); + break; +#endif default: pCallbacks->ErrorUnknownSubobject(SubobjectType); return E_INVALIDARG; @@ -4750,12 +4838,6 @@ class CD3DX12_STATE_OBJECT_DESC CD3DX12_STATE_OBJECT_DESC& operator=(CD3DX12_STATE_OBJECT_DESC&& other) = default; operator const D3D12_STATE_OBJECT_DESC& () { - // Do final preparation work - for (auto& ownedSubobject : m_OwnedSubobjectHelpers) - { - ownedSubobject->Finalize(); - } - #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) m_RepointedSubobjectVectors.clear(); m_RepointedPrograms.clear(); @@ -4855,6 +4937,14 @@ class CD3DX12_STATE_OBJECT_DESC return pSubobject; } + template + T* CreateSubobject(U&& arg) + { + T* pSubobject = new T(std::forward(arg), *this); + m_OwnedSubobjectHelpers.emplace_back(pSubobject); + return pSubobject; + } + private: D3D12_STATE_SUBOBJECT* TrackSubobject(D3D12_STATE_SUBOBJECT_TYPE Type, void* pDesc) { @@ -4944,7 +5034,6 @@ class CD3DX12_STATE_OBJECT_DESC { m_pSubobject = ContainingStateObject.TrackSubobject(Type(), Data()); } - virtual void Finalize() {}; operator const D3D12_STATE_SUBOBJECT& () const noexcept { return *m_pSubobject; } protected: virtual void* Data() noexcept = 0; @@ -4988,12 +5077,19 @@ class CD3DX12_STATE_OBJECT_DESC friend class CD3DX12_DEPTH_STENCIL1_SUBOBJECT; friend class CD3DX12_SAMPLE_MASK_SUBOBJECT; friend class CD3DX12_NODE_OUTPUT_OVERRIDES; + friend class CD3DX12_NODE_HELPER_BASE; friend class CD3DX12_SHADER_NODE; friend class CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES; friend class CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES; friend class CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES; friend class CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES; #endif // D3D12_SDK_VERSION >= 612 +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618) + friend class CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT; + friend class CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT; + friend class CD3DX12_COMPILER_EXISTING_COLLECTION_SUBOBJECT; + friend class CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT; +#endif }; //------------------------------------------------------------------------------------------------ @@ -5327,10 +5423,23 @@ class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT { public: CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT() noexcept + : m_Desc({}) { Init(); } CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_SHADER_CONFIG &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_SHADER_CONFIG &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5349,11 +5458,11 @@ class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; } operator const D3D12_RAYTRACING_SHADER_CONFIG&() const noexcept { return m_Desc; } + operator D3D12_RAYTRACING_SHADER_CONFIG&() noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_RAYTRACING_SHADER_CONFIG m_Desc; @@ -5365,10 +5474,23 @@ class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT { public: CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT() noexcept + : m_Desc({}) { Init(); } CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5386,11 +5508,11 @@ class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG; } operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const noexcept { return m_Desc; } + operator D3D12_RAYTRACING_PIPELINE_CONFIG&() noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_RAYTRACING_PIPELINE_CONFIG m_Desc; @@ -5402,10 +5524,23 @@ class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT { public: CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT() noexcept + : m_Desc({}) { Init(); } CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG1 &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG1 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5424,11 +5559,11 @@ class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1; } operator const D3D12_RAYTRACING_PIPELINE_CONFIG1&() const noexcept { return m_Desc; } + operator D3D12_RAYTRACING_PIPELINE_CONFIG1&() noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_RAYTRACING_PIPELINE_CONFIG1 m_Desc; @@ -5471,6 +5606,7 @@ class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT D3DX12_COM_PTR m_pRootSig; }; + //------------------------------------------------------------------------------------------------ class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE @@ -5508,16 +5644,197 @@ class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT D3DX12_COM_PTR m_pRootSig; }; +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618) +//------------------------------------------------------------------------------------------------ +class CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT() noexcept + : m_Desc({}) + { + Init(); + } + CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(const CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete; + CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(const CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete; + CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default; + CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default; + void SetRootSignature(const D3D12_SERIALIZED_ROOT_SIGNATURE_DESC* pDesc) noexcept + { + if (pDesc) + { + m_Desc.Desc = {}; + m_Desc.Desc.pSerializedBlob = pDesc->pSerializedBlob; + m_Desc.Desc.SerializedBlobSizeInBytes = pDesc->SerializedBlobSizeInBytes; + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_SERIALIZED_ROOT_SIGNATURE; + } + operator const D3D12_GLOBAL_SERIALIZED_ROOT_SIGNATURE&() const noexcept { return m_Desc; } + operator D3D12_GLOBAL_SERIALIZED_ROOT_SIGNATURE&() noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_GLOBAL_SERIALIZED_ROOT_SIGNATURE m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT() noexcept + : m_Desc({}) + { + Init(); + } + CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(const CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete; + CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(const CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete; + CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default; + CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default; + void SetRootSignature(const D3D12_SERIALIZED_ROOT_SIGNATURE_DESC* pDesc) noexcept + { + if (pDesc) + { + m_Desc.Desc = {}; + m_Desc.Desc.pSerializedBlob = pDesc->pSerializedBlob; + m_Desc.Desc.SerializedBlobSizeInBytes = pDesc->SerializedBlobSizeInBytes; + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_SERIALIZED_ROOT_SIGNATURE; + } + operator const D3D12_LOCAL_SERIALIZED_ROOT_SIGNATURE&() const noexcept { return m_Desc; } + operator D3D12_LOCAL_SERIALIZED_ROOT_SIGNATURE&() noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_LOCAL_SERIALIZED_ROOT_SIGNATURE m_Desc; +}; + + +//------------------------------------------------------------------------------------------------ +class CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT(const CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& other) = delete; + CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& operator=(const CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& other) = delete; + CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT(CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT&& other) = default; + CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& operator=(CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT&& other) = default; + void SetExistingCollection(const void* pKey, UINT KeySize) noexcept + { + const unsigned char* pKeyBytes = static_cast(pKey); + m_Key.clear(); + m_Key.insert(m_Key.begin(), pKeyBytes, pKeyBytes + KeySize); + m_Desc.pKey = m_Key.data(); + m_Desc.KeySize = KeySize; + } + void DefineExport( + LPCWSTR Name, + LPCWSTR ExportToRename = nullptr, + D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) + { + D3D12_EXPORT_DESC Export; + Export.Name = m_Strings.LocalCopy(Name); + Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); + Export.Flags = Flags; + m_Exports.push_back(Export); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + m_Desc.NumExports = static_cast(m_Exports.size()); + } + template + void DefineExports(LPCWSTR(&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + void DefineExports(const LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION_BY_KEY; + } + operator const D3D12_EXISTING_COLLECTION_BY_KEY_DESC&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_EXISTING_COLLECTION_BY_KEY_DESC m_Desc; + std::vector m_Key; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +#endif // defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618) + //------------------------------------------------------------------------------------------------ class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE { public: CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT() noexcept + : m_Desc({}) { Init(); } CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(const D3D12_STATE_OBJECT_CONFIG &desc) noexcept + : m_Desc(desc) + { + Init(); + } + CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(const D3D12_STATE_OBJECT_CONFIG &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5535,11 +5852,11 @@ class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG; } operator const D3D12_STATE_OBJECT_CONFIG&() const noexcept { return m_Desc; } + operator D3D12_STATE_OBJECT_CONFIG&() noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_STATE_OBJECT_CONFIG m_Desc; @@ -5551,10 +5868,23 @@ class CD3DX12_NODE_MASK_SUBOBJECT { public: CD3DX12_NODE_MASK_SUBOBJECT() noexcept + : m_Desc({}) { Init(); } CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_NODE_MASK_SUBOBJECT(const D3D12_NODE_MASK &desc) noexcept + : m_Desc(desc) + { + Init(); + } + CD3DX12_NODE_MASK_SUBOBJECT(const D3D12_NODE_MASK &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5572,11 +5902,11 @@ class CD3DX12_NODE_MASK_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK; } operator const D3D12_NODE_MASK&() const noexcept { return m_Desc; } + operator D3D12_NODE_MASK&() noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_NODE_MASK m_Desc; @@ -5597,6 +5927,20 @@ class CD3DX12_STREAM_OUTPUT_SUBOBJECT Init(); AddToStateObject(ContainingStateObject); } + void AddSODeclEntry(const D3D12_SO_DECLARATION_ENTRY &entry) + { + m_soDecalEntries.emplace_back(D3D12_SO_DECLARATION_ENTRY{ + entry.Stream, + m_Strings.LocalCopy(entry.SemanticName), + entry.SemanticIndex, + entry.StartComponent, + entry.ComponentCount, + entry.OutputSlot + }); + m_Desc.NumEntries++; + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.pSODeclaration = &m_soDecalEntries[0]; + } void SetSODeclEntries(const D3D12_SO_DECLARATION_ENTRY* soDeclEntries, UINT numEntries) { m_soDecalEntries.resize(numEntries); @@ -5611,13 +5955,20 @@ class CD3DX12_STREAM_OUTPUT_SUBOBJECT soDeclEntries[i].OutputSlot }; } - // Below: using ugly way to get pointer in case .data() is not defined - m_Desc.pSODeclaration = &m_soDecalEntries[0]; m_Desc.NumEntries = numEntries; + // Below: using ugly way to get pointer in case .data() is not defined + if (numEntries > 0) + { + m_Desc.pSODeclaration = &m_soDecalEntries[0]; + } } void SetBufferStrides(const UINT* bufferStrides, UINT numStrides) { - m_Desc.pBufferStrides = bufferStrides; + for (UINT i = 0; i < numStrides; ++i) + { + m_Strides[i] = bufferStrides[i]; + } + m_Desc.pBufferStrides = m_Strides; m_Desc.NumStrides = numStrides; } void SetRasterizedStream(UINT rasterizedStream) @@ -5640,6 +5991,7 @@ class CD3DX12_STREAM_OUTPUT_SUBOBJECT D3D12_STREAM_OUTPUT_DESC m_Desc; CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::vector m_soDecalEntries; + UINT m_Strides[D3D12_SO_STREAM_COUNT]; }; //------------------------------------------------------------------------------------------------ @@ -5648,10 +6000,23 @@ class CD3DX12_BLEND_SUBOBJECT { public: CD3DX12_BLEND_SUBOBJECT() + : m_Desc(CD3DX12_BLEND_DESC(D3D12_DEFAULT)) { Init(); } CD3DX12_BLEND_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(CD3DX12_BLEND_DESC(D3D12_DEFAULT)) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_BLEND_SUBOBJECT(const D3D12_BLEND_DESC &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_BLEND_SUBOBJECT(const D3D12_BLEND_DESC &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5682,11 +6047,11 @@ class CD3DX12_BLEND_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_BLEND; } operator const D3D12_BLEND_DESC& () const noexcept { return m_Desc; } + operator D3D12_BLEND_DESC& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = CD3DX12_BLEND_DESC(D3D12_DEFAULT); } void* Data() noexcept override { return &m_Desc; } CD3DX12_BLEND_DESC m_Desc; @@ -5698,10 +6063,23 @@ class CD3DX12_RASTERIZER_SUBOBJECT { public: CD3DX12_RASTERIZER_SUBOBJECT() + : m_Desc(CD3DX12_RASTERIZER_DESC2(D3D12_DEFAULT)) { Init(); } CD3DX12_RASTERIZER_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(CD3DX12_RASTERIZER_DESC2(D3D12_DEFAULT)) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_RASTERIZER_SUBOBJECT(const D3D12_RASTERIZER_DESC2 &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_RASTERIZER_SUBOBJECT(const D3D12_RASTERIZER_DESC2 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5751,11 +6129,11 @@ class CD3DX12_RASTERIZER_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_RASTERIZER; } operator const D3D12_RASTERIZER_DESC2& () const noexcept { return m_Desc; } + operator D3D12_RASTERIZER_DESC2& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = CD3DX12_RASTERIZER_DESC2(D3D12_DEFAULT); } void* Data() noexcept override { return &m_Desc; } CD3DX12_RASTERIZER_DESC2 m_Desc; @@ -5767,10 +6145,23 @@ class CD3DX12_DEPTH_STENCIL2_SUBOBJECT { public: CD3DX12_DEPTH_STENCIL2_SUBOBJECT() + : m_Desc(CD3DX12_DEPTH_STENCIL_DESC2(D3D12_DEFAULT)) { Init(); } CD3DX12_DEPTH_STENCIL2_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(CD3DX12_DEPTH_STENCIL_DESC2(D3D12_DEFAULT)) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_DEPTH_STENCIL2_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC2 &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_DEPTH_STENCIL2_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC2 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5822,11 +6213,11 @@ class CD3DX12_DEPTH_STENCIL2_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL2; } operator const D3D12_DEPTH_STENCIL_DESC2& () const noexcept { return m_Desc; } + operator D3D12_DEPTH_STENCIL_DESC2& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = CD3DX12_DEPTH_STENCIL_DESC2(D3D12_DEFAULT); } void* Data() noexcept override { return &m_Desc; } CD3DX12_DEPTH_STENCIL_DESC2 m_Desc; @@ -5858,43 +6249,25 @@ class CD3DX12_INPUT_LAYOUT_SUBOBJECT inputLayoutElementDesc.InputSlotClass, inputLayoutElementDesc.InstanceDataStepRate }); - ++m_numElements; + ++m_Desc.NumElements; + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.pInputElementDescs = &m_inputLayoutElements[0]; } D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override { return D3D12_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT; } operator const D3D12_INPUT_LAYOUT_DESC& () const noexcept { return m_Desc; } - virtual void Finalize() override - { - if (m_numElements > 0) - { - std::list::iterator inputLayoutIt = m_inputLayoutElements.begin(); - m_inputLayoutElementsVector.resize(m_numElements); - for (UINT i = 0; inputLayoutIt != m_inputLayoutElements.end(); i++, inputLayoutIt++) - { - m_inputLayoutElementsVector[i] = *inputLayoutIt; - } - // Below: using ugly way to get pointer in case .data() is not defined - m_Desc.pInputElementDescs = &m_inputLayoutElementsVector[0]; - } - m_Desc.NumElements = m_numElements; - } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); m_Desc = {}; - m_Desc.pInputElementDescs = nullptr; - m_numElements = 0; m_inputLayoutElements.clear(); - m_inputLayoutElementsVector.clear(); } void* Data() noexcept override { return &m_Desc; } D3D12_INPUT_LAYOUT_DESC m_Desc; - std::list m_inputLayoutElements; - std::vector m_inputLayoutElementsVector; - UINT m_numElements; + std::vector m_inputLayoutElements; CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; }; @@ -5904,10 +6277,23 @@ class CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT { public: CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT() + : m_Desc(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED) { Init(); } CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5921,6 +6307,7 @@ class CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE; } operator const D3D12_INDEX_BUFFER_STRIP_CUT_VALUE& () const noexcept { return m_Desc; } + operator D3D12_INDEX_BUFFER_STRIP_CUT_VALUE& () noexcept { return m_Desc; } private: void Init() noexcept { @@ -5936,10 +6323,23 @@ class CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT { public: CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT() + : m_Desc(D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED) { Init(); } CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(D3D12_PRIMITIVE_TOPOLOGY_TYPE desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(D3D12_PRIMITIVE_TOPOLOGY_TYPE desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5953,6 +6353,7 @@ class CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY; } operator const D3D12_PRIMITIVE_TOPOLOGY_TYPE& () const noexcept { return m_Desc; } + operator D3D12_PRIMITIVE_TOPOLOGY_TYPE& () noexcept { return m_Desc; } private: void Init() noexcept { @@ -5968,10 +6369,23 @@ class CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT { public: CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT() + : m_Desc({}) { Init(); } CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(const D3D12_RT_FORMAT_ARRAY &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(const D3D12_RT_FORMAT_ARRAY &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -5989,11 +6403,11 @@ class CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS; } operator const D3D12_RT_FORMAT_ARRAY& () const noexcept { return m_Desc; } + operator D3D12_RT_FORMAT_ARRAY& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_RT_FORMAT_ARRAY m_Desc; @@ -6005,10 +6419,23 @@ class CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT { public: CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT() + : m_Desc(DXGI_FORMAT_UNKNOWN) { Init(); } CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(DXGI_FORMAT_UNKNOWN) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(DXGI_FORMAT desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(DXGI_FORMAT desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -6022,6 +6449,7 @@ class CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT; } operator const DXGI_FORMAT& () const noexcept { return m_Desc; } + operator DXGI_FORMAT& () noexcept { return m_Desc; } private: void Init() noexcept { @@ -6037,10 +6465,23 @@ class CD3DX12_SAMPLE_DESC_SUBOBJECT { public: CD3DX12_SAMPLE_DESC_SUBOBJECT() + : m_Desc({1, 0}) { Init(); } CD3DX12_SAMPLE_DESC_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc({1, 0}) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_SAMPLE_DESC_SUBOBJECT(const DXGI_SAMPLE_DESC &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_SAMPLE_DESC_SUBOBJECT(const DXGI_SAMPLE_DESC &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -6058,6 +6499,7 @@ class CD3DX12_SAMPLE_DESC_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_SAMPLE_DESC; } operator const DXGI_SAMPLE_DESC& () const noexcept { return m_Desc; } + operator DXGI_SAMPLE_DESC& () noexcept { return m_Desc; } private: void Init() noexcept { @@ -6074,10 +6516,23 @@ class CD3DX12_FLAGS_SUBOBJECT { public: CD3DX12_FLAGS_SUBOBJECT() + : m_Desc(D3D12_PIPELINE_STATE_FLAG_NONE) { Init(); } CD3DX12_FLAGS_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(D3D12_PIPELINE_STATE_FLAG_NONE) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_FLAGS_SUBOBJECT(D3D12_PIPELINE_STATE_FLAGS desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_FLAGS_SUBOBJECT(D3D12_PIPELINE_STATE_FLAGS desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -6091,11 +6546,11 @@ class CD3DX12_FLAGS_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_FLAGS; } operator const D3D12_PIPELINE_STATE_FLAGS& () const noexcept { return m_Desc; } + operator D3D12_PIPELINE_STATE_FLAGS& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = {}; } void* Data() noexcept override { return &m_Desc; } D3D12_PIPELINE_STATE_FLAGS m_Desc; @@ -6117,7 +6572,7 @@ class CD3DX12_VIEW_INSTANCING_SUBOBJECT } void AddViewInstanceLocation(D3D12_VIEW_INSTANCE_LOCATION viewInstanceLocation) { - m_viewInstanceCount++; + m_Desc.ViewInstanceCount++; m_viewInstanceLocations.emplace_back( D3D12_VIEW_INSTANCE_LOCATION { @@ -6125,6 +6580,8 @@ class CD3DX12_VIEW_INSTANCING_SUBOBJECT viewInstanceLocation.RenderTargetArrayIndex } ); + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.pViewInstanceLocations = &m_viewInstanceLocations[0]; } void SetFlags(D3D12_VIEW_INSTANCING_FLAGS flags) { @@ -6135,35 +6592,16 @@ class CD3DX12_VIEW_INSTANCING_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING; } operator const D3D12_VIEW_INSTANCING_DESC& () const noexcept { return m_Desc; } - virtual void Finalize() override - { - if (m_viewInstanceCount > 0) - { - m_viewInstanceLocationsVector.resize(m_viewInstanceCount); - std::list::iterator viewInstancingLocationIt = m_viewInstanceLocations.begin(); - for (UINT i = 0; viewInstancingLocationIt != m_viewInstanceLocations.end(); i++, viewInstancingLocationIt++) - { - m_viewInstanceLocationsVector[i] = *viewInstancingLocationIt; - } - // Below: using ugly way to get pointer in case .data() is not defined - m_Desc.pViewInstanceLocations = &m_viewInstanceLocationsVector[0]; - } - m_Desc.ViewInstanceCount = m_viewInstanceCount; - } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); m_Desc = CD3DX12_VIEW_INSTANCING_DESC(D3D12_DEFAULT); - m_viewInstanceCount = 0; m_viewInstanceLocations.clear(); - m_viewInstanceLocationsVector.clear(); } void* Data() noexcept override { return &m_Desc; } CD3DX12_VIEW_INSTANCING_DESC m_Desc; - UINT m_viewInstanceCount; - std::list m_viewInstanceLocations; - std::vector m_viewInstanceLocationsVector; + std::vector m_viewInstanceLocations; }; //------------------------------------------------------------------------------------------------ @@ -6172,10 +6610,23 @@ class CD3DX12_DEPTH_STENCIL_SUBOBJECT { public: CD3DX12_DEPTH_STENCIL_SUBOBJECT() + : m_Desc(CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT)) { Init(); } CD3DX12_DEPTH_STENCIL_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT)) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_DEPTH_STENCIL_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_DEPTH_STENCIL_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -6227,11 +6678,11 @@ class CD3DX12_DEPTH_STENCIL_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL; } operator const D3D12_DEPTH_STENCIL_DESC& () const noexcept { return m_Desc; } + operator D3D12_DEPTH_STENCIL_DESC& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); } void* Data() noexcept override { return &m_Desc; } CD3DX12_DEPTH_STENCIL_DESC m_Desc; @@ -6243,10 +6694,23 @@ class CD3DX12_DEPTH_STENCIL1_SUBOBJECT { public: CD3DX12_DEPTH_STENCIL1_SUBOBJECT() + : m_Desc(CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEFAULT)) { Init(); } CD3DX12_DEPTH_STENCIL1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEFAULT)) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_DEPTH_STENCIL1_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC1 &desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_DEPTH_STENCIL1_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC1 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -6302,11 +6766,11 @@ class CD3DX12_DEPTH_STENCIL1_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1; } operator const D3D12_DEPTH_STENCIL_DESC1& () const noexcept { return m_Desc; } + operator D3D12_DEPTH_STENCIL_DESC1& () noexcept { return m_Desc; } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); - m_Desc = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEFAULT); } void* Data() noexcept override { return &m_Desc; } CD3DX12_DEPTH_STENCIL_DESC1 m_Desc; @@ -6318,10 +6782,23 @@ class CD3DX12_SAMPLE_MASK_SUBOBJECT { public: CD3DX12_SAMPLE_MASK_SUBOBJECT() + : m_Desc(0xffffffffu) { Init(); } CD3DX12_SAMPLE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(0xffffffffu) + { + Init(); + AddToStateObject(ContainingStateObject); + } + CD3DX12_SAMPLE_MASK_SUBOBJECT(UINT desc) + : m_Desc(desc) + { + Init(); + } + CD3DX12_SAMPLE_MASK_SUBOBJECT(UINT desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + : m_Desc(desc) { Init(); AddToStateObject(ContainingStateObject); @@ -6335,6 +6812,7 @@ class CD3DX12_SAMPLE_MASK_SUBOBJECT return D3D12_STATE_SUBOBJECT_TYPE_SAMPLE_MASK; } operator const UINT& () const noexcept { return m_Desc; } + operator UINT& () noexcept { return m_Desc; } private: void Init() noexcept { @@ -6365,72 +6843,32 @@ class CD3DX12_GENERIC_PROGRAM_SUBOBJECT void AddExport(LPCWSTR exportName) { m_Exports.emplace_back(m_Strings.LocalCopy(exportName)); - m_numExports++; + m_Desc.NumExports++; + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.pExports = &m_Exports[0]; } void AddSubobject(const D3D12_STATE_SUBOBJECT& subobject) { m_Subobjects.emplace_back(&subobject); - m_numSubobjects++; + m_Desc.NumSubobjects++; + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.ppSubobjects = &m_Subobjects[0]; } D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override { return D3D12_STATE_SUBOBJECT_TYPE_GENERIC_PROGRAM; } operator const D3D12_GENERIC_PROGRAM_DESC& () const noexcept { return m_Desc; } - virtual void Finalize() override - { - // Set exports - if (m_numExports > 0) - { - m_ExportsVector.resize(m_numExports); - std::list::iterator exportIt = m_Exports.begin(); - for (UINT i = 0; exportIt != m_Exports.end(); i++, exportIt++) - { - m_ExportsVector[i] = *exportIt; - } - // Below: using ugly way to get pointer in case .data() is not defined - m_Desc.pExports = &m_ExportsVector[0]; - } - else - { - m_Desc.pExports = nullptr; - } - m_Desc.NumExports = m_numExports; - - // Set subobjects - if (m_numSubobjects > 0) - { - m_SubobjectsVector.resize(m_numSubobjects); - std::list::iterator subobjectIt = m_Subobjects.begin(); - for (UINT i = 0; subobjectIt != m_Subobjects.end(); i++, subobjectIt++) - { - m_SubobjectsVector[i] = *subobjectIt; - } - // Below: using ugly way to get pointer in case .data() is not defined - m_Desc.ppSubobjects = &m_SubobjectsVector[0]; - } - else - { - m_Desc.ppSubobjects = nullptr; - } - m_Desc.NumSubobjects = m_numSubobjects; - } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); m_Desc = {}; - m_numExports = 0; - m_numSubobjects = 0; } void* Data() noexcept override { return &m_Desc; } D3D12_GENERIC_PROGRAM_DESC m_Desc; - std::list m_Exports; - std::vector m_ExportsVector; - UINT m_numExports; - std::list m_Subobjects; - std::vector m_SubobjectsVector; - UINT m_numSubobjects; + std::vector m_Exports; + std::vector m_Subobjects; CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; }; @@ -6486,11 +6924,28 @@ class CD3DX12_NODE_OUTPUT_OVERRIDES UINT* m_pNumOutputOverrides; }; +//------------------------------------------------------------------------------------------------ +class CD3DX12_WORK_GRAPH_SUBOBJECT; + //------------------------------------------------------------------------------------------------ class CD3DX12_NODE_HELPER_BASE { +protected: + struct Backreference + { + CD3DX12_WORK_GRAPH_SUBOBJECT *m_pGraph; + UINT m_NodeIndex; + }; public: + CD3DX12_NODE_HELPER_BASE(const Backreference &BackRef) + : m_BackRef(BackRef) + { + } virtual ~CD3DX12_NODE_HELPER_BASE() = default; +protected: + D3D12_NODE *GetNode() const; + const Backreference m_BackRef; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; }; //------------------------------------------------------------------------------------------------ @@ -6500,22 +6955,25 @@ class CD3DX12_SHADER_NODE // Not specifying launch mode. { public: CD3DX12_SHADER_NODE( - D3D12_NODE* pNode, + const Backreference &BackRef, LPCWSTR _Shader = nullptr) + : CD3DX12_NODE_HELPER_BASE(BackRef) { - m_pDesc = pNode; - m_pDesc->NodeType = D3D12_NODE_TYPE_SHADER; + GetNode()->NodeType = D3D12_NODE_TYPE_SHADER; Shader(_Shader); } void Shader(LPCWSTR _Shader) { - m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader); } - D3D12_NODE* m_pDesc; -private: - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; } }; +#endif // D3D12_SDK_VERSION >= 612 + + +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + //------------------------------------------------------------------------------------------------ // Use this class when defining a broadcasting launch node where configuration parameters // need to be overridden. If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE @@ -6524,21 +6982,23 @@ class CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES { public: CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES( - D3D12_NODE* pNode, + const Backreference &BackRef, LPCWSTR _Shader = nullptr) : - m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) + CD3DX12_NODE_HELPER_BASE(BackRef), + m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) { Overrides = {}; - m_pDesc = pNode; - m_pDesc->NodeType = D3D12_NODE_TYPE_SHADER; - m_pDesc->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_BROADCASTING_LAUNCH; - m_pDesc->Shader.pBroadcastingLaunchOverrides = &Overrides; + D3D12_NODE *pNode = GetNode(); + pNode->NodeType = D3D12_NODE_TYPE_SHADER; + pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_BROADCASTING_LAUNCH; + pNode->Shader.pBroadcastingLaunchOverrides = &Overrides; Shader(_Shader); } void Shader(LPCWSTR _Shader) { - m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader); } + LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; } void LocalRootArgumentsTableIndex(UINT index) { m_UINTs.emplace_front(index); @@ -6574,10 +7034,8 @@ class CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES return m_NodeOutputOverrides; } D3D12_BROADCASTING_LAUNCH_OVERRIDES Overrides; - D3D12_NODE* m_pDesc; private: // Cached parameters - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::forward_list m_UINTs; struct UINT3 { @@ -6598,21 +7056,23 @@ class CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES { public: CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES( - D3D12_NODE* pNode, + const Backreference &BackRef, LPCWSTR _Shader = nullptr) : - m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) + CD3DX12_NODE_HELPER_BASE(BackRef), + m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) { Overrides = {}; - m_pDesc = pNode; - m_pDesc->NodeType = D3D12_NODE_TYPE_SHADER; - m_pDesc->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_COALESCING_LAUNCH; - m_pDesc->Shader.pCoalescingLaunchOverrides = &Overrides; + D3D12_NODE *pNode = GetNode(); + pNode->NodeType = D3D12_NODE_TYPE_SHADER; + pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_COALESCING_LAUNCH; + pNode->Shader.pCoalescingLaunchOverrides = &Overrides; Shader(_Shader); } void Shader(LPCWSTR _Shader) { - m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader); } + LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; } void LocalRootArgumentsTableIndex(UINT index) { m_UINTs.emplace_front(index); @@ -6638,10 +7098,8 @@ class CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES return m_NodeOutputOverrides; } D3D12_COALESCING_LAUNCH_OVERRIDES Overrides; - D3D12_NODE* m_pDesc; private: // Cached parameters - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::forward_list m_UINTs; struct UINT3 { @@ -6662,21 +7120,23 @@ class CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES { public: CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES( - D3D12_NODE* pNode, + const Backreference &BackRef, LPCWSTR _Shader = nullptr) : - m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) + CD3DX12_NODE_HELPER_BASE(BackRef), + m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) { Overrides = {}; - m_pDesc = pNode; - m_pDesc->NodeType = D3D12_NODE_TYPE_SHADER; - m_pDesc->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_THREAD_LAUNCH; - m_pDesc->Shader.pThreadLaunchOverrides = &Overrides; + D3D12_NODE *pNode = GetNode(); + pNode->NodeType = D3D12_NODE_TYPE_SHADER; + pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_THREAD_LAUNCH; + pNode->Shader.pThreadLaunchOverrides = &Overrides; Shader(_Shader); } void Shader(LPCWSTR _Shader) { - m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader); } + LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; } void LocalRootArgumentsTableIndex(UINT index) { m_UINTs.emplace_front(index); @@ -6702,10 +7162,8 @@ class CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES return m_NodeOutputOverrides; } D3D12_THREAD_LAUNCH_OVERRIDES Overrides; - D3D12_NODE* m_pDesc; private: // Cached parameters - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::forward_list m_UINTs; std::forward_list m_NodeIDs; CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides; @@ -6722,21 +7180,23 @@ class CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES { public: CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES( - D3D12_NODE* pNode, + const Backreference &BackRef, LPCWSTR _Shader = nullptr) : - m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) + CD3DX12_NODE_HELPER_BASE(BackRef), + m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides) { Overrides = {}; - m_pDesc = pNode; - m_pDesc->NodeType = D3D12_NODE_TYPE_SHADER; - m_pDesc->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_COMMON_COMPUTE; - m_pDesc->Shader.pThreadLaunchOverrides = &Overrides; + D3D12_NODE *pNode = GetNode(); + pNode->NodeType = D3D12_NODE_TYPE_SHADER; + pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_COMMON_COMPUTE; + pNode->Shader.pThreadLaunchOverrides = &Overrides; Shader(_Shader); } void Shader(LPCWSTR _Shader) { - m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader); } + LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; } void LocalRootArgumentsTableIndex(UINT index) { m_UINTs.emplace_front(index); @@ -6762,10 +7222,8 @@ class CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES return m_NodeOutputOverrides; } D3D12_THREAD_LAUNCH_OVERRIDES Overrides; - D3D12_NODE* m_pDesc; private: // Cached parameters - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::forward_list m_UINTs; std::forward_list m_NodeIDs; CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides; @@ -6793,6 +7251,8 @@ class CD3DX12_WORK_GRAPH_SUBOBJECT { m_Desc.Flags |= D3D12_WORK_GRAPH_FLAG_INCLUDE_ALL_AVAILABLE_NODES; } + + void SetProgramName(LPCWSTR ProgramName) { m_Desc.ProgramName = m_Strings.LocalCopy(ProgramName); @@ -6800,15 +7260,17 @@ class CD3DX12_WORK_GRAPH_SUBOBJECT void AddEntrypoint(D3D12_NODE_ID Entrypoint) { m_Entrypoints.emplace_back(D3D12_NODE_ID{ m_Strings.LocalCopy(Entrypoint.Name),Entrypoint.ArrayIndex }); - m_NumEntrypoints++; + m_Desc.NumEntrypoints++; + m_Desc.pEntrypoints = m_Entrypoints.data(); } template T* CreateNode() { m_NodeDescs.push_back({}); - m_NumNodes++; - T* pNodeHelper = new T(&m_NodeDescs.back()); + m_Desc.NumExplicitlyDefinedNodes++; + m_Desc.pExplicitlyDefinedNodes = m_NodeDescs.data(); + T* pNodeHelper = new T({this, (UINT)m_NodeDescs.size() - 1}); m_OwnedNodeHelpers.emplace_back(pNodeHelper); return pNodeHelper; } @@ -6842,51 +7304,36 @@ class CD3DX12_WORK_GRAPH_SUBOBJECT pNode->Shader(Shader); return pNode; } +#endif // D3D12_SDK_VERSION >= 612 + + +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + operator const D3D12_WORK_GRAPH_DESC& () noexcept { return m_Desc; } - virtual void Finalize() override - { - m_EntrypointsVector.resize(m_NumEntrypoints); - std::list::iterator entryIt = m_Entrypoints.begin(); - for (UINT n = 0; n < m_NumEntrypoints; n++, entryIt++) - { - m_EntrypointsVector[n] = *entryIt; - } - m_Desc.NumEntrypoints = m_NumEntrypoints; - m_Desc.pEntrypoints = m_EntrypointsVector.data(); - - m_NodeDescsVector.resize(m_NumNodes); - std::list::iterator nodeIt = m_NodeDescs.begin(); - for (UINT n = 0; n < m_NumNodes; n++, nodeIt++) - { - m_NodeDescsVector[n] = *nodeIt; - } - m_Desc.NumExplicitlyDefinedNodes = m_NumNodes; - m_Desc.pExplicitlyDefinedNodes = m_NodeDescsVector.data(); - } private: void Init() noexcept { SUBOBJECT_HELPER_BASE::Init(); m_Desc = {}; + m_Entrypoints.clear(); m_NodeDescs.clear(); - m_NodeDescsVector.clear(); - m_NumNodes = 0; - m_NumEntrypoints = 0; } void* Data() noexcept override { return &m_Desc; } D3D12_WORK_GRAPH_DESC m_Desc; - std::list m_Entrypoints; - UINT m_NumEntrypoints; - std::vector m_EntrypointsVector; - std::list m_NodeDescs; - UINT m_NumNodes; - std::vector m_NodeDescsVector; + std::vector m_Entrypoints; + std::vector m_NodeDescs; CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; - std::list> m_OwnedNodeHelpers; + std::vector> m_OwnedNodeHelpers; + friend class CD3DX12_NODE_HELPER_BASE; }; + +inline D3D12_NODE * CD3DX12_NODE_HELPER_BASE::GetNode() const +{ + return &m_BackRef.m_pGraph->m_NodeDescs[m_BackRef.m_NodeIndex]; +} #endif // D3D12_SDK_VERSION >= 612 #undef D3DX12_COM_PTR @@ -7252,6 +7699,10 @@ class CD3DX12FeatureSupport D3D12_WORK_GRAPHS_TIER WorkGraphsTier() const noexcept; #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 617) + D3D12_TIGHT_ALIGNMENT_TIER TightAlignmentSupportTier() const noexcept; +#endif + private: // Private structs and helpers declaration struct ProtectedResourceSessionTypesLocal : D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES { @@ -7341,6 +7792,9 @@ class CD3DX12FeatureSupport #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) D3D12_FEATURE_DATA_D3D12_OPTIONS21 m_dOptions21; #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 617) + D3D12_FEATURE_DATA_TIGHT_ALIGNMENT m_dTightAlignment; +#endif }; // Implementations for CD3DX12FeatureSupport functions @@ -7435,6 +7889,9 @@ inline CD3DX12FeatureSupport::CD3DX12FeatureSupport() noexcept #if defined (D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) , m_dOptions21{} #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 617) +, m_dTightAlignment{} +#endif {} inline HRESULT CD3DX12FeatureSupport::Init(ID3D12Device* pDevice) @@ -7610,6 +8067,13 @@ inline HRESULT CD3DX12FeatureSupport::Init(ID3D12Device* pDevice) } #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 617) + if (FAILED(m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_TIGHT_ALIGNMENT, &m_dTightAlignment, sizeof(m_dTightAlignment)))) + { + m_dTightAlignment = {}; + } +#endif + // Initialize per-node feature support data structures const UINT uNodeCount = m_pDevice->GetNodeCount(); m_dProtectedResourceSessionSupport.resize(uNodeCount); @@ -7988,6 +8452,11 @@ FEATURE_SUPPORT_GET(D3D12_EXECUTE_INDIRECT_TIER, m_dOptions21, ExecuteIndirectTi FEATURE_SUPPORT_GET(D3D12_WORK_GRAPHS_TIER, m_dOptions21, WorkGraphsTier); #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 617) +// 51: TightAlignment +FEATURE_SUPPORT_GET_NAME(D3D12_TIGHT_ALIGNMENT_TIER, m_dTightAlignment, SupportTier, TightAlignmentSupportTier); +#endif + // Helper function to decide the highest shader model supported by the system // Stores the result in m_dShaderModel // Must be updated whenever a new shader model is added to the d3d12.h header