From f51741ff06d638c21d3d0e0540dec7e790e3d2e3 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Fri, 17 May 2024 19:11:34 -0700 Subject: [PATCH] ADO pipeline changes for OpenSSF Best Practices (#232) --- Audio/AudioEngine.cpp | 2 +- CMakeLists.txt | 2 +- DirectXTK_Windows10_2022.vcxproj | 2 +- README.md | 6 + Src/GamePad.cpp | 2 +- Src/d3dx12.h | 1770 +++++++++++++++++++++-- Src/pch.h | 2 +- build/DirectXTK12-GitHub-Dev17.yml | 36 +- build/DirectXTK12-GitHub-Test-Dev17.yml | 26 +- build/DirectXTK12-GitHub.yml | 53 +- build/DirectXTK12-SDL.yml | 35 + 11 files changed, 1723 insertions(+), 213 deletions(-) diff --git a/Audio/AudioEngine.cpp b/Audio/AudioEngine.cpp index 808a3e63..90d5a8f7 100644 --- a/Audio/AudioEngine.cpp +++ b/Audio/AudioEngine.cpp @@ -1483,7 +1483,7 @@ X3DAUDIO_HANDLE& AudioEngine::Get3DHandle() const noexcept #ifdef _MSC_VER #pragma comment(lib,"runtimeobject.lib") #pragma warning(push) -#pragma warning(disable: 4471 5204 5256) +#pragma warning(disable: 4471 5204 5256 6553) #endif #ifdef __clang__ #pragma clang diagnostic ignored "-Wnonportable-system-include-path" diff --git a/CMakeLists.txt b/CMakeLists.txt index de3c0993..b98c1bcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -420,7 +420,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14) elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") if(ENABLE_CODE_ANALYSIS) - target_compile_options(${PROJECT_NAME} PRIVATE /analyze) + target_compile_options(${PROJECT_NAME} PRIVATE /analyze /WX) endif() if(ENABLE_SPECTRE_MITIGATION diff --git a/DirectXTK_Windows10_2022.vcxproj b/DirectXTK_Windows10_2022.vcxproj index fa21a02e..c04b777d 100644 --- a/DirectXTK_Windows10_2022.vcxproj +++ b/DirectXTK_Windows10_2022.vcxproj @@ -204,7 +204,7 @@ true Windows Store 10.0 - 10.0.17763.0 + 10.0.18362.0 10.0 x64 diff --git a/README.md b/README.md index 2f7d8efe..45b897a8 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ For the latest version of DirectXTK12, bug reports, etc. please visit the projec ## Release Notes +FOR SECURITY ADVISORIES, see [GitHub](https://github.com/microsoft/DirectXTK12/security/advisories). + +For a full change history, see [CHANGELOG.md](https://github.com/microsoft/DirectXTK12/blob/main/CHANGELOG.md). + * Starting with the February 2023 release, the Mouse class implementation of relative mouse movement was updated to accumulate changes between calls to ``GetState``. By default, each time you call ``GetState`` the deltas are reset which works for scenarios where you use relative movement but only call the method once per frame. If you call it more than once per frame, then add an explicit call to ``EndOfInputFrame`` to use an explicit reset model instead. * As of the September 2022 release, the library makes use of C++11 inline namespaces for differing types that have the same names in the DirectX 11 and DirectX 12 version of the *DirectX Tool Kit*. This provides a link-unique name such as ``DirectX::DX12::SpriteBatch`` that will appear in linker output messages. In most use cases, however, there is no need to add explicit ``DX12`` namespace resolution in client code. @@ -114,6 +118,8 @@ This project welcomes contributions and suggestions. Most contributions require When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. +Tests for new features should also be submitted as a PR to the [Test Suite](https://github.com/walbourn/directxtk12test/wiki) repository. + ## Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more informatsion see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/Src/GamePad.cpp b/Src/GamePad.cpp index 17bcada9..302a6bd3 100644 --- a/Src/GamePad.cpp +++ b/Src/GamePad.cpp @@ -422,7 +422,7 @@ bool GamePad::GetDevice(int player, _Outptr_ IGameInputDevice * *device) noexcep #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable : 4471 5204 5256) +#pragma warning(disable : 4471 5204 5256 6553) #endif #include #ifdef _MSC_VER diff --git a/Src/d3dx12.h b/Src/d3dx12.h index 5bc5b4d5..8e8e204c 100644 --- a/Src/d3dx12.h +++ b/Src/d3dx12.h @@ -2176,15 +2176,6 @@ constexpr UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneS return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; } -//------------------------------------------------------------------------------------------------ -template -inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept -{ - MipSlice = static_cast(Subresource % MipLevels); - ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); - PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); -} - //------------------------------------------------------------------------------------------------ inline UINT8 D3D12GetFormatPlaneCount( _In_ ID3D12Device* pDevice, @@ -2480,6 +2471,16 @@ struct CD3DX12_VIEW_INSTANCING_DESC : public D3D12_VIEW_INSTANCING_DESC } }; +//------------------------------------------------------------------------------------------------ +template +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept +{ + MipSlice = static_cast(Subresource % MipLevels); + ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); +} + + //------------------------------------------------------------------------------------------------ // Row-by-row memcpy inline void MemcpySubresource( @@ -2829,6 +2830,29 @@ inline UINT64 UpdateSubresources( constexpr bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) noexcept { return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } +//------------------------------------------------------------------------------------------------ +template< typename T > +inline T D3DX12Align(T uValue, T uAlign) +{ + // Assert power of 2 alignment + D3DX12_ASSERT(0 == (uAlign & (uAlign - 1))); + T uMask = uAlign - 1; + T uResult = (uValue + uMask) & ~uMask; + D3DX12_ASSERT(uResult >= uValue); + D3DX12_ASSERT(0 == (uResult % uAlign)); + return uResult; +} + +//------------------------------------------------------------------------------------------------ +template< typename T > +inline T D3DX12AlignAtLeast(T uValue, T uAlign) +{ + T aligned = D3DX12Align(uValue, uAlign); + return aligned > uAlign ? aligned : uAlign; +} + +// D3DX12GetCopyableFootprints is not included as it relies on D3D12_PROPERTY_LAYOUT_FORMAT_TABLE + //------------------------------------------------------------------------------------------------ template inline ID3D12CommandList * const * CommandListCast(t_CommandListType * const * pp) noexcept @@ -3203,6 +3227,9 @@ struct ID3DX12PipelineParserCallbacks virtual void ErrorBadInputParameter(UINT /*ParameterIndex*/) {} virtual void ErrorDuplicateSubobject(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE /*DuplicateType*/) {} virtual void ErrorUnknownSubobject(UINT /*UnknownTypeValue*/) {} +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 613) + virtual void FinalizeCb() {} +#endif virtual ~ID3DX12PipelineParserCallbacks() = default; }; @@ -3840,6 +3867,7 @@ struct CD3DX12_PIPELINE_MESH_STATE_STREAM : Flags(Desc.Flags) , NodeMask(Desc.NodeMask) , pRootSignature(Desc.pRootSignature) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) , PS(Desc.PS) , AS(Desc.AS) , MS(Desc.MS) @@ -3856,6 +3884,7 @@ struct CD3DX12_PIPELINE_MESH_STATE_STREAM CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; CD3DX12_PIPELINE_STATE_STREAM_PS PS; CD3DX12_PIPELINE_STATE_STREAM_AS AS; CD3DX12_PIPELINE_STATE_STREAM_MS MS; @@ -3871,21 +3900,22 @@ struct CD3DX12_PIPELINE_MESH_STATE_STREAM D3DX12_MESH_SHADER_PIPELINE_STATE_DESC MeshShaderDescV0() const noexcept { D3DX12_MESH_SHADER_PIPELINE_STATE_DESC D; - D.Flags = this->Flags; - D.NodeMask = this->NodeMask; - D.pRootSignature = this->pRootSignature; - D.PS = this->PS; - D.AS = this->AS; - D.MS = this->MS; - D.BlendState = this->BlendState; - D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); - D.DSVFormat = this->DSVFormat; - D.RasterizerState = this->RasterizerState; - D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.PS = this->PS; + D.AS = this->AS; + D.MS = this->MS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); - D.SampleDesc = this->SampleDesc; - D.SampleMask = this->SampleMask; - D.CachedPSO = this->CachedPSO; + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; return D; } }; @@ -4178,7 +4208,87 @@ struct CD3DX12_PIPELINE_STATE_STREAM4_PARSE_HELPER : public ID3DX12PipelineParse }; #endif // D3D12_SDK_VERSION >= 608 -#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 610) +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 613) +// This SDK 613 version has better primitive topology default handling than the v610 equivalent below. +struct CD3DX12_PIPELINE_STATE_STREAM5_PARSE_HELPER : public ID3DX12PipelineParserCallbacks +{ + CD3DX12_PIPELINE_STATE_STREAM5 PipelineStream; + CD3DX12_PIPELINE_STATE_STREAM5_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; + } + } + +private: + bool SeenDSS; + bool SeenMS; + bool SeenTopology; +}; +#elif defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 610) struct CD3DX12_PIPELINE_STATE_STREAM5_PARSE_HELPER : public ID3DX12PipelineParserCallbacks { CD3DX12_PIPELINE_STATE_STREAM5 PipelineStream; @@ -4478,6 +4588,9 @@ inline HRESULT D3DX12ParsePipelineStream(const D3D12_PIPELINE_STATE_STREAM_DESC& return E_INVALIDARG; } } +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 613) + pCallbacks->FinalizeCb(); +#endif return S_OK; } @@ -4516,17 +4629,6 @@ inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS return true; } -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4062) -#endif - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wswitch-default" -#endif - inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS &b) noexcept { if (a.Type != b.Type) return false; @@ -4542,6 +4644,8 @@ inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12 if (!(a.PreserveLocal == b.PreserveLocal)) return false; break; #endif + default: + break; } return true; } @@ -4561,19 +4665,13 @@ inline bool operator==(const D3D12_RENDER_PASS_ENDING_ACCESS& a, const D3D12_REN if (!(a.PreserveLocal == b.PreserveLocal)) return false; break; #endif + default: + break; } return true; } -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - inline bool operator==( const D3D12_RENDER_PASS_RENDER_TARGET_DESC &a, const D3D12_RENDER_PASS_RENDER_TARGET_DESC &b) noexcept { if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; @@ -4608,6 +4706,8 @@ inline bool operator==( const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &a, const D3D // //================================================================================================ #include +#include +#include #include #include #include @@ -4636,9 +4736,22 @@ class CD3DX12_STATE_OBJECT_DESC Init(Type); } void SetStateObjectType(D3D12_STATE_OBJECT_TYPE Type) noexcept { m_Desc.Type = Type; } - operator const D3D12_STATE_OBJECT_DESC&() + CD3DX12_STATE_OBJECT_DESC(const CD3DX12_STATE_OBJECT_DESC& other) = delete; + CD3DX12_STATE_OBJECT_DESC& operator=(const CD3DX12_STATE_OBJECT_DESC& other) = delete; + CD3DX12_STATE_OBJECT_DESC(CD3DX12_STATE_OBJECT_DESC&& other) = default; + 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(); +#endif m_RepointedAssociations.clear(); m_SubobjectArray.clear(); m_SubobjectArray.reserve(m_Desc.NumSubobjects); @@ -4666,12 +4779,36 @@ class CD3DX12_STATE_OBJECT_DESC m_RepointedAssociations.push_back(Repointed); m_SubobjectArray[i].pDesc = &m_RepointedAssociations.back(); } +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + else if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_GENERIC_PROGRAM) + { + auto originalGenericProgramDesc = + static_cast(m_SubobjectArray[i].pDesc); + D3D12_GENERIC_PROGRAM_DESC Repointed = *originalGenericProgramDesc; + if (originalGenericProgramDesc->NumSubobjects > 0) + { + m_RepointedSubobjectVectors.emplace_back(std::vector()); + std::vector& repointedGenericProgramSubobjects = m_RepointedSubobjectVectors.back(); + repointedGenericProgramSubobjects.resize(originalGenericProgramDesc->NumSubobjects); + for (UINT s = 0; s < originalGenericProgramDesc->NumSubobjects; s++) + { + auto pWrapper = + static_cast(originalGenericProgramDesc->ppSubobjects[s]); + repointedGenericProgramSubobjects[s] = pWrapper->pSubobjectArrayLocation; + } + // Below: using ugly way to get pointer in case .data() is not defined + Repointed.ppSubobjects = &repointedGenericProgramSubobjects[0]; + } + m_RepointedPrograms.push_back(Repointed); + m_SubobjectArray[i].pDesc = &m_RepointedPrograms.back(); + } +#endif } // Below: using ugly way to get pointer in case .data() is not defined m_Desc.pSubobjects = m_Desc.NumSubobjects ? &m_SubobjectArray[0] : nullptr; return m_Desc; } - operator const D3D12_STATE_OBJECT_DESC*() + operator const D3D12_STATE_OBJECT_DESC* () { // Cast calls the above final preparation work return &static_cast(*this); @@ -4729,6 +4866,10 @@ class CD3DX12_STATE_OBJECT_DESC m_SubobjectList.clear(); m_SubobjectArray.clear(); m_RepointedAssociations.clear(); +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + m_RepointedSubobjectVectors.clear(); + m_RepointedPrograms.clear(); +#endif } typedef struct SUBOBJECT_WRAPPER : public D3D12_STATE_SUBOBJECT { @@ -4741,13 +4882,21 @@ class CD3DX12_STATE_OBJECT_DESC std::vector m_SubobjectArray; // Built at the end, copying list contents std::list - m_RepointedAssociations; // subobject type that contains pointers to other subobjects, - // repointed to flattened array + m_RepointedAssociations; // subobject type that contains pointers to other subobjects, + // repointed to flattened array + +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + std::list> + m_RepointedSubobjectVectors; + std::list + m_RepointedPrograms; +#endif + template class StringContainer { public: - LPCWSTR LocalCopy(LPCWSTR string, bool bSingleString = false) + CStr LocalCopy(CStr string, bool bSingleString = false) { if (string) { @@ -4769,38 +4918,34 @@ class CD3DX12_STATE_OBJECT_DESC } void clear() noexcept { m_Strings.clear(); } private: - std::list m_Strings; + std::list m_Strings; }; +public: class SUBOBJECT_HELPER_BASE { public: SUBOBJECT_HELPER_BASE() noexcept { Init(); } virtual ~SUBOBJECT_HELPER_BASE() = default; virtual D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept = 0; + SUBOBJECT_HELPER_BASE(const SUBOBJECT_HELPER_BASE& other) = delete; + SUBOBJECT_HELPER_BASE& operator=(const SUBOBJECT_HELPER_BASE& other) = delete; + SUBOBJECT_HELPER_BASE(SUBOBJECT_HELPER_BASE&& other) = default; + SUBOBJECT_HELPER_BASE& operator=(SUBOBJECT_HELPER_BASE&& other) = default; void AddToStateObject(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) { 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; void Init() noexcept { m_pSubobject = nullptr; } D3D12_STATE_SUBOBJECT* m_pSubobject; }; -#if(__cplusplus >= 201103L) - std::list> m_OwnedSubobjectHelpers; -#else - class OWNED_HELPER - { - public: - OWNED_HELPER(const SUBOBJECT_HELPER_BASE* pHelper) noexcept { m_pHelper = pHelper; } - ~OWNED_HELPER() { delete m_pHelper; } - const SUBOBJECT_HELPER_BASE* m_pHelper; - }; - - std::list m_OwnedSubobjectHelpers; -#endif +private: + std::list> m_OwnedSubobjectHelpers; friend class CD3DX12_DXIL_LIBRARY_SUBOBJECT; friend class CD3DX12_EXISTING_COLLECTION_SUBOBJECT; @@ -4814,6 +4959,33 @@ class CD3DX12_STATE_OBJECT_DESC friend class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT; friend class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT; friend class CD3DX12_NODE_MASK_SUBOBJECT; + //TODO: SDK Version check should include all the newly added subobject type for the public release. + // The SDK version check will be changed based on when we release state objects. +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + friend class CD3DX12_GENERIC_PROGRAM_SUBOBJECT; + friend class CD3DX12_WORK_GRAPH_SUBOBJECT; + friend class CD3DX12_STREAM_OUTPUT_SUBOBJECT; + friend class CD3DX12_BLEND_SUBOBJECT; + friend class CD3DX12_RASTERIZER_SUBOBJECT; + friend class CD3DX12_DEPTH_STENCIL2_SUBOBJECT; + friend class CD3DX12_INPUT_LAYOUT_SUBOBJECT; + friend class CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT; + friend class CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT; + friend class CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT; + friend class CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT; + friend class CD3DX12_SAMPLE_DESC_SUBOBJECT; + friend class CD3DX12_FLAGS_SUBOBJECT; + friend class CD3DX12_VIEW_INSTANCING_SUBOBJECT; + friend class CD3DX12_DEPTH_STENCIL_SUBOBJECT; + friend class CD3DX12_DEPTH_STENCIL1_SUBOBJECT; + friend class CD3DX12_SAMPLE_MASK_SUBOBJECT; + friend class CD3DX12_NODE_OUTPUT_OVERRIDES; + 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 }; //------------------------------------------------------------------------------------------------ @@ -4867,7 +5039,6 @@ class CD3DX12_DXIL_LIBRARY_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_DXIL_LIBRARY_DESC&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -4879,7 +5050,7 @@ class CD3DX12_DXIL_LIBRARY_SUBOBJECT } void* Data() noexcept override { return &m_Desc; } D3D12_DXIL_LIBRARY_DESC m_Desc; - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::vector m_Exports; }; @@ -4934,7 +5105,6 @@ class CD3DX12_EXISTING_COLLECTION_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_EXISTING_COLLECTION_DESC&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -4948,7 +5118,7 @@ class CD3DX12_EXISTING_COLLECTION_SUBOBJECT void* Data() noexcept override { return &m_Desc; } D3D12_EXISTING_COLLECTION_DESC m_Desc; D3DX12_COM_PTR m_CollectionRef; - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::vector m_Exports; }; @@ -4995,7 +5165,6 @@ class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5007,7 +5176,7 @@ class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT } void* Data() noexcept override { return &m_Desc; } D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; std::vector m_Exports; }; @@ -5054,7 +5223,6 @@ class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION { return D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5067,8 +5235,8 @@ class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION } void* Data() noexcept override { return &m_Desc; } D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; - CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; - CD3DX12_STATE_OBJECT_DESC::StringContainer m_SubobjectName; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_SubobjectName; std::vector m_Exports; }; @@ -5107,7 +5275,6 @@ class CD3DX12_HIT_GROUP_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_HIT_GROUP_DESC&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5122,7 +5289,7 @@ class CD3DX12_HIT_GROUP_SUBOBJECT void* Data() noexcept override { return &m_Desc; } D3D12_HIT_GROUP_DESC m_Desc; static constexpr UINT m_NumStrings = 4; - CD3DX12_STATE_OBJECT_DESC::StringContainer + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings[m_NumStrings]; // one string for every entrypoint name }; @@ -5149,7 +5316,6 @@ class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_RAYTRACING_SHADER_CONFIG&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5183,7 +5349,6 @@ class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5218,7 +5383,6 @@ class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_RAYTRACING_PIPELINE_CONFIG1&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5252,7 +5416,6 @@ class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); } private: void Init() noexcept @@ -5286,7 +5449,6 @@ class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); } private: void Init() noexcept @@ -5320,7 +5482,6 @@ class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_STATE_OBJECT_CONFIG&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5354,7 +5515,6 @@ class CD3DX12_NODE_MASK_SUBOBJECT { return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK; } - operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } operator const D3D12_NODE_MASK&() const noexcept { return m_Desc; } private: void Init() noexcept @@ -5366,74 +5526,1385 @@ class CD3DX12_NODE_MASK_SUBOBJECT D3D12_NODE_MASK m_Desc; }; -#endif // !D3DX12_NO_STATE_OBJECT_HELPERS - - -#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 608) - -//================================================================================================ -// D3DX12 Enhanced Barrier Helpers -//================================================================================================ - -class CD3DX12_BARRIER_SUBRESOURCE_RANGE : public D3D12_BARRIER_SUBRESOURCE_RANGE +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) +//------------------------------------------------------------------------------------------------ +class CD3DX12_STREAM_OUTPUT_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE { public: - CD3DX12_BARRIER_SUBRESOURCE_RANGE() = default; - CD3DX12_BARRIER_SUBRESOURCE_RANGE(const D3D12_BARRIER_SUBRESOURCE_RANGE &o) noexcept : - D3D12_BARRIER_SUBRESOURCE_RANGE(o) - {} - explicit CD3DX12_BARRIER_SUBRESOURCE_RANGE(UINT Subresource) noexcept : - D3D12_BARRIER_SUBRESOURCE_RANGE{ Subresource, 0, 0, 0, 0, 0 } - {} - CD3DX12_BARRIER_SUBRESOURCE_RANGE( - UINT firstMipLevel, - UINT numMips, - UINT firstArraySlice, - UINT numArraySlices, - UINT firstPlane = 0, - UINT numPlanes = 1) noexcept : - D3D12_BARRIER_SUBRESOURCE_RANGE + CD3DX12_STREAM_OUTPUT_SUBOBJECT() + { + Init(); + } + CD3DX12_STREAM_OUTPUT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetSODeclEntries(const D3D12_SO_DECLARATION_ENTRY* soDeclEntries, UINT numEntries) + { + m_soDecalEntries.resize(numEntries); + for (UINT i = 0; i < numEntries; i++) { - firstMipLevel, - numMips, - firstArraySlice, - numArraySlices, - firstPlane, - numPlanes + m_soDecalEntries[i] = D3D12_SO_DECLARATION_ENTRY{ + soDeclEntries[i].Stream, + m_Strings.LocalCopy(soDeclEntries[i].SemanticName), + soDeclEntries[i].SemanticIndex, + soDeclEntries[i].StartComponent, + soDeclEntries[i].ComponentCount, + 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; + } + void SetBufferStrides(const UINT* bufferStrides, UINT numStrides) + { + m_Desc.pBufferStrides = bufferStrides; + m_Desc.NumStrides = numStrides; + } + void SetRasterizedStream(UINT rasterizedStream) + { + m_Desc.RasterizedStream = rasterizedStream; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT; + } + operator const D3D12_STREAM_OUTPUT_DESC& () const noexcept { return m_Desc; } + +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_STREAM_OUTPUT_DESC m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_soDecalEntries; }; -class CD3DX12_GLOBAL_BARRIER : public D3D12_GLOBAL_BARRIER +//------------------------------------------------------------------------------------------------ +class CD3DX12_BLEND_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE { public: - CD3DX12_GLOBAL_BARRIER() = default; - CD3DX12_GLOBAL_BARRIER(const D3D12_GLOBAL_BARRIER &o) noexcept : D3D12_GLOBAL_BARRIER(o){} - CD3DX12_GLOBAL_BARRIER( - D3D12_BARRIER_SYNC syncBefore, - D3D12_BARRIER_SYNC syncAfter, - D3D12_BARRIER_ACCESS accessBefore, - D3D12_BARRIER_ACCESS accessAfter) noexcept : D3D12_GLOBAL_BARRIER { - syncBefore, - syncAfter, - accessBefore, - accessAfter - } - {} + CD3DX12_BLEND_SUBOBJECT() + { + Init(); + } + CD3DX12_BLEND_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetAlphaToCoverageEnable(bool alphaToCoverageEnable) + { + m_Desc.AlphaToCoverageEnable = alphaToCoverageEnable; + } + void SetIndependentBlendEnable(bool independentBlendEnable) + { + m_Desc.IndependentBlendEnable = independentBlendEnable; + } + void SetRenderTarget(UINT renderTargetIndex, const D3D12_RENDER_TARGET_BLEND_DESC& renderTargetBlendDesc) + { + m_Desc.RenderTarget[renderTargetIndex].BlendEnable = renderTargetBlendDesc.BlendEnable; + m_Desc.RenderTarget[renderTargetIndex].BlendOp = renderTargetBlendDesc.BlendOp; + m_Desc.RenderTarget[renderTargetIndex].BlendOpAlpha = renderTargetBlendDesc.BlendOpAlpha; + m_Desc.RenderTarget[renderTargetIndex].DestBlend = renderTargetBlendDesc.DestBlend; + m_Desc.RenderTarget[renderTargetIndex].DestBlendAlpha = renderTargetBlendDesc.DestBlendAlpha; + m_Desc.RenderTarget[renderTargetIndex].LogicOp = renderTargetBlendDesc.LogicOp; + m_Desc.RenderTarget[renderTargetIndex].LogicOpEnable = renderTargetBlendDesc.LogicOpEnable; + m_Desc.RenderTarget[renderTargetIndex].RenderTargetWriteMask = renderTargetBlendDesc.RenderTargetWriteMask; + m_Desc.RenderTarget[renderTargetIndex].SrcBlend = renderTargetBlendDesc.SrcBlend; + m_Desc.RenderTarget[renderTargetIndex].SrcBlendAlpha = renderTargetBlendDesc.SrcBlendAlpha; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_BLEND; + } + operator const D3D12_BLEND_DESC& () const 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; }; -class CD3DX12_BUFFER_BARRIER : public D3D12_BUFFER_BARRIER +//------------------------------------------------------------------------------------------------ +class CD3DX12_RASTERIZER_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE { public: - CD3DX12_BUFFER_BARRIER() = default; - CD3DX12_BUFFER_BARRIER(const D3D12_BUFFER_BARRIER &o) noexcept : D3D12_BUFFER_BARRIER(o){} - CD3DX12_BUFFER_BARRIER( - D3D12_BARRIER_SYNC syncBefore, - D3D12_BARRIER_SYNC syncAfter, - D3D12_BARRIER_ACCESS accessBefore, - D3D12_BARRIER_ACCESS accessAfter, - ID3D12Resource *pRes) noexcept : D3D12_BUFFER_BARRIER { - syncBefore, + CD3DX12_RASTERIZER_SUBOBJECT() + { + Init(); + } + CD3DX12_RASTERIZER_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetFillMode(D3D12_FILL_MODE fillMode) + { + m_Desc.FillMode = fillMode; + } + void SetCullMode(D3D12_CULL_MODE cullMode) + { + m_Desc.CullMode = cullMode; + } + void SetFrontCounterClockwise(BOOL frontCounterClockwise) + { + m_Desc.FrontCounterClockwise = frontCounterClockwise; + } + void SetDepthBias(FLOAT depthBias) + { + m_Desc.DepthBias = depthBias; + } + void SetDepthBiasClamp(FLOAT depthBiasClamp) + { + m_Desc.DepthBiasClamp = depthBiasClamp; + } + void SetSlopeScaledDepthBias(FLOAT slopeScaledDepthBias) + { + m_Desc.SlopeScaledDepthBias = slopeScaledDepthBias; + } + void SetDepthClipEnable(BOOL depthClipEnable) + { + m_Desc.DepthClipEnable = depthClipEnable; + } + void SetLineRasterizationMode(D3D12_LINE_RASTERIZATION_MODE lineRasterizationMode) + { + m_Desc.LineRasterizationMode = lineRasterizationMode; + } + void SetForcedSampleCount(UINT forcedSampleCount) + { + m_Desc.ForcedSampleCount = forcedSampleCount; + } + void SetConservativeRaster(D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + m_Desc.ConservativeRaster = conservativeRaster; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_RASTERIZER; + } + operator const D3D12_RASTERIZER_DESC2& () const 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DEPTH_STENCIL2_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DEPTH_STENCIL2_SUBOBJECT() + { + Init(); + } + CD3DX12_DEPTH_STENCIL2_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetDepthEnable(BOOL depthEnable) + { + m_Desc.DepthEnable = depthEnable; + } + void SetDepthWriteMask(D3D12_DEPTH_WRITE_MASK depthWriteMask) + { + m_Desc.DepthWriteMask = depthWriteMask; + } + void SetDepthFunc(D3D12_COMPARISON_FUNC depthFunc) + { + m_Desc.DepthFunc = depthFunc; + } + void SetStencilEnable(BOOL stencilEnable) + { + m_Desc.StencilEnable = stencilEnable; + } + void SetFrontFace(D3D12_DEPTH_STENCILOP_DESC1 frontFace) + { + m_Desc.FrontFace = { + frontFace.StencilFailOp, + frontFace.StencilDepthFailOp, + frontFace.StencilPassOp, + frontFace.StencilFunc, + frontFace.StencilReadMask, + frontFace.StencilWriteMask + }; + } + void SetBackFace(D3D12_DEPTH_STENCILOP_DESC1 backFace) + { + m_Desc.BackFace = { + backFace.StencilFailOp, + backFace.StencilDepthFailOp, + backFace.StencilPassOp, + backFace.StencilFunc, + backFace.StencilReadMask, + backFace.StencilWriteMask + }; + } + void SetDepthBoundsTestEnable(BOOL depthBoundsTestEnable) + { + m_Desc.DepthBoundsTestEnable = depthBoundsTestEnable; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL2; + } + operator const D3D12_DEPTH_STENCIL_DESC2& () const 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_INPUT_LAYOUT_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_INPUT_LAYOUT_SUBOBJECT() + { + Init(); + } + CD3DX12_INPUT_LAYOUT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void AddInputLayoutElementDesc(D3D12_INPUT_ELEMENT_DESC inputLayoutElementDesc) + { + m_inputLayoutElements.emplace_back( + D3D12_INPUT_ELEMENT_DESC{ + m_Strings.LocalCopy(inputLayoutElementDesc.SemanticName), + inputLayoutElementDesc.SemanticIndex, + inputLayoutElementDesc.Format, + inputLayoutElementDesc.InputSlot, + inputLayoutElementDesc.AlignedByteOffset, + inputLayoutElementDesc.InputSlotClass, + inputLayoutElementDesc.InstanceDataStepRate + }); + ++m_numElements; + } + 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; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT() + { + Init(); + } + CD3DX12_IB_STRIP_CUT_VALUE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetIBStripCutValue(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ibStripCutValue) + { + m_Desc = ibStripCutValue; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE; + } + operator const D3D12_INDEX_BUFFER_STRIP_CUT_VALUE& () const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT() + { + Init(); + } + CD3DX12_PRIMITIVE_TOPOLOGY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE primitiveTopologytype) + { + m_Desc = primitiveTopologytype; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY; + } + operator const D3D12_PRIMITIVE_TOPOLOGY_TYPE& () const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_PRIMITIVE_TOPOLOGY_TYPE m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT() + { + Init(); + } + CD3DX12_RENDER_TARGET_FORMATS_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetNumRenderTargets(UINT numRenderTargets) + { + m_Desc.NumRenderTargets = numRenderTargets; + } + void SetRenderTargetFormat(UINT renderTarget, DXGI_FORMAT renderTargetFormat) + { + m_Desc.RTFormats[renderTarget] = renderTargetFormat; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS; + } + operator const D3D12_RT_FORMAT_ARRAY& () const 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT() + { + Init(); + } + CD3DX12_DEPTH_STENCIL_FORMAT_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetDepthStencilFormat(DXGI_FORMAT depthStencilFormat) + { + m_Desc = depthStencilFormat; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT; + } + operator const DXGI_FORMAT& () const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + } + void* Data() noexcept override { return &m_Desc; } + DXGI_FORMAT m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_SAMPLE_DESC_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_SAMPLE_DESC_SUBOBJECT() + { + Init(); + } + CD3DX12_SAMPLE_DESC_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetCount(UINT count) + { + m_Desc.Count = count; + } + void SetQuality(UINT quality) + { + m_Desc.Quality = quality; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_SAMPLE_DESC; + } + operator const DXGI_SAMPLE_DESC& () const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + DXGI_SAMPLE_DESC m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_FLAGS_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_FLAGS_SUBOBJECT() + { + Init(); + } + CD3DX12_FLAGS_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetFlags(D3D12_PIPELINE_STATE_FLAGS flags) + { + m_Desc = flags; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_FLAGS; + } + operator const D3D12_PIPELINE_STATE_FLAGS& () const 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_VIEW_INSTANCING_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_VIEW_INSTANCING_SUBOBJECT() + { + Init(); + } + CD3DX12_VIEW_INSTANCING_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void AddViewInstanceLocation(D3D12_VIEW_INSTANCE_LOCATION viewInstanceLocation) + { + m_viewInstanceCount++; + m_viewInstanceLocations.emplace_back( + D3D12_VIEW_INSTANCE_LOCATION + { + viewInstanceLocation.ViewportArrayIndex, + viewInstanceLocation.RenderTargetArrayIndex + } + ); + } + void SetFlags(D3D12_VIEW_INSTANCING_FLAGS flags) + { + m_Desc.Flags = flags; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DEPTH_STENCIL_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DEPTH_STENCIL_SUBOBJECT() + { + Init(); + } + CD3DX12_DEPTH_STENCIL_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetDepthEnable(BOOL depthEnable) + { + m_Desc.DepthEnable = depthEnable; + } + void SetDepthWriteMask(D3D12_DEPTH_WRITE_MASK depthWriteMask) + { + m_Desc.DepthWriteMask = depthWriteMask; + } + void SetDepthFunc(D3D12_COMPARISON_FUNC depthFunc) + { + m_Desc.DepthFunc = depthFunc; + } + void SetStencilEnable(BOOL stencilEnable) + { + m_Desc.StencilEnable = stencilEnable; + } + void SetStencilReadMask(UINT8 stencilReadMask) + { + m_Desc.StencilReadMask = stencilReadMask; + } + void SetStencilWriteMask(UINT8 stencilWriteMask) + { + m_Desc.StencilWriteMask = stencilWriteMask; + } + void SetFrontFace(D3D12_DEPTH_STENCILOP_DESC frontFace) + { + m_Desc.FrontFace = { + frontFace.StencilFailOp, + frontFace.StencilDepthFailOp, + frontFace.StencilPassOp, + frontFace.StencilFunc + }; + } + void SetBackFace(D3D12_DEPTH_STENCILOP_DESC backFace) + { + m_Desc.BackFace = { + backFace.StencilFailOp, + backFace.StencilDepthFailOp, + backFace.StencilPassOp, + backFace.StencilFunc + }; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL; + } + operator const D3D12_DEPTH_STENCIL_DESC& () const 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DEPTH_STENCIL1_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DEPTH_STENCIL1_SUBOBJECT() + { + Init(); + } + CD3DX12_DEPTH_STENCIL1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetDepthEnable(BOOL depthEnable) + { + m_Desc.DepthEnable = depthEnable; + } + void SetDepthWriteMask(D3D12_DEPTH_WRITE_MASK depthWriteMask) + { + m_Desc.DepthWriteMask = depthWriteMask; + } + void SetDepthFunc(D3D12_COMPARISON_FUNC depthFunc) + { + m_Desc.DepthFunc = depthFunc; + } + void SetStencilEnable(BOOL stencilEnable) + { + m_Desc.StencilEnable = stencilEnable; + } + void SetStencilReadMask(UINT8 stencilReadMask) + { + m_Desc.StencilReadMask = stencilReadMask; + } + void SetStencilWriteMask(UINT8 stencilWriteMask) + { + m_Desc.StencilWriteMask = stencilWriteMask; + } + void SetFrontFace(D3D12_DEPTH_STENCILOP_DESC frontFace) + { + m_Desc.FrontFace = { + frontFace.StencilFailOp, + frontFace.StencilDepthFailOp, + frontFace.StencilPassOp, + frontFace.StencilFunc + }; + } + void SetBackFace(D3D12_DEPTH_STENCILOP_DESC backFace) + { + m_Desc.BackFace = { + backFace.StencilFailOp, + backFace.StencilDepthFailOp, + backFace.StencilPassOp, + backFace.StencilFunc + }; + } + void SetDepthBoundsTestEnable(BOOL depthBoundsTestEnable) + { + m_Desc.DepthBoundsTestEnable = depthBoundsTestEnable; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1; + } + operator const D3D12_DEPTH_STENCIL_DESC1& () const 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_SAMPLE_MASK_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_SAMPLE_MASK_SUBOBJECT() + { + Init(); + } + CD3DX12_SAMPLE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetSampleMask(UINT sampleMask) + { + m_Desc = sampleMask; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_SAMPLE_MASK; + } + operator const UINT& () const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + } + void* Data() noexcept override { return &m_Desc; } + UINT m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_GENERIC_PROGRAM_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_GENERIC_PROGRAM_SUBOBJECT() + { + Init(); + } + CD3DX12_GENERIC_PROGRAM_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetProgramName(LPCWSTR ProgramName) + { + m_Desc.ProgramName = m_Strings.LocalCopy(ProgramName); + } + void AddExport(LPCWSTR exportName) + { + m_Exports.emplace_back(m_Strings.LocalCopy(exportName)); + m_numExports++; + } + void AddSubobject(const D3D12_STATE_SUBOBJECT& subobject) + { + m_Subobjects.emplace_back(&subobject); + m_numSubobjects++; + } + 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; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_NODE_OUTPUT_OVERRIDES +{ +public: + CD3DX12_NODE_OUTPUT_OVERRIDES(const D3D12_NODE_OUTPUT_OVERRIDES** ppOwner, UINT* pNumOutputOverrides) noexcept + { + m_Desc.clear(); + m_ppOwner = ppOwner; + *m_ppOwner = nullptr; + m_pNumOutputOverrides = pNumOutputOverrides; + *m_pNumOutputOverrides = 0; + } + void NewOutputOverride() + { + m_Desc.emplace_back(D3D12_NODE_OUTPUT_OVERRIDES{}); + *m_ppOwner = m_Desc.data(); + (*m_pNumOutputOverrides)++; + } + void OutputIndex(UINT index) + { + m_Desc.back().OutputIndex = index; + } + void NewName(LPCWSTR Name, UINT ArrayIndex = 0) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(Name),ArrayIndex }); + m_Desc.back().pNewName = &m_NodeIDs.front(); + } + void AllowSparseNodes(BOOL bAllow) + { + m_UINTs.emplace_front((UINT)bAllow); + m_Desc.back().pAllowSparseNodes = (BOOL*)&m_UINTs.front(); + } + void MaxOutputRecords(UINT maxOutputRecords) noexcept + { + m_UINTs.emplace_front(maxOutputRecords); + m_Desc.back().pMaxRecords = &m_UINTs.front(); + } + void MaxOutputRecordsSharedWith(UINT outputIndex) noexcept + { + m_UINTs.emplace_front(outputIndex); + m_Desc.back().pMaxRecordsSharedWithOutputIndex = &m_UINTs.front(); + } +private: + std::vector m_Desc; + // Cached parameters + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::forward_list m_UINTs; + std::forward_list m_NodeIDs; + const D3D12_NODE_OUTPUT_OVERRIDES** m_ppOwner; + UINT* m_pNumOutputOverrides; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_NODE_HELPER_BASE +{ +public: + virtual ~CD3DX12_NODE_HELPER_BASE() = default; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_SHADER_NODE // Not specifying launch mode. + // Don't need to distinguish if no parameter overriding is happening + : public CD3DX12_NODE_HELPER_BASE +{ +public: + CD3DX12_SHADER_NODE( + D3D12_NODE* pNode, + LPCWSTR _Shader = nullptr) + { + m_pDesc = pNode; + m_pDesc->NodeType = D3D12_NODE_TYPE_SHADER; + Shader(_Shader); + } + void Shader(LPCWSTR _Shader) + { + m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + } + D3D12_NODE* m_pDesc; +private: + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; +}; + +//------------------------------------------------------------------------------------------------ +// 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 +class CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES + : public CD3DX12_NODE_HELPER_BASE +{ +public: + CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES( + D3D12_NODE* pNode, + LPCWSTR _Shader = nullptr) : + 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; + Shader(_Shader); + } + void Shader(LPCWSTR _Shader) + { + m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + } + void LocalRootArgumentsTableIndex(UINT index) + { + m_UINTs.emplace_front(index); + Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front(); + } + void ProgramEntry(BOOL bIsProgramEntry) + { + m_UINTs.emplace_front(bIsProgramEntry); + Overrides.pProgramEntry = (BOOL*)&m_UINTs.front(); + } + void NewName(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pNewName = &m_NodeIDs.front(); + } + void ShareInputOf(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pShareInputOf = &m_NodeIDs.front(); + } + void DispatchGrid(UINT x, UINT y, UINT z) + { + m_UINT3s.emplace_front(UINT3{ x,y,z }); + Overrides.pDispatchGrid = (UINT*)&m_UINT3s.front(); + } + void MaxDispatchGrid(UINT x, UINT y, UINT z) + { + m_UINT3s.emplace_front(UINT3{x,y,z}); + Overrides.pMaxDispatchGrid = (UINT*)&m_UINT3s.front(); + } + CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides() + { + 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 + { + UINT x; + UINT y; + UINT z; + }; + std::forward_list m_UINT3s; + std::forward_list m_NodeIDs; + CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides; +}; + +//------------------------------------------------------------------------------------------------ +// Use this class when defining a coalescing launch node where configuration parameters +// need to be overridden. If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE +class CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES + : public CD3DX12_NODE_HELPER_BASE +{ +public: + CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES( + D3D12_NODE* pNode, + LPCWSTR _Shader = nullptr) : + 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; + Shader(_Shader); + } + void Shader(LPCWSTR _Shader) + { + m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + } + void LocalRootArgumentsTableIndex(UINT index) + { + m_UINTs.emplace_front(index); + Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front(); + } + void ProgramEntry(BOOL bIsProgramEntry) + { + m_UINTs.emplace_front(bIsProgramEntry); + Overrides.pProgramEntry = (BOOL*)&m_UINTs.front(); + } + void NewName(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pNewName = &m_NodeIDs.front(); + } + void ShareInputOf(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pShareInputOf = &m_NodeIDs.front(); + } + CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides() + { + 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 + { + UINT x; + UINT y; + UINT z; + }; + std::forward_list m_UINT3s; + std::forward_list m_NodeIDs; + CD3DX12_NODE_OUTPUT_OVERRIDES m_NodeOutputOverrides; +}; + +//------------------------------------------------------------------------------------------------ +// Use this class when defining a thread launch node where configuration parameters +// need to be overridden. If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE +class CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES + : public CD3DX12_NODE_HELPER_BASE +{ +public: + CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES( + D3D12_NODE* pNode, + LPCWSTR _Shader = nullptr) : + 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; + Shader(_Shader); + } + void Shader(LPCWSTR _Shader) + { + m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + } + void LocalRootArgumentsTableIndex(UINT index) + { + m_UINTs.emplace_front(index); + Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front(); + } + void ProgramEntry(BOOL bIsProgramEntry) + { + m_UINTs.emplace_front(bIsProgramEntry); + Overrides.pProgramEntry = (BOOL*)&m_UINTs.front(); + } + void NewName(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pNewName = &m_NodeIDs.front(); + } + void ShareInputOf(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pShareInputOf = &m_NodeIDs.front(); + } + CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides() + { + 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; +}; + +//------------------------------------------------------------------------------------------------ +// Use this class when defining a node where configuration parameters +// need to be overridden for parameters that are common to all launch node types. +// This option is a convenience if you don't want to determine what the launch mode is +// and just want to override a setting that isn't specific to launch mode. +// If overrides are not needed, just use CD3DX12_COMPUTE_SHADER_NODE +class CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES + : public CD3DX12_NODE_HELPER_BASE +{ +public: + CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES( + D3D12_NODE* pNode, + LPCWSTR _Shader = nullptr) : + 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; + Shader(_Shader); + } + void Shader(LPCWSTR _Shader) + { + m_pDesc->Shader.Shader = m_Strings.LocalCopy(_Shader); + } + void LocalRootArgumentsTableIndex(UINT index) + { + m_UINTs.emplace_front(index); + Overrides.pLocalRootArgumentsTableIndex = &m_UINTs.front(); + } + void ProgramEntry(BOOL bIsProgramEntry) + { + m_UINTs.emplace_front(bIsProgramEntry); + Overrides.pProgramEntry = (BOOL*)&m_UINTs.front(); + } + void NewName(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pNewName = &m_NodeIDs.front(); + } + void ShareInputOf(D3D12_NODE_ID NodeID) + { + m_NodeIDs.emplace_front(D3D12_NODE_ID{ m_Strings.LocalCopy(NodeID.Name),NodeID.ArrayIndex }); + Overrides.pShareInputOf = &m_NodeIDs.front(); + } + CD3DX12_NODE_OUTPUT_OVERRIDES& NodeOutputOverrides() + { + 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; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_WORK_GRAPH_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_WORK_GRAPH_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_WORK_GRAPH_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_WORK_GRAPH; + } + void IncludeAllAvailableNodes() + { + m_Desc.Flags |= D3D12_WORK_GRAPH_FLAG_INCLUDE_ALL_AVAILABLE_NODES; + } + void SetProgramName(LPCWSTR ProgramName) + { + m_Desc.ProgramName = m_Strings.LocalCopy(ProgramName); + } + void AddEntrypoint(D3D12_NODE_ID Entrypoint) + { + m_Entrypoints.emplace_back(D3D12_NODE_ID{ m_Strings.LocalCopy(Entrypoint.Name),Entrypoint.ArrayIndex }); + m_NumEntrypoints++; + } + + template + T* CreateNode() + { + m_NodeDescs.push_back({}); + m_NumNodes++; + T* pNodeHelper = new T(&m_NodeDescs.back()); + m_OwnedNodeHelpers.emplace_back(pNodeHelper); + return pNodeHelper; + } + CD3DX12_SHADER_NODE* CreateShaderNode(LPCWSTR Shader = nullptr) + { + auto pNode = CreateNode(); + pNode->Shader(Shader); + return pNode; + } + CD3DX12_BROADCASTING_LAUNCH_NODE_OVERRIDES* CreateBroadcastingLaunchNodeOverrides(LPCWSTR Shader = nullptr) + { + auto pNode = CreateNode(); + pNode->Shader(Shader); + return pNode; + } + CD3DX12_COALESCING_LAUNCH_NODE_OVERRIDES* CreateCoalescingLaunchNodeOverrides(LPCWSTR Shader = nullptr) + { + auto pNode = CreateNode(); + pNode->Shader(Shader); + return pNode; + } + CD3DX12_THREAD_LAUNCH_NODE_OVERRIDES* CreateThreadLaunchNodeOverrides(LPCWSTR Shader = nullptr) + { + auto pNode = CreateNode(); + pNode->Shader(Shader); + return pNode; + } + CD3DX12_COMMON_COMPUTE_NODE_OVERRIDES* CreateCommonComputeNodeOverrides(LPCWSTR Shader = nullptr) + { + auto pNode = CreateNode(); + pNode->Shader(Shader); + return pNode; + } + 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_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; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::list> m_OwnedNodeHelpers; +}; +#endif // D3D12_SDK_VERSION >= 612 + +#undef D3DX12_COM_PTR +#undef D3DX12_COM_PTR_GET +#undef D3DX12_COM_PTR_ADDRESSOF + +#endif // !D3DX12_NO_STATE_OBJECT_HELPERS + + +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 608) + +//================================================================================================ +// D3DX12 Enhanced Barrier Helpers +//================================================================================================ + +class CD3DX12_BARRIER_SUBRESOURCE_RANGE : public D3D12_BARRIER_SUBRESOURCE_RANGE +{ +public: + CD3DX12_BARRIER_SUBRESOURCE_RANGE() = default; + CD3DX12_BARRIER_SUBRESOURCE_RANGE(const D3D12_BARRIER_SUBRESOURCE_RANGE &o) noexcept : + D3D12_BARRIER_SUBRESOURCE_RANGE(o) + {} + explicit CD3DX12_BARRIER_SUBRESOURCE_RANGE(UINT Subresource) noexcept : + D3D12_BARRIER_SUBRESOURCE_RANGE{ Subresource, 0, 0, 0, 0, 0 } + {} + CD3DX12_BARRIER_SUBRESOURCE_RANGE( + UINT firstMipLevel, + UINT numMips, + UINT firstArraySlice, + UINT numArraySlices, + UINT firstPlane = 0, + UINT numPlanes = 1) noexcept : + D3D12_BARRIER_SUBRESOURCE_RANGE + { + firstMipLevel, + numMips, + firstArraySlice, + numArraySlices, + firstPlane, + numPlanes + } + {} +}; + +class CD3DX12_GLOBAL_BARRIER : public D3D12_GLOBAL_BARRIER +{ +public: + CD3DX12_GLOBAL_BARRIER() = default; + CD3DX12_GLOBAL_BARRIER(const D3D12_GLOBAL_BARRIER &o) noexcept : D3D12_GLOBAL_BARRIER(o){} + CD3DX12_GLOBAL_BARRIER( + D3D12_BARRIER_SYNC syncBefore, + D3D12_BARRIER_SYNC syncAfter, + D3D12_BARRIER_ACCESS accessBefore, + D3D12_BARRIER_ACCESS accessAfter) noexcept : D3D12_GLOBAL_BARRIER { + syncBefore, + syncAfter, + accessBefore, + accessAfter + } + {} +}; + +class CD3DX12_BUFFER_BARRIER : public D3D12_BUFFER_BARRIER +{ +public: + CD3DX12_BUFFER_BARRIER() = default; + CD3DX12_BUFFER_BARRIER(const D3D12_BUFFER_BARRIER &o) noexcept : D3D12_BUFFER_BARRIER(o){} + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC syncBefore, + D3D12_BARRIER_SYNC syncAfter, + D3D12_BARRIER_ACCESS accessBefore, + D3D12_BARRIER_ACCESS accessAfter, + ID3D12Resource *pRes) noexcept : D3D12_BUFFER_BARRIER { + syncBefore, syncAfter, accessBefore, accessAfter, @@ -5720,6 +7191,11 @@ class CD3DX12FeatureSupport BOOL ComputeOnlyWriteWatchSupported() const noexcept; #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + D3D12_EXECUTE_INDIRECT_TIER ExecuteIndirectTier() const noexcept; + D3D12_WORK_GRAPHS_TIER WorkGraphsTier() const noexcept; +#endif + private: // Private structs and helpers declaration struct ProtectedResourceSessionTypesLocal : D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES { @@ -5806,6 +7282,9 @@ class CD3DX12FeatureSupport #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 611) D3D12_FEATURE_DATA_D3D12_OPTIONS20 m_dOptions20; #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + D3D12_FEATURE_DATA_D3D12_OPTIONS21 m_dOptions21; +#endif }; // Implementations for CD3DX12FeatureSupport functions @@ -5897,6 +7376,9 @@ inline CD3DX12FeatureSupport::CD3DX12FeatureSupport() noexcept #if defined (D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 611) , m_dOptions20{} #endif +#if defined (D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) +, m_dOptions21{} +#endif {} inline HRESULT CD3DX12FeatureSupport::Init(ID3D12Device* pDevice) @@ -6065,6 +7547,13 @@ inline HRESULT CD3DX12FeatureSupport::Init(ID3D12Device* pDevice) } #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + if (FAILED(m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS21, &m_dOptions21, sizeof(m_dOptions21)))) + { + m_dOptions21 = {}; + } +#endif + // Initialize per-node feature support data structures const UINT uNodeCount = m_pDevice->GetNodeCount(); m_dProtectedResourceSessionSupport.resize(uNodeCount); @@ -6437,6 +7926,12 @@ FEATURE_SUPPORT_GET(UINT, m_dOptions19, MaxViewDescriptorHeapSize); FEATURE_SUPPORT_GET(BOOL, m_dOptions20, ComputeOnlyWriteWatchSupported); #endif +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) +// 50: Options21 +FEATURE_SUPPORT_GET(D3D12_EXECUTE_INDIRECT_TIER, m_dOptions21, ExecuteIndirectTier); +FEATURE_SUPPORT_GET(D3D12_WORK_GRAPHS_TIER, m_dOptions21, WorkGraphsTier); +#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 @@ -6447,6 +7942,9 @@ inline HRESULT CD3DX12FeatureSupport::QueryHighestShaderModel() const D3D_SHADER_MODEL allModelVersions[] = { +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) + D3D_SHADER_MODEL_6_9, +#endif #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 606) D3D_SHADER_MODEL_6_8, #endif diff --git a/Src/pch.h b/Src/pch.h index 4404bc95..7207c7eb 100644 --- a/Src/pch.h +++ b/Src/pch.h @@ -238,7 +238,7 @@ #endif #pragma warning(push) -#pragma warning(disable : 4467 4986 5038 5204 5220) +#pragma warning(disable : 4467 4986 5038 5204 5220 6101) #ifdef __MINGW32__ #include #else diff --git a/build/DirectXTK12-GitHub-Dev17.yml b/build/DirectXTK12-GitHub-Dev17.yml index 26e997bb..21c80c16 100644 --- a/build/DirectXTK12-GitHub-Dev17.yml +++ b/build/DirectXTK12-GitHub-Dev17.yml @@ -12,22 +12,50 @@ schedules: include: - main -trigger: none +trigger: + branches: + include: + - main + paths: + exclude: + - '*.md' + - LICENSE + - CMake* + - '.nuget/*' + - build/*.cmake + - build/*.cmd + - build/*.in + - build/*.json + - build/*.props + - build/*.ps1 + - build/*.targets + - build/*.xvd pr: branches: include: - main paths: - include: - - build/DirectXTK12-GitHub-Dev17.yml + exclude: + - '*.md' + - LICENSE + - CMake* + - '.nuget/*' + - build/*.cmake + - build/*.cmd + - build/*.in + - build/*.json + - build/*.props + - build/*.ps1 + - build/*.targets + - build/*.xvd + drafts: false resources: repositories: - repository: self type: git ref: refs/heads/main - trigger: none name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) diff --git a/build/DirectXTK12-GitHub-Test-Dev17.yml b/build/DirectXTK12-GitHub-Test-Dev17.yml index 5cf5c3b6..1b12b45f 100644 --- a/build/DirectXTK12-GitHub-Test-Dev17.yml +++ b/build/DirectXTK12-GitHub-Test-Dev17.yml @@ -36,6 +36,7 @@ pool: variables: Codeql.Enabled: false + VC_PATH: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC' GITHUB_PAT: $(GITHUBPUBLICTOKEN) GUID_FEED: $(ADOFeedGUID) @@ -44,6 +45,8 @@ jobs: displayName: 'Win32 Desktop for x64/x86' timeoutInMinutes: 60 cancelTimeoutInMinutes: 1 + workspace: + clean: all steps: - checkout: self clean: true @@ -212,6 +215,8 @@ jobs: - job: CMAKE_BUILD displayName: 'CMake BUILD_TESTING=ON' timeoutInMinutes: 60 + workspace: + clean: all steps: - checkout: self clean: true @@ -229,20 +234,13 @@ jobs: script: git clone --quiet --no-tags https://%GITHUB_PAT%@github.com/walbourn/directxtk12test.git Tests workingDirectory: $(Build.SourcesDirectory) failOnStderr: true - - task: ChocolateyCommand@0 - displayName: Install Ninja - inputs: - command: 'install' - installPackageId: 'ninja' - task: CmdLine@2 displayName: Setup environment for CMake to use VS inputs: script: | - @echo off - pushd "C:\Program Files (x86)\Microsoft Visual Studio\Installer\" - for /f "delims=" %%x in ('.\vswhere.exe -latest -property InstallationPath') do set VSPATH=%%x - popd - call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x64 + call "$(VC_PATH)\Auxiliary\Build\vcvars64.bat" + echo ##vso[task.setvariable variable=WindowsSdkVerBinPath;]%WindowsSdkVerBinPath% + echo ##vso[task.prependpath]%VSINSTALLDIR%Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja echo ##vso[task.prependpath]%VCINSTALLDIR%Tools\Llvm\x64\bin echo ##vso[task.prependpath]%WindowsSdkBinPath%x64 echo ##vso[task.prependpath]%WindowsSdkVerBinPath%x64 @@ -304,14 +302,10 @@ jobs: inputs: Contents: 'out' - task: CmdLine@2 - displayName: Set LIB for ARM64 + displayName: Switch compiler to ARM64 inputs: script: | - @echo off - pushd "C:\Program Files (x86)\Microsoft Visual Studio\Installer\" - for /f "delims=" %%x in ('.\vswhere.exe -latest -property InstallationPath') do set VSPATH=%%x - popd - call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" arm64 + call "$(VC_PATH)\Auxiliary\Build\vcvarsamd64_arm64.bat" echo ##vso[task.setvariable variable=LIB;]%LIB% - task: CMake@1 diff --git a/build/DirectXTK12-GitHub.yml b/build/DirectXTK12-GitHub.yml index 29f64031..1b38078e 100644 --- a/build/DirectXTK12-GitHub.yml +++ b/build/DirectXTK12-GitHub.yml @@ -63,7 +63,7 @@ variables: Codeql.Enabled: false pool: - vmImage: windows-2022 + vmImage: windows-2019 jobs: - job: DESKTOP_BUILD @@ -116,54 +116,3 @@ jobs: msbuildArgs: /p:PreferredToolArchitecture=x64 platform: ARM64 configuration: Release - -- job: UWP_BUILD - displayName: 'Universal Windows Platform (UWP)' - timeoutInMinutes: 120 - cancelTimeoutInMinutes: 1 - steps: - - checkout: self - clean: true - fetchTags: false - - task: VSBuild@1 - displayName: Build solution DirectXTK_Windows10_2022.sln 32dbg - inputs: - solution: DirectXTK_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x86 - configuration: Debug - - task: VSBuild@1 - displayName: Build solution DirectXTK_Windows10_2022.sln 32rel - inputs: - solution: DirectXTK_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x86 - configuration: Release - - task: VSBuild@1 - displayName: Build solution DirectXTK_Windows10_2022.sln 64dbg - inputs: - solution: DirectXTK_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x64 - configuration: Debug - - task: VSBuild@1 - displayName: Build solution DirectXTK_Windows10_2022.sln 64rel - inputs: - solution: DirectXTK_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x64 - configuration: Release - - task: VSBuild@1 - displayName: Build solution DirectXTK_Windows10_2022.sln arm64dbg - inputs: - solution: DirectXTK_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: ARM64 - configuration: Debug - - task: VSBuild@1 - displayName: Build solution DirectXTK_Windows10_2022.sln arm64rel - inputs: - solution: DirectXTK_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: ARM64 - configuration: Release diff --git a/build/DirectXTK12-SDL.yml b/build/DirectXTK12-SDL.yml index 18c11dff..06cc6d80 100644 --- a/build/DirectXTK12-SDL.yml +++ b/build/DirectXTK12-SDL.yml @@ -26,6 +26,7 @@ name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) variables: Codeql.Enabled: true Codeql.Language: cpp + VC_PATH: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC' VS_GENERATOR: 'Visual Studio 17 2022' pool: @@ -98,3 +99,37 @@ jobs: GdnBreakPolicyMinSev: 'Error' - task: ComponentGovernanceComponentDetection@0 displayName: Component Detection + +- job: VC_PREFAST + displayName: 'Build using /analyze (PREFAST)' + workspace: + clean: all + steps: + - checkout: self + clean: true + fetchTags: false + - task: CmdLine@2 + displayName: Setup environment for CMake to use VS + inputs: + script: | + call "$(VC_PATH)\Auxiliary\Build\vcvars64.bat" + echo ##vso[task.setvariable variable=WindowsSdkVerBinPath;]%WindowsSdkVerBinPath% + echo ##vso[task.prependpath]%VSINSTALLDIR%Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja + echo ##vso[task.prependpath]%VCINSTALLDIR%Tools\Llvm\x64\bin + echo ##vso[task.prependpath]%WindowsSdkBinPath%x64 + echo ##vso[task.prependpath]%WindowsSdkVerBinPath%x64 + echo ##vso[task.prependpath]%VCToolsInstallDir%bin\Hostx64\x64 + echo ##vso[task.setvariable variable=EXTERNAL_INCLUDE;]%EXTERNAL_INCLUDE% + echo ##vso[task.setvariable variable=INCLUDE;]%INCLUDE% + echo ##vso[task.setvariable variable=LIB;]%LIB% + + - task: CMake@1 + displayName: CMake Config + inputs: + cwd: '$(Build.SourcesDirectory)' + cmakeArgs: --preset=x64-Debug -DENABLE_CODE_ANALYSIS=ON + - task: CMake@1 + displayName: CMake Build + inputs: + cwd: '$(Build.SourcesDirectory)' + cmakeArgs: --build out/build/x64-Debug