Path: blob/master/thirdparty/directx_headers/include/directx/d3dx12_state_object.h
21646 views
//*********************************************************1//2// Copyright (c) Microsoft Corporation.3// Licensed under the MIT License (MIT).4//5//*********************************************************67#pragma once89#ifndef __cplusplus10#error D3DX12 requires C++11#endif1213#include "d3dx12_default.h"14#include "d3d12.h"15#include "d3dx12_core.h"1617//================================================================================================18// D3DX12 State Object Creation Helpers19//20// Helper classes for creating new style state objects out of an arbitrary set of subobjects.21// Uses STL22//23// Start by instantiating CD3DX12_STATE_OBJECT_DESC (see its public methods).24// One of its methods is CreateSubobject(), which has a comment showing a couple of options for25// defining subobjects using the helper classes for each subobject (CD3DX12_DXIL_LIBRARY_SUBOBJECT26// etc.). The subobject helpers each have methods specific to the subobject for configuring its27// contents.28//29//================================================================================================30#include <list>31#include <forward_list>32#include <vector>33#include <memory>34#include <string>35#include <vector>36#ifndef D3DX12_USE_ATL37#include <wrl/client.h>38#define D3DX12_COM_PTR Microsoft::WRL::ComPtr39#define D3DX12_COM_PTR_GET(x) x.Get()40#define D3DX12_COM_PTR_ADDRESSOF(x) x.GetAddressOf()41#else42#include <atlbase.h>43#define D3DX12_COM_PTR ATL::CComPtr44#define D3DX12_COM_PTR_GET(x) x.p45#define D3DX12_COM_PTR_ADDRESSOF(x) &x.p46#endif4748//------------------------------------------------------------------------------------------------49class CD3DX12_STATE_OBJECT_DESC50{51public:52CD3DX12_STATE_OBJECT_DESC() noexcept53{54Init(D3D12_STATE_OBJECT_TYPE_COLLECTION);55}56CD3DX12_STATE_OBJECT_DESC(D3D12_STATE_OBJECT_TYPE Type) noexcept57{58Init(Type);59}60void SetStateObjectType(D3D12_STATE_OBJECT_TYPE Type) noexcept { m_Desc.Type = Type; }61CD3DX12_STATE_OBJECT_DESC(const CD3DX12_STATE_OBJECT_DESC& other) = delete;62CD3DX12_STATE_OBJECT_DESC& operator=(const CD3DX12_STATE_OBJECT_DESC& other) = delete;63CD3DX12_STATE_OBJECT_DESC(CD3DX12_STATE_OBJECT_DESC&& other) = default;64CD3DX12_STATE_OBJECT_DESC& operator=(CD3DX12_STATE_OBJECT_DESC&& other) = default;65operator const D3D12_STATE_OBJECT_DESC& ()66{67#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)68m_RepointedSubobjectVectors.clear();69m_RepointedPrograms.clear();70#endif71m_RepointedAssociations.clear();72m_SubobjectArray.clear();73m_SubobjectArray.reserve(m_Desc.NumSubobjects);74// Flatten subobjects into an array (each flattened subobject still has a75// member that's a pointer to its desc that's not flattened)76for (auto Iter = m_SubobjectList.begin();77Iter != m_SubobjectList.end(); Iter++)78{79m_SubobjectArray.push_back(*Iter);80// Store new location in array so we can redirect pointers contained in subobjects81Iter->pSubobjectArrayLocation = &m_SubobjectArray.back();82}83// For subobjects with pointer fields, create a new copy of those subobject definitions84// with fixed pointers85for (UINT i = 0; i < m_Desc.NumSubobjects; i++)86{87if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION)88{89auto pOriginalSubobjectAssociation =90static_cast<const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION*>(m_SubobjectArray[i].pDesc);91D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION Repointed = *pOriginalSubobjectAssociation;92auto pWrapper =93static_cast<const SUBOBJECT_WRAPPER*>(pOriginalSubobjectAssociation->pSubobjectToAssociate);94Repointed.pSubobjectToAssociate = pWrapper->pSubobjectArrayLocation;95m_RepointedAssociations.push_back(Repointed);96m_SubobjectArray[i].pDesc = &m_RepointedAssociations.back();97}98#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)99else if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GENERIC_PROGRAM)100{101auto originalGenericProgramDesc =102static_cast<const D3D12_GENERIC_PROGRAM_DESC*>(m_SubobjectArray[i].pDesc);103D3D12_GENERIC_PROGRAM_DESC Repointed = *originalGenericProgramDesc;104if (originalGenericProgramDesc->NumSubobjects > 0)105{106m_RepointedSubobjectVectors.emplace_back(std::vector<const D3D12_STATE_SUBOBJECT*>());107std::vector<D3D12_STATE_SUBOBJECT const*>& repointedGenericProgramSubobjects = m_RepointedSubobjectVectors.back();108repointedGenericProgramSubobjects.resize(originalGenericProgramDesc->NumSubobjects);109for (UINT s = 0; s < originalGenericProgramDesc->NumSubobjects; s++)110{111auto pWrapper =112static_cast<const SUBOBJECT_WRAPPER*>(originalGenericProgramDesc->ppSubobjects[s]);113repointedGenericProgramSubobjects[s] = pWrapper->pSubobjectArrayLocation;114}115// Below: using ugly way to get pointer in case .data() is not defined116Repointed.ppSubobjects = &repointedGenericProgramSubobjects[0];117}118m_RepointedPrograms.push_back(Repointed);119m_SubobjectArray[i].pDesc = &m_RepointedPrograms.back();120}121#endif122}123// Below: using ugly way to get pointer in case .data() is not defined124m_Desc.pSubobjects = m_Desc.NumSubobjects ? &m_SubobjectArray[0] : nullptr;125return m_Desc;126}127operator const D3D12_STATE_OBJECT_DESC* ()128{129// Cast calls the above final preparation work130return &static_cast<const D3D12_STATE_OBJECT_DESC&>(*this);131}132133// CreateSubobject creates a sububject helper (e.g. CD3DX12_HIT_GROUP_SUBOBJECT)134// whose lifetime is owned by this class.135// e.g.136//137// CD3DX12_STATE_OBJECT_DESC Collection1(D3D12_STATE_OBJECT_TYPE_COLLECTION);138// auto Lib0 = Collection1.CreateSubobject<CD3DX12_DXIL_LIBRARY_SUBOBJECT>();139// Lib0->SetDXILLibrary(&pMyAppDxilLibs[0]);140// Lib0->DefineExport(L"rayGenShader0"); // in practice these export listings might be141// // data/engine driven142// etc.143//144// Alternatively, users can instantiate sububject helpers explicitly, such as via local145// variables instead, passing the state object desc that should point to it into the helper146// constructor (or call mySubobjectHelper.AddToStateObject(Collection1)).147// In this alternative scenario, the user must keep the subobject alive as long as the state148// object it is associated with is alive, else its pointer references will be stale.149// e.g.150//151// CD3DX12_STATE_OBJECT_DESC RaytracingState2(D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);152// CD3DX12_DXIL_LIBRARY_SUBOBJECT LibA(RaytracingState2);153// LibA.SetDXILLibrary(&pMyAppDxilLibs[4]); // not manually specifying exports154// // - meaning all exports in the libraries155// // are exported156// etc.157158template<typename T>159T* CreateSubobject()160{161T* pSubobject = new T(*this);162m_OwnedSubobjectHelpers.emplace_back(pSubobject);163return pSubobject;164}165166template<typename T, typename U>167T* CreateSubobject(U&& arg)168{169T* pSubobject = new T(std::forward<U>(arg), *this);170m_OwnedSubobjectHelpers.emplace_back(pSubobject);171return pSubobject;172}173174private:175D3D12_STATE_SUBOBJECT* TrackSubobject(D3D12_STATE_SUBOBJECT_TYPE Type, void* pDesc)176{177SUBOBJECT_WRAPPER Subobject;178Subobject.pSubobjectArrayLocation = nullptr;179Subobject.Type = Type;180Subobject.pDesc = pDesc;181m_SubobjectList.push_back(Subobject);182m_Desc.NumSubobjects++;183return &m_SubobjectList.back();184}185void Init(D3D12_STATE_OBJECT_TYPE Type) noexcept186{187SetStateObjectType(Type);188m_Desc.pSubobjects = nullptr;189m_Desc.NumSubobjects = 0;190m_SubobjectList.clear();191m_SubobjectArray.clear();192m_RepointedAssociations.clear();193#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)194m_RepointedSubobjectVectors.clear();195m_RepointedPrograms.clear();196#endif197}198typedef struct SUBOBJECT_WRAPPER : public D3D12_STATE_SUBOBJECT199{200D3D12_STATE_SUBOBJECT* pSubobjectArrayLocation; // new location when flattened into array201// for repointing pointers in subobjects202} SUBOBJECT_WRAPPER;203D3D12_STATE_OBJECT_DESC m_Desc;204std::list<SUBOBJECT_WRAPPER> m_SubobjectList; // Pointers to list nodes handed out so205// these can be edited live206std::vector<D3D12_STATE_SUBOBJECT> m_SubobjectArray; // Built at the end, copying list contents207208std::list<D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION>209m_RepointedAssociations; // subobject type that contains pointers to other subobjects,210// repointed to flattened array211212#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)213std::list<std::vector<D3D12_STATE_SUBOBJECT const*>>214m_RepointedSubobjectVectors;215std::list<D3D12_GENERIC_PROGRAM_DESC>216m_RepointedPrograms;217#endif218219template<typename CStr, typename StdStr>220class StringContainer221{222public:223CStr LocalCopy(CStr string, bool bSingleString = false)224{225if (string)226{227if (bSingleString)228{229m_Strings.clear();230m_Strings.push_back(string);231}232else233{234m_Strings.push_back(string);235}236return m_Strings.back().c_str();237}238else239{240return nullptr;241}242}243void clear() noexcept { m_Strings.clear(); }244private:245std::list<StdStr> m_Strings;246};247248public:249class SUBOBJECT_HELPER_BASE250{251public:252SUBOBJECT_HELPER_BASE() noexcept { Init(); }253virtual ~SUBOBJECT_HELPER_BASE() = default;254virtual D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept = 0;255SUBOBJECT_HELPER_BASE(const SUBOBJECT_HELPER_BASE& other) = delete;256SUBOBJECT_HELPER_BASE& operator=(const SUBOBJECT_HELPER_BASE& other) = delete;257SUBOBJECT_HELPER_BASE(SUBOBJECT_HELPER_BASE&& other) = default;258SUBOBJECT_HELPER_BASE& operator=(SUBOBJECT_HELPER_BASE&& other) = default;259void AddToStateObject(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)260{261m_pSubobject = ContainingStateObject.TrackSubobject(Type(), Data());262}263operator const D3D12_STATE_SUBOBJECT& () const noexcept { return *m_pSubobject; }264protected:265virtual void* Data() noexcept = 0;266void Init() noexcept { m_pSubobject = nullptr; }267D3D12_STATE_SUBOBJECT* m_pSubobject;268};269270private:271std::list<std::unique_ptr<SUBOBJECT_HELPER_BASE>> m_OwnedSubobjectHelpers;272273friend class CD3DX12_DXIL_LIBRARY_SUBOBJECT;274friend class CD3DX12_EXISTING_COLLECTION_SUBOBJECT;275friend class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT;276friend class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION;277friend class CD3DX12_HIT_GROUP_SUBOBJECT;278friend class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT;279friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT;280friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT;281friend class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT;282friend class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT;283friend class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT;284friend class CD3DX12_NODE_MASK_SUBOBJECT;285//TODO: SDK Version check should include all the newly added subobject type for the public release.286// The SDK version check will be changed based on when we release state objects.287#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)288friend class CD3DX12_GENERIC_PROGRAM_SUBOBJECT;289friend class CD3DX12_WORK_GRAPH_SUBOBJECT;290friend class CD3DX12_STREAM_OUTPUT_SUBOBJECT;291friend class CD3DX12_BLEND_SUBOBJECT;292friend class CD3DX12_RASTERIZER_SUBOBJECT;293friend class CD3DX12_DEPTH_STENCIL2_SUBOBJECT;294friend class CD3DX12_INPUT_LAYOUT_SUBOBJECT;295friend class CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT;296friend class CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT;297friend class CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT;298friend class CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT;299friend class CD3DX12_SAMPLE_DESC_SUBOBJECT;300friend class CD3DX12_FLAGS_SUBOBJECT;301friend class CD3DX12_VIEW_INSTANCING_SUBOBJECT;302friend class CD3DX12_DEPTH_STENCIL_SUBOBJECT;303friend class CD3DX12_DEPTH_STENCIL1_SUBOBJECT;304friend class CD3DX12_SAMPLE_MASK_SUBOBJECT;305friend class CD3DX12_NODE_OUTPUT_OVERRIDES;306friend class CD3DX12_NODE_HELPER_BASE;307friend class CD3DX12_SHADER_NODE;308friend class CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES;309friend class CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES;310friend class CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES;311friend class CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES;312#endif // D3D12_SDK_VERSION >= 612313#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618)314friend class CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT;315friend class CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT;316friend class CD3DX12_COMPILER_EXISTING_COLLECTION_SUBOBJECT;317friend class CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT;318#endif319};320321//------------------------------------------------------------------------------------------------322class CD3DX12_DXIL_LIBRARY_SUBOBJECT323: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE324{325public:326CD3DX12_DXIL_LIBRARY_SUBOBJECT() noexcept327{328Init();329}330CD3DX12_DXIL_LIBRARY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)331{332Init();333AddToStateObject(ContainingStateObject);334}335CD3DX12_DXIL_LIBRARY_SUBOBJECT(const CD3DX12_DXIL_LIBRARY_SUBOBJECT& other) = delete;336CD3DX12_DXIL_LIBRARY_SUBOBJECT& operator=(const CD3DX12_DXIL_LIBRARY_SUBOBJECT& other) = delete;337CD3DX12_DXIL_LIBRARY_SUBOBJECT(CD3DX12_DXIL_LIBRARY_SUBOBJECT&& other) = default;338CD3DX12_DXIL_LIBRARY_SUBOBJECT& operator=(CD3DX12_DXIL_LIBRARY_SUBOBJECT&& other) = default;339void SetDXILLibrary(const D3D12_SHADER_BYTECODE* pCode) noexcept340{341static const D3D12_SHADER_BYTECODE Default = {};342m_Desc.DXILLibrary = pCode ? *pCode : Default;343}344void DefineExport(345LPCWSTR Name,346LPCWSTR ExportToRename = nullptr,347D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE)348{349D3D12_EXPORT_DESC Export;350Export.Name = m_Strings.LocalCopy(Name);351Export.ExportToRename = m_Strings.LocalCopy(ExportToRename);352Export.Flags = Flags;353m_Exports.push_back(Export);354m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined355m_Desc.NumExports = static_cast<UINT>(m_Exports.size());356}357template<size_t N>358void DefineExports(LPCWSTR(&Exports)[N])359{360for (UINT i = 0; i < N; i++)361{362DefineExport(Exports[i]);363}364}365void DefineExports(const LPCWSTR* Exports, UINT N)366{367for (UINT i = 0; i < N; i++)368{369DefineExport(Exports[i]);370}371}372D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override373{374return D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY;375}376operator const D3D12_DXIL_LIBRARY_DESC&() const noexcept { return m_Desc; }377private:378void Init() noexcept379{380SUBOBJECT_HELPER_BASE::Init();381m_Desc = {};382m_Strings.clear();383m_Exports.clear();384}385void* Data() noexcept override { return &m_Desc; }386D3D12_DXIL_LIBRARY_DESC m_Desc;387CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;388std::vector<D3D12_EXPORT_DESC> m_Exports;389};390391//------------------------------------------------------------------------------------------------392class CD3DX12_EXISTING_COLLECTION_SUBOBJECT393: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE394{395public:396CD3DX12_EXISTING_COLLECTION_SUBOBJECT() noexcept397{398Init();399}400CD3DX12_EXISTING_COLLECTION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)401{402Init();403AddToStateObject(ContainingStateObject);404}405CD3DX12_EXISTING_COLLECTION_SUBOBJECT(const CD3DX12_EXISTING_COLLECTION_SUBOBJECT& other) = delete;406CD3DX12_EXISTING_COLLECTION_SUBOBJECT& operator=(const CD3DX12_EXISTING_COLLECTION_SUBOBJECT& other) = delete;407CD3DX12_EXISTING_COLLECTION_SUBOBJECT(CD3DX12_EXISTING_COLLECTION_SUBOBJECT&& other) = default;408CD3DX12_EXISTING_COLLECTION_SUBOBJECT& operator=(CD3DX12_EXISTING_COLLECTION_SUBOBJECT&& other) = default;409void SetExistingCollection(ID3D12StateObject*pExistingCollection) noexcept410{411m_Desc.pExistingCollection = pExistingCollection;412m_CollectionRef = pExistingCollection;413}414void DefineExport(415LPCWSTR Name,416LPCWSTR ExportToRename = nullptr,417D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE)418{419D3D12_EXPORT_DESC Export;420Export.Name = m_Strings.LocalCopy(Name);421Export.ExportToRename = m_Strings.LocalCopy(ExportToRename);422Export.Flags = Flags;423m_Exports.push_back(Export);424m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined425m_Desc.NumExports = static_cast<UINT>(m_Exports.size());426}427template<size_t N>428void DefineExports(LPCWSTR(&Exports)[N])429{430for (UINT i = 0; i < N; i++)431{432DefineExport(Exports[i]);433}434}435void DefineExports(const LPCWSTR* Exports, UINT N)436{437for (UINT i = 0; i < N; i++)438{439DefineExport(Exports[i]);440}441}442D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override443{444return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION;445}446operator const D3D12_EXISTING_COLLECTION_DESC&() const noexcept { return m_Desc; }447private:448void Init() noexcept449{450SUBOBJECT_HELPER_BASE::Init();451m_Desc = {};452m_CollectionRef = nullptr;453m_Strings.clear();454m_Exports.clear();455}456void* Data() noexcept override { return &m_Desc; }457D3D12_EXISTING_COLLECTION_DESC m_Desc;458D3DX12_COM_PTR<ID3D12StateObject> m_CollectionRef;459CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;460std::vector<D3D12_EXPORT_DESC> m_Exports;461};462463//------------------------------------------------------------------------------------------------464class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT465: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE466{467public:468CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT() noexcept469{470Init();471}472CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)473{474Init();475AddToStateObject(ContainingStateObject);476}477CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(const CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT& other) = delete;478CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT& operator=(const CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT& other) = delete;479CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT&& other) = default;480CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT& operator=(CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT&& other) = default;481void SetSubobjectToAssociate(const D3D12_STATE_SUBOBJECT& SubobjectToAssociate) noexcept482{483m_Desc.pSubobjectToAssociate = &SubobjectToAssociate;484}485void AddExport(LPCWSTR Export)486{487m_Desc.NumExports++;488m_Exports.push_back(m_Strings.LocalCopy(Export));489m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined490}491template<size_t N>492void AddExports(LPCWSTR (&Exports)[N])493{494for (UINT i = 0; i < N; i++)495{496AddExport(Exports[i]);497}498}499void AddExports(const LPCWSTR* Exports, UINT N)500{501for (UINT i = 0; i < N; i++)502{503AddExport(Exports[i]);504}505}506D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override507{508return D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;509}510operator const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; }511private:512void Init() noexcept513{514SUBOBJECT_HELPER_BASE::Init();515m_Desc = {};516m_Strings.clear();517m_Exports.clear();518}519void* Data() noexcept override { return &m_Desc; }520D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc;521CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;522std::vector<LPCWSTR> m_Exports;523};524525//------------------------------------------------------------------------------------------------526class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION527: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE528{529public:530CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION() noexcept531{532Init();533}534CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)535{536Init();537AddToStateObject(ContainingStateObject);538}539CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(const CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION& other) = delete;540CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION& operator=(const CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION& other) = delete;541CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&& other) = default;542CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION& operator=(CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&& other) = default;543void SetSubobjectNameToAssociate(LPCWSTR SubobjectToAssociate)544{545m_Desc.SubobjectToAssociate = m_SubobjectName.LocalCopy(SubobjectToAssociate, true);546}547void AddExport(LPCWSTR Export)548{549m_Desc.NumExports++;550m_Exports.push_back(m_Strings.LocalCopy(Export));551m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined552}553template<size_t N>554void AddExports(LPCWSTR (&Exports)[N])555{556for (UINT i = 0; i < N; i++)557{558AddExport(Exports[i]);559}560}561void AddExports(const LPCWSTR* Exports, UINT N)562{563for (UINT i = 0; i < N; i++)564{565AddExport(Exports[i]);566}567}568D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override569{570return D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION;571}572operator const D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; }573private:574void Init() noexcept575{576SUBOBJECT_HELPER_BASE::Init();577m_Desc = {};578m_Strings.clear();579m_SubobjectName.clear();580m_Exports.clear();581}582void* Data() noexcept override { return &m_Desc; }583D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc;584CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;585CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_SubobjectName;586std::vector<LPCWSTR> m_Exports;587};588589//------------------------------------------------------------------------------------------------590class CD3DX12_HIT_GROUP_SUBOBJECT591: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE592{593public:594CD3DX12_HIT_GROUP_SUBOBJECT() noexcept595{596Init();597}598CD3DX12_HIT_GROUP_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)599{600Init();601AddToStateObject(ContainingStateObject);602}603CD3DX12_HIT_GROUP_SUBOBJECT(const CD3DX12_HIT_GROUP_SUBOBJECT& other) = delete;604CD3DX12_HIT_GROUP_SUBOBJECT& operator=(const CD3DX12_HIT_GROUP_SUBOBJECT& other) = delete;605CD3DX12_HIT_GROUP_SUBOBJECT(CD3DX12_HIT_GROUP_SUBOBJECT&& other) = default;606CD3DX12_HIT_GROUP_SUBOBJECT& operator=(CD3DX12_HIT_GROUP_SUBOBJECT&& other) = default;607void SetHitGroupExport(LPCWSTR exportName)608{609m_Desc.HitGroupExport = m_Strings[0].LocalCopy(exportName, true);610}611void SetHitGroupType(D3D12_HIT_GROUP_TYPE Type) noexcept { m_Desc.Type = Type; }612void SetAnyHitShaderImport(LPCWSTR importName)613{614m_Desc.AnyHitShaderImport = m_Strings[1].LocalCopy(importName, true);615}616void SetClosestHitShaderImport(LPCWSTR importName)617{618m_Desc.ClosestHitShaderImport = m_Strings[2].LocalCopy(importName, true);619}620void SetIntersectionShaderImport(LPCWSTR importName)621{622m_Desc.IntersectionShaderImport = m_Strings[3].LocalCopy(importName, true);623}624D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override625{626return D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;627}628operator const D3D12_HIT_GROUP_DESC&() const noexcept { return m_Desc; }629private:630void Init() noexcept631{632SUBOBJECT_HELPER_BASE::Init();633m_Desc = {};634for (UINT i = 0; i < m_NumStrings; i++)635{636m_Strings[i].clear();637}638}639void* Data() noexcept override { return &m_Desc; }640D3D12_HIT_GROUP_DESC m_Desc;641static constexpr UINT m_NumStrings = 4;642CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring>643m_Strings[m_NumStrings]; // one string for every entrypoint name644};645646//------------------------------------------------------------------------------------------------647class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT648: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE649{650public:651CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT() noexcept652: m_Desc({})653{654Init();655}656CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)657: m_Desc({})658{659Init();660AddToStateObject(ContainingStateObject);661}662CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_SHADER_CONFIG &desc)663: m_Desc(desc)664{665Init();666}667CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_SHADER_CONFIG &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)668: m_Desc(desc)669{670Init();671AddToStateObject(ContainingStateObject);672}673CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(const CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT& other) = delete;674CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT& operator=(const CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT& other) = delete;675CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT&& other) = default;676CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT& operator=(CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT&& other) = default;677void Config(UINT MaxPayloadSizeInBytes, UINT MaxAttributeSizeInBytes) noexcept678{679m_Desc.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes;680m_Desc.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes;681}682D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override683{684return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG;685}686operator const D3D12_RAYTRACING_SHADER_CONFIG&() const noexcept { return m_Desc; }687operator D3D12_RAYTRACING_SHADER_CONFIG&() noexcept { return m_Desc; }688private:689void Init() noexcept690{691SUBOBJECT_HELPER_BASE::Init();692}693void* Data() noexcept override { return &m_Desc; }694D3D12_RAYTRACING_SHADER_CONFIG m_Desc;695};696697//------------------------------------------------------------------------------------------------698class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT699: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE700{701public:702CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT() noexcept703: m_Desc({})704{705Init();706}707CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)708: m_Desc({})709{710Init();711AddToStateObject(ContainingStateObject);712}713CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG &desc)714: m_Desc(desc)715{716Init();717}718CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)719: m_Desc(desc)720{721Init();722AddToStateObject(ContainingStateObject);723}724CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(const CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT& other) = delete;725CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT& operator=(const CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT& other) = delete;726CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT&& other) = default;727CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT& operator=(CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT&& other) = default;728void Config(UINT MaxTraceRecursionDepth) noexcept729{730m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth;731}732D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override733{734return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG;735}736operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const noexcept { return m_Desc; }737operator D3D12_RAYTRACING_PIPELINE_CONFIG&() noexcept { return m_Desc; }738private:739void Init() noexcept740{741SUBOBJECT_HELPER_BASE::Init();742}743void* Data() noexcept override { return &m_Desc; }744D3D12_RAYTRACING_PIPELINE_CONFIG m_Desc;745};746747//------------------------------------------------------------------------------------------------748class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT749: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE750{751public:752CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT() noexcept753: m_Desc({})754{755Init();756}757CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)758: m_Desc({})759{760Init();761AddToStateObject(ContainingStateObject);762}763CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG1 &desc)764: m_Desc(desc)765{766Init();767}768CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(const D3D12_RAYTRACING_PIPELINE_CONFIG1 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)769: m_Desc(desc)770{771Init();772AddToStateObject(ContainingStateObject);773}774CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(const CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT& other) = delete;775CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT& operator=(const CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT& other) = delete;776CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT&& other) = default;777CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT& operator=(CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT&& other) = default;778void Config(UINT MaxTraceRecursionDepth, D3D12_RAYTRACING_PIPELINE_FLAGS Flags) noexcept779{780m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth;781m_Desc.Flags = Flags;782}783D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override784{785return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1;786}787operator const D3D12_RAYTRACING_PIPELINE_CONFIG1&() const noexcept { return m_Desc; }788operator D3D12_RAYTRACING_PIPELINE_CONFIG1&() noexcept { return m_Desc; }789private:790void Init() noexcept791{792SUBOBJECT_HELPER_BASE::Init();793}794void* Data() noexcept override { return &m_Desc; }795D3D12_RAYTRACING_PIPELINE_CONFIG1 m_Desc;796};797798//------------------------------------------------------------------------------------------------799class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT800: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE801{802public:803CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT() noexcept804{805Init();806}807CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)808{809Init();810AddToStateObject(ContainingStateObject);811}812CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(const CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT& other) = delete;813CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT& operator=(const CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT& other) = delete;814CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT&& other) = default;815CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT& operator=(CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT&& other) = default;816void SetRootSignature(ID3D12RootSignature* pRootSig) noexcept817{818m_pRootSig = pRootSig;819}820D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override821{822return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE;823}824operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); }825private:826void Init() noexcept827{828SUBOBJECT_HELPER_BASE::Init();829m_pRootSig = nullptr;830}831void* Data() noexcept override { return D3DX12_COM_PTR_ADDRESSOF(m_pRootSig); }832D3DX12_COM_PTR<ID3D12RootSignature> m_pRootSig;833};834835836//------------------------------------------------------------------------------------------------837class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT838: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE839{840public:841CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT() noexcept842{843Init();844}845CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)846{847Init();848AddToStateObject(ContainingStateObject);849}850CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(const CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT& other) = delete;851CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT& operator=(const CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT& other) = delete;852CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT&& other) = default;853CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT& operator=(CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT&& other) = default;854void SetRootSignature(ID3D12RootSignature* pRootSig) noexcept855{856m_pRootSig = pRootSig;857}858D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override859{860return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;861}862operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); }863private:864void Init() noexcept865{866SUBOBJECT_HELPER_BASE::Init();867m_pRootSig = nullptr;868}869void* Data() noexcept override { return D3DX12_COM_PTR_ADDRESSOF(m_pRootSig); }870D3DX12_COM_PTR<ID3D12RootSignature> m_pRootSig;871};872873#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618)874//------------------------------------------------------------------------------------------------875class CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT876: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE877{878public:879CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT() noexcept880: m_Desc({})881{882Init();883}884CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)885: m_Desc({})886{887Init();888AddToStateObject(ContainingStateObject);889}890CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(const CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete;891CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(const CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete;892CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default;893CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(CD3DX12_GLOBAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default;894void SetRootSignature(const D3D12_SERIALIZED_ROOT_SIGNATURE_DESC* pDesc) noexcept895{896if (pDesc)897{898m_Desc.Desc = {};899m_Desc.Desc.pSerializedBlob = pDesc->pSerializedBlob;900m_Desc.Desc.SerializedBlobSizeInBytes = pDesc->SerializedBlobSizeInBytes;901}902}903D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override904{905return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_SERIALIZED_ROOT_SIGNATURE;906}907operator const D3D12_GLOBAL_SERIALIZED_ROOT_SIGNATURE&() const noexcept { return m_Desc; }908operator D3D12_GLOBAL_SERIALIZED_ROOT_SIGNATURE&() noexcept { return m_Desc; }909private:910void Init() noexcept911{912SUBOBJECT_HELPER_BASE::Init();913m_Desc = {};914}915void* Data() noexcept override { return &m_Desc; }916D3D12_GLOBAL_SERIALIZED_ROOT_SIGNATURE m_Desc;917};918919//------------------------------------------------------------------------------------------------920class CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT921: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE922{923public:924CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT() noexcept925: m_Desc({})926{927Init();928}929CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)930: m_Desc({})931{932Init();933AddToStateObject(ContainingStateObject);934}935CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(const CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete;936CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(const CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& other) = delete;937CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default;938CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT& operator=(CD3DX12_LOCAL_SERIALIZED_ROOT_SIGNATURE_SUBOBJECT&& other) = default;939void SetRootSignature(const D3D12_SERIALIZED_ROOT_SIGNATURE_DESC* pDesc) noexcept940{941if (pDesc)942{943m_Desc.Desc = {};944m_Desc.Desc.pSerializedBlob = pDesc->pSerializedBlob;945m_Desc.Desc.SerializedBlobSizeInBytes = pDesc->SerializedBlobSizeInBytes;946}947}948D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override949{950return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_SERIALIZED_ROOT_SIGNATURE;951}952operator const D3D12_LOCAL_SERIALIZED_ROOT_SIGNATURE&() const noexcept { return m_Desc; }953operator D3D12_LOCAL_SERIALIZED_ROOT_SIGNATURE&() noexcept { return m_Desc; }954private:955void Init() noexcept956{957SUBOBJECT_HELPER_BASE::Init();958m_Desc = {};959}960void* Data() noexcept override { return &m_Desc; }961D3D12_LOCAL_SERIALIZED_ROOT_SIGNATURE m_Desc;962};963964965//------------------------------------------------------------------------------------------------966class CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT967: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE968{969public:970CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT() noexcept971{972Init();973}974CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)975{976Init();977AddToStateObject(ContainingStateObject);978}979CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT(const CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& other) = delete;980CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& operator=(const CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& other) = delete;981CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT(CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT&& other) = default;982CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT& operator=(CD3DX12_EXISTING_COLLECTION_BY_KEY_SUBOBJECT&& other) = default;983void SetExistingCollection(const void* pKey, UINT KeySize) noexcept984{985const unsigned char* pKeyBytes = static_cast<const unsigned char *>(pKey);986m_Key.clear();987m_Key.insert(m_Key.begin(), pKeyBytes, pKeyBytes + KeySize);988m_Desc.pKey = m_Key.data();989m_Desc.KeySize = KeySize;990}991void DefineExport(992LPCWSTR Name,993LPCWSTR ExportToRename = nullptr,994D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE)995{996D3D12_EXPORT_DESC Export;997Export.Name = m_Strings.LocalCopy(Name);998Export.ExportToRename = m_Strings.LocalCopy(ExportToRename);999Export.Flags = Flags;1000m_Exports.push_back(Export);1001m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined1002m_Desc.NumExports = static_cast<UINT>(m_Exports.size());1003}1004template<size_t N>1005void DefineExports(LPCWSTR(&Exports)[N])1006{1007for (UINT i = 0; i < N; i++)1008{1009DefineExport(Exports[i]);1010}1011}1012void DefineExports(const LPCWSTR* Exports, UINT N)1013{1014for (UINT i = 0; i < N; i++)1015{1016DefineExport(Exports[i]);1017}1018}1019D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1020{1021return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION_BY_KEY;1022}1023operator const D3D12_EXISTING_COLLECTION_BY_KEY_DESC&() const noexcept { return m_Desc; }1024private:1025void Init() noexcept1026{1027SUBOBJECT_HELPER_BASE::Init();1028m_Desc = {};1029m_Strings.clear();1030m_Exports.clear();1031}1032void* Data() noexcept override { return &m_Desc; }1033D3D12_EXISTING_COLLECTION_BY_KEY_DESC m_Desc;1034std::vector<unsigned char> m_Key;1035CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;1036std::vector<D3D12_EXPORT_DESC> m_Exports;1037};10381039#endif // defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 618)10401041//------------------------------------------------------------------------------------------------1042class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT1043: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1044{1045public:1046CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT() noexcept1047: m_Desc({})1048{1049Init();1050}1051CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1052: m_Desc({})1053{1054Init();1055AddToStateObject(ContainingStateObject);1056}1057CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(const D3D12_STATE_OBJECT_CONFIG &desc) noexcept1058: m_Desc(desc)1059{1060Init();1061}1062CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(const D3D12_STATE_OBJECT_CONFIG &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1063: m_Desc(desc)1064{1065Init();1066AddToStateObject(ContainingStateObject);1067}1068CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(const CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT& other) = delete;1069CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT& operator=(const CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT& other) = delete;1070CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT&& other) = default;1071CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT& operator=(CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT&& other) = default;1072void SetFlags(D3D12_STATE_OBJECT_FLAGS Flags) noexcept1073{1074m_Desc.Flags = Flags;1075}1076D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1077{1078return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG;1079}1080operator const D3D12_STATE_OBJECT_CONFIG&() const noexcept { return m_Desc; }1081operator D3D12_STATE_OBJECT_CONFIG&() noexcept { return m_Desc; }1082private:1083void Init() noexcept1084{1085SUBOBJECT_HELPER_BASE::Init();1086}1087void* Data() noexcept override { return &m_Desc; }1088D3D12_STATE_OBJECT_CONFIG m_Desc;1089};10901091//------------------------------------------------------------------------------------------------1092class CD3DX12_NODE_MASK_SUBOBJECT1093: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1094{1095public:1096CD3DX12_NODE_MASK_SUBOBJECT() noexcept1097: m_Desc({})1098{1099Init();1100}1101CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1102: m_Desc({})1103{1104Init();1105AddToStateObject(ContainingStateObject);1106}1107CD3DX12_NODE_MASK_SUBOBJECT(const D3D12_NODE_MASK &desc) noexcept1108: m_Desc(desc)1109{1110Init();1111}1112CD3DX12_NODE_MASK_SUBOBJECT(const D3D12_NODE_MASK &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1113: m_Desc(desc)1114{1115Init();1116AddToStateObject(ContainingStateObject);1117}1118CD3DX12_NODE_MASK_SUBOBJECT(const CD3DX12_NODE_MASK_SUBOBJECT& other) = delete;1119CD3DX12_NODE_MASK_SUBOBJECT& operator=(const CD3DX12_NODE_MASK_SUBOBJECT& other) = delete;1120CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_NODE_MASK_SUBOBJECT&& other) = default;1121CD3DX12_NODE_MASK_SUBOBJECT& operator=(CD3DX12_NODE_MASK_SUBOBJECT&& other) = default;1122void SetNodeMask(UINT NodeMask) noexcept1123{1124m_Desc.NodeMask = NodeMask;1125}1126D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1127{1128return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK;1129}1130operator const D3D12_NODE_MASK&() const noexcept { return m_Desc; }1131operator D3D12_NODE_MASK&() noexcept { return m_Desc; }1132private:1133void Init() noexcept1134{1135SUBOBJECT_HELPER_BASE::Init();1136}1137void* Data() noexcept override { return &m_Desc; }1138D3D12_NODE_MASK m_Desc;1139};11401141#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)1142//------------------------------------------------------------------------------------------------1143class CD3DX12_STREAM_OUTPUT_SUBOBJECT1144: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1145{1146public:1147CD3DX12_STREAM_OUTPUT_SUBOBJECT()1148{1149Init();1150}1151CD3DX12_STREAM_OUTPUT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1152{1153Init();1154AddToStateObject(ContainingStateObject);1155}1156void AddSODeclEntry(const D3D12_SO_DECLARATION_ENTRY &entry)1157{1158m_soDecalEntries.emplace_back(D3D12_SO_DECLARATION_ENTRY{1159entry.Stream,1160m_Strings.LocalCopy(entry.SemanticName),1161entry.SemanticIndex,1162entry.StartComponent,1163entry.ComponentCount,1164entry.OutputSlot1165});1166m_Desc.NumEntries++;1167// Below: using ugly way to get pointer in case .data() is not defined1168m_Desc.pSODeclaration = &m_soDecalEntries[0];1169}1170void SetSODeclEntries(const D3D12_SO_DECLARATION_ENTRY* soDeclEntries, UINT numEntries)1171{1172m_soDecalEntries.resize(numEntries);1173for (UINT i = 0; i < numEntries; i++)1174{1175m_soDecalEntries[i] = D3D12_SO_DECLARATION_ENTRY{1176soDeclEntries[i].Stream,1177m_Strings.LocalCopy(soDeclEntries[i].SemanticName),1178soDeclEntries[i].SemanticIndex,1179soDeclEntries[i].StartComponent,1180soDeclEntries[i].ComponentCount,1181soDeclEntries[i].OutputSlot1182};1183}1184m_Desc.NumEntries = numEntries;1185// Below: using ugly way to get pointer in case .data() is not defined1186if (numEntries > 0)1187{1188m_Desc.pSODeclaration = &m_soDecalEntries[0];1189}1190}1191void SetBufferStrides(const UINT* bufferStrides, UINT numStrides)1192{1193for (UINT i = 0; i < numStrides; ++i)1194{1195m_Strides[i] = bufferStrides[i];1196}1197m_Desc.pBufferStrides = m_Strides;1198m_Desc.NumStrides = numStrides;1199}1200void SetRasterizedStream(UINT rasterizedStream)1201{1202m_Desc.RasterizedStream = rasterizedStream;1203}1204D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1205{1206return D3D12_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT;1207}1208operator const D3D12_STREAM_OUTPUT_DESC& () const noexcept { return m_Desc; }12091210private:1211void Init()1212{1213SUBOBJECT_HELPER_BASE::Init();1214m_Desc = {};1215}1216void* Data() noexcept override { return &m_Desc; }1217D3D12_STREAM_OUTPUT_DESC m_Desc;1218CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCSTR, std::string> m_Strings;1219std::vector<D3D12_SO_DECLARATION_ENTRY> m_soDecalEntries;1220UINT m_Strides[D3D12_SO_STREAM_COUNT];1221};12221223//------------------------------------------------------------------------------------------------1224class CD3DX12_BLEND_SUBOBJECT1225: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1226{1227public:1228CD3DX12_BLEND_SUBOBJECT()1229: m_Desc(CD3DX12_BLEND_DESC(D3D12_DEFAULT))1230{1231Init();1232}1233CD3DX12_BLEND_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1234: m_Desc(CD3DX12_BLEND_DESC(D3D12_DEFAULT))1235{1236Init();1237AddToStateObject(ContainingStateObject);1238}1239CD3DX12_BLEND_SUBOBJECT(const D3D12_BLEND_DESC &desc)1240: m_Desc(desc)1241{1242Init();1243}1244CD3DX12_BLEND_SUBOBJECT(const D3D12_BLEND_DESC &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1245: m_Desc(desc)1246{1247Init();1248AddToStateObject(ContainingStateObject);1249}1250void SetAlphaToCoverageEnable(bool alphaToCoverageEnable)1251{1252m_Desc.AlphaToCoverageEnable = alphaToCoverageEnable;1253}1254void SetIndependentBlendEnable(bool independentBlendEnable)1255{1256m_Desc.IndependentBlendEnable = independentBlendEnable;1257}1258void SetRenderTarget(UINT renderTargetIndex, const D3D12_RENDER_TARGET_BLEND_DESC& renderTargetBlendDesc)1259{1260m_Desc.RenderTarget[renderTargetIndex].BlendEnable = renderTargetBlendDesc.BlendEnable;1261m_Desc.RenderTarget[renderTargetIndex].BlendOp = renderTargetBlendDesc.BlendOp;1262m_Desc.RenderTarget[renderTargetIndex].BlendOpAlpha = renderTargetBlendDesc.BlendOpAlpha;1263m_Desc.RenderTarget[renderTargetIndex].DestBlend = renderTargetBlendDesc.DestBlend;1264m_Desc.RenderTarget[renderTargetIndex].DestBlendAlpha = renderTargetBlendDesc.DestBlendAlpha;1265m_Desc.RenderTarget[renderTargetIndex].LogicOp = renderTargetBlendDesc.LogicOp;1266m_Desc.RenderTarget[renderTargetIndex].LogicOpEnable = renderTargetBlendDesc.LogicOpEnable;1267m_Desc.RenderTarget[renderTargetIndex].RenderTargetWriteMask = renderTargetBlendDesc.RenderTargetWriteMask;1268m_Desc.RenderTarget[renderTargetIndex].SrcBlend = renderTargetBlendDesc.SrcBlend;1269m_Desc.RenderTarget[renderTargetIndex].SrcBlendAlpha = renderTargetBlendDesc.SrcBlendAlpha;1270}1271D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1272{1273return D3D12_STATE_SUBOBJECT_TYPE_BLEND;1274}1275operator const D3D12_BLEND_DESC& () const noexcept { return m_Desc; }1276operator D3D12_BLEND_DESC& () noexcept { return m_Desc; }1277private:1278void Init() noexcept1279{1280SUBOBJECT_HELPER_BASE::Init();1281}1282void* Data() noexcept override { return &m_Desc; }1283CD3DX12_BLEND_DESC m_Desc;1284};12851286//------------------------------------------------------------------------------------------------1287class CD3DX12_RASTERIZER_SUBOBJECT1288: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1289{1290public:1291CD3DX12_RASTERIZER_SUBOBJECT()1292: m_Desc(CD3DX12_RASTERIZER_DESC2(D3D12_DEFAULT))1293{1294Init();1295}1296CD3DX12_RASTERIZER_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1297: m_Desc(CD3DX12_RASTERIZER_DESC2(D3D12_DEFAULT))1298{1299Init();1300AddToStateObject(ContainingStateObject);1301}1302CD3DX12_RASTERIZER_SUBOBJECT(const D3D12_RASTERIZER_DESC2 &desc)1303: m_Desc(desc)1304{1305Init();1306}1307CD3DX12_RASTERIZER_SUBOBJECT(const D3D12_RASTERIZER_DESC2 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1308: m_Desc(desc)1309{1310Init();1311AddToStateObject(ContainingStateObject);1312}1313void SetFillMode(D3D12_FILL_MODE fillMode)1314{1315m_Desc.FillMode = fillMode;1316}1317void SetCullMode(D3D12_CULL_MODE cullMode)1318{1319m_Desc.CullMode = cullMode;1320}1321void SetFrontCounterClockwise(BOOL frontCounterClockwise)1322{1323m_Desc.FrontCounterClockwise = frontCounterClockwise;1324}1325void SetDepthBias(FLOAT depthBias)1326{1327m_Desc.DepthBias = depthBias;1328}1329void SetDepthBiasClamp(FLOAT depthBiasClamp)1330{1331m_Desc.DepthBiasClamp = depthBiasClamp;1332}1333void SetSlopeScaledDepthBias(FLOAT slopeScaledDepthBias)1334{1335m_Desc.SlopeScaledDepthBias = slopeScaledDepthBias;1336}1337void SetDepthClipEnable(BOOL depthClipEnable)1338{1339m_Desc.DepthClipEnable = depthClipEnable;1340}1341void SetLineRasterizationMode(D3D12_LINE_RASTERIZATION_MODE lineRasterizationMode)1342{1343m_Desc.LineRasterizationMode = lineRasterizationMode;1344}1345void SetForcedSampleCount(UINT forcedSampleCount)1346{1347m_Desc.ForcedSampleCount = forcedSampleCount;1348}1349void SetConservativeRaster(D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster)1350{1351m_Desc.ConservativeRaster = conservativeRaster;1352}1353D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1354{1355return D3D12_STATE_SUBOBJECT_TYPE_RASTERIZER;1356}1357operator const D3D12_RASTERIZER_DESC2& () const noexcept { return m_Desc; }1358operator D3D12_RASTERIZER_DESC2& () noexcept { return m_Desc; }1359private:1360void Init() noexcept1361{1362SUBOBJECT_HELPER_BASE::Init();1363}1364void* Data() noexcept override { return &m_Desc; }1365CD3DX12_RASTERIZER_DESC2 m_Desc;1366};13671368//------------------------------------------------------------------------------------------------1369class CD3DX12_DEPTH_STENCIL2_SUBOBJECT1370: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1371{1372public:1373CD3DX12_DEPTH_STENCIL2_SUBOBJECT()1374: m_Desc(CD3DX12_DEPTH_STENCIL_DESC2(D3D12_DEFAULT))1375{1376Init();1377}1378CD3DX12_DEPTH_STENCIL2_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1379: m_Desc(CD3DX12_DEPTH_STENCIL_DESC2(D3D12_DEFAULT))1380{1381Init();1382AddToStateObject(ContainingStateObject);1383}1384CD3DX12_DEPTH_STENCIL2_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC2 &desc)1385: m_Desc(desc)1386{1387Init();1388}1389CD3DX12_DEPTH_STENCIL2_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC2 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1390: m_Desc(desc)1391{1392Init();1393AddToStateObject(ContainingStateObject);1394}1395void SetDepthEnable(BOOL depthEnable)1396{1397m_Desc.DepthEnable = depthEnable;1398}1399void SetDepthWriteMask(D3D12_DEPTH_WRITE_MASK depthWriteMask)1400{1401m_Desc.DepthWriteMask = depthWriteMask;1402}1403void SetDepthFunc(D3D12_COMPARISON_FUNC depthFunc)1404{1405m_Desc.DepthFunc = depthFunc;1406}1407void SetStencilEnable(BOOL stencilEnable)1408{1409m_Desc.StencilEnable = stencilEnable;1410}1411void SetFrontFace(D3D12_DEPTH_STENCILOP_DESC1 frontFace)1412{1413m_Desc.FrontFace = {1414frontFace.StencilFailOp,1415frontFace.StencilDepthFailOp,1416frontFace.StencilPassOp,1417frontFace.StencilFunc,1418frontFace.StencilReadMask,1419frontFace.StencilWriteMask1420};1421}1422void SetBackFace(D3D12_DEPTH_STENCILOP_DESC1 backFace)1423{1424m_Desc.BackFace = {1425backFace.StencilFailOp,1426backFace.StencilDepthFailOp,1427backFace.StencilPassOp,1428backFace.StencilFunc,1429backFace.StencilReadMask,1430backFace.StencilWriteMask1431};1432}1433void SetDepthBoundsTestEnable(BOOL depthBoundsTestEnable)1434{1435m_Desc.DepthBoundsTestEnable = depthBoundsTestEnable;1436}1437D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1438{1439return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL2;1440}1441operator const D3D12_DEPTH_STENCIL_DESC2& () const noexcept { return m_Desc; }1442operator D3D12_DEPTH_STENCIL_DESC2& () noexcept { return m_Desc; }1443private:1444void Init() noexcept1445{1446SUBOBJECT_HELPER_BASE::Init();1447}1448void* Data() noexcept override { return &m_Desc; }1449CD3DX12_DEPTH_STENCIL_DESC2 m_Desc;1450};14511452//------------------------------------------------------------------------------------------------1453class CD3DX12_INPUT_LAYOUT_SUBOBJECT1454: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1455{1456public:1457CD3DX12_INPUT_LAYOUT_SUBOBJECT()1458{1459Init();1460}1461CD3DX12_INPUT_LAYOUT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1462{1463Init();1464AddToStateObject(ContainingStateObject);1465}1466void AddInputLayoutElementDesc(D3D12_INPUT_ELEMENT_DESC inputLayoutElementDesc)1467{1468m_inputLayoutElements.emplace_back(1469D3D12_INPUT_ELEMENT_DESC{1470m_Strings.LocalCopy(inputLayoutElementDesc.SemanticName),1471inputLayoutElementDesc.SemanticIndex,1472inputLayoutElementDesc.Format,1473inputLayoutElementDesc.InputSlot,1474inputLayoutElementDesc.AlignedByteOffset,1475inputLayoutElementDesc.InputSlotClass,1476inputLayoutElementDesc.InstanceDataStepRate1477});1478++m_Desc.NumElements;1479// Below: using ugly way to get pointer in case .data() is not defined1480m_Desc.pInputElementDescs = &m_inputLayoutElements[0];1481}1482D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1483{1484return D3D12_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT;1485}1486operator const D3D12_INPUT_LAYOUT_DESC& () const noexcept { return m_Desc; }1487private:1488void Init() noexcept1489{1490SUBOBJECT_HELPER_BASE::Init();1491m_Desc = {};1492m_inputLayoutElements.clear();1493}1494void* Data() noexcept override { return &m_Desc; }1495D3D12_INPUT_LAYOUT_DESC m_Desc;1496std::vector<D3D12_INPUT_ELEMENT_DESC> m_inputLayoutElements;1497CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCSTR, std::string> m_Strings;1498};14991500//------------------------------------------------------------------------------------------------1501class CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT1502: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1503{1504public:1505CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT()1506: m_Desc(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED)1507{1508Init();1509}1510CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1511: m_Desc(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED)1512{1513Init();1514AddToStateObject(ContainingStateObject);1515}1516CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE desc)1517: m_Desc(desc)1518{1519Init();1520}1521CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1522: m_Desc(desc)1523{1524Init();1525AddToStateObject(ContainingStateObject);1526}1527void SetIBStripCutValue(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ibStripCutValue)1528{1529m_Desc = ibStripCutValue;1530}1531D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1532{1533return D3D12_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE;1534}1535operator const D3D12_INDEX_BUFFER_STRIP_CUT_VALUE& () const noexcept { return m_Desc; }1536operator D3D12_INDEX_BUFFER_STRIP_CUT_VALUE& () noexcept { return m_Desc; }1537private:1538void Init() noexcept1539{1540SUBOBJECT_HELPER_BASE::Init();1541}1542void* Data() noexcept override { return &m_Desc; }1543D3D12_INDEX_BUFFER_STRIP_CUT_VALUE m_Desc;1544};15451546//------------------------------------------------------------------------------------------------1547class CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT1548: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1549{1550public:1551CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT()1552: m_Desc(D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED)1553{1554Init();1555}1556CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1557: m_Desc(D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED)1558{1559Init();1560AddToStateObject(ContainingStateObject);1561}1562CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(D3D12_PRIMITIVE_TOPOLOGY_TYPE desc)1563: m_Desc(desc)1564{1565Init();1566}1567CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(D3D12_PRIMITIVE_TOPOLOGY_TYPE desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1568: m_Desc(desc)1569{1570Init();1571AddToStateObject(ContainingStateObject);1572}1573void SetPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE primitiveTopologytype)1574{1575m_Desc = primitiveTopologytype;1576}1577D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1578{1579return D3D12_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY;1580}1581operator const D3D12_PRIMITIVE_TOPOLOGY_TYPE& () const noexcept { return m_Desc; }1582operator D3D12_PRIMITIVE_TOPOLOGY_TYPE& () noexcept { return m_Desc; }1583private:1584void Init() noexcept1585{1586SUBOBJECT_HELPER_BASE::Init();1587}1588void* Data() noexcept override { return &m_Desc; }1589D3D12_PRIMITIVE_TOPOLOGY_TYPE m_Desc;1590};15911592//------------------------------------------------------------------------------------------------1593class CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT1594: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1595{1596public:1597CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT()1598: m_Desc({})1599{1600Init();1601}1602CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1603: m_Desc({})1604{1605Init();1606AddToStateObject(ContainingStateObject);1607}1608CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(const D3D12_RT_FORMAT_ARRAY &desc)1609: m_Desc(desc)1610{1611Init();1612}1613CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(const D3D12_RT_FORMAT_ARRAY &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1614: m_Desc(desc)1615{1616Init();1617AddToStateObject(ContainingStateObject);1618}1619void SetNumRenderTargets(UINT numRenderTargets)1620{1621m_Desc.NumRenderTargets = numRenderTargets;1622}1623void SetRenderTargetFormat(UINT renderTarget, DXGI_FORMAT renderTargetFormat)1624{1625m_Desc.RTFormats[renderTarget] = renderTargetFormat;1626}1627D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1628{1629return D3D12_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS;1630}1631operator const D3D12_RT_FORMAT_ARRAY& () const noexcept { return m_Desc; }1632operator D3D12_RT_FORMAT_ARRAY& () noexcept { return m_Desc; }1633private:1634void Init() noexcept1635{1636SUBOBJECT_HELPER_BASE::Init();1637}1638void* Data() noexcept override { return &m_Desc; }1639D3D12_RT_FORMAT_ARRAY m_Desc;1640};16411642//------------------------------------------------------------------------------------------------1643class CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT1644: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1645{1646public:1647CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT()1648: m_Desc(DXGI_FORMAT_UNKNOWN)1649{1650Init();1651}1652CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1653: m_Desc(DXGI_FORMAT_UNKNOWN)1654{1655Init();1656AddToStateObject(ContainingStateObject);1657}1658CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(DXGI_FORMAT desc)1659: m_Desc(desc)1660{1661Init();1662}1663CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(DXGI_FORMAT desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1664: m_Desc(desc)1665{1666Init();1667AddToStateObject(ContainingStateObject);1668}1669void SetDepthStencilFormat(DXGI_FORMAT depthStencilFormat)1670{1671m_Desc = depthStencilFormat;1672}1673D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1674{1675return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT;1676}1677operator const DXGI_FORMAT& () const noexcept { return m_Desc; }1678operator DXGI_FORMAT& () noexcept { return m_Desc; }1679private:1680void Init() noexcept1681{1682SUBOBJECT_HELPER_BASE::Init();1683}1684void* Data() noexcept override { return &m_Desc; }1685DXGI_FORMAT m_Desc;1686};16871688//------------------------------------------------------------------------------------------------1689class CD3DX12_SAMPLE_DESC_SUBOBJECT1690: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1691{1692public:1693CD3DX12_SAMPLE_DESC_SUBOBJECT()1694: m_Desc({1, 0})1695{1696Init();1697}1698CD3DX12_SAMPLE_DESC_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1699: m_Desc({1, 0})1700{1701Init();1702AddToStateObject(ContainingStateObject);1703}1704CD3DX12_SAMPLE_DESC_SUBOBJECT(const DXGI_SAMPLE_DESC &desc)1705: m_Desc(desc)1706{1707Init();1708}1709CD3DX12_SAMPLE_DESC_SUBOBJECT(const DXGI_SAMPLE_DESC &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1710: m_Desc(desc)1711{1712Init();1713AddToStateObject(ContainingStateObject);1714}1715void SetCount(UINT count)1716{1717m_Desc.Count = count;1718}1719void SetQuality(UINT quality)1720{1721m_Desc.Quality = quality;1722}1723D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1724{1725return D3D12_STATE_SUBOBJECT_TYPE_SAMPLE_DESC;1726}1727operator const DXGI_SAMPLE_DESC& () const noexcept { return m_Desc; }1728operator DXGI_SAMPLE_DESC& () noexcept { return m_Desc; }1729private:1730void Init() noexcept1731{1732SUBOBJECT_HELPER_BASE::Init();1733m_Desc = {};1734}1735void* Data() noexcept override { return &m_Desc; }1736DXGI_SAMPLE_DESC m_Desc;1737};17381739//------------------------------------------------------------------------------------------------1740class CD3DX12_FLAGS_SUBOBJECT1741: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1742{1743public:1744CD3DX12_FLAGS_SUBOBJECT()1745: m_Desc(D3D12_PIPELINE_STATE_FLAG_NONE)1746{1747Init();1748}1749CD3DX12_FLAGS_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1750: m_Desc(D3D12_PIPELINE_STATE_FLAG_NONE)1751{1752Init();1753AddToStateObject(ContainingStateObject);1754}1755CD3DX12_FLAGS_SUBOBJECT(D3D12_PIPELINE_STATE_FLAGS desc)1756: m_Desc(desc)1757{1758Init();1759}1760CD3DX12_FLAGS_SUBOBJECT(D3D12_PIPELINE_STATE_FLAGS desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1761: m_Desc(desc)1762{1763Init();1764AddToStateObject(ContainingStateObject);1765}1766void SetFlags(D3D12_PIPELINE_STATE_FLAGS flags)1767{1768m_Desc = flags;1769}1770D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1771{1772return D3D12_STATE_SUBOBJECT_TYPE_FLAGS;1773}1774operator const D3D12_PIPELINE_STATE_FLAGS& () const noexcept { return m_Desc; }1775operator D3D12_PIPELINE_STATE_FLAGS& () noexcept { return m_Desc; }1776private:1777void Init() noexcept1778{1779SUBOBJECT_HELPER_BASE::Init();1780}1781void* Data() noexcept override { return &m_Desc; }1782D3D12_PIPELINE_STATE_FLAGS m_Desc;1783};17841785//------------------------------------------------------------------------------------------------1786class CD3DX12_VIEW_INSTANCING_SUBOBJECT1787: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1788{1789public:1790CD3DX12_VIEW_INSTANCING_SUBOBJECT()1791{1792Init();1793}1794CD3DX12_VIEW_INSTANCING_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1795{1796Init();1797AddToStateObject(ContainingStateObject);1798}1799void AddViewInstanceLocation(D3D12_VIEW_INSTANCE_LOCATION viewInstanceLocation)1800{1801m_Desc.ViewInstanceCount++;1802m_viewInstanceLocations.emplace_back(1803D3D12_VIEW_INSTANCE_LOCATION1804{1805viewInstanceLocation.ViewportArrayIndex,1806viewInstanceLocation.RenderTargetArrayIndex1807}1808);1809// Below: using ugly way to get pointer in case .data() is not defined1810m_Desc.pViewInstanceLocations = &m_viewInstanceLocations[0];1811}1812void SetFlags(D3D12_VIEW_INSTANCING_FLAGS flags)1813{1814m_Desc.Flags = flags;1815}1816D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1817{1818return D3D12_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING;1819}1820operator const D3D12_VIEW_INSTANCING_DESC& () const noexcept { return m_Desc; }1821private:1822void Init() noexcept1823{1824SUBOBJECT_HELPER_BASE::Init();1825m_Desc = CD3DX12_VIEW_INSTANCING_DESC(D3D12_DEFAULT);1826m_viewInstanceLocations.clear();1827}1828void* Data() noexcept override { return &m_Desc; }1829CD3DX12_VIEW_INSTANCING_DESC m_Desc;1830std::vector<D3D12_VIEW_INSTANCE_LOCATION> m_viewInstanceLocations;1831};18321833//------------------------------------------------------------------------------------------------1834class CD3DX12_DEPTH_STENCIL_SUBOBJECT1835: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1836{1837public:1838CD3DX12_DEPTH_STENCIL_SUBOBJECT()1839: m_Desc(CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT))1840{1841Init();1842}1843CD3DX12_DEPTH_STENCIL_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1844: m_Desc(CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT))1845{1846Init();1847AddToStateObject(ContainingStateObject);1848}1849CD3DX12_DEPTH_STENCIL_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC &desc)1850: m_Desc(desc)1851{1852Init();1853}1854CD3DX12_DEPTH_STENCIL_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1855: m_Desc(desc)1856{1857Init();1858AddToStateObject(ContainingStateObject);1859}1860void SetDepthEnable(BOOL depthEnable)1861{1862m_Desc.DepthEnable = depthEnable;1863}1864void SetDepthWriteMask(D3D12_DEPTH_WRITE_MASK depthWriteMask)1865{1866m_Desc.DepthWriteMask = depthWriteMask;1867}1868void SetDepthFunc(D3D12_COMPARISON_FUNC depthFunc)1869{1870m_Desc.DepthFunc = depthFunc;1871}1872void SetStencilEnable(BOOL stencilEnable)1873{1874m_Desc.StencilEnable = stencilEnable;1875}1876void SetStencilReadMask(UINT8 stencilReadMask)1877{1878m_Desc.StencilReadMask = stencilReadMask;1879}1880void SetStencilWriteMask(UINT8 stencilWriteMask)1881{1882m_Desc.StencilWriteMask = stencilWriteMask;1883}1884void SetFrontFace(D3D12_DEPTH_STENCILOP_DESC frontFace)1885{1886m_Desc.FrontFace = {1887frontFace.StencilFailOp,1888frontFace.StencilDepthFailOp,1889frontFace.StencilPassOp,1890frontFace.StencilFunc1891};1892}1893void SetBackFace(D3D12_DEPTH_STENCILOP_DESC backFace)1894{1895m_Desc.BackFace = {1896backFace.StencilFailOp,1897backFace.StencilDepthFailOp,1898backFace.StencilPassOp,1899backFace.StencilFunc1900};1901}1902D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1903{1904return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL;1905}1906operator const D3D12_DEPTH_STENCIL_DESC& () const noexcept { return m_Desc; }1907operator D3D12_DEPTH_STENCIL_DESC& () noexcept { return m_Desc; }1908private:1909void Init() noexcept1910{1911SUBOBJECT_HELPER_BASE::Init();1912}1913void* Data() noexcept override { return &m_Desc; }1914CD3DX12_DEPTH_STENCIL_DESC m_Desc;1915};19161917//------------------------------------------------------------------------------------------------1918class CD3DX12_DEPTH_STENCIL1_SUBOBJECT1919: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE1920{1921public:1922CD3DX12_DEPTH_STENCIL1_SUBOBJECT()1923: m_Desc(CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEFAULT))1924{1925Init();1926}1927CD3DX12_DEPTH_STENCIL1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1928: m_Desc(CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEFAULT))1929{1930Init();1931AddToStateObject(ContainingStateObject);1932}1933CD3DX12_DEPTH_STENCIL1_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC1 &desc)1934: m_Desc(desc)1935{1936Init();1937}1938CD3DX12_DEPTH_STENCIL1_SUBOBJECT(const D3D12_DEPTH_STENCIL_DESC1 &desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)1939: m_Desc(desc)1940{1941Init();1942AddToStateObject(ContainingStateObject);1943}1944void SetDepthEnable(BOOL depthEnable)1945{1946m_Desc.DepthEnable = depthEnable;1947}1948void SetDepthWriteMask(D3D12_DEPTH_WRITE_MASK depthWriteMask)1949{1950m_Desc.DepthWriteMask = depthWriteMask;1951}1952void SetDepthFunc(D3D12_COMPARISON_FUNC depthFunc)1953{1954m_Desc.DepthFunc = depthFunc;1955}1956void SetStencilEnable(BOOL stencilEnable)1957{1958m_Desc.StencilEnable = stencilEnable;1959}1960void SetStencilReadMask(UINT8 stencilReadMask)1961{1962m_Desc.StencilReadMask = stencilReadMask;1963}1964void SetStencilWriteMask(UINT8 stencilWriteMask)1965{1966m_Desc.StencilWriteMask = stencilWriteMask;1967}1968void SetFrontFace(D3D12_DEPTH_STENCILOP_DESC frontFace)1969{1970m_Desc.FrontFace = {1971frontFace.StencilFailOp,1972frontFace.StencilDepthFailOp,1973frontFace.StencilPassOp,1974frontFace.StencilFunc1975};1976}1977void SetBackFace(D3D12_DEPTH_STENCILOP_DESC backFace)1978{1979m_Desc.BackFace = {1980backFace.StencilFailOp,1981backFace.StencilDepthFailOp,1982backFace.StencilPassOp,1983backFace.StencilFunc1984};1985}1986void SetDepthBoundsTestEnable(BOOL depthBoundsTestEnable)1987{1988m_Desc.DepthBoundsTestEnable = depthBoundsTestEnable;1989}1990D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override1991{1992return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1;1993}1994operator const D3D12_DEPTH_STENCIL_DESC1& () const noexcept { return m_Desc; }1995operator D3D12_DEPTH_STENCIL_DESC1& () noexcept { return m_Desc; }1996private:1997void Init() noexcept1998{1999SUBOBJECT_HELPER_BASE::Init();2000}2001void* Data() noexcept override { return &m_Desc; }2002CD3DX12_DEPTH_STENCIL_DESC1 m_Desc;2003};20042005//------------------------------------------------------------------------------------------------2006class CD3DX12_SAMPLE_MASK_SUBOBJECT2007: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE2008{2009public:2010CD3DX12_SAMPLE_MASK_SUBOBJECT()2011: m_Desc(0xffffffffu)2012{2013Init();2014}2015CD3DX12_SAMPLE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)2016: m_Desc(0xffffffffu)2017{2018Init();2019AddToStateObject(ContainingStateObject);2020}2021CD3DX12_SAMPLE_MASK_SUBOBJECT(UINT desc)2022: m_Desc(desc)2023{2024Init();2025}2026CD3DX12_SAMPLE_MASK_SUBOBJECT(UINT desc, CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)2027: m_Desc(desc)2028{2029Init();2030AddToStateObject(ContainingStateObject);2031}2032void SetSampleMask(UINT sampleMask)2033{2034m_Desc = sampleMask;2035}2036D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override2037{2038return D3D12_STATE_SUBOBJECT_TYPE_SAMPLE_MASK;2039}2040operator const UINT& () const noexcept { return m_Desc; }2041operator UINT& () noexcept { return m_Desc; }2042private:2043void Init() noexcept2044{2045SUBOBJECT_HELPER_BASE::Init();2046}2047void* Data() noexcept override { return &m_Desc; }2048UINT m_Desc;2049};20502051//------------------------------------------------------------------------------------------------2052class CD3DX12_GENERIC_PROGRAM_SUBOBJECT2053: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE2054{2055public:2056CD3DX12_GENERIC_PROGRAM_SUBOBJECT()2057{2058Init();2059}2060CD3DX12_GENERIC_PROGRAM_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)2061{2062Init();2063AddToStateObject(ContainingStateObject);2064}2065void SetProgramName(LPCWSTR ProgramName)2066{2067m_Desc.ProgramName = m_Strings.LocalCopy(ProgramName);2068}2069void AddExport(LPCWSTR exportName)2070{2071m_Exports.emplace_back(m_Strings.LocalCopy(exportName));2072m_Desc.NumExports++;2073// Below: using ugly way to get pointer in case .data() is not defined2074m_Desc.pExports = &m_Exports[0];2075}2076void AddSubobject(const D3D12_STATE_SUBOBJECT& subobject)2077{2078m_Subobjects.emplace_back(&subobject);2079m_Desc.NumSubobjects++;2080// Below: using ugly way to get pointer in case .data() is not defined2081m_Desc.ppSubobjects = &m_Subobjects[0];2082}2083D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override2084{2085return D3D12_STATE_SUBOBJECT_TYPE_GENERIC_PROGRAM;2086}2087operator const D3D12_GENERIC_PROGRAM_DESC& () const noexcept { return m_Desc; }2088private:2089void Init() noexcept2090{2091SUBOBJECT_HELPER_BASE::Init();2092m_Desc = {};2093}2094void* Data() noexcept override { return &m_Desc; }2095D3D12_GENERIC_PROGRAM_DESC m_Desc;2096std::vector<LPCWSTR> m_Exports;2097std::vector<D3D12_STATE_SUBOBJECT const*> m_Subobjects;2098CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;2099};21002101//------------------------------------------------------------------------------------------------2102class CD3DX12_NODE_OUTPUT_OVERRIDES2103{2104public:2105CD3DX12_NODE_OUTPUT_OVERRIDES(const D3D12_NODE_OUTPUT_OVERRIDES** ppOwner, UINT* pNumOutputOverrides) noexcept2106{2107m_Desc.clear();2108m_ppOwner = ppOwner;2109*m_ppOwner = nullptr;2110m_pNumOutputOverrides = pNumOutputOverrides;2111*m_pNumOutputOverrides = 0;2112}2113void NewOutputOverride()2114{2115m_Desc.emplace_back(D3D12_NODE_OUTPUT_OVERRIDES{});2116*m_ppOwner = m_Desc.data();2117(*m_pNumOutputOverrides)++;2118}2119void OutputIndex(UINT index)2120{2121m_Desc.back().OutputIndex = index;2122}2123void NewName(LPCWSTR Name, UINT ArrayIndex = 0)2124{2125m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(Name),ArrayIndex });2126m_Desc.back().pNewName = &m_NodeIDs.front();2127}2128void AllowSparseNodes(BOOL bAllow)2129{2130m_UINTs.emplace_front((UINT)bAllow);2131m_Desc.back().pAllowSparseNodes = (BOOL*)&m_UINTs.front();2132}2133void MaxOutputRecords(UINT maxOutputRecords) noexcept2134{2135m_UINTs.emplace_front(maxOutputRecords);2136m_Desc.back().pMaxRecords = &m_UINTs.front();2137}2138void MaxOutputRecordsSharedWith(UINT outputIndex) noexcept2139{2140m_UINTs.emplace_front(outputIndex);2141m_Desc.back().pMaxRecordsSharedWithOutputIndex = &m_UINTs.front();2142}2143private:2144std::vector<D3D12_NODE_OUTPUT_OVERRIDES> m_Desc;2145// Cached parameters2146CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;2147std::forward_list<UINT> m_UINTs;2148std::forward_list<D3D12_NODE_ID> m_NodeIDs;2149const D3D12_NODE_OUTPUT_OVERRIDES** m_ppOwner;2150UINT* m_pNumOutputOverrides;2151};21522153//------------------------------------------------------------------------------------------------2154class CD3DX12_WORK_GRAPH_SUBOBJECT;21552156//------------------------------------------------------------------------------------------------2157class CD3DX12_NODE_HELPER_BASE2158{2159protected:2160struct Backreference2161{2162CD3DX12_WORK_GRAPH_SUBOBJECT *m_pGraph;2163UINT m_NodeIndex;2164};2165public:2166CD3DX12_NODE_HELPER_BASE(const Backreference &BackRef)2167: m_BackRef(BackRef)2168{2169}2170virtual ~CD3DX12_NODE_HELPER_BASE() = default;2171protected:2172D3D12_NODE *GetNode() const;2173const Backreference m_BackRef;2174CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;2175};21762177//------------------------------------------------------------------------------------------------2178class CD3DX12_SHADER_NODE // Not specifying launch mode.2179// Don't need to distinguish if no parameter overriding is happening2180: public CD3DX12_NODE_HELPER_BASE2181{2182public:2183CD3DX12_SHADER_NODE(2184const Backreference &BackRef,2185LPCWSTR _Shader = nullptr)2186: CD3DX12_NODE_HELPER_BASE(BackRef)2187{2188GetNode()->NodeType = D3D12_NODE_TYPE_SHADER;2189Shader(_Shader);2190}2191void Shader(LPCWSTR _Shader)2192{2193GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader);2194}2195LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; }2196};21972198#endif // D3D12_SDK_VERSION >= 612219922002201#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)22022203//------------------------------------------------------------------------------------------------2204// Use this class when defining a broadcasting launch node where configuration parameters2205// need to be overridden. If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE2206class CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES2207: public CD3DX12_NODE_HELPER_BASE2208{2209public:2210CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES(2211const Backreference &BackRef,2212LPCWSTR _Shader = nullptr) :2213CD3DX12_NODE_HELPER_BASE(BackRef),2214m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides)2215{2216Overrides = {};2217D3D12_NODE *pNode = GetNode();2218pNode->NodeType = D3D12_NODE_TYPE_SHADER;2219pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_BROADCASTING_LAUNCH;2220pNode->Shader.pBroadcastingLaunchOverrides = &Overrides;2221Shader(_Shader);2222}2223void Shader(LPCWSTR _Shader)2224{2225GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader);2226}2227LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; }2228void LocalRootArgumentsTableIndex(UINT index)2229{2230m_UINTs.emplace_front(index);2231Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front();2232}2233void ProgramEntry(BOOL bIsProgramEntry)2234{2235m_UINTs.emplace_front(bIsProgramEntry);2236Overrides.pProgramEntry = (BOOL*)&m_UINTs.front();2237}2238void NewName(D3D12_NODE_ID NodeID)2239{2240m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2241Overrides.pNewName = &m_NodeIDs.front();2242}2243void ShareInputOf(D3D12_NODE_ID NodeID)2244{2245m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2246Overrides.pShareInputOf = &m_NodeIDs.front();2247}2248void DispatchGrid(UINT x, UINT y, UINT z)2249{2250m_UINT3s.emplace_front(UINT3{ x,y,z });2251Overrides.pDispatchGrid = (UINT*)&m_UINT3s.front();2252}2253void MaxDispatchGrid(UINT x, UINT y, UINT z)2254{2255m_UINT3s.emplace_front(UINT3{x,y,z});2256Overrides.pMaxDispatchGrid = (UINT*)&m_UINT3s.front();2257}2258CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides()2259{2260return m_NodeOutputOverrides;2261}2262D3D12_BROADCASTING_LAUNCH_OVERRIDES Overrides;2263private:2264// Cached parameters2265std::forward_list<UINT> m_UINTs;2266struct UINT32267{2268UINT x;2269UINT y;2270UINT z;2271};2272std::forward_list<UINT3> m_UINT3s;2273std::forward_list<D3D12_NODE_ID> m_NodeIDs;2274CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides;2275};22762277//------------------------------------------------------------------------------------------------2278// Use this class when defining a coalescing launch node where configuration parameters2279// need to be overridden. If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE2280class CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES2281: public CD3DX12_NODE_HELPER_BASE2282{2283public:2284CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES(2285const Backreference &BackRef,2286LPCWSTR _Shader = nullptr) :2287CD3DX12_NODE_HELPER_BASE(BackRef),2288m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides)2289{2290Overrides = {};2291D3D12_NODE *pNode = GetNode();2292pNode->NodeType = D3D12_NODE_TYPE_SHADER;2293pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_COALESCING_LAUNCH;2294pNode->Shader.pCoalescingLaunchOverrides = &Overrides;2295Shader(_Shader);2296}2297void Shader(LPCWSTR _Shader)2298{2299GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader);2300}2301LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; }2302void LocalRootArgumentsTableIndex(UINT index)2303{2304m_UINTs.emplace_front(index);2305Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front();2306}2307void ProgramEntry(BOOL bIsProgramEntry)2308{2309m_UINTs.emplace_front(bIsProgramEntry);2310Overrides.pProgramEntry = (BOOL*)&m_UINTs.front();2311}2312void NewName(D3D12_NODE_ID NodeID)2313{2314m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2315Overrides.pNewName = &m_NodeIDs.front();2316}2317void ShareInputOf(D3D12_NODE_ID NodeID)2318{2319m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2320Overrides.pShareInputOf = &m_NodeIDs.front();2321}2322CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides()2323{2324return m_NodeOutputOverrides;2325}2326D3D12_COALESCING_LAUNCH_OVERRIDES Overrides;2327private:2328// Cached parameters2329std::forward_list<UINT> m_UINTs;2330struct UINT32331{2332UINT x;2333UINT y;2334UINT z;2335};2336std::forward_list<UINT3> m_UINT3s;2337std::forward_list<D3D12_NODE_ID> m_NodeIDs;2338CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides;2339};23402341//------------------------------------------------------------------------------------------------2342// Use this class when defining a thread launch node where configuration parameters2343// need to be overridden. If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE2344class CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES2345: public CD3DX12_NODE_HELPER_BASE2346{2347public:2348CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES(2349const Backreference &BackRef,2350LPCWSTR _Shader = nullptr) :2351CD3DX12_NODE_HELPER_BASE(BackRef),2352m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides)2353{2354Overrides = {};2355D3D12_NODE *pNode = GetNode();2356pNode->NodeType = D3D12_NODE_TYPE_SHADER;2357pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_THREAD_LAUNCH;2358pNode->Shader.pThreadLaunchOverrides = &Overrides;2359Shader(_Shader);2360}2361void Shader(LPCWSTR _Shader)2362{2363GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader);2364}2365LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; }2366void LocalRootArgumentsTableIndex(UINT index)2367{2368m_UINTs.emplace_front(index);2369Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front();2370}2371void ProgramEntry(BOOL bIsProgramEntry)2372{2373m_UINTs.emplace_front(bIsProgramEntry);2374Overrides.pProgramEntry = (BOOL*)&m_UINTs.front();2375}2376void NewName(D3D12_NODE_ID NodeID)2377{2378m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2379Overrides.pNewName = &m_NodeIDs.front();2380}2381void ShareInputOf(D3D12_NODE_ID NodeID)2382{2383m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2384Overrides.pShareInputOf = &m_NodeIDs.front();2385}2386CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides()2387{2388return m_NodeOutputOverrides;2389}2390D3D12_THREAD_LAUNCH_OVERRIDES Overrides;2391private:2392// Cached parameters2393std::forward_list<UINT> m_UINTs;2394std::forward_list<D3D12_NODE_ID> m_NodeIDs;2395CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides;2396};23972398//------------------------------------------------------------------------------------------------2399// Use this class when defining a node where configuration parameters2400// need to be overridden for parameters that are common to all launch node types.2401// This option is a convenience if you don't want to determine what the launch mode is2402// and just want to override a setting that isn't specific to launch mode.2403// If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE2404class CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES2405: public CD3DX12_NODE_HELPER_BASE2406{2407public:2408CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES(2409const Backreference &BackRef,2410LPCWSTR _Shader = nullptr) :2411CD3DX12_NODE_HELPER_BASE(BackRef),2412m_NodeOutputOverrides(&Overrides.pOutputOverrides, &Overrides.NumOutputOverrides)2413{2414Overrides = {};2415D3D12_NODE *pNode = GetNode();2416pNode->NodeType = D3D12_NODE_TYPE_SHADER;2417pNode->Shader.OverridesType = D3D12_NODE_OVERRIDES_TYPE_COMMON_COMPUTE;2418pNode->Shader.pThreadLaunchOverrides = &Overrides;2419Shader(_Shader);2420}2421void Shader(LPCWSTR _Shader)2422{2423GetNode()->Shader.Shader = m_Strings.LocalCopy(_Shader);2424}2425LPCWSTR GetShaderName() const { return GetNode()->Shader.Shader; }2426void LocalRootArgumentsTableIndex(UINT index)2427{2428m_UINTs.emplace_front(index);2429Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front();2430}2431void ProgramEntry(BOOL bIsProgramEntry)2432{2433m_UINTs.emplace_front(bIsProgramEntry);2434Overrides.pProgramEntry = (BOOL*)&m_UINTs.front();2435}2436void NewName(D3D12_NODE_ID NodeID)2437{2438m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2439Overrides.pNewName = &m_NodeIDs.front();2440}2441void ShareInputOf(D3D12_NODE_ID NodeID)2442{2443m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex });2444Overrides.pShareInputOf = &m_NodeIDs.front();2445}2446CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides()2447{2448return m_NodeOutputOverrides;2449}2450D3D12_THREAD_LAUNCH_OVERRIDES Overrides;2451private:2452// Cached parameters2453std::forward_list<UINT> m_UINTs;2454std::forward_list<D3D12_NODE_ID> m_NodeIDs;2455CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides;2456};24572458//------------------------------------------------------------------------------------------------2459class CD3DX12_WORK_GRAPH_SUBOBJECT2460: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE2461{2462public:2463CD3DX12_WORK_GRAPH_SUBOBJECT() noexcept2464{2465Init();2466}2467CD3DX12_WORK_GRAPH_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)2468{2469Init();2470AddToStateObject(ContainingStateObject);2471}2472D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override2473{2474return D3D12_STATE_SUBOBJECT_TYPE_WORK_GRAPH;2475}2476void IncludeAllAvailableNodes()2477{2478m_Desc.Flags |= D3D12_WORK_GRAPH_FLAG_INCLUDE_ALL_AVAILABLE_NODES;2479}248024812482void SetProgramName(LPCWSTR ProgramName)2483{2484m_Desc.ProgramName = m_Strings.LocalCopy(ProgramName);2485}2486void AddEntrypoint(D3D12_NODE_ID Entrypoint)2487{2488m_Entrypoints.emplace_back(D3D12_NODE_ID{ m_Strings.LocalCopy(Entrypoint.Name),Entrypoint.ArrayIndex });2489m_Desc.NumEntrypoints++;2490m_Desc.pEntrypoints = m_Entrypoints.data();2491}24922493template<typename T>2494T* CreateNode()2495{2496m_NodeDescs.push_back({});2497m_Desc.NumExplicitlyDefinedNodes++;2498m_Desc.pExplicitlyDefinedNodes = m_NodeDescs.data();2499T* pNodeHelper = new T({this, (UINT)m_NodeDescs.size() - 1});2500m_OwnedNodeHelpers.emplace_back(pNodeHelper);2501return pNodeHelper;2502}2503CD3DX12_SHADER_NODE* CreateShaderNode(LPCWSTR Shader = nullptr)2504{2505auto pNode = CreateNode<CD3DX12_SHADER_NODE>();2506pNode->Shader(Shader);2507return pNode;2508}2509CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES* CreateBroadcastingLaunchNodeOverrides(LPCWSTR Shader = nullptr)2510{2511auto pNode = CreateNode<CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES>();2512pNode->Shader(Shader);2513return pNode;2514}2515CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES* CreateCoalescingLaunchNodeOverrides(LPCWSTR Shader = nullptr)2516{2517auto pNode = CreateNode<CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES>();2518pNode->Shader(Shader);2519return pNode;2520}2521CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES* CreateThreadLaunchNodeOverrides(LPCWSTR Shader = nullptr)2522{2523auto pNode = CreateNode<CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES>();2524pNode->Shader(Shader);2525return pNode;2526}2527CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES* CreateCommonComputeNodeOverrides(LPCWSTR Shader = nullptr)2528{2529auto pNode = CreateNode<CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES>();2530pNode->Shader(Shader);2531return pNode;2532}2533#endif // D3D12_SDK_VERSION >= 612253425352536#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)25372538operator const D3D12_WORK_GRAPH_DESC& () noexcept2539{2540return m_Desc;2541}2542private:2543void Init() noexcept2544{2545SUBOBJECT_HELPER_BASE::Init();2546m_Desc = {};2547m_Entrypoints.clear();2548m_NodeDescs.clear();2549}2550void* Data() noexcept override { return &m_Desc; }2551D3D12_WORK_GRAPH_DESC m_Desc;2552std::vector<D3D12_NODE_ID> m_Entrypoints;2553std::vector<D3D12_NODE> m_NodeDescs;2554CD3DX12_STATE_OBJECT_DESC::StringContainer<LPCWSTR, std::wstring> m_Strings;2555std::vector<std::unique_ptr<const CD3DX12_NODE_HELPER_BASE>> m_OwnedNodeHelpers;2556friend class CD3DX12_NODE_HELPER_BASE;2557};25582559inline D3D12_NODE * CD3DX12_NODE_HELPER_BASE::GetNode() const2560{2561return &m_BackRef.m_pGraph->m_NodeDescs[m_BackRef.m_NodeIndex];2562}2563#endif // D3D12_SDK_VERSION >= 61225642565#undef D3DX12_COM_PTR2566#undef D3DX12_COM_PTR_GET2567#undef D3DX12_COM_PTR_ADDRESSOF25682569257025712572