diff --git a/CMakeLists.txt b/CMakeLists.txt index e5d97b9..ee9bcf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -570,7 +570,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") if(ENABLE_CODE_ANALYSIS) foreach(t IN LISTS TOOL_EXES ITEMS ${PROJECT_NAME}) - target_compile_options(${t} PRIVATE /analyze) + target_compile_options(${t} PRIVATE /analyze /WX) endforeach() endif() diff --git a/DDSTextureLoader/DDSTextureLoader11.cpp b/DDSTextureLoader/DDSTextureLoader11.cpp index c7e4a32..eed802b 100644 --- a/DDSTextureLoader/DDSTextureLoader11.cpp +++ b/DDSTextureLoader/DDSTextureLoader11.cpp @@ -1786,29 +1786,19 @@ namespace ); if (result > 0) { - const char* pstrName = strrchr(strFileA, '\\'); - if (!pstrName) - { - pstrName = strFileA; - } - else - { - pstrName++; - } - if (texture && *texture) { (*texture)->SetPrivateData(WKPDID_D3DDebugObjectName, - static_cast(strnlen_s(pstrName, MAX_PATH)), - pstrName + static_cast(result), + strFileA ); } if (textureView && *textureView) { (*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName, - static_cast(strnlen_s(pstrName, MAX_PATH)), - pstrName + static_cast(result), + strFileA ); } } diff --git a/DirectXTex/DirectXTexMipmaps.cpp b/DirectXTex/DirectXTexMipmaps.cpp index 19683ab..29ec19f 100644 --- a/DirectXTex/DirectXTexMipmaps.cpp +++ b/DirectXTex/DirectXTexMipmaps.cpp @@ -71,7 +71,7 @@ namespace _In_ IWICBitmap* src, _In_ TEX_FILTER_FLAGS filter, _In_ const WICPixelFormatGUID& desiredPixelFormat, - _COM_Outptr_ IWICBitmap** dest) noexcept + __RPC__deref_out_opt /* needed to match WIC annotation */ IWICBitmap** dest) noexcept { if (!dest) return E_POINTER; diff --git a/DirectXTex/DirectXTex_Windows10_2022.vcxproj b/DirectXTex/DirectXTex_Windows10_2022.vcxproj index 7dd2fff..bc5c661 100644 --- a/DirectXTex/DirectXTex_Windows10_2022.vcxproj +++ b/DirectXTex/DirectXTex_Windows10_2022.vcxproj @@ -88,7 +88,7 @@ true Windows Store 10.0 - 10.0.17763.0 + 10.0.18362.0 10.0 x64 diff --git a/DirectXTex/d3dx12.h b/DirectXTex/d3dx12.h index 5bc5b4d..8e8e204 100644 --- a/DirectXTex/d3dx12.h +++ b/DirectXTex/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 @@ private: }; #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 @@ public: 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 @@ public: 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 @@ private: 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 @@ private: 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 @@ private: } 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 @@ private: 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 @@ public: { 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 @@ private: } 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 @@ public: { 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 @@ private: 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 @@ public: { 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 @@ private: } 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 @@ public: { 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 @@ private: } 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 @@ public: { 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 @@ private: 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 @@ public: { 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 @@ public: { 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 @@ public: { 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 @@ public: { 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 @@ public: { 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 @@ public: { 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 @@ public: { 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,6 +5526,1317 @@ private: D3D12_NODE_MASK m_Desc; }; +#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612) +//------------------------------------------------------------------------------------------------ +class CD3DX12_STREAM_OUTPUT_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + 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++) + { + 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_BLEND_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + 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_RASTERIZER_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + 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 @@ -5720,6 +7191,11 @@ public: // Function declaration 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 @@ private: // Member data #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/README.md b/README.md index f9df172..60d482b 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,10 @@ For the latest version of DirectXTex, bug reports, etc. please visit the project ## Release Notes +FOR SECURITY ADVISORIES, see [GitHub](https://github.com/microsoft/DirectXTex/security/advisories). + +For a full change history, see [CHANGELOG.md](https://github.com/microsoft/DirectXTex/blob/main/CHANGELOG.md). + * Starting with the July 2022 release, the ``bool forceSRGB`` parameter for the CreateTextureEx and CreateShaderResourceViewEx functions is now a ``CREATETEX_FLAGS`` typed enum bitmask flag parameter. This may have a *breaking change* impact to client code. Replace ``true`` with ``CREATETEX_FORCE_SRGB`` and ``false`` with ``CREATETEX_DEFAULT``. * Starting with the June 2020 release, this library makes use of typed enum bitmask flags per the recommendation of the _C++ Standard_ section *17.5.2.1.3 Bitmask types*. This is consistent with Direct3D 12's use of the ``DEFINE_ENUM_FLAG_OPERATORS`` macro. This may have *breaking change* impacts to client code: @@ -106,6 +110,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/directxtextest/wiki) repository. + ## Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information 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/WICTextureLoader/WICTextureLoader11.cpp b/WICTextureLoader/WICTextureLoader11.cpp index dee8d35..550c6fc 100644 --- a/WICTextureLoader/WICTextureLoader11.cpp +++ b/WICTextureLoader/WICTextureLoader11.cpp @@ -802,29 +802,19 @@ namespace ); if (result > 0) { - const char* pstrName = strrchr(strFileA, '\\'); - if (!pstrName) - { - pstrName = strFileA; - } - else - { - pstrName++; - } - if (texture && *texture) { (*texture)->SetPrivateData(WKPDID_D3DDebugObjectName, - static_cast(strnlen_s(pstrName, MAX_PATH)), - pstrName + static_cast(result), + strFileA ); } if (textureView && *textureView) { (*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName, - static_cast(strnlen_s(pstrName, MAX_PATH)), - pstrName + static_cast(result), + strFileA ); } } diff --git a/build/DirectXTex-GitHub-Dev17.yml b/build/DirectXTex-GitHub-Dev17.yml index 3ce2fd5..f396981 100644 --- a/build/DirectXTex-GitHub-Dev17.yml +++ b/build/DirectXTex-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 + - Auxiliary/* pr: branches: include: - main paths: - include: - - build/DirectXTex-GitHub-Dev17.yml + exclude: + - '*.md' + - LICENSE + - CMake* + - '.nuget/*' + - build/*.cmake + - build/*.cmd + - build/*.in + - build/*.json + - build/*.props + - build/*.ps1 + - build/*.targets + - Auxiliary/* + 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/DirectXTex-GitHub-Test-Dev17.yml b/build/DirectXTex-GitHub-Test-Dev17.yml index 56fa4b3..7217879 100644 --- a/build/DirectXTex-GitHub-Test-Dev17.yml +++ b/build/DirectXTex-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) jobs: @@ -171,20 +172,13 @@ jobs: script: git clone --quiet --no-tags https://%GITHUB_PAT%@github.com/walbourn/directxtextest.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 @@ -246,14 +240,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/DirectXTex-GitHub.yml b/build/DirectXTex-GitHub.yml index c48b421..617e470 100644 --- a/build/DirectXTex-GitHub.yml +++ b/build/DirectXTex-GitHub.yml @@ -63,7 +63,7 @@ variables: Codeql.Enabled: false pool: - vmImage: windows-2022 + vmImage: windows-2019 jobs: - job: DESKTOP_BUILD @@ -223,54 +223,3 @@ jobs: msbuildArgs: /p:PreferredToolArchitecture=x64 /p:SpectreMitigation=Spectre 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 DirectXTex_Windows10_2022.sln 32dbg - inputs: - solution: DirectXTex_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x86 - configuration: Debug - - task: VSBuild@1 - displayName: Build solution DirectXTex_Windows10_2022.sln 32rel - inputs: - solution: DirectXTex_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x86 - configuration: Release - - task: VSBuild@1 - displayName: Build solution DirectXTex_Windows10_2022.sln 64dbg - inputs: - solution: DirectXTex_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x64 - configuration: Debug - - task: VSBuild@1 - displayName: Build solution DirectXTex_Windows10_2022.sln 64rel - inputs: - solution: DirectXTex_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: x64 - configuration: Release - - task: VSBuild@1 - displayName: Build solution DirectXTex_Windows10_2022.sln arm64dbg - inputs: - solution: DirectXTex_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: ARM64 - configuration: Debug - - task: VSBuild@1 - displayName: Build solution DirectXTex_Windows10_2022.sln arm64rel - inputs: - solution: DirectXTex_Windows10_2022.sln - msbuildArgs: /p:PreferredToolArchitecture=x64 - platform: ARM64 - configuration: Release diff --git a/build/DirectXTex-SDL.yml b/build/DirectXTex-SDL.yml index cb2e923..6b4ae3e 100644 --- a/build/DirectXTex-SDL.yml +++ b/build/DirectXTex-SDL.yml @@ -13,7 +13,14 @@ schedules: - main trigger: none -pr: none + +pr: + branches: + include: + - main + paths: + include: + - build/DirectXTex-SDL.yml resources: repositories: @@ -26,6 +33,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: @@ -104,3 +112,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