From da52d8bbc1ffcf82ed98e0198ecb2bc25530b2c0 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 2 Dec 2018 15:36:10 -0800 Subject: Added explicit state transition control to CopyBuffer() and CopyTexture() methods --- .../GraphicsEngine/include/DeviceContextBase.h | 45 ++- Graphics/GraphicsEngine/include/TextureBase.h | 4 +- Graphics/GraphicsEngine/interface/DeviceContext.h | 134 ++++---- Graphics/GraphicsEngine/src/Texture.cpp | 24 +- .../include/DeviceContextD3D11Impl.h | 21 +- .../src/DeviceContextD3D11Impl.cpp | 43 ++- .../GraphicsEngineD3D12/include/CommandContext.h | 2 +- .../include/DeviceContextD3D12Impl.h | 46 ++- .../GraphicsEngineD3D12/src/CommandContext.cpp | 8 +- .../src/DeviceContextD3D12Impl.cpp | 116 ++++--- .../include/DeviceContextGLImpl.h | 21 +- .../src/DeviceContextGLImpl.cpp | 33 +- .../include/DeviceContextVkImpl.h | 41 ++- .../src/DeviceContextVkImpl.cpp | 339 +++++++++------------ .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 2 +- 15 files changed, 440 insertions(+), 439 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index 9de83dec..0d0a6337 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -114,7 +114,13 @@ public: virtual void UpdateBuffer(IBuffer* pBuffer, Uint32 Offset, Uint32 Size, const PVoid pData, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override = 0; /// Base implementation of IDeviceContext::CopyBuffer(); validates input parameters. - virtual void CopyBuffer(IBuffer *pSrcBuffer, Uint32 SrcOffset, IBuffer *pDstBuffer, Uint32 DstOffset, Uint32 Size)override = 0; + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode)override = 0; /// Base implementation of IDeviceContext::MapBuffer(); validates input parameters. virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData)override = 0; @@ -127,16 +133,7 @@ public: RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode )override = 0; /// Base implementaiton of IDeviceContext::CopyTexture(); validates input parameters - virtual void CopyTexture( ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box *pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ )override = 0; + virtual void CopyTexture( const CopyTextureAttribs& CopyAttribs )override = 0; /// Base implementaiton of IDeviceContext::MapTextureSubresource() virtual void MapTextureSubresource(ITexture* pTexture, @@ -706,7 +703,13 @@ inline void DeviceContextBase inline void DeviceContextBase :: - CopyBuffer(IBuffer *pSrcBuffer, Uint32 SrcOffset, IBuffer *pDstBuffer, Uint32 DstOffset, Uint32 Size) + CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) { VERIFY(pSrcBuffer != nullptr, "Source buffer must not be null"); VERIFY(pDstBuffer != nullptr, "Destination buffer must not be null"); @@ -791,21 +794,11 @@ inline void DeviceContextBase inline void DeviceContextBase :: - CopyTexture( ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ ) + CopyTexture( const CopyTextureAttribs& CopyAttribs ) { - VERIFY( pSrcTexture, "pSrcTexture must not be null" ); - VERIFY( pDstTexture, "pSrcTexture must not be null" ); - ValidateCopyTextureParams( pSrcTexture->GetDesc(), SrcMipLevel, SrcSlice, pSrcBox, - pDstTexture->GetDesc(), DstMipLevel, DstSlice, DstX, DstY, DstZ ); + VERIFY( CopyAttribs.pSrcTexture, "Src texture must not be null" ); + VERIFY( CopyAttribs.pDstTexture, "Dst texture must not be null" ); + ValidateCopyTextureParams( CopyAttribs ); } template diff --git a/Graphics/GraphicsEngine/include/TextureBase.h b/Graphics/GraphicsEngine/include/TextureBase.h index 1aaec627..990b9bc2 100644 --- a/Graphics/GraphicsEngine/include/TextureBase.h +++ b/Graphics/GraphicsEngine/include/TextureBase.h @@ -38,9 +38,7 @@ namespace Diligent void ValidateTextureDesc(const TextureDesc& TexDesc); void ValidateUpdateTextureParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData ); -void ValidateCopyTextureParams( const TextureDesc& SrcTexDesc, Uint32 SrcMipLevel, Uint32 SrcSlice, const Box* pSrcBox, - const TextureDesc& DstTexDesc, Uint32 DstMipLevel, Uint32 DstSlice, - Uint32 DstX, Uint32 DstY, Uint32 DstZ ); +void ValidateCopyTextureParams( const CopyTextureAttribs& CopyAttribs ); void ValidateMapTextureParams(const TextureDesc& TexDesc, Uint32 MipLevel, Uint32 ArraySlice, diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 2d252810..c515ce88 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -296,27 +296,6 @@ enum SET_RENDER_TARGETS_FLAGS }; DEFINE_FLAG_ENUM_OPERATORS(SET_RENDER_TARGETS_FLAGS) -/// Defines state transitions performed by IDeviceContext::ClearRenderTarget() command -enum CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE -{ - /// Perform no state transitions - CLEAR_RENDER_TARGET_NO_TRANSITION = 0, - - /// Transition the render target to the required state. - /// \remarks In D3D12 backend, the render target must always be transitioned to - /// Diligent::RESOURCE_STATE_RENDER_TARGET state. In Vulkan backend - /// however this depends on whether the render pass has been started. - /// To clear render target outside of render pass, it must be in - /// Diligent::RESOURCE_STATE_COPY_DEST state. Inside a render pass it - /// must be in Diligent::RESOURCE_STATE_RENDER_TARGET state. - CLEAR_RENDER_TARGET_TRANSITION_STATE, - - /// Do not perform transition, but verify that the state is correct. - /// This mode only has effect in debug and development builds. No validation - /// is performed in release build. - CLEAR_RENDER_TARGET_VERIFY_STATE -}; - /// Defines resource state transitions performed by various commands enum RESOURCE_STATE_TRANSITION_MODE { @@ -400,6 +379,60 @@ struct Rect }; +/// Defines copy texture command attributes + +/// This structure is used by IDeviceContext::CopyTexture() +struct CopyTextureAttribs +{ + /// Source texture to copy data from. + ITexture* pSrcTexture = nullptr; + + /// Mip level of the source texture to copy data from. + Uint32 SrcMipLevel = 0; + + /// Array slice of the source texture to copy data from. Must be 0 for non-array textures. + Uint32 SrcSlice = 0; + + /// Source region to copy. Use nullptr to copy the entire subresource. + const Box* pSrcBox = nullptr; + + /// Source texture state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE). + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_NONE; + + /// Destination texture to copy data to. + ITexture* pDstTexture = nullptr; + + /// Mip level to copy data to. + Uint32 DstMipLevel = 0; + + /// Array slice to copy data to. Must be 0 for non-array textures. + Uint32 DstSlice = 0; + + /// X offset on the destination subresource. + Uint32 DstX = 0; + + /// Y offset on the destination subresource. + Uint32 DstY = 0; + + /// Z offset on the destination subresource + Uint32 DstZ = 0; + + /// Destination texture state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE). + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_NONE; + + CopyTextureAttribs(){} + + CopyTextureAttribs(ITexture* _pSrcTexture, + RESOURCE_STATE_TRANSITION_MODE _SrcTextureTransitionMode, + ITexture* _pDstTexture, + RESOURCE_STATE_TRANSITION_MODE _DstTextureTransitionMode) : + pSrcTexture (_pSrcTexture), + SrcTextureTransitionMode(_SrcTextureTransitionMode), + pDstTexture (_pDstTexture), + DstTextureTransitionMode(_DstTextureTransitionMode) + {} +}; + /// Device context interface /// \remarks Device context keeps strong references to all objects currently bound to @@ -638,10 +671,16 @@ public: /// Diligent::TEXTURE_VIEW_RENDER_TARGET. /// \param [in] RGBA - A 4-component array that represents the color to fill the render target with. /// If nullptr is provided, the default array {0,0,0,0} will be used. - /// \param [in] StateTransitionMode - Defines requires state transitions (see Diligent::CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE) + /// \param [in] StateTransitionMode - Defines requires state transitions (see Diligent::RESOURCE_STATE_TRANSITION_MODE) /// \remarks The full extent of the view is always cleared. Viewport and scissor settings are not applied. - /// \note The render target view must be bound to the pipeline for clear operation to be performed. - virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode) = 0; + /// \note The render target view must be bound to the pipeline for clear operation to be performed in OpenGL backend. + /// \remarks In D3D12 backend clearing render targets requires textures to always be transitioned to + /// Diligent::RESOURCE_STATE_RENDER_TARGET state. In Vulkan backend however this depends on whether a + /// render pass has been started. To clear render target outside of a render pass, the texture must be transitioned to + /// Diligent::RESOURCE_STATE_COPY_DEST state. Inside a render pass it must be in Diligent::RESOURCE_STATE_RENDER_TARGET + /// state. When using Diligent::RESOURCE_STATE_TRANSITION_TRANSITION mode, the engine takes care of proper + /// resource state transition, otherwise it is the responsibility of the application. + virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) = 0; /// Finishes recording commands and generates a command list @@ -684,13 +723,21 @@ public: /// Copies the data from one buffer to another - /// \param [in] pSrcBuffer - Source buffer to copy data from. - /// \param [in] SrcOffset - Offset in bytes from the beginning of the source buffer to the beginning of data to copy. - /// \param [in] pDstBuffer - Destination buffer to copy data to. - /// \param [in] DstOffset - Offset in bytes from the beginning of the destination buffer to the beginning - /// of the destination region. - /// \param [in] Size - Size in bytes of data to copy. - virtual void CopyBuffer(IBuffer* pSrcBuffer, Uint32 SrcOffset, IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size) = 0; + /// \param [in] pSrcBuffer - Source buffer to copy data from. + /// \param [in] SrcOffset - Offset in bytes from the beginning of the source buffer to the beginning of data to copy. + /// \param [in] SrcBufferTransitionMode - State transition mode of the source buffer (see Diligent::RESOURCE_STATE_TRANSITION_MODE). + /// \param [in] pDstBuffer - Destination buffer to copy data to. + /// \param [in] DstOffset - Offset in bytes from the beginning of the destination buffer to the beginning + /// of the destination region. + /// \param [in] Size - Size in bytes of data to copy. + /// \param [in] DstBufferTransitionMode - State transition mode of the destination buffer (see Diligent::RESOURCE_STATE_TRANSITION_MODE) + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) = 0; /// Maps the buffer @@ -730,29 +777,8 @@ public: /// Copies data from one texture to another - /// \param [in] pSrcTexture - Source texture to copy data from - /// \param [in] SrcMipLevel - Mip level of the source texture to copy data from. - /// \param [in] SrcSlice - Array slice of the source texture to copy data from. - /// Should be 0 for non-array textures. - /// \param [in] pSrcBox - Source region to copy. - /// Use nullptr to copy the entire subresource. - /// \param [in] pDstTexture - Destination texture to copy data to - /// \param [in] DstMipLevel - Mip level to copy data to. - /// \param [in] DstSlice - Array slice to copy data to. - /// Must be 0 for non-array textures. - /// \param [in] DstX - X offset on the destination subresource - /// \param [in] DstY - Y offset on the destination subresource - /// \param [in] DstZ - Z offset on the destination subresource - virtual void CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box *pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ) = 0; + /// \param [in] CopyAttribs - Structure describing copy command attributes, see Diligent::CopyTextureAttribs for details. + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs) = 0; /// Maps the texture subresource diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp index 7276d956..90d616a9 100644 --- a/Graphics/GraphicsEngine/src/Texture.cpp +++ b/Graphics/GraphicsEngine/src/Texture.cpp @@ -214,37 +214,39 @@ void ValidateUpdateTextureParams( const TextureDesc& TexDesc, Uint32 MipLevel, U #endif } -void ValidateCopyTextureParams( const TextureDesc &SrcTexDesc, Uint32 SrcMipLevel, Uint32 SrcSlice, const Box *pSrcBox, - const TextureDesc &DstTexDesc, Uint32 DstMipLevel, Uint32 DstSlice, - Uint32 DstX, Uint32 DstY, Uint32 DstZ ) +void ValidateCopyTextureParams(const CopyTextureAttribs& CopyAttribs ) { + VERIFY_EXPR(CopyAttribs.pSrcTexture != nullptr && CopyAttribs.pDstTexture != nullptr); Box SrcBox; + const auto& SrcTexDesc = CopyAttribs.pSrcTexture->GetDesc(); + const auto& DstTexDesc = CopyAttribs.pDstTexture->GetDesc(); + auto pSrcBox = CopyAttribs.pSrcBox; if( pSrcBox == nullptr ) { - SrcBox.MaxX = std::max( SrcTexDesc.Width >> SrcMipLevel, 1u ); + SrcBox.MaxX = std::max( SrcTexDesc.Width >> CopyAttribs.SrcMipLevel, 1u ); if( SrcTexDesc.Type == RESOURCE_DIM_TEX_1D || SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) SrcBox.MaxY = 1; else - SrcBox.MaxY = std::max( SrcTexDesc.Height >> SrcMipLevel, 1u ); + SrcBox.MaxY = std::max( SrcTexDesc.Height >> CopyAttribs.SrcMipLevel, 1u ); if( SrcTexDesc.Type == RESOURCE_DIM_TEX_3D ) - SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> SrcMipLevel, 1u ); + SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> CopyAttribs.SrcMipLevel, 1u ); else SrcBox.MaxZ = 1; pSrcBox = &SrcBox; } - ValidateTextureRegion(SrcTexDesc, SrcMipLevel, SrcSlice, *pSrcBox); + ValidateTextureRegion(SrcTexDesc, CopyAttribs.SrcMipLevel, CopyAttribs.SrcSlice, *pSrcBox); Box DstBox; - DstBox.MinX = DstX; + DstBox.MinX = CopyAttribs.DstX; DstBox.MaxX = DstBox.MinX + (pSrcBox->MaxX - pSrcBox->MinX); - DstBox.MinY = DstY; + DstBox.MinY = CopyAttribs.DstY; DstBox.MaxY = DstBox.MinY + (pSrcBox->MaxY - pSrcBox->MinY); - DstBox.MinZ = DstZ; + DstBox.MinZ = CopyAttribs.DstZ; DstBox.MaxZ = DstBox.MinZ + (pSrcBox->MaxZ - pSrcBox->MinZ); - ValidateTextureRegion(DstTexDesc, DstMipLevel, DstSlice, DstBox); + ValidateTextureRegion(DstTexDesc, CopyAttribs.DstMipLevel, CopyAttribs.DstSlice, DstBox); } void ValidateMapTextureParams(const TextureDesc& TexDesc, diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index 1c4027fe..d396f12f 100755 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -89,7 +89,7 @@ public: virtual void ClearDepthStencil(ITextureView* pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float fDepth, Uint8 Stencil)override final; - virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode)override final; + virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; virtual void Flush()override final; @@ -99,7 +99,13 @@ public: const PVoid pData, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; - virtual void CopyBuffer(IBuffer* pSrcBuffer, Uint32 SrcOffset, IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size)override final; + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode)override final; virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData)override final; @@ -113,16 +119,7 @@ public: RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; - virtual void CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ)override final; + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs)override final; virtual void MapTextureSubresource( ITexture* pTexture, Uint32 MipLevel, diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index a63f6ac6..9c2466c2 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -902,7 +902,7 @@ namespace Diligent m_pd3d11DeviceContext->ClearDepthStencilView( pd3d11DSV, d3d11ClearFlags, fDepth, Stencil ); } - void DeviceContextD3D11Impl::ClearRenderTarget( ITextureView* pView, const float *RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode ) + void DeviceContextD3D11Impl::ClearRenderTarget( ITextureView* pView, const float *RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode ) { if (pView == nullptr) { @@ -959,9 +959,15 @@ namespace Diligent m_pd3d11DeviceContext->UpdateSubresource(pBufferD3D11Impl->m_pd3d11Buffer, 0, pDstBox, pData, 0, 0); } - void DeviceContextD3D11Impl::CopyBuffer(IBuffer *pSrcBuffer, Uint32 SrcOffset, IBuffer *pDstBuffer, Uint32 DstOffset, Uint32 Size) + void DeviceContextD3D11Impl::CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) { - TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, pDstBuffer, DstOffset, Size); + TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, SrcBufferTransitionMode, pDstBuffer, DstOffset, Size, DstBufferTransitionMode); auto* pSrcBufferD3D11Impl = ValidatedCast( pSrcBuffer ); auto* pDstBufferD3D11Impl = ValidatedCast( pDstBuffer ); @@ -1044,25 +1050,15 @@ namespace Diligent m_pd3d11DeviceContext->UpdateSubresource(pTexD3D11->GetD3D11Texture(), SubresIndex, &D3D11Box, SubresData.pData, SubresData.Stride, SubresData.DepthStride); } - void DeviceContextD3D11Impl::CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ) - { - TDeviceContextBase::CopyTexture( pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, - pDstTexture, DstMipLevel, DstSlice, DstX, DstY, DstZ ); - - auto* pSrcTexD3D11 = ValidatedCast( pSrcTexture ); - auto* pDstTexD3D11 = ValidatedCast( pDstTexture ); + void DeviceContextD3D11Impl::CopyTexture(const CopyTextureAttribs& CopyAttribs) + { + TDeviceContextBase::CopyTexture( CopyAttribs ); + + auto* pSrcTexD3D11 = ValidatedCast( CopyAttribs.pSrcTexture ); + auto* pDstTexD3D11 = ValidatedCast( CopyAttribs.pDstTexture ); D3D11_BOX D3D11SrcBox,* pD3D11SrcBox = nullptr; - if( pSrcBox ) + if (const auto* pSrcBox = CopyAttribs.pSrcBox) { D3D11SrcBox.left = pSrcBox->MinX; D3D11SrcBox.right = pSrcBox->MaxX; @@ -1072,9 +1068,10 @@ namespace Diligent D3D11SrcBox.back = pSrcBox->MaxZ; pD3D11SrcBox = &D3D11SrcBox; } - auto SrcSubRes = D3D11CalcSubresource(SrcMipLevel, SrcSlice, pSrcTexD3D11->GetDesc().MipLevels); - auto DstSubRes = D3D11CalcSubresource(DstMipLevel, DstSlice, pDstTexD3D11->GetDesc().MipLevels); - m_pd3d11DeviceContext->CopySubresourceRegion(pDstTexD3D11->GetD3D11Texture(), DstSubRes, DstX, DstY, DstZ, pSrcTexD3D11->GetD3D11Texture(), SrcSubRes, pD3D11SrcBox); + auto SrcSubRes = D3D11CalcSubresource(CopyAttribs.SrcMipLevel, CopyAttribs.SrcSlice, pSrcTexD3D11->GetDesc().MipLevels); + auto DstSubRes = D3D11CalcSubresource(CopyAttribs.DstMipLevel, CopyAttribs.DstSlice, pDstTexD3D11->GetDesc().MipLevels); + m_pd3d11DeviceContext->CopySubresourceRegion(pDstTexD3D11->GetD3D11Texture(), DstSubRes, CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ, + pSrcTexD3D11->GetD3D11Texture(), SrcSubRes, pD3D11SrcBox); } diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.h b/Graphics/GraphicsEngineD3D12/include/CommandContext.h index 35546844..159d6f0f 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.h +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.h @@ -174,7 +174,7 @@ protected: class GraphicsContext : public CommandContext { public: - void ClearRenderTarget( ITextureViewD3D12 *pRTV, const float *Color, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode ); + void ClearRenderTarget( ITextureViewD3D12 *pRTV, const float *Color, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode ); void ClearDepthStencil( ITextureViewD3D12 *pDSV, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float Depth, UINT8 Stencil ); void SetRootSignature( ID3D12RootSignature *pRootSig ) diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h index ff006981..262a049e 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h @@ -91,7 +91,7 @@ public: virtual void ClearDepthStencil( ITextureView* pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float fDepth, Uint8 Stencil)override final; - virtual void ClearRenderTarget( ITextureView* pView, const float* RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode )override final; + virtual void ClearRenderTarget( ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode )override final; virtual void Flush()override final; @@ -101,7 +101,13 @@ public: const PVoid pData, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; - virtual void CopyBuffer(IBuffer* pSrcBuffer, Uint32 SrcOffset, IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size)override final; + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode)override final; virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData)override final; @@ -115,16 +121,7 @@ public: RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode)override final; - virtual void CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ)override final; + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs)override final; virtual void MapTextureSubresource( ITexture* pTexture, Uint32 MipLevel, @@ -158,8 +155,18 @@ public: Uint64 DstOffset, Uint64 NumBytes, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); - void CopyTextureRegion(class TextureD3D12Impl *pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX* pD3D12SrcBox, - class TextureD3D12Impl *pDstTexture, Uint32 DstSubResIndex, Uint32 DstX, Uint32 DstY, Uint32 DstZ); + + void CopyTextureRegion(class TextureD3D12Impl* pSrcTexture, + Uint32 SrcSubResIndex, + const D3D12_BOX* pD3D12SrcBox, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + class TextureD3D12Impl* pDstTexture, + Uint32 DstSubResIndex, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode); + void CopyTextureRegion(IBuffer* pSrcBuffer, Uint32 SrcOffset, Uint32 SrcStride, @@ -206,6 +213,17 @@ private: void CommitScissorRects(class GraphicsContext &GraphCtx, bool ScissorEnable); void Flush(bool RequestNewCmdCtx); void RequestCommandContext(RenderDeviceD3D12Impl* pDeviceD3D12Impl); + inline void TransitionOrVerifyBufferState(CommandContext& CmdCtx, + BufferD3D12Impl& Buffer, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName); + inline void TransitionOrVerifyTextureState(CommandContext& CmdCtx, + TextureD3D12Impl& Texture, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName); + struct TextureUploadSpace { diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp index 54babb58..cfb4ba77 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -191,22 +191,22 @@ void CommandContext::ClearUAVUint( ITextureViewD3D12* pTexView, const UINT* Colo } -void GraphicsContext::ClearRenderTarget( ITextureViewD3D12* pRTV, const float* Color, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode ) +void GraphicsContext::ClearRenderTarget( ITextureViewD3D12* pRTV, const float* Color, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode ) { auto *pTexture = ValidatedCast( pRTV->GetTexture() ); - if (StateTransitionMode == CLEAR_RENDER_TARGET_TRANSITION_STATE) + if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) { if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET)) TransitionResource(pTexture, RESOURCE_STATE_RENDER_TARGET); } #ifdef DEVELOPMENT - else if (StateTransitionMode == CLEAR_RENDER_TARGET_VERIFY_STATE) + else if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) { if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET)) { LOG_ERROR_MESSAGE("Render target '", pTexture->GetDesc().Name, "' being cleared is not transitioned to RESOURCE_STATE_RENDER_TARGET state. " "Actual texture state: ", GetResourceStateString(pTexture->GetState()), ". " - "Use CLEAR_RENDER_TARGET_TRANSITION_STATE mode or explicitly transition the resource using IDeviceContext::TransitionResourceStates() method."); + "Use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the resource using IDeviceContext::TransitionResourceStates() method."); } } #endif diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index af7c2beb..60bf0633 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -586,7 +586,7 @@ namespace Diligent ++m_State.NumCommands; } - void DeviceContextD3D12Impl::ClearRenderTarget( ITextureView* pView, const float* RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode ) + void DeviceContextD3D12Impl::ClearRenderTarget( ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode ) { ITextureViewD3D12 *pd3d12RTV = nullptr; if( pView != nullptr ) @@ -872,17 +872,7 @@ namespace Diligent { auto& CmdCtx = GetCmdContext(); VERIFY_EXPR( static_cast(NumBytes) == NumBytes ); - if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) - { - if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_COPY_DEST)) - CmdCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_COPY_DEST); - } -#ifdef DEVELOPMENT - else if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) - { - DvpVerifyBufferState(*pBuffD3D12, RESOURCE_STATE_COPY_DEST, "Updating buffer (DeviceContextD3D12Impl::UpdateBufferRegion)"); - } -#endif + TransitionOrVerifyBufferState(CmdCtx, *pBuffD3D12, StateTransitionMode, RESOURCE_STATE_COPY_DEST, "Updating buffer (DeviceContextD3D12Impl::UpdateBufferRegion)"); size_t DstBuffDataStartByteOffset; auto *pd3d12Buff = pBuffD3D12->GetD3D12Buffer(DstBuffDataStartByteOffset, this); VERIFY(DstBuffDataStartByteOffset == 0, "Dst buffer must not be suballocated"); @@ -909,9 +899,15 @@ namespace Diligent UpdateBufferRegion(pBuffD3D12, TmpSpace, Offset, Size, StateTransitionMode); } - void DeviceContextD3D12Impl::CopyBuffer(IBuffer* pSrcBuffer, Uint32 SrcOffset, IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size) + void DeviceContextD3D12Impl::CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) { - TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, pDstBuffer, DstOffset, Size); + TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, SrcBufferTransitionMode, pDstBuffer, DstOffset, Size, DstBufferTransitionMode); auto* pSrcBuffD3D12 = ValidatedCast(pSrcBuffer); auto* pDstBuffD3D12 = ValidatedCast(pDstBuffer); @@ -919,10 +915,9 @@ namespace Diligent VERIFY(pDstBuffD3D12->GetDesc().Usage != USAGE_DYNAMIC, "Dynamic buffers cannot be copy destinations"); auto& CmdCtx = GetCmdContext(); - if (pSrcBuffD3D12->IsInKnownState() && !pSrcBuffD3D12->CheckState(RESOURCE_STATE_COPY_SOURCE)) - CmdCtx.TransitionResource(pSrcBuffD3D12, RESOURCE_STATE_COPY_SOURCE); - if (pDstBuffD3D12->IsInKnownState() && !pDstBuffD3D12->CheckState(RESOURCE_STATE_COPY_DEST)) - CmdCtx.TransitionResource(pDstBuffD3D12, RESOURCE_STATE_COPY_DEST); + TransitionOrVerifyBufferState(CmdCtx, *pSrcBuffD3D12, SrcBufferTransitionMode, RESOURCE_STATE_COPY_SOURCE, "Using resource as copy source (DeviceContextD3D12Impl::CopyBuffer)"); + TransitionOrVerifyBufferState(CmdCtx, *pDstBuffD3D12, DstBufferTransitionMode, RESOURCE_STATE_COPY_DEST, "Using resource as copy destination (DeviceContextD3D12Impl::CopyBuffer)"); + size_t DstDataStartByteOffset; auto* pd3d12DstBuff = pDstBuffD3D12->GetD3D12Buffer(DstDataStartByteOffset, this); VERIFY(DstDataStartByteOffset == 0, "Dst buffer must not be suballocated"); @@ -1081,27 +1076,17 @@ namespace Diligent } } - void DeviceContextD3D12Impl::CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ) + void DeviceContextD3D12Impl::CopyTexture(const CopyTextureAttribs& CopyAttribs) { - TDeviceContextBase::CopyTexture( pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, - pDstTexture, DstMipLevel, DstSlice, DstX, DstY, DstZ ); + TDeviceContextBase::CopyTexture( CopyAttribs ); - auto* pSrcTexD3D12 = ValidatedCast( pSrcTexture ); - auto* pDstTexD3D12 = ValidatedCast( pDstTexture ); + auto* pSrcTexD3D12 = ValidatedCast( CopyAttribs.pSrcTexture ); + auto* pDstTexD3D12 = ValidatedCast( CopyAttribs.pDstTexture ); const auto& SrcTexDesc = pSrcTexD3D12->GetDesc(); const auto& DstTexDesc = pDstTexD3D12->GetDesc(); D3D12_BOX D3D12SrcBox, *pD3D12SrcBox = nullptr; - if( pSrcBox ) + if (const auto* pSrcBox = CopyAttribs.pSrcBox) { D3D12SrcBox.left = pSrcBox->MinX; D3D12SrcBox.right = pSrcBox->MaxX; @@ -1112,20 +1097,27 @@ namespace Diligent pD3D12SrcBox = &D3D12SrcBox; } - auto DstSubResIndex = D3D12CalcSubresource(DstMipLevel, DstSlice, 0, DstTexDesc.MipLevels, DstTexDesc.ArraySize); - auto SrcSubResIndex = D3D12CalcSubresource(SrcMipLevel, SrcSlice, 0, SrcTexDesc.MipLevels, SrcTexDesc.ArraySize); - CopyTextureRegion(pSrcTexD3D12, SrcSubResIndex, pD3D12SrcBox, pDstTexD3D12, DstSubResIndex, DstX, DstY, DstZ); + auto DstSubResIndex = D3D12CalcSubresource(CopyAttribs.DstMipLevel, CopyAttribs.DstSlice, 0, DstTexDesc.MipLevels, DstTexDesc.ArraySize); + auto SrcSubResIndex = D3D12CalcSubresource(CopyAttribs.SrcMipLevel, CopyAttribs.SrcSlice, 0, SrcTexDesc.MipLevels, SrcTexDesc.ArraySize); + CopyTextureRegion(pSrcTexD3D12, SrcSubResIndex, pD3D12SrcBox, CopyAttribs.SrcTextureTransitionMode, + pDstTexD3D12, DstSubResIndex, CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ, + CopyAttribs.DstTextureTransitionMode); } - void DeviceContextD3D12Impl::CopyTextureRegion(TextureD3D12Impl* pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX* pD3D12SrcBox, - TextureD3D12Impl* pDstTexture, Uint32 DstSubResIndex, Uint32 DstX, Uint32 DstY, Uint32 DstZ) + void DeviceContextD3D12Impl::CopyTextureRegion(TextureD3D12Impl* pSrcTexture, + Uint32 SrcSubResIndex, + const D3D12_BOX* pD3D12SrcBox, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + TextureD3D12Impl* pDstTexture, + Uint32 DstSubResIndex, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode) { auto& CmdCtx = GetCmdContext(); - - if (pSrcTexture->IsInKnownState() && !pSrcTexture->CheckState(RESOURCE_STATE_COPY_SOURCE)) - CmdCtx.TransitionResource(pSrcTexture, RESOURCE_STATE_COPY_SOURCE); - if (pDstTexture->IsInKnownState() && !pDstTexture->CheckState(RESOURCE_STATE_COPY_DEST)) - CmdCtx.TransitionResource(pDstTexture, RESOURCE_STATE_COPY_DEST); + TransitionOrVerifyTextureState(CmdCtx, *pSrcTexture, SrcTextureTransitionMode, RESOURCE_STATE_COPY_SOURCE, "Using resource as copy source (DeviceContextD3D12Impl::CopyTextureRegion)"); + TransitionOrVerifyTextureState(CmdCtx, *pDstTexture, DstTextureTransitionMode, RESOURCE_STATE_COPY_DEST, "Using resource as copy destination (DeviceContextD3D12Impl::CopyTextureRegion)"); D3D12_TEXTURE_COPY_LOCATION DstLocation = {}, SrcLocation = {}; @@ -1472,6 +1464,44 @@ namespace Diligent } } + void DeviceContextD3D12Impl::TransitionOrVerifyBufferState(CommandContext& CmdCtx, + BufferD3D12Impl& Buffer, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName) + { + if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + { + if (Buffer.IsInKnownState() && !Buffer.CheckState(RequiredState)) + CmdCtx.TransitionResource(&Buffer, RequiredState); + } +#ifdef DEVELOPMENT + else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) + { + DvpVerifyBufferState(Buffer, RequiredState, OperationName); + } +#endif + } + + void DeviceContextD3D12Impl::TransitionOrVerifyTextureState(CommandContext& CmdCtx, + TextureD3D12Impl& Texture, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName) + { + if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + { + if (Texture.IsInKnownState() && !Texture.CheckState(RequiredState)) + CmdCtx.TransitionResource(&Texture, RequiredState); + } +#ifdef DEVELOPMENT + else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) + { + DvpVerifyTextureState(Texture, RequiredState, OperationName); + } +#endif + } + void DeviceContextD3D12Impl::TransitionTextureState(ITexture *pTexture, D3D12_RESOURCE_STATES State) { VERIFY_EXPR(pTexture != nullptr); diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 325b5ab6..e667f0f8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -74,7 +74,7 @@ public: virtual void ClearDepthStencil( ITextureView *pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float fDepth, Uint8 Stencil)override final; - virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode )override final; + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode )override final; virtual void Flush()override final; @@ -84,7 +84,13 @@ public: const PVoid pData, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; - virtual void CopyBuffer(IBuffer *pSrcBuffer, Uint32 SrcOffset, IBuffer *pDstBuffer, Uint32 DstOffset, Uint32 Size)override final; + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode)override final; virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData)override final; @@ -98,16 +104,7 @@ public: RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionMode)override final; - virtual void CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ)override final; + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs)override final; virtual void MapTextureSubresource( ITexture* pTexture, Uint32 MipLevel, diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 4f5b56b2..bdbfdce8 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -908,7 +908,7 @@ namespace Diligent m_ContextState.EnableScissorTest( ScissorTestEnabled ); } - void DeviceContextGLImpl::ClearRenderTarget( ITextureView *pView, const float *RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode ) + void DeviceContextGLImpl::ClearRenderTarget( ITextureView *pView, const float *RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode ) { // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. // Viewport and scissor settings are not applied. @@ -1023,9 +1023,15 @@ namespace Diligent pBufferGL->UpdateData(m_ContextState, Offset, Size, pData); } - void DeviceContextGLImpl::CopyBuffer(IBuffer *pSrcBuffer, Uint32 SrcOffset, IBuffer *pDstBuffer, Uint32 DstOffset, Uint32 Size) + void DeviceContextGLImpl::CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) { - TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, pDstBuffer, DstOffset, Size); + TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, SrcBufferTransitionMode, pDstBuffer, DstOffset, Size, DstBufferTransitionMode); auto* pSrcBufferGL = ValidatedCast(pSrcBuffer); auto* pDstBufferGL = ValidatedCast(pDstBuffer); @@ -1059,22 +1065,13 @@ namespace Diligent pTexGL->UpdateData(m_ContextState, MipLevel, Slice, DstBox, SubresData); } - void DeviceContextGLImpl::CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ) + void DeviceContextGLImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs) { - TDeviceContextBase::CopyTexture( pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, - pDstTexture, DstMipLevel, DstSlice, DstX, DstY, DstZ ); - auto* pSrcTexGL = ValidatedCast(pSrcTexture); - auto* pDstTexGL = ValidatedCast(pDstTexture); - pDstTexGL->CopyData(this, pSrcTexGL, SrcMipLevel, SrcSlice, pSrcBox, DstMipLevel, DstSlice, DstX, DstY, DstZ); + TDeviceContextBase::CopyTexture( CopyAttribs ); + auto* pSrcTexGL = ValidatedCast(CopyAttribs.pSrcTexture); + auto* pDstTexGL = ValidatedCast(CopyAttribs.pDstTexture); + pDstTexGL->CopyData(this, pSrcTexGL, CopyAttribs.SrcMipLevel, CopyAttribs.SrcSlice, CopyAttribs.pSrcBox, + CopyAttribs.DstMipLevel, CopyAttribs.DstSlice, CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ); } void DeviceContextGLImpl::MapTextureSubresource( ITexture* pTexture, diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 4f207929..a6f034b2 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -98,7 +98,7 @@ public: virtual void ClearDepthStencil( ITextureView* pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float fDepth, Uint8 Stencil)override final; - virtual void ClearRenderTarget( ITextureView* pView, const float* RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode )override final; + virtual void ClearRenderTarget( ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode )override final; virtual void Flush()override final; @@ -108,7 +108,13 @@ public: const PVoid pData, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; - virtual void CopyBuffer(IBuffer* pSrcBuffer, Uint32 SrcOffset, IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size)override final; + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode)override final; virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData)override final; @@ -122,16 +128,7 @@ public: RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionModee)override final; - virtual void CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ)override final; + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs)override final; virtual void MapTextureSubresource( ITexture* pTexture, Uint32 MipLevel, @@ -195,8 +192,11 @@ public: Uint64 SrcOffset, RESOURCE_STATE_TRANSITION_MODE TransitionMode); - void CopyBufferRegion(BufferVkImpl* pSrcBuffVk, BufferVkImpl* pDstBuffVk, Uint64 SrcOffset, Uint64 DstOffset, Uint64 NumBytes); - void CopyTextureRegion(TextureVkImpl* pSrcTexture, TextureVkImpl* pDstTexture, const VkImageCopy &CopyRegion); + void CopyTextureRegion(TextureVkImpl* pSrcTexture, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + TextureVkImpl* pDstTexture, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode, + const VkImageCopy& CopyRegion); void UpdateTextureRegion(const void* pSrcData, Uint32 SrcStride, @@ -243,6 +243,19 @@ private: void CommitViewports(); void CommitScissorRects(); + inline void TransitionOrVerifyBufferState(BufferVkImpl& Buffer, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + VkAccessFlagBits ExpectedAccessFlags, + const char* OperationName); + + inline void TransitionOrVerifyTextureState(TextureVkImpl& Texture, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + VkImageLayout ExpectedLayout, + const char* OperationName); + + inline void EnsureVkCmdBuffer() { // Make sure that the number of commands in the context is at least one, diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index b0fe445b..412b452c 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -496,23 +496,14 @@ namespace Diligent if (pIndirectDrawAttribsVk != nullptr) { // Buffer memory barries must be executed outside of render pass - if(drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER) - { - if (pIndirectDrawAttribsVk->IsInKnownState()) - { - if (!pIndirectDrawAttribsVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT)) - { - TransitionBufferState(*pIndirectDrawAttribsVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true); - } - VERIFY_EXPR(pIndirectDrawAttribsVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT)); - } - } -#ifdef DEVELOPMENT - else if (VerifyStates) - { - DvpVerifyBufferState(*pIndirectDrawAttribsVk, RESOURCE_STATE_INDIRECT_ARGUMENT, "Indirect draw (DeviceContextVkImpl::Draw)"); - } -#endif + auto TransitionMode = + (drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER) ? + RESOURCE_STATE_TRANSITION_MODE_TRANSITION : + (VerifyStates ? + RESOURCE_STATE_TRANSITION_MODE_VERIFY : + RESOURCE_STATE_TRANSITION_MODE_NONE); + TransitionOrVerifyBufferState(*pIndirectDrawAttribsVk, TransitionMode, RESOURCE_STATE_INDIRECT_ARGUMENT, + VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect draw (DeviceContextVkImpl::Draw)"); } #ifdef DEVELOPMENT @@ -581,24 +572,15 @@ namespace Diligent pBufferVk->DvpVerifyDynamicAllocation(this); #endif - if (DispatchAttrs.Flags & DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER) - { - // Buffer memory barries must be executed outside of render pass - if (pBufferVk->IsInKnownState()) - { - if (!pBufferVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT)) - { - TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true); - } - VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT)); - } - } -#ifdef DEVELOPMENT - else if (DispatchAttrs.Flags & DISPATCH_FLAG_VERIFY_STATES) - { - DvpVerifyBufferState(*pBufferVk, RESOURCE_STATE_INDIRECT_ARGUMENT, "Indirect dispatch (DeviceContextVkImpl::DispatchCompute)"); - } -#endif + // Buffer memory barries must be executed outside of render pass + auto TransitionMode = + (DispatchAttrs.Flags & DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER) ? + RESOURCE_STATE_TRANSITION_MODE_TRANSITION : + ((DispatchAttrs.Flags & DISPATCH_FLAG_VERIFY_STATES) ? + RESOURCE_STATE_TRANSITION_MODE_VERIFY : + RESOURCE_STATE_TRANSITION_MODE_NONE); + TransitionOrVerifyBufferState(*pBufferVk, TransitionMode, RESOURCE_STATE_INDIRECT_ARGUMENT, + VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect dispatch (DeviceContextVkImpl::DispatchCompute)"); m_CommandBuffer.DispatchIndirect(pBufferVk->GetVkBuffer(), pBufferVk->GetDynamicOffset(m_ContextId, this) + DispatchAttrs.DispatchArgsByteOffset); } @@ -680,25 +662,15 @@ namespace Diligent auto* pTexture = pVkDSV->GetTexture(); auto* pTextureVk = ValidatedCast(pTexture); - if (ClearFlags & CLEAR_DEPTH_STENCIL_TRANSITION_STATE_FLAG) - { - // Image layout must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL (17.1) - if (pTextureVk->IsInKnownState()) - { - if (!pTextureVk->CheckState(RESOURCE_STATE_COPY_DEST)) - { - TransitionTextureState(*pTextureVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, true); - } - VERIFY_EXPR(pTextureVk->GetLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - } - } -#ifdef DEVELOPMENT - else if(ClearFlags & CLEAR_DEPTH_STENCIL_VERIFY_STATE_FLAG) - { - DvpVerifyTextureState(*pTextureVk, RESOURCE_STATE_COPY_DEST, "Clearing depth-stencil buffer outside of render pass (DeviceContextVkImpl::ClearDepthStencil)"); - } -#endif - + // Image layout must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL (17.1) + auto TransitionMode = + (ClearFlags & CLEAR_DEPTH_STENCIL_TRANSITION_STATE_FLAG) ? + RESOURCE_STATE_TRANSITION_MODE_TRANSITION : + ((ClearFlags & CLEAR_DEPTH_STENCIL_VERIFY_STATE_FLAG) ? + RESOURCE_STATE_TRANSITION_MODE_VERIFY : + RESOURCE_STATE_TRANSITION_MODE_NONE); + TransitionOrVerifyTextureState(*pTextureVk, TransitionMode, RESOURCE_STATE_COPY_DEST, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + "Clearing depth-stencil buffer outside of render pass (DeviceContextVkImpl::ClearDepthStencil)"); VkClearDepthStencilValue ClearValue; ClearValue.depth = fDepth; @@ -742,7 +714,7 @@ namespace Diligent return ClearValue; } - void DeviceContextVkImpl::ClearRenderTarget( ITextureView *pView, const float *RGBA, CLEAR_RENDER_TARGET_STATE_TRANSITION_MODE StateTransitionMode ) + void DeviceContextVkImpl::ClearRenderTarget( ITextureView *pView, const float *RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode ) { ITextureViewVk* pVkRTV = nullptr; if ( pView != nullptr ) @@ -826,23 +798,9 @@ namespace Diligent auto* pTextureVk = ValidatedCast(pTexture); // Image layout must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL (17.1) - if (StateTransitionMode == CLEAR_RENDER_TARGET_TRANSITION_STATE) - { - if (pTextureVk->IsInKnownState()) - { - if (!pTextureVk->CheckState(RESOURCE_STATE_COPY_DEST)) - { - TransitionTextureState(*pTextureVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, true); - } - VERIFY_EXPR(pTextureVk->GetLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - } - } -#ifdef DEVELOPMENT - else if (StateTransitionMode == CLEAR_RENDER_TARGET_VERIFY_STATE) - { - DvpVerifyTextureState(*pTextureVk, RESOURCE_STATE_COPY_DEST, "Clearing render target outside of render pass (DeviceContextVkImpl::ClearRenderTarget)"); - } -#endif + TransitionOrVerifyTextureState(*pTextureVk, StateTransitionMode, RESOURCE_STATE_COPY_DEST, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + "Clearing render target outside of render pass (DeviceContextVkImpl::ClearRenderTarget)"); + auto ClearValue = ClearValueToVkClearValue(RGBA, ViewDesc.Format); VkImageSubresourceRange Subresource; Subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -1086,23 +1044,13 @@ namespace Diligent { auto* pDSVVk = m_pBoundDepthStencil.RawPtr(); auto* pDepthBufferVk = ValidatedCast(pDSVVk->GetTexture()); - if (Flags & SET_RENDER_TARGETS_FLAG_TRANSITION_DEPTH) - { - if (pDepthBufferVk->IsInKnownState()) - { - if (!pDepthBufferVk->CheckState(RESOURCE_STATE_DEPTH_WRITE)) - { - TransitionTextureState(*pDepthBufferVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_DEPTH_WRITE, true); - } - VERIFY_EXPR(pDepthBufferVk->GetLayout() == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - } - } -#ifdef DEVELOPMENT - else if (Flags & SET_RENDER_TARGETS_FLAG_VERIFY_STATES) - { - DvpVerifyTextureState(*pDepthBufferVk, RESOURCE_STATE_DEPTH_WRITE, "Binding depth-stencil buffer (DeviceContextVkImpl::TransitionRenderTargets)"); - } -#endif + auto DepthTransitionMode = (Flags & SET_RENDER_TARGETS_FLAG_TRANSITION_DEPTH) ? + RESOURCE_STATE_TRANSITION_MODE_TRANSITION : + ((Flags & SET_RENDER_TARGETS_FLAG_VERIFY_STATES) ? + RESOURCE_STATE_TRANSITION_MODE_VERIFY : + RESOURCE_STATE_TRANSITION_MODE_NONE); + TransitionOrVerifyTextureState(*pDepthBufferVk, DepthTransitionMode, RESOURCE_STATE_DEPTH_WRITE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + "Binding depth-stencil buffer (DeviceContextVkImpl::TransitionRenderTargets)"); } for (Uint32 rt=0; rt < m_NumBoundRenderTargets; ++rt) @@ -1111,23 +1059,13 @@ namespace Diligent { auto* pRTVVk = ValidatedCast(pRTV); auto* pRenderTargetVk = ValidatedCast(pRTVVk->GetTexture()); - if (Flags & SET_RENDER_TARGETS_FLAG_TRANSITION_COLOR) - { - if (pRenderTargetVk->IsInKnownState()) - { - if (!pRenderTargetVk->CheckState(RESOURCE_STATE_RENDER_TARGET)) - { - TransitionTextureState(*pRenderTargetVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_RENDER_TARGET, true); - } - VERIFY_EXPR(pRenderTargetVk->GetLayout() == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - } - } -#ifdef DEVELOPMENT - else if (Flags & SET_RENDER_TARGETS_FLAG_VERIFY_STATES) - { - DvpVerifyTextureState(*pRenderTargetVk, RESOURCE_STATE_RENDER_TARGET, "Binding render targets (DeviceContextVkImpl::TransitionRenderTargets)"); - } -#endif + auto RTTransitionMode = (Flags & SET_RENDER_TARGETS_FLAG_TRANSITION_COLOR) ? + RESOURCE_STATE_TRANSITION_MODE_TRANSITION : + ((Flags & SET_RENDER_TARGETS_FLAG_VERIFY_STATES) ? + RESOURCE_STATE_TRANSITION_MODE_VERIFY : + RESOURCE_STATE_TRANSITION_MODE_NONE); + TransitionOrVerifyTextureState(*pRenderTargetVk, RTTransitionMode, RESOURCE_STATE_RENDER_TARGET, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + "Binding render targets (DeviceContextVkImpl::TransitionRenderTargets)"); } } } @@ -1236,23 +1174,8 @@ namespace Diligent #endif EnsureVkCmdBuffer(); - if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) - { - if (pBuffVk->IsInKnownState()) - { - if (!pBuffVk->CheckState(RESOURCE_STATE_COPY_DEST)) - { - TransitionBufferState(*pBuffVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, true); - } - VERIFY_EXPR(pBuffVk->CheckAccessFlags(VK_ACCESS_TRANSFER_WRITE_BIT)); - } - } -#ifdef DEVELOPMENT - else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) - { - DvpVerifyBufferState(*pBuffVk, RESOURCE_STATE_COPY_DEST, "Updating buffer (DeviceContextVkImpl::UpdateBufferRegion)"); - } -#endif + TransitionOrVerifyBufferState(*pBuffVk, TransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, "Updating buffer (DeviceContextVkImpl::UpdateBufferRegion)"); + VkBufferCopy CopyRegion; CopyRegion.srcOffset = SrcOffset; CopyRegion.dstOffset = DstOffset; @@ -1291,12 +1214,18 @@ namespace Diligent // pages will be discarded } - void DeviceContextVkImpl::CopyBuffer(IBuffer* pSrcBuffer, Uint32 SrcOffset, IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size) + void DeviceContextVkImpl::CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) { - TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, pDstBuffer, DstOffset, Size); + TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, SrcBufferTransitionMode, pDstBuffer, DstOffset, Size, DstBufferTransitionMode); - auto *pSrcBuffVk = ValidatedCast(pSrcBuffer); - auto *pDstBuffVk = ValidatedCast(pDstBuffer); + auto* pSrcBuffVk = ValidatedCast(pSrcBuffer); + auto* pDstBuffVk = ValidatedCast(pDstBuffer); #ifdef DEVELOPMENT if (pDstBuffVk->GetDesc().Usage == USAGE_DYNAMIC) @@ -1307,22 +1236,8 @@ namespace Diligent #endif EnsureVkCmdBuffer(); - if (pSrcBuffVk->IsInKnownState()) - { - if (!pSrcBuffVk->CheckState(RESOURCE_STATE_COPY_SOURCE)) - { - TransitionBufferState(*pSrcBuffVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_SOURCE, true); - } - VERIFY_EXPR(pSrcBuffVk->CheckAccessFlags(VK_ACCESS_TRANSFER_READ_BIT)); - } - if (pDstBuffVk->IsInKnownState()) - { - if (!pDstBuffVk->CheckState(RESOURCE_STATE_COPY_DEST)) - { - TransitionBufferState(*pDstBuffVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, true); - } - VERIFY_EXPR(pDstBuffVk->CheckAccessFlags(VK_ACCESS_TRANSFER_WRITE_BIT)); - } + TransitionOrVerifyBufferState(*pSrcBuffVk, SrcBufferTransitionMode, RESOURCE_STATE_COPY_SOURCE, VK_ACCESS_TRANSFER_READ_BIT, "Using buffer as copy source (DeviceContextVkImpl::CopyBuffer)"); + TransitionOrVerifyBufferState(*pDstBuffVk, DstBufferTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, "Using buffer as copy destination (DeviceContextVkImpl::CopyBuffer)"); VkBufferCopy CopyRegion; CopyRegion.srcOffset = SrcOffset + pSrcBuffVk->GetDynamicOffset(m_ContextId, this); @@ -1448,25 +1363,15 @@ namespace Diligent } } - void DeviceContextVkImpl::CopyTexture(ITexture* pSrcTexture, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - ITexture* pDstTexture, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ) + void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs) { - TDeviceContextBase::CopyTexture( pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, - pDstTexture, DstMipLevel, DstSlice, DstX, DstY, DstZ ); + TDeviceContextBase::CopyTexture( CopyAttribs ); - auto* pSrcTexVk = ValidatedCast( pSrcTexture ); - auto* pDstTexVk = ValidatedCast( pDstTexture ); + auto* pSrcTexVk = ValidatedCast( CopyAttribs.pSrcTexture ); + auto* pDstTexVk = ValidatedCast( CopyAttribs.pDstTexture ); const auto& DstTexDesc = pDstTexVk->GetDesc(); VkImageCopy CopyRegion = {}; - if( pSrcBox ) + if (auto* pSrcBox = CopyAttribs.pSrcBox) { CopyRegion.srcOffset.x = pSrcBox->MinX; CopyRegion.srcOffset.y = pSrcBox->MinY; @@ -1478,10 +1383,10 @@ namespace Diligent else { CopyRegion.srcOffset = VkOffset3D{0,0,0}; - CopyRegion.extent.width = std::max(DstTexDesc.Width >> SrcMipLevel, 1u); - CopyRegion.extent.height = std::max(DstTexDesc.Height >> SrcMipLevel, 1u); + CopyRegion.extent.width = std::max(DstTexDesc.Width >> CopyAttribs.SrcMipLevel, 1u); + CopyRegion.extent.height = std::max(DstTexDesc.Height >> CopyAttribs.SrcMipLevel, 1u); if(DstTexDesc.Type == RESOURCE_DIM_TEX_3D) - CopyRegion.extent.depth = std::max(DstTexDesc.Depth >> SrcMipLevel, 1u); + CopyRegion.extent.depth = std::max(DstTexDesc.Depth >> CopyAttribs.SrcMipLevel, 1u); else CopyRegion.extent.depth = 1; } @@ -1497,42 +1402,35 @@ namespace Diligent else aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - CopyRegion.srcSubresource.baseArrayLayer = SrcSlice; + CopyRegion.srcSubresource.baseArrayLayer = CopyAttribs.SrcSlice; CopyRegion.srcSubresource.layerCount = 1; - CopyRegion.srcSubresource.mipLevel = SrcMipLevel; + CopyRegion.srcSubresource.mipLevel = CopyAttribs.SrcMipLevel; CopyRegion.srcSubresource.aspectMask = aspectMask; - CopyRegion.dstSubresource.baseArrayLayer = DstSlice; + CopyRegion.dstSubresource.baseArrayLayer = CopyAttribs.DstSlice; CopyRegion.dstSubresource.layerCount = 1; - CopyRegion.dstSubresource.mipLevel = DstMipLevel; + CopyRegion.dstSubresource.mipLevel = CopyAttribs.DstMipLevel; CopyRegion.dstSubresource.aspectMask = aspectMask; - CopyRegion.dstOffset.x = DstX; - CopyRegion.dstOffset.y = DstY; - CopyRegion.dstOffset.z = DstZ; + CopyRegion.dstOffset.x = CopyAttribs.DstX; + CopyRegion.dstOffset.y = CopyAttribs.DstY; + CopyRegion.dstOffset.z = CopyAttribs.DstZ; - CopyTextureRegion(pSrcTexVk, pDstTexVk, CopyRegion); + CopyTextureRegion(pSrcTexVk, CopyAttribs.SrcTextureTransitionMode, pDstTexVk, CopyAttribs.DstTextureTransitionMode, CopyRegion); } - void DeviceContextVkImpl::CopyTextureRegion(TextureVkImpl *pSrcTexture, TextureVkImpl *pDstTexture, const VkImageCopy &CopyRegion) + void DeviceContextVkImpl::CopyTextureRegion(TextureVkImpl* pSrcTexture, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + TextureVkImpl* pDstTexture, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode, + const VkImageCopy& CopyRegion) { EnsureVkCmdBuffer(); - if (pSrcTexture->IsInKnownState()) - { - if (!pSrcTexture->CheckState(RESOURCE_STATE_COPY_SOURCE)) - { - TransitionTextureState(*pSrcTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_SOURCE, true); - } - VERIFY_EXPR(pSrcTexture->GetLayout() == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - } - if (pDstTexture->IsInKnownState()) - { - if (!pDstTexture->CheckState(RESOURCE_STATE_COPY_DEST)) - { - TransitionTextureState(*pDstTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, true); - } - VERIFY_EXPR(pDstTexture->GetLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - } + TransitionOrVerifyTextureState(*pSrcTexture, SrcTextureTransitionMode, RESOURCE_STATE_COPY_SOURCE, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + "Using texture as transfer source (DeviceContextVkImpl::CopyTextureRegion)"); + TransitionOrVerifyTextureState(*pDstTexture, DstTextureTransitionMode, RESOURCE_STATE_COPY_DEST, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + "Using texture as transfer destination (DeviceContextVkImpl::CopyTextureRegion)"); + // srcImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL // dstImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL (18.3) m_CommandBuffer.CopyImage(pSrcTexture->GetVkImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, pDstTexture->GetVkImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &CopyRegion); @@ -1676,23 +1574,8 @@ namespace Diligent RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode) { EnsureVkCmdBuffer(); - if (TextureTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) - { - if (TextureVk.IsInKnownState()) - { - if (!TextureVk.CheckState(RESOURCE_STATE_COPY_DEST)) - { - TransitionTextureState(TextureVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, true); - } - VERIFY_EXPR(TextureVk.GetLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - } - } -#ifdef DEVELOPMENT - else if (TextureTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) - { - DvpVerifyTextureState(TextureVk, RESOURCE_STATE_COPY_DEST, "Using texture as copy destination (DeviceContextVkImpl::CopyBufferToTexture)"); - } -#endif + TransitionOrVerifyTextureState(TextureVk, TextureTransitionMode, RESOURCE_STATE_COPY_DEST, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + "Using texture as copy destination (DeviceContextVkImpl::CopyBufferToTexture)"); VkBufferImageCopy CopyRegion = {}; VERIFY( (BufferOffset % 4) == 0, "Source buffer offset must be multiple of 4 (18.4)"); @@ -1985,6 +1868,31 @@ namespace Diligent } } + void DeviceContextVkImpl::TransitionOrVerifyTextureState(TextureVkImpl& Texture, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + VkImageLayout ExpectedLayout, + const char* OperationName) + { + if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + { + if (Texture.IsInKnownState()) + { + if (!Texture.CheckState(RequiredState)) + { + TransitionTextureState(Texture, RESOURCE_STATE_UNKNOWN, RequiredState, true); + } + VERIFY_EXPR(Texture.GetLayout() == ExpectedLayout); + } + } +#ifdef DEVELOPMENT + else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) + { + DvpVerifyTextureState(Texture, RequiredState, OperationName); + } +#endif + } + void DeviceContextVkImpl::TransitionImageLayout(TextureVkImpl& TextureVk, VkImageLayout OldLayout, VkImageLayout NewLayout, const VkImageSubresourceRange& SubresRange) { VERIFY(TextureVk.GetLayout() != NewLayout, "The texture is already transitioned to correct layout"); @@ -2050,6 +1958,31 @@ namespace Diligent } } + void DeviceContextVkImpl::TransitionOrVerifyBufferState(BufferVkImpl& Buffer, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + VkAccessFlagBits ExpectedAccessFlags, + const char* OperationName) + { + if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + { + if (Buffer.IsInKnownState()) + { + if (!Buffer.CheckState(RequiredState)) + { + TransitionBufferState(Buffer, RESOURCE_STATE_UNKNOWN, RequiredState, true); + } + VERIFY_EXPR(Buffer.CheckAccessFlags(ExpectedAccessFlags)); + } + } +#ifdef DEVELOPMENT + else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) + { + DvpVerifyBufferState(Buffer, RequiredState, OperationName); + } +#endif + } + VulkanDynamicAllocation DeviceContextVkImpl::AllocateDynamicSpace(Uint32 SizeInBytes, Uint32 Alignment) { auto DynAlloc = m_DynamicHeap.Allocate(SizeInBytes, Alignment); diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index dafa664e..ad68c9a0 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -419,7 +419,7 @@ void SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk) { // Vulkan validation layers do not like uninitialized memory. // Clear back buffer first time we acquire it. This will use vkCmdClearColorImage() - pDeviceCtxVk->ClearRenderTarget(GetCurrentBackBufferRTV(), nullptr, CLEAR_RENDER_TARGET_TRANSITION_STATE); + pDeviceCtxVk->ClearRenderTarget(GetCurrentBackBufferRTV(), nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_SwapChainImagesInitialized[m_BackBufferIndex] = true; } } -- cgit v1.2.3