diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-11-10 06:17:46 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-11-10 06:17:46 +0000 |
| commit | 9e62ec0d4b9c7ea9d6fc3d19b9d29481dffb697c (patch) | |
| tree | f9f26c569259ec3b83c9b19dbe0c40f472243ce6 /Graphics | |
| parent | Allowed swap chains without the depth buffer (diff) | |
| download | DiligentCore-9e62ec0d4b9c7ea9d6fc3d19b9d29481dffb697c.tar.gz DiligentCore-9e62ec0d4b9c7ea9d6fc3d19b9d29481dffb697c.zip | |
Added 'ResolveTextureSubresource' device context command (API Version 240041) (not yet implemented in OpenGL backend)
Diffstat (limited to 'Graphics')
22 files changed, 253 insertions, 17 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index 5ed6dc56..98962e44 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -161,6 +161,10 @@ public: /// Sets the strong pointer to the swap chain virtual void SetSwapChain( ISwapChain* pSwapChain )override final { m_pSwapChain = pSwapChain; } + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs)override = 0; + /// Returns the swap chain ISwapChain* GetSwapChain() { return m_pSwapChain; } @@ -1250,6 +1254,40 @@ bool DeviceContextBase<BaseInterface,ImplementationTraits> :: return true; } +template<typename BaseInterface, typename ImplementationTraits> +void DeviceContextBase<BaseInterface,ImplementationTraits> :: + ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) +{ + VERIFY_EXPR(pSrcTexture != nullptr && pDstTexture != nullptr); + const auto& SrcTexDesc = pSrcTexture->GetDesc(); + const auto& DstTexDesc = pDstTexture->GetDesc(); + DEV_CHECK_ERR(SrcTexDesc.SampleCount > 1, "Source texture '", SrcTexDesc.Name, "' of a resolve operation is not multi-sampled"); + DEV_CHECK_ERR(DstTexDesc.SampleCount == 1, "Destination texture '", DstTexDesc.Name, "' of a resolve operation is multi-sampled"); + auto SrcMipLevelProps = GetMipLevelProperties(SrcTexDesc, ResolveAttribs.SrcMipLevel); + auto DstMipLevelProps = GetMipLevelProperties(DstTexDesc, ResolveAttribs.DstMipLevel); + DEV_CHECK_ERR(SrcMipLevelProps.LogicalWidth == DstMipLevelProps.LogicalWidth && SrcMipLevelProps.LogicalHeight == DstMipLevelProps.LogicalHeight, + "The size (", SrcMipLevelProps.LogicalWidth, "x", SrcMipLevelProps.LogicalHeight, ") of the source subresource of a resolve operation " + "(texture '", SrcTexDesc.Name, "', mip ", ResolveAttribs.SrcMipLevel, ", slice ", ResolveAttribs.SrcSlice, + ") does not match the size (", DstMipLevelProps.LogicalWidth, "x", DstMipLevelProps.LogicalHeight, + ") of the destination subresource (texture '", DstTexDesc.Name, "', mip ", ResolveAttribs.DstMipLevel, ", slice ", + ResolveAttribs.DstSlice, ")"); + + const auto& SrcFmtAttribs = GetTextureFormatAttribs(SrcTexDesc.Format); + const auto& DstFmtAttribs = GetTextureFormatAttribs(DstTexDesc.Format); + const auto& ResolveFmtAttribs = GetTextureFormatAttribs(ResolveAttribs.Format); + if (ResolveAttribs.Format != TEX_FORMAT_UNKNOWN) + { + DEV_CHECK_ERR(!SrcFmtAttribs.IsTypeless && !DstFmtAttribs.IsTypeless, + "Format of a resolve operations must not be unknown when one of the texture formats is typeless"); + } + if (SrcFmtAttribs.IsTypeless || DstFmtAttribs.IsTypeless) + { + DEV_CHECK_ERR(!ResolveFmtAttribs.IsTypeless, "Format of a resolve operations must not be typeless when one of the texture formats is typeless"); + } +} + #endif // DEVELOPMENT } diff --git a/Graphics/GraphicsEngine/interface/APIInfo.h b/Graphics/GraphicsEngine/interface/APIInfo.h index b59997de..cdfcf2ac 100644 --- a/Graphics/GraphicsEngine/interface/APIInfo.h +++ b/Graphics/GraphicsEngine/interface/APIInfo.h @@ -26,7 +26,7 @@ /// \file /// Diligent API information -#define DILIGENT_API_VERSION 240040 +#define DILIGENT_API_VERSION 240041 #include "../../../Primitives/interface/BasicTypes.h" diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index baa2dd64..f631482f 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -403,6 +403,36 @@ struct DispatchComputeIndirectAttribs {} }; + +/// Describes multi-sampled texture resolve command arguments. + +/// This structure is used by IDeviceContext::ResolveTextureSubresource(). +struct ResolveTextureSubresourceAttribs +{ + /// Mip level of the source multi-sampled texture to resolve. + Uint32 SrcMipLevel = 0; + + /// Array slice of the source multi-sampled texture to resolve. + Uint32 SrcSlice = 0; + + /// Source texture state transition mode, see Diligent::RESOURCE_STATE_TRANSITION_MODE. + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_NONE; + + /// Mip level of the destination non-multi-sampled texture. + Uint32 DstMipLevel = 0; + + /// Array slice of the destination non-multi-sampled texture. + Uint32 DstSlice = 0; + + /// Destination texture state transition mode, see Diligent::RESOURCE_STATE_TRANSITION_MODE. + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_NONE; + + /// If one or both textures are typeless, specifies the type of the typeless texture. + /// If both texture formats are not typeless, in which case they must be identical, this member must be + /// either TEX_FORMAT_UNKNOWN, or match this format. + TEXTURE_FORMAT Format = TEX_FORMAT_UNKNOWN; +}; + /// Defines allowed flags for IDeviceContext::SetVertexBuffers() function. enum SET_VERTEX_BUFFERS_FLAGS : Uint8 { @@ -1151,7 +1181,7 @@ public: /// When StateTransitionDesc::UpdateResourceState is set to true, the method may update the state of the /// corresponding resource which is not thread safe. No other threads should read or write the sate of that /// resource. - + /// /// \note Any method that uses Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode may alter /// the state of resources it works with. Diligent::RESOURCE_STATE_TRANSITION_MODE_VERIFY mode /// makes the method read the states, but not write them. When Diligent::RESOURCE_STATE_TRANSITION_MODE_NONE @@ -1161,6 +1191,16 @@ public: /// Refer to http://diligentgraphics.com/2018/12/09/resource-state-management/ for detailed explanation /// of resource state management in Diligent Engine. virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) = 0; + + + /// Resolves a multi-sampled texture subresource into a non-multi-sampled texture subresource. + + /// \param [in] pSrcTexture - Source multi-sampled texture. + /// \param [in] pDstTexture - Destination non-multi-sampled texture. + /// \param [in] ResolveAttribs - Resolve command attributes, see Diligent::ResolveTextureSubresourceAttribs for details. + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index bc2fe679..449f2b84 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1209,9 +1209,6 @@ namespace Diligent /// Swap chain usage flags. Default value is Diligent::SWAP_CHAIN_USAGE_RENDER_TARGET SWAP_CHAIN_USAGE_FLAGS Usage = SWAP_CHAIN_USAGE_RENDER_TARGET; - /// Sample count. Default value is 1 - Uint32 SamplesCount = 1; - /// Number of buffers int the swap chain Uint32 BufferCount = 2; @@ -1234,7 +1231,6 @@ namespace Diligent Uint32 _Height, TEXTURE_FORMAT _ColorBufferFormat, TEXTURE_FORMAT _DepthBufferFormat, - Uint32 _SamplesCount = SwapChainDesc{}.SamplesCount, Uint32 _BufferCount = SwapChainDesc{}.BufferCount, Float32 _DefaultDepthValue = SwapChainDesc{}.DefaultDepthValue, Uint8 _DefaultStencilValue = SwapChainDesc{}.DefaultStencilValue, @@ -1243,7 +1239,6 @@ namespace Diligent Height (_Height), ColorBufferFormat (_ColorBufferFormat), DepthBufferFormat (_DepthBufferFormat), - SamplesCount (_SamplesCount), BufferCount (_BufferCount), DefaultDepthValue (_DefaultDepthValue), DefaultStencilValue (_DefaultStencilValue), diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index 3ecb3388..81d40cb4 100755 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -184,6 +184,11 @@ public: /// Implementation of IDeviceContext::TransitionResourceStates() in Direct3D11 backend.
virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final;
+ /// Implementation of IDeviceContext::ResolveTextureSubresource() in Direct3D11 backend.
+ virtual void ResolveTextureSubresource(ITexture* pSrcTexture,
+ ITexture* pDstTexture,
+ const ResolveTextureSubresourceAttribs& ResolveAttribs)override final;
+
/// Implementation of IDeviceContext::FinishCommandList() in Direct3D11 backend.
void FinishCommandList(class ICommandList** ppCommandList)override final;
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 7a4c1762..93e7362c 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -2051,6 +2051,27 @@ namespace Diligent }
}
+ void DeviceContextD3D11Impl::ResolveTextureSubresource(ITexture* pSrcTexture,
+ ITexture* pDstTexture,
+ const ResolveTextureSubresourceAttribs& ResolveAttribs)
+ {
+ TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs);
+
+ auto* pSrcTexD3D11 = ValidatedCast<TextureBaseD3D11>(pSrcTexture);
+ auto* pDstTexD3D11 = ValidatedCast<TextureBaseD3D11>(pDstTexture);
+ const auto& SrcTexDesc = pSrcTexD3D11->GetDesc();
+ const auto& DstTexDesc = pDstTexD3D11->GetDesc();
+
+ auto Format = ResolveAttribs.Format;
+ if (Format == TEX_FORMAT_UNKNOWN)
+ Format = SrcTexDesc.Format;
+
+ auto DXGIFmt = TexFormatToDXGI_Format(Format);
+ auto SrcSubresIndex = D3D11CalcSubresource(ResolveAttribs.SrcMipLevel, ResolveAttribs.SrcSlice, SrcTexDesc.MipLevels);
+ auto DstSubresIndex = D3D11CalcSubresource(ResolveAttribs.DstMipLevel, ResolveAttribs.DstSlice, DstTexDesc.MipLevels);
+ m_pd3d11DeviceContext->ResolveSubresource(pDstTexD3D11->GetD3D11Texture(), DstSubresIndex, pSrcTexD3D11->GetD3D11Texture(), SrcSubresIndex, DXGIFmt);
+ }
+
#ifdef VERIFY_CONTEXT_BINDINGS
DEFINE_D3D11CTX_FUNC_POINTERS(GetCBMethods, GetConstantBuffers)
DEFINE_D3D11CTX_FUNC_POINTERS(GetSRVMethods, GetShaderResources)
diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp index 4b6797e4..b11955f5 100644 --- a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp @@ -91,7 +91,7 @@ void SwapChainD3D11Impl::CreateRTVandDSV() DepthBufferDesc.MipLevels = 1; DepthBufferDesc.ArraySize = 1; DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat; - DepthBufferDesc.SampleCount = m_SwapChainDesc.SamplesCount; + DepthBufferDesc.SampleCount = 1; DepthBufferDesc.Usage = USAGE_DEFAULT; DepthBufferDesc.BindFlags = BIND_DEPTH_STENCIL; DepthBufferDesc.CPUAccessFlags = CPU_ACCESS_NONE; diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.h b/Graphics/GraphicsEngineD3D12/include/CommandContext.h index b58e8f34..a8c95d41 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.h +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.h @@ -97,6 +97,12 @@ public: void TransitionResource(const StateTransitionDesc& Barrier); //void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); + void ResolveSubresource(ID3D12Resource *pDstResource, UINT DstSubresource, ID3D12Resource *pSrcResource, UINT SrcSubresource, DXGI_FORMAT Format) + { + FlushResourceBarriers(); + m_pCommandList->ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); + } + void FlushResourceBarriers() { if (!m_PendingResourceBarriers.empty()) diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h index fb672aee..077fcd7c 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h @@ -182,6 +182,11 @@ public: /// Implementation of IDeviceContext::TransitionResourceStates() in Direct3D12 backend. virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final; + /// Implementation of IDeviceContext::ResolveTextureSubresource() in Direct3D12 backend. + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs)override final; + /// Implementation of IDeviceContext::FinishCommandList() in Direct3D12 backend. virtual void FinishCommandList(class ICommandList** ppCommandList)override final; diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 5cc74244..32a07203 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -1760,4 +1760,30 @@ namespace Diligent auto& CmdCtx = GetCmdContext(); return CmdCtx.GetCommandList(); } + + void DeviceContextD3D12Impl::ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) + { + TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + + auto* pSrcTexD3D12 = ValidatedCast<TextureD3D12Impl>(pSrcTexture); + auto* pDstTexD3D12 = ValidatedCast<TextureD3D12Impl>(pDstTexture); + const auto& SrcTexDesc = pSrcTexD3D12->GetDesc(); + const auto& DstTexDesc = pDstTexD3D12->GetDesc(); + + auto& CmdCtx = GetCmdContext(); + TransitionOrVerifyTextureState(CmdCtx, *pSrcTexD3D12, ResolveAttribs.SrcTextureTransitionMode, RESOURCE_STATE_RESOLVE_SOURCE, "Resolving multi-sampled texture (DeviceContextD3D12Impl::ResolveTextureSubresource)"); + TransitionOrVerifyTextureState(CmdCtx, *pDstTexD3D12, ResolveAttribs.DstTextureTransitionMode, RESOURCE_STATE_RESOLVE_DEST, "Resolving multi-sampled texture (DeviceContextD3D12Impl::ResolveTextureSubresource)"); + + auto Format = ResolveAttribs.Format; + if (Format == TEX_FORMAT_UNKNOWN) + Format = SrcTexDesc.Format; + + auto DXGIFmt = TexFormatToDXGI_Format(Format); + auto SrcSubresIndex = D3D12CalcSubresource(ResolveAttribs.SrcMipLevel, ResolveAttribs.SrcSlice, 0, SrcTexDesc.MipLevels, SrcTexDesc.ArraySize); + auto DstSubresIndex = D3D12CalcSubresource(ResolveAttribs.DstMipLevel, ResolveAttribs.DstSlice, 0, DstTexDesc.MipLevels, DstTexDesc.ArraySize); + + CmdCtx.ResolveSubresource(pDstTexD3D12->GetD3D12Resource(), DstSubresIndex, pSrcTexD3D12->GetD3D12Resource(), SrcSubresIndex, DXGIFmt); + } } diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp index ab9d3be6..9517c93f 100644 --- a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp @@ -65,7 +65,7 @@ SwapChainD3D12Impl::~SwapChainD3D12Impl() void SwapChainD3D12Impl::InitBuffersAndViews() { m_pBackBufferRTV.resize(m_SwapChainDesc.BufferCount); - for(Uint32 backbuff = 0; backbuff < m_SwapChainDesc.BufferCount; ++backbuff) + for (Uint32 backbuff = 0; backbuff < m_SwapChainDesc.BufferCount; ++backbuff) { CComPtr<ID3D12Resource> pBackBuffer; auto hr = m_pSwapChain->GetBuffer(backbuff, __uuidof(pBackBuffer), reinterpret_cast<void**>( static_cast<ID3D12Resource**>(&pBackBuffer) )); @@ -97,7 +97,7 @@ void SwapChainD3D12Impl::InitBuffersAndViews() DepthBufferDesc.Width = m_SwapChainDesc.Width; DepthBufferDesc.Height = m_SwapChainDesc.Height; DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat; - DepthBufferDesc.SampleCount = m_SwapChainDesc.SamplesCount; + DepthBufferDesc.SampleCount = 1; DepthBufferDesc.Usage = USAGE_DEFAULT; DepthBufferDesc.BindFlags = BIND_DEPTH_STENCIL; diff --git a/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h b/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h index e64460df..b15a3adb 100644 --- a/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h +++ b/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h @@ -151,6 +151,10 @@ public: virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final; + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs)override final; + void FinishCommandList(class ICommandList** ppCommandList)override final; virtual void ExecuteCommandList(class ICommandList* pCommandList)override final; diff --git a/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm b/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm index 0aff2c81..410a6a84 100644 --- a/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm +++ b/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm @@ -72,9 +72,17 @@ namespace Diligent LOG_ERROR_MESSAGE("DeviceContextMtlImpl::TransitionShaderResources() is not implemented"); } + void DeviceContextMtlImpl::ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) + { + TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + LOG_ERROR_MESSAGE("DeviceContextMtlImpl::ResolveTextureSubresource() is not implemented"); + } + void DeviceContextMtlImpl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { - if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0 /*Dummy*/)) + if (!TDeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0 /*Dummy*/)) return; LOG_ERROR_MESSAGE("DeviceContextMtlImpl::CommitShaderResources() is not implemented"); diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 7eb69f18..70265a11 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -176,6 +176,11 @@ public: /// Implementation of IDeviceContext::TransitionResourceStates() in OpenGL backend. virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final; + /// Implementation of IDeviceContext::ResolveTextureSubresource() in OpenGL backend. + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs)override final; + /// Implementation of IDeviceContext::FinishCommandList() in OpenGL backend. virtual void FinishCommandList(class ICommandList** ppCommandList)override final; diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index f85bd454..9358ad1e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -1132,4 +1132,12 @@ namespace Diligent { } + + void DeviceContextGLImpl::ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) + { + TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + + } } diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 14f9975b..d8b89810 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -246,6 +246,10 @@ public: virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final; + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs)override final; + VkDescriptorSet AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName = "") { // Descriptor pools are externally synchronized, meaning that the application must not allocate diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h index a95dce56..517b7e50 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h @@ -412,6 +412,22 @@ namespace VulkanUtilities vkCmdBlitImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); } + __forceinline void ResolveImage(VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + // Resolve must be performed outside of render pass. + EndRenderPass(); + } + vkCmdResolveImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); + } + void FlushBarriers(); __forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer) diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index c4e1e6cd..7231ac5e 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -2249,4 +2249,59 @@ namespace Diligent } } } + + void DeviceContextVkImpl::ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) + { + TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + + auto* pSrcTexVk = ValidatedCast<TextureVkImpl>(pSrcTexture); + auto* pDstTexVk = ValidatedCast<TextureVkImpl>(pDstTexture); + const auto& SrcTexDesc = pSrcTexVk->GetDesc(); + const auto& DstTexDesc = pDstTexVk->GetDesc(); + + DEV_CHECK_ERR(SrcTexDesc.Format == DstTexDesc.Format, "Vulkan requires that source and destination textures of a resolve operation " + "have the same format (18.6)");(void)DstTexDesc; + + EnsureVkCmdBuffer(); + // srcImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL (18.6) + TransitionOrVerifyTextureState(*pSrcTexVk, ResolveAttribs.SrcTextureTransitionMode, RESOURCE_STATE_RESOLVE_SOURCE, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + "Resolving multi-sampled texture (DeviceContextVkImpl::ResolveTextureSubresource)"); + + // dstImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL (18.6) + TransitionOrVerifyTextureState(*pDstTexVk, ResolveAttribs.DstTextureTransitionMode, RESOURCE_STATE_RESOLVE_DEST, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + "Resolving multi-sampled texture (DeviceContextVkImpl::ResolveTextureSubresource)"); + + const auto& ResolveFmtAttribs = GetTextureFormatAttribs(SrcTexDesc.Format); + DEV_CHECK_ERR(ResolveFmtAttribs.ComponentType != COMPONENT_TYPE_DEPTH && ResolveFmtAttribs.ComponentType != COMPONENT_TYPE_DEPTH_STENCIL, + "Vulkan only allows resolve operation for color formats");(void)ResolveFmtAttribs; + // The aspectMask member of srcSubresource and dstSubresource must only contain VK_IMAGE_ASPECT_COLOR_BIT (18.6) + VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + VkImageResolve ResolveRegion; + ResolveRegion.srcSubresource.baseArrayLayer = ResolveAttribs.SrcSlice; + ResolveRegion.srcSubresource.layerCount = 1; + ResolveRegion.srcSubresource.mipLevel = ResolveAttribs.SrcMipLevel; + ResolveRegion.srcSubresource.aspectMask = aspectMask; + + ResolveRegion.dstSubresource.baseArrayLayer = ResolveAttribs.DstSlice; + ResolveRegion.dstSubresource.layerCount = 1; + ResolveRegion.dstSubresource.mipLevel = ResolveAttribs.DstMipLevel; + ResolveRegion.dstSubresource.aspectMask = aspectMask; + + ResolveRegion.srcOffset = VkOffset3D{}; + ResolveRegion.dstOffset = VkOffset3D{}; + const auto& MipAttribs = GetMipLevelProperties(SrcTexDesc, ResolveAttribs.SrcMipLevel); + ResolveRegion.extent = VkExtent3D + { + static_cast<uint32_t>(MipAttribs.LogicalWidth), + static_cast<uint32_t>(MipAttribs.LogicalHeight), + static_cast<uint32_t>(MipAttribs.Depth) + }; + + m_CommandBuffer.ResolveImage(pSrcTexVk->GetVkImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + pDstTexVk->GetVkImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &ResolveRegion); + } } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 41ff3a9e..1c4cd26c 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -55,7 +55,7 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( RenderPassCI.attachmentCount = (DSVFormat != TEX_FORMAT_UNKNOWN ? 1 : 0) + NumRenderTargets; uint32_t AttachmentInd = 0; - VkSampleCountFlagBits SampleCountFlags = static_cast<VkSampleCountFlagBits>(1 << (SampleCount - 1)); + VkSampleCountFlagBits SampleCountFlags = static_cast<VkSampleCountFlagBits>(SampleCount); VkAttachmentReference* pDepthAttachmentReference = nullptr; if (DSVFormat != TEX_FORMAT_UNKNOWN) { @@ -356,7 +356,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters MSStateCI.flags = 0; // reserved for future use // If subpass uses color and/or depth/stencil attachments, then the rasterizationSamples member of // pMultisampleState must be the same as the sample count for those subpass attachments - MSStateCI.rasterizationSamples = static_cast<VkSampleCountFlagBits>(1 << (GraphicsPipeline.SmplDesc.Count-1)); + MSStateCI.rasterizationSamples = static_cast<VkSampleCountFlagBits>(GraphicsPipeline.SmplDesc.Count); MSStateCI.sampleShadingEnable = VK_FALSE; MSStateCI.minSampleShading = 0; // a minimum fraction of sample shading if sampleShadingEnable is set to VK_TRUE. uint32_t SampleMask[] = {GraphicsPipeline.SampleMask, 0}; // Vulkan spec allows up to 64 samples diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 31edb0af..e1d3a8cd 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -412,7 +412,7 @@ void SwapChainVkImpl::InitBuffersAndViews() DepthBufferDesc.Width = m_SwapChainDesc.Width; DepthBufferDesc.Height = m_SwapChainDesc.Height; DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat; - DepthBufferDesc.SampleCount = m_SwapChainDesc.SamplesCount; + DepthBufferDesc.SampleCount = 1; DepthBufferDesc.Usage = USAGE_DEFAULT; DepthBufferDesc.BindFlags = BIND_DEPTH_STENCIL; diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp index b74d4f60..12deef67 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp @@ -110,7 +110,7 @@ TextureVkImpl :: TextureVkImpl(IReferenceCounters* pRefCounters, else ImageCI.arrayLayers = 1; - ImageCI.samples = static_cast<VkSampleCountFlagBits>(1 << (m_Desc.SampleCount-1)); + ImageCI.samples = static_cast<VkSampleCountFlagBits>(m_Desc.SampleCount); ImageCI.tiling = VK_IMAGE_TILING_OPTIMAL; ImageCI.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index fa286903..9987f013 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1294,8 +1294,8 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag) case RESOURCE_STATE_INDIRECT_ARGUMENT: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED; case RESOURCE_STATE_COPY_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; case RESOURCE_STATE_COPY_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - case RESOURCE_STATE_RESOLVE_DEST: UNSUPPORTED("Not currently implemented"); return VK_IMAGE_LAYOUT_UNDEFINED; - case RESOURCE_STATE_RESOLVE_SOURCE: UNSUPPORTED("Not currently implemented"); return VK_IMAGE_LAYOUT_UNDEFINED; + case RESOURCE_STATE_RESOLVE_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case RESOURCE_STATE_RESOLVE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; case RESOURCE_STATE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; default: |
