diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2017-11-13 02:54:50 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2017-11-13 02:54:50 +0000 |
| commit | 8e24a0919d30f939140e776bc5e64bd77767e99c (patch) | |
| tree | bfa1c37385cafe7d6c192ed0c8eb936aa828cb5a /Graphics/GraphicsEngine | |
| parent | Merge from dev branch (diff) | |
| download | DiligentCore-8e24a0919d30f939140e776bc5e64bd77767e99c.tar.gz DiligentCore-8e24a0919d30f939140e776bc5e64bd77767e99c.zip | |
Updated to Diligent Engine 2.1
Diffstat (limited to 'Graphics/GraphicsEngine')
28 files changed, 628 insertions, 331 deletions
diff --git a/Graphics/GraphicsEngine/include/BufferBase.h b/Graphics/GraphicsEngine/include/BufferBase.h index d559ba27..fa9a3f50 100644 --- a/Graphics/GraphicsEngine/include/BufferBase.h +++ b/Graphics/GraphicsEngine/include/BufferBase.h @@ -41,27 +41,26 @@ namespace Diligent /// (Diligent::IBufferD3D11, Diligent::IBufferD3D12 or Diligent::IBufferGL). /// \tparam BufferViewImplType - type of the buffer view implementation /// (Diligent::BufferViewD3D11Impl, Diligent::BufferViewD3D12Impl or Diligent::BufferViewGLImpl) -/// \tparam TBuffObjAllocator - type of the allocator that is used to allocate memory for the buffer object instances /// \tparam TBuffViewObjAllocator - type of the allocator that is used to allocate memory for the buffer view object instances -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -class BufferBase : public DeviceObjectBase < BaseInterface, BufferDesc, TBuffObjAllocator > +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +class BufferBase : public DeviceObjectBase < BaseInterface, BufferDesc> { public: - typedef DeviceObjectBase<BaseInterface, BufferDesc, TBuffObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, BufferDesc> TDeviceObjectBase; - /// \param BuffObjAllocator - allocator that was used to allocate memory for this instance of the buffer object. + /// \param pRefCounters - reference counters object that controls the lifetime of this buffer. /// \param BuffViewObjAllocator - allocator that is used to allocate memory for the buffer view instances. /// This parameter is only used for debug purposes. /// \param pDevice - pointer to the device. /// \param BuffDesc - buffer description. /// \param bIsDeviceInternal - flag indicating if the buffer is an internal device object and /// must not keep a strong reference to the device. - BufferBase( TBuffObjAllocator &BuffObjAllocator, + BufferBase( IReferenceCounters *pRefCounters, TBuffViewObjAllocator &BuffViewObjAllocator, IRenderDevice *pDevice, - const BufferDesc& BuffDesc, - bool bIsDeviceInternal = false ) : - TDeviceObjectBase( BuffObjAllocator, pDevice, BuffDesc, nullptr, bIsDeviceInternal ), + const BufferDesc& BuffDesc, + bool bIsDeviceInternal) : + TDeviceObjectBase( pRefCounters, pDevice, BuffDesc, bIsDeviceInternal), #ifdef _DEBUG m_dbgBuffViewAllocator(BuffViewObjAllocator), #endif @@ -92,10 +91,10 @@ public: VERIFY_BUFFER( this->m_Desc.ElementByteStride != 0, "Element stride cannot be zero for structured buffer" ); } - if( this->m_Desc.Mode == BUFFER_MODE_FORMATED ) + if( this->m_Desc.Mode == BUFFER_MODE_FORMATTED ) { - VERIFY_BUFFER( this->m_Desc.Format.ValueType != VT_UNDEFINED, "Value type is not specified for a formated buffer" ); - VERIFY_BUFFER( this->m_Desc.Format.NumComponents != 0, "Num components cannot be zero in a formated buffer" ); + VERIFY_BUFFER( this->m_Desc.Format.ValueType != VT_UNDEFINED, "Value type is not specified for a formatted buffer" ); + VERIFY_BUFFER( this->m_Desc.Format.NumComponents != 0, "Num components cannot be zero in a formatted buffer" ); if( this->m_Desc.ElementByteStride == 0 ) this->m_Desc.ElementByteStride = static_cast<Uint32>(GetValueSize( this->m_Desc.Format.ValueType )) * this->m_Desc.Format.NumComponents; } @@ -114,7 +113,7 @@ public: virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; /// Base implementation of IBuffer::Unmap() - virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override = 0; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags )override = 0; /// Implementation of IBuffer::CreateView(); calls CreateViewInternal() virtual function /// that creates buffer view for the specific engine implementation. @@ -151,73 +150,76 @@ protected: std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator> > m_pDefaultSRV; }; -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) { VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DEFAULT, "Only default usage buffers can be updated with UpdateData()" ); VERIFY_BUFFER( Offset < this->m_Desc.uiSizeInBytes, "Offset (", Offset, ") exceeds the buffer size (", this->m_Desc.uiSizeInBytes, ")" ); VERIFY_BUFFER( Size + Offset <= this->m_Desc.uiSizeInBytes, "Update region [", Offset, ",", Size + Offset, ") is out of buffer bounds [0,",this->m_Desc.uiSizeInBytes,")" ); } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size ) { VERIFY_BUFFER( DstOffset + Size <= this->m_Desc.uiSizeInBytes, "Destination range [", DstOffset, ",", DstOffset + Size, ") is out of buffer bounds [0,",this->m_Desc.uiSizeInBytes,")" ); VERIFY_BUFFER( SrcOffset + Size <= pSrcBuffer->GetDesc().uiSizeInBytes, "Source range [", SrcOffset, ",", SrcOffset + Size, ") is out of buffer bounds [0,",this->m_Desc.uiSizeInBytes,")" ); } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) { switch( MapType ) { case MAP_READ: VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read from" ); VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading was not created with CPU_ACCESS_READ flag" ); + VERIFY_BUFFER( (MapFlags & MAP_FLAG_DISCARD) == 0, "MAP_FLAG_DISCARD is not valid when mapping buffer for reading" ); break; case MAP_WRITE: - VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be written to" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DYNAMIC || this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE or USAGE_DYNAMIC can be mapped for writing" ); VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for writing was not created with CPU_ACCESS_WRITE flag" ); break; case MAP_READ_WRITE: - VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read and written" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be mapped for reading and writing" ); VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_WRITE flag" ); VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_READ flag" ); - break; - - case MAP_WRITE_DISCARD: - VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write discard flag" ); - VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); - break; - - case MAP_WRITE_NO_OVERWRITE: - VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write no overwrite flag" ); - VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); + VERIFY_BUFFER( (MapFlags & MAP_FLAG_DISCARD) == 0, "MAP_FLAG_DISCARD is not valid when mapping buffer for reading and writing" ); break; default: UNEXPECTED( "Unknown map type" ); } + + if (this->m_Desc.Usage == USAGE_DYNAMIC) + { + VERIFY((MapFlags & MAP_FLAG_DISCARD) != 0 && MapType == MAP_WRITE, "Dynamic buffers can only be mapped for writing with discard flag") + } + + if ( (MapFlags & MAP_FLAG_DISCARD) != 0 ) + { + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DYNAMIC || this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only dynamic and staging buffers can be mapped with discard flag" ); + VERIFY_BUFFER( MapType == MAP_WRITE, "MAP_FLAG_DISCARD is only valid when mapping buffer for writing" ); + } } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: Unmap( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags ) { } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView ) { CreateViewInternal( ViewDesc, ppView, false ); } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ) { if( ViewDesc.ByteWidth == 0 ) ViewDesc.ByteWidth = this->m_Desc.uiSizeInBytes; @@ -234,8 +236,8 @@ void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewO } } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -IBufferView* BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> ::GetDefaultView( BUFFER_VIEW_TYPE ViewType ) +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +IBufferView* BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> ::GetDefaultView( BUFFER_VIEW_TYPE ViewType ) { switch( ViewType ) { @@ -245,8 +247,8 @@ IBufferView* BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TB } } -template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> -void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CreateDefaultViews() +template<class BaseInterface, class BufferViewImplType, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffViewObjAllocator> :: CreateDefaultViews() { if( this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS ) { diff --git a/Graphics/GraphicsEngine/include/BufferViewBase.h b/Graphics/GraphicsEngine/include/BufferViewBase.h index 0e0819a3..ff14fc95 100644 --- a/Graphics/GraphicsEngine/include/BufferViewBase.h +++ b/Graphics/GraphicsEngine/include/BufferViewBase.h @@ -34,33 +34,36 @@ namespace Diligent { +class IRenderDevice; +class IBuffer; + /// Template class implementing base functionality for a buffer view object /// \tparam BaseInterface - base interface that this class will inheret /// (Diligent::IBufferViewD3D11, Diligent::IBufferViewD3D12 or Diligent::IBufferViewGL). /// \tparam BuffViewObjAllocator - type of the allocator that is used to allocate memory for the buffer view object instances -template<class BaseInterface, class BuffViewObjAllocator> -class BufferViewBase : public DeviceObjectBase<BaseInterface, BufferViewDesc, BuffViewObjAllocator> +template<class BaseInterface> +class BufferViewBase : public DeviceObjectBase<BaseInterface, BufferViewDesc> { public: - typedef DeviceObjectBase<BaseInterface, BufferViewDesc, BuffViewObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, BufferViewDesc> TDeviceObjectBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the buffer view object + /// \param pRefCounters - reference counters object that controls the lifetime of this buffer view. /// \param pDevice - pointer to the render device. /// \param ViewDesc - buffer view description. /// \param pBuffer - pointer to the buffer that the view is to be created for. /// \param bIsDefaultView - flag indicating if the view is default view, and is thus /// part of the buffer object. In this case the view will attach /// to the buffer's reference counters. - BufferViewBase( BuffViewObjAllocator &ObjAllocator, - class IRenderDevice *pDevice, + BufferViewBase( IReferenceCounters *pRefCounters, + IRenderDevice *pDevice, const BufferViewDesc& ViewDesc, - class IBuffer *pBuffer, + IBuffer *pBuffer, bool bIsDefaultView ) : // Default views are created as part of the buffer, so we cannot not keep strong // reference to the buffer to avoid cyclic links. Instead, we will attach to the // reference counters of the buffer. - TDeviceObjectBase( ObjAllocator, pDevice, ViewDesc, bIsDefaultView ? pBuffer : nullptr ), + TDeviceObjectBase( pRefCounters, pDevice, ViewDesc), m_pBuffer( pBuffer ), // For non-default view, we will keep strong reference to buffer m_spBuffer(bIsDefaultView ? nullptr : pBuffer) @@ -81,7 +84,7 @@ protected: /// Strong reference to the buffer. Used for non-default views /// to keep the buffer alive - Diligent::RefCntAutoPtr<IBuffer> m_spBuffer; + RefCntAutoPtr<IBuffer> m_spBuffer; }; } diff --git a/Graphics/GraphicsEngine/include/CommandListBase.h b/Graphics/GraphicsEngine/include/CommandListBase.h index 36e7f8f9..cf94b48f 100644 --- a/Graphics/GraphicsEngine/include/CommandListBase.h +++ b/Graphics/GraphicsEngine/include/CommandListBase.h @@ -41,19 +41,18 @@ struct CommandListDesc : public DeviceObjectAttribs /// \tparam BaseInterface - base interface that this class will inheret /// (Diligent::ICommandListD3D11 or Diligent::ICommandListD3D12). -/// \tparam CommandListObjAllocator - allocator that is used to allocate memory for command list object instances -template<class BaseInterface, class CommandListObjAllocator> -class CommandListBase : public DeviceObjectBase<BaseInterface, CommandListDesc, CommandListObjAllocator> +template<class BaseInterface> +class CommandListBase : public DeviceObjectBase<BaseInterface, CommandListDesc> { public: - typedef DeviceObjectBase<BaseInterface, CommandListDesc, CommandListObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, CommandListDesc> TDeviceObjectBase; - /// \param ObjAllocator - Allocator that was used to allocate memory for this instance of the command list object + /// \param pRefCounters - reference counters object that controls the lifetime of this command list. /// \param pDevice - pointer to the device. /// \param bIsDeviceInternal - flag indicating if the CommandList is an internal device object and /// must not keep a strong reference to the device. - CommandListBase( CommandListObjAllocator &ObjAllocator, IRenderDevice *pDevice, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( ObjAllocator, pDevice, CommandListDesc(), nullptr, bIsDeviceInternal ) + CommandListBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pRefCounters, pDevice, CommandListDesc(), bIsDeviceInternal ) {} ~CommandListBase() diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index 4bf89b0f..736cd265 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -65,51 +65,42 @@ struct VertexStreamInfo /// The context also keeps strong references to the device and /// the swap chain. template<typename BaseInterface> -class DeviceContextBase : public ObjectBase<BaseInterface, IMemoryAllocator> +class DeviceContextBase : public ObjectBase<BaseInterface> { public: - typedef ObjectBase<BaseInterface, IMemoryAllocator> TObjectBase; + typedef ObjectBase<BaseInterface> TObjectBase; - /// \param RawMemAllocator - allocator that was used to allocate memory for this instance of the device context object. + /// \param pRefCounters - reference counters object that controls the lifetime of this device context. /// \param pRenderDevice - render device. /// \param bIsDeferred - flag indicating if this instance is a deferred context - DeviceContextBase(IMemoryAllocator& RawMemAllocator, IRenderDevice *pRenderDevice, bool bIsDeferred) : - TObjectBase(nullptr, &RawMemAllocator), + DeviceContextBase(IReferenceCounters *pRefCounters, IRenderDevice *pRenderDevice, bool bIsDeferred) : + TObjectBase(pRefCounters), m_pDevice(pRenderDevice), - m_IndexDataStartOffset( 0 ), - m_StencilRef( 0 ), - m_NumVertexStreams(0), m_bIsDeferred(bIsDeferred) { - for( int i = 0; i < 4; ++i ) - m_BlendFactors[i] = -1; - // Set dummy render target array size to make sure that - // render targets are actually bound the first time - // SetRenderTargets() is called - m_NumBoundRenderTargets = _countof(m_pBoundRenderTargets); } ~DeviceContextBase() { } - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceContext, ObjectBase<BaseInterface> ) + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceContext, TObjectBase ) /// Base implementation of IDeviceContext::SetVertexBuffers(); validates parameters and /// caches references to the buffers. - inline virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) = 0; + inline virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override = 0; - inline virtual void ClearState() = 0; + inline virtual void InvalidateState()override = 0; /// Base implementation of IDeviceContext::SetPipelineState(); caches references to the pipeline state object. - inline virtual void SetPipelineState(IPipelineState *pPipelineState) = 0; + inline virtual void SetPipelineState(IPipelineState *pPipelineState)override = 0; /// Base implementation of IDeviceContext::CommitShaderResources(); validates parameters. inline bool CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags, int); /// Base implementation of IDeviceContext::SetIndexBuffer(); caches the strong reference to the index buffer - inline virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) = 0; + inline virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override = 0; /// Caches the viewports inline void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ); @@ -122,13 +113,13 @@ public: inline bool SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy = 0 ); /// Sets the strong pointer to the swap chain - inline void SetSwapChain( ISwapChain *pSwapChain ) { m_pSwapChain = pSwapChain; } + virtual void SetSwapChain( ISwapChain *pSwapChain )override final { m_pSwapChain = pSwapChain; } /// Returns the swap chain ISwapChain *GetSwapChain() { return m_pSwapChain; } /// Returns true if currently bound frame buffer is the default frame buffer - inline bool IsDefaultFBBound(){ return m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil == nullptr; } + inline bool IsDefaultFBBound(){ return m_IsDefaultFramebufferBound; } /// Returns currently bound pipeline state and blend factors inline void GetPipelineState(IPipelineState **ppPSO, float* BlendFactors, Uint32 &StencilRef); @@ -173,13 +164,13 @@ protected: RefCntAutoPtr<IBuffer> m_pIndexBuffer; /// Offset from the beginning of the index buffer to the start of the index data, in bytes. - Uint32 m_IndexDataStartOffset; + Uint32 m_IndexDataStartOffset = 0; /// Current stencil reference value - Uint32 m_StencilRef; + Uint32 m_StencilRef = 0; /// Curent blend factors - Float32 m_BlendFactors[4]; + Float32 m_BlendFactors[4] = { -1, -1, -1, -1 }; /// Current viewports Viewport m_Viewports[MaxRenderTargets]; @@ -195,11 +186,14 @@ protected: RefCntAutoPtr<ITextureView> m_pBoundRenderTargets[MaxRenderTargets]; /// Number of bound render targets Uint32 m_NumBoundRenderTargets = 0; + /// Flag indicating if default render target & depth-stencil + /// buffer are currently bound + bool m_IsDefaultFramebufferBound = false; /// Strong references to the bound depth stencil view RefCntAutoPtr<ITextureView> m_pBoundDepthStencil; - bool m_bIsDeferred = false; + const bool m_bIsDeferred = false; }; @@ -278,12 +272,10 @@ inline bool DeviceContextBase<BaseInterface> :: CommitShaderResources(IShaderRes } template<typename BaseInterface> -inline void DeviceContextBase<BaseInterface> :: ClearState() +inline void DeviceContextBase<BaseInterface> :: InvalidateState() { - UNSUPPORTED("This function is deprecated") - //m_VertexStreams.clear(); - //m_pIndexBuffer.Release(); - //m_IndexDataStartOffset = 0; + DeviceContextBase<BaseInterface> :: ClearStateCache(); + m_IsDefaultFramebufferBound = false; } template<typename BaseInterface> @@ -351,6 +343,7 @@ inline void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTW RTHeight = 0; // First, try to find non-null render target for( Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt ) + { if( auto *pRTView = m_pBoundRenderTargets[rt].RawPtr() ) { // Use render target size as viewport size @@ -362,6 +355,7 @@ inline void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTW VERIFY( RTWidth > 0 && RTHeight > 0, "RT dimension is zero" ); break; } + } // If render target was not found, check depth stencil if( RTWidth == 0 || RTHeight == 0 ) @@ -381,9 +375,16 @@ inline void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTW // use default RT size if( RTWidth == 0 || RTHeight == 0 ) { - const auto &SwapChainDesc = m_pSwapChain->GetDesc(); - RTWidth = SwapChainDesc.Width; - RTHeight = SwapChainDesc.Height; + if (m_pSwapChain) + { + const auto &SwapChainDesc = m_pSwapChain->GetDesc(); + RTWidth = SwapChainDesc.Width; + RTHeight = SwapChainDesc.Height; + } + else + { + LOG_ERROR("Failed to determine default render target size: swap chain is not initialized in the device context") + } } } @@ -451,7 +452,7 @@ inline bool DeviceContextBase<BaseInterface> :: SetRenderTargets( Uint32 NumRend if( NumRenderTargets != m_NumBoundRenderTargets ) { bBindRenderTargets = true; - for(Uint32 rt=NumRenderTargets; rt<m_NumBoundRenderTargets; ++rt ) + for(Uint32 rt = NumRenderTargets; rt < m_NumBoundRenderTargets; ++rt ) m_pBoundRenderTargets[rt].Release(); m_NumBoundRenderTargets = NumRenderTargets; @@ -491,6 +492,17 @@ inline bool DeviceContextBase<BaseInterface> :: SetRenderTargets( Uint32 NumRend bBindRenderTargets = true; } + if (NumRenderTargets == 0 && pDepthStencil == nullptr) + { + if (!m_IsDefaultFramebufferBound) + { + m_IsDefaultFramebufferBound = true; + bBindRenderTargets = true; + } + } + else + m_IsDefaultFramebufferBound = false; + return bBindRenderTargets; } @@ -560,7 +572,7 @@ inline void DeviceContextBase<BaseInterface> :: ClearStateCache() m_ScissorRects[sr] = Rect(); m_NumScissorRects = 0; - /// Vector of strong references to bound render targets + // Vector of strong references to bound render targets for(Uint32 rt=0; rt < m_NumBoundRenderTargets; ++rt ) m_pBoundRenderTargets[rt].Release(); #ifdef _DEBUG @@ -569,8 +581,7 @@ inline void DeviceContextBase<BaseInterface> :: ClearStateCache() VERIFY(m_pBoundRenderTargets[rt] == nullptr, "Non-null render target found") } #endif - // Set this to max RT count to force render targets to be bound next time - m_NumBoundRenderTargets = _countof(m_pBoundRenderTargets); + m_NumBoundRenderTargets = 0; m_pBoundDepthStencil.Release(); } diff --git a/Graphics/GraphicsEngine/include/DeviceObjectBase.h b/Graphics/GraphicsEngine/include/DeviceObjectBase.h index 40bc3d89..7cbdef12 100644 --- a/Graphics/GraphicsEngine/include/DeviceObjectBase.h +++ b/Graphics/GraphicsEngine/include/DeviceObjectBase.h @@ -35,25 +35,25 @@ namespace Diligent template<typename BaseInterface> class RenderDeviceBase; +class IRenderDevice; + /// Template class implementing base functionality for a device object -template<class BaseInterface, typename ObjectDescType, typename TObjectAllocator> -class DeviceObjectBase : public ObjectBase<BaseInterface, TObjectAllocator> +template<class BaseInterface, typename ObjectDescType> +class DeviceObjectBase : public ObjectBase<BaseInterface> { public: - typedef ObjectBase<BaseInterface, TObjectAllocator> TBase; + typedef ObjectBase<BaseInterface> TBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance + /// \param pRefCounters - reference counters object that controls the lifetime of this device object /// \param pDevice - pointer to the render device. /// \param ObjDesc - object description. - /// \param pOwner - owner object. /// \param bIsDeviceInternal - flag indicating if the object is an internal device object /// and must not keep a strong reference to the device. - DeviceObjectBase( TObjectAllocator &ObjAllocator, - class IRenderDevice *pDevice, + DeviceObjectBase( IReferenceCounters *pRefCounters, + IRenderDevice *pDevice, const ObjectDescType &ObjDesc, - IObject *pOwner = nullptr, bool bIsDeviceInternal = false) : - TBase(pOwner, &ObjAllocator), + TBase(pRefCounters), m_pDevice( pDevice ), // Do not keep strong reference to the device if the object is an internal device object m_spDevice( bIsDeviceInternal ? nullptr : pDevice ), @@ -69,10 +69,35 @@ public: //m_pDevice->AddResourceToHash( this ); - ERROR! } + DeviceObjectBase( const DeviceObjectBase& ) = delete; + DeviceObjectBase( DeviceObjectBase&& ) = delete; + DeviceObjectBase& operator = ( const DeviceObjectBase& ) = delete; + DeviceObjectBase& operator = ( DeviceObjectBase&& ) = delete; + virtual ~DeviceObjectBase() { } + inline virtual Atomics::Long Release()override final + { + // Render device owns allocators for all types of device objects, + // so it must be destroyed after all device objects are released. + // Consider the following scenario: an object A ownes last strong + // reference to the device: + // + // 1. A::~A() completes + // 2. A::~DeviceObjectBase() completes + // 3. A::m_spDevice is released + // Render device is destroyed, all allocators are invalid + // 4. RefCountersImpl::ObjectWrapperBase::DestroyObject() calls + // m_pAllocator->Free(m_pObject) - crash! + + // We must keep the device alive while the object is being destroyed + RefCntAutoPtr<IRenderDevice> pDevice(m_spDevice); + // Note that internal device object do not keep strong reference to the device + return TBase::Release(); + } + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceObject, TBase ) virtual const ObjectDescType& GetDesc()const override final @@ -93,6 +118,13 @@ public: IRenderDevice *GetDevice()const{return m_pDevice;} +private: + /// Strong reference to the device + RefCntAutoPtr<IRenderDevice> m_spDevice; + + /// Pointer to the device + IRenderDevice *m_pDevice; + protected: /// Copy of a device object name. @@ -108,17 +140,6 @@ protected: // Template argument is only used to separate counters for // different groups of objects UniqueIdHelper<BaseInterface> m_UniqueID; - -private: - /// Pointer to the device - IRenderDevice *m_pDevice; - /// Strong reference to the device - RefCntAutoPtr<IRenderDevice> m_spDevice; - - DeviceObjectBase( const DeviceObjectBase& ); - DeviceObjectBase( DeviceObjectBase&& ); - const DeviceObjectBase& operator = ( const DeviceObjectBase& ); - const DeviceObjectBase& operator = ( DeviceObjectBase&& ); }; } diff --git a/Graphics/GraphicsEngine/include/EngineMemory.h b/Graphics/GraphicsEngine/include/EngineMemory.h index 3f5a91d3..8c7e2cfe 100644 --- a/Graphics/GraphicsEngine/include/EngineMemory.h +++ b/Graphics/GraphicsEngine/include/EngineMemory.h @@ -36,12 +36,13 @@ namespace Diligent /// Returns raw memory allocator IMemoryAllocator& GetRawAllocator(); -} -#define NEW(Allocator, Desc, Type, ...) new(Allocator, Desc, __FILE__, __LINE__) Type(Allocator, ##__VA_ARGS__) #define ALLOCATE(Allocator, Desc, Size) (Allocator).Allocate(Size, Desc, __FILE__, __LINE__) #define FREE(Allocator, Ptr) Allocator.Free(Ptr) +} + + #if 0 inline void* operator new(size_t Size, const char* dbgDescription, const char* dbgFileName, const int dbgLineNumber) { diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.h b/Graphics/GraphicsEngine/include/PipelineStateBase.h index ecb9975d..0c57d212 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.h +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.h @@ -42,20 +42,20 @@ namespace Diligent /// \tparam RenderDeviceBaseInterface - base interface for the render device /// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceD3D12, Diligent::IRenderDeviceGL, /// or Diligent::IRenderDeviceGLES). -template<class BaseInterface, class RenderDeviceBaseInterface, class PSOAllocator> -class PipelineStateBase : public DeviceObjectBase<BaseInterface, PipelineStateDesc, PSOAllocator> +template<class BaseInterface, class RenderDeviceBaseInterface> +class PipelineStateBase : public DeviceObjectBase<BaseInterface, PipelineStateDesc> { public: - typedef DeviceObjectBase<BaseInterface, PipelineStateDesc, PSOAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, PipelineStateDesc> TDeviceObjectBase; typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the pipeline state object + /// \param pRefCounters - reference counters object that controls the lifetime of this PSO /// \param pDevice - pointer to the device. /// \param PSODesc - pipeline state description. /// \param bIsDeviceInternal - flag indicating if the blend state is an internal device object and /// must not keep a strong reference to the device. - PipelineStateBase( PSOAllocator &ObjAllocator, IRenderDevice *pDevice, const PipelineStateDesc& PSODesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( ObjAllocator, pDevice, PSODesc, nullptr, bIsDeviceInternal ), + PipelineStateBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const PipelineStateDesc& PSODesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pRefCounters, pDevice, PSODesc, bIsDeviceInternal ), m_LayoutElements( PSODesc.GraphicsPipeline.InputLayout.NumElements, LayoutElement(), STD_ALLOCATOR_RAW_MEM(LayoutElement, GetRawAllocator(), "Allocator for vector<LayoutElement>" ) ), m_NumShaders(0) { diff --git a/Graphics/GraphicsEngine/include/RenderDeviceBase.h b/Graphics/GraphicsEngine/include/RenderDeviceBase.h index a76b2e73..56ae5288 100644 --- a/Graphics/GraphicsEngine/include/RenderDeviceBase.h +++ b/Graphics/GraphicsEngine/include/RenderDeviceBase.h @@ -178,12 +178,13 @@ namespace Diligent /// keep strong reference to the device. /// Device only holds weak reference to the immediate context. template<typename BaseInterface> -class RenderDeviceBase : public ObjectBase<BaseInterface, IMemoryAllocator> +class RenderDeviceBase : public ObjectBase<BaseInterface> { public: - typedef ObjectBase<BaseInterface, IMemoryAllocator> TObjectBase; + typedef ObjectBase<BaseInterface> TObjectBase; + /// \param pRefCounters - reference counters object that controls the lifetime of this render device /// \param RawMemAllocator - allocator that will be used to allocate memory for all device objects (including render device itself) /// \param NumDeferredContexts - number of deferred device contexts /// \param TextureObjSize - size of the texture object, in bytes @@ -196,7 +197,8 @@ public: /// \param SRBSize - size of the shader resource binding object, in bytes /// \remarks Render device uses fixed block allocators (see FixedBlockMemoryAllocator) to allocate memory for /// device objects. The object sizes provided to constructor are used to initialize the allocators. - RenderDeviceBase(IMemoryAllocator &RawMemAllocator, + RenderDeviceBase(IReferenceCounters *pRefCounters, + IMemoryAllocator &RawMemAllocator, Uint32 NumDeferredContexts, size_t TextureObjSize, size_t TexViewObjSize, @@ -206,7 +208,7 @@ public: size_t SamplerObjSize, size_t PSOSize, size_t SRBSize) : - TObjectBase(nullptr, &RawMemAllocator), + TObjectBase(pRefCounters), m_TextureFormatsInfo( TEX_FORMAT_NUM_FORMATS, TextureFormatInfoExt(), STD_ALLOCATOR_RAW_MEM(TextureFormatInfoExt, RawMemAllocator, "Allocator for vector<TextureFormatInfoExt>") ), m_TexFmtInfoInitFlags( TEX_FORMAT_NUM_FORMATS, false, STD_ALLOCATOR_RAW_MEM(bool, RawMemAllocator, "Allocator for vector<bool>") ), m_wpDeferredContexts(NumDeferredContexts, RefCntWeakPtr<IDeviceContext>(), STD_ALLOCATOR_RAW_MEM(RefCntWeakPtr<IDeviceContext>, RawMemAllocator, "Allocator for vector< RefCntWeakPtr<IDeviceContext> >")), @@ -387,7 +389,7 @@ void RenderDeviceBase<BaseInterface>::CreateResourceMapping( const ResourceMappi return; VERIFY( *ppMapping == nullptr, "Overwriting reference to existing object may cause memory leaks" ); - auto *pResourceMapping( NEW(m_ResMappingAllocator, "ResourceMappingImpl instance", ResourceMappingImpl, GetRawAllocator()) ); + auto *pResourceMapping( NEW_RC_OBJ(m_ResMappingAllocator, "ResourceMappingImpl instance", ResourceMappingImpl)(GetRawAllocator()) ); pResourceMapping->QueryInterface( IID_ResourceMapping, reinterpret_cast<IObject**>(ppMapping) ); if( MappingDesc.pEntries ) { diff --git a/Graphics/GraphicsEngine/include/ResourceMappingImpl.h b/Graphics/GraphicsEngine/include/ResourceMappingImpl.h index d31161a2..39bc0f0a 100644 --- a/Graphics/GraphicsEngine/include/ResourceMappingImpl.h +++ b/Graphics/GraphicsEngine/include/ResourceMappingImpl.h @@ -90,15 +90,15 @@ namespace Diligent class FixedBlockMemoryAllocator; /// Implementation of the resource mapping - class ResourceMappingImpl : public ObjectBase<IResourceMapping, FixedBlockMemoryAllocator> + class ResourceMappingImpl : public ObjectBase<IResourceMapping> { public: - typedef ObjectBase<IResourceMapping, FixedBlockMemoryAllocator> TObjectBase; + typedef ObjectBase<IResourceMapping> TObjectBase; - /// \param ObjAllocator allocator that was used to allocate memory for this instance of the resource mapping object. - /// \param RawMemAllocator raw memory allocator that is used by the m_HashTable member - ResourceMappingImpl(FixedBlockMemoryAllocator &ObjAllocator, IMemoryAllocator &RawMemAllocator) : - TObjectBase(nullptr, &ObjAllocator), + /// \param pRefCounters - reference counters object that controls the lifetime of this resource mapping + /// \param RawMemAllocator - raw memory allocator that is used by the m_HashTable member + ResourceMappingImpl(IReferenceCounters *pRefCounters, IMemoryAllocator &RawMemAllocator) : + TObjectBase(pRefCounters), m_HashTable(STD_ALLOCATOR_RAW_MEM(HashTableElem, RawMemAllocator, "Allocator for unordered_map< ResMappingHashKey, RefCntAutoPtr<IDeviceObject> >") ) {} @@ -119,7 +119,7 @@ namespace Diligent virtual void GetResource( const Char *Name, IDeviceObject **ppResource, Uint32 ArrayIndex )override final; /// Returns number of resources in the resource mapping. - virtual size_t GetSize(); + virtual size_t GetSize()override final; private: diff --git a/Graphics/GraphicsEngine/include/SamplerBase.h b/Graphics/GraphicsEngine/include/SamplerBase.h index 27c67e7b..47744db5 100644 --- a/Graphics/GraphicsEngine/include/SamplerBase.h +++ b/Graphics/GraphicsEngine/include/SamplerBase.h @@ -39,21 +39,20 @@ namespace Diligent /// (Diligent::ISamplerD3D11, Diligent::ISamplerD3D12 or Diligent::ISamplerGL). /// \tparam RenderDeviceBaseInterface - base interface for the render device /// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceD3D12, Diligent::IRenderDeviceGL, or Diligent::IRenderDeviceGLES). -/// \tparam SamplerObjAllocator - type of the allocator that is used to allocate memory for the sampler object instances -template<class BaseInterface, class RenderDeviceBaseInterface, class SamplerObjAllocator> -class SamplerBase : public DeviceObjectBase<BaseInterface, SamplerDesc, SamplerObjAllocator> +template<class BaseInterface, class RenderDeviceBaseInterface> +class SamplerBase : public DeviceObjectBase<BaseInterface, SamplerDesc> { public: - typedef DeviceObjectBase<BaseInterface, SamplerDesc, SamplerObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, SamplerDesc> TDeviceObjectBase; typedef RenderDeviceBase<RenderDeviceBaseInterface> TRenderDeviceBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the sampler object + /// \param pRefCounters - reference counters object that controls the lifetime of this sampler. /// \param pDevice - pointer to the device. /// \param SamDesc - sampler description. /// \param bIsDeviceInternal - flag indicating if the sampler is an internal device object and /// must not keep a strong reference to the device. - SamplerBase( SamplerObjAllocator &ObjAllocator, IRenderDevice *pDevice, const SamplerDesc& SamDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( ObjAllocator, pDevice, SamDesc, nullptr, bIsDeviceInternal ) + SamplerBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const SamplerDesc& SamDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pRefCounters, pDevice, SamDesc, bIsDeviceInternal ) {} ~SamplerBase() diff --git a/Graphics/GraphicsEngine/include/ShaderBase.h b/Graphics/GraphicsEngine/include/ShaderBase.h index c4c99f95..17b8a453 100644 --- a/Graphics/GraphicsEngine/include/ShaderBase.h +++ b/Graphics/GraphicsEngine/include/ShaderBase.h @@ -168,20 +168,19 @@ struct DummyShaderVariable : ShaderVariableBase /// (Diligent::IShaderD3D11, Diligent::IShaderD3D12 or Diligent::IShaderGL). /// \tparam RenderDeviceBaseInterface - base interface for the render device /// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceD3D12, Diligent::IRenderDeviceGL, or Diligent::IRenderDeviceGLES). -/// \tparam ShaderObjAllocator - type of the allocator that is used to allocate memory for the shader object instances -template<class BaseInterface, class RenderDeviceBaseInterface, class ShaderObjAllocator> -class ShaderBase : public DeviceObjectBase<BaseInterface, ShaderDesc, ShaderObjAllocator> +template<class BaseInterface, class RenderDeviceBaseInterface> +class ShaderBase : public DeviceObjectBase<BaseInterface, ShaderDesc> { public: - typedef DeviceObjectBase<BaseInterface, ShaderDesc, ShaderObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, ShaderDesc> TDeviceObjectBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the shader object + /// \param pRefCounters - reference counters object that controls the lifetime of this shader. /// \param pDevice - pointer to the device. /// \param ShdrDesc - shader description. /// \param bIsDeviceInternal - flag indicating if the shader is an internal device object and /// must not keep a strong reference to the device. - ShaderBase( ShaderObjAllocator &ObjAllocator, IRenderDevice *pDevice, const ShaderDesc& ShdrDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( ObjAllocator, pDevice, ShdrDesc, nullptr, bIsDeviceInternal ), + ShaderBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const ShaderDesc& ShdrDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( pRefCounters, pDevice, ShdrDesc, bIsDeviceInternal ), m_DummyShaderVar(*this), m_VariablesDesc(ShdrDesc.NumVariables, ShaderVariableDesc(), STD_ALLOCATOR_RAW_MEM(ShaderVariableDesc, GetRawAllocator(), "Allocator for vector<ShaderVariableDesc>") ), m_StringPool(ShdrDesc.NumVariables + ShdrDesc.NumStaticSamplers, String(), STD_ALLOCATOR_RAW_MEM(String, GetRawAllocator(), "Allocator for vector<String>")), @@ -209,9 +208,9 @@ public: m_StaticSamplers[s].TextureName = Str->c_str(); #ifdef _DEBUG const auto &BorderColor = m_StaticSamplers[s].Desc.BorderColor; - if( !(BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 0 || - BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 1 || - BorderColor[0] == 1 && BorderColor[1] == 1 && BorderColor[2] == 1 && BorderColor[3] == 0) ) + if( !( (BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 0) || + (BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 1) || + (BorderColor[0] == 1 && BorderColor[1] == 1 && BorderColor[2] == 1 && BorderColor[3] == 0) ) ) { LOG_WARNING_MESSAGE("Static sampler for variable \"", *Str , "\" specifies border color (", BorderColor[0], ", ", BorderColor[1], ", ", BorderColor[2], ", ", BorderColor[3], "). D3D12 static samplers only allow transparent black (0,0,0,1), opaque black (0,0,0,0) or opaque white (1,1,1,0) as border colors") } diff --git a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h index 03e04882..c969a46d 100644 --- a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h +++ b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h @@ -38,19 +38,18 @@ namespace Diligent /// \tparam BaseInterface - base interface that this class will inheret /// (Diligent::IShaderResourceBindingGL, Diligent::IShaderResourceBindingD3D11, or Diligent::IShaderResourceBindingD3D12). -/// \tparam SRBAllocator - type of the allocator that is used to allocate memory for the shader resource binding object instances -template<class BaseInterface, class SRBAllocator> -class ShaderResourceBindingBase : public ObjectBase<BaseInterface, SRBAllocator> +template<class BaseInterface> +class ShaderResourceBindingBase : public ObjectBase<BaseInterface> { public: - typedef ObjectBase<BaseInterface, SRBAllocator> TObjectBase; + typedef ObjectBase<BaseInterface> TObjectBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the shader resource binding object + /// \param pRefCounters - reference counters object that controls the lifetime of this SRB. /// \param pPSO - pipeline state that this SRB belongs to. /// \param IsInternal - flag indicating if the shader resource binding is an internal PSO object and /// must not keep a strong reference to the PSO. - ShaderResourceBindingBase( SRBAllocator &ObjAllocator, IPipelineState *pPSO, bool IsInternal = false ) : - TObjectBase( IsInternal ? pPSO : nullptr, &ObjAllocator ), + ShaderResourceBindingBase( IReferenceCounters *pRefCounters, IPipelineState *pPSO, bool IsInternal = false ) : + TObjectBase( pRefCounters ), m_pPSO( pPSO ), m_spPSO( IsInternal ? nullptr : pPSO ) {} @@ -68,7 +67,7 @@ protected: /// Strong reference to PSO. We must use strong reference, because /// shader resource binding uses PSO's memory allocator to allocate /// memory for shader resource cache. - Diligent::RefCntAutoPtr<IPipelineState> m_spPSO; + RefCntAutoPtr<IPipelineState> m_spPSO; IPipelineState *m_pPSO; }; diff --git a/Graphics/GraphicsEngine/include/SwapChainBase.h b/Graphics/GraphicsEngine/include/SwapChainBase.h index 5718cb23..9634e737 100644 --- a/Graphics/GraphicsEngine/include/SwapChainBase.h +++ b/Graphics/GraphicsEngine/include/SwapChainBase.h @@ -28,6 +28,7 @@ #include "SwapChain.h" #include "DeviceObjectBase.h" +#include "Errors.h" namespace Diligent { @@ -36,24 +37,23 @@ namespace Diligent /// \tparam BaseInterface - base interface that this class will inheret /// (Diligent::ISwapChainGL, Diligent::ISwapChainD3D11, or Diligent::ISwapChainD3D12). -/// \tparam SwapChainAllocator - type of the allocator that is used to allocate memory for the swap chain object instance /// \remarks Swap chain holds the strong reference to the device and a weak reference to the /// immediate context. -template<class BaseInterface, class SwapChainAllocator> -class SwapChainBase : public ObjectBase<BaseInterface, SwapChainAllocator> +template<class BaseInterface> +class SwapChainBase : public ObjectBase<BaseInterface> { public: - typedef ObjectBase<BaseInterface, SwapChainAllocator> TObjectBase; + typedef ObjectBase<BaseInterface> TObjectBase; - /// \param Allocator - allocator that was used to allocate memory for this instance of the swap chain object + /// \param pRefCounters - reference counters object that controls the lifetime of this swap chain. /// \param pDevice - pointer to the device. /// \param pDeviceContext - pointer to the device context. /// \param SCDesc - swap chain description - SwapChainBase( SwapChainAllocator &Allocator, + SwapChainBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, IDeviceContext *pDeviceContext, const SwapChainDesc& SCDesc ) : - TObjectBase(nullptr, &Allocator), + TObjectBase(pRefCounters), m_pRenderDevice(pDevice), m_wpDeviceContext(pDeviceContext), m_SwapChainDesc(SCDesc) diff --git a/Graphics/GraphicsEngine/include/TextureBase.h b/Graphics/GraphicsEngine/include/TextureBase.h index b4d16ef8..cbf1bff1 100644 --- a/Graphics/GraphicsEngine/include/TextureBase.h +++ b/Graphics/GraphicsEngine/include/TextureBase.h @@ -47,27 +47,26 @@ void VliadateCopyTextureDataParams( const TextureDesc &SrcTexDesc, Uint32 SrcMip /// (Diligent::ITextureD3D11, Diligent::ITextureD3D12 or Diligent::ITextureGL). /// \tparam TTextureViewImpl - type of the texture view implementation /// (Diligent::TextureViewD3D11Impl, Diligent::TextureViewD3D12Impl or Diligent::TextureViewGLImpl). -/// \tparam TTexObjAllocator - type of the allocator that is used to allocate memory for the texture object instances /// \tparam TTexViewObjAllocator - type of the allocator that is used to allocate memory for the texture view object instances -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -class TextureBase : public DeviceObjectBase<BaseInterface, TextureDesc, TTexObjAllocator> +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +class TextureBase : public DeviceObjectBase<BaseInterface, TextureDesc> { public: - typedef DeviceObjectBase<BaseInterface, TextureDesc, TTexObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, TextureDesc> TDeviceObjectBase; - /// \param TexObjAllocator - allocator that was used to allocate memory for this instance of the texture object + /// \param pRefCounters - reference counters object that controls the lifetime of this texture. /// \param TexViewObjAllocator - allocator that is used to allocate memory for the instances of the texture view object. /// This parameter is only used for debug purposes. /// \param pDevice - pointer to the device /// \param Desc - texture description /// \param bIsDeviceInternal - flag indicating if the texture is an internal device object and /// must not keep a strong reference to the device - TextureBase( TTexObjAllocator &TexObjAllocator, + TextureBase( IReferenceCounters *pRefCounters, TTexViewObjAllocator &TexViewObjAllocator, IRenderDevice *pDevice, const TextureDesc& Desc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( TexObjAllocator, pDevice, Desc, nullptr, bIsDeviceInternal ), + TDeviceObjectBase( pRefCounters, pDevice, Desc, bIsDeviceInternal ), #ifdef _DEBUG m_dbgTexViewObjAllocator(TexViewObjAllocator), #endif @@ -115,7 +114,7 @@ public: } /// Base implementaiton of ITexture::UpdateData(); validates input parameters - virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) = 0; + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override = 0; /// Base implementaiton of ITexture::CopyData(); validates input parameters virtual void CopyData( IDeviceContext *pContext, @@ -127,13 +126,13 @@ public: Uint32 DstSlice, Uint32 DstX, Uint32 DstY, - Uint32 DstZ ) = 0; + Uint32 DstZ )override = 0; /// Base implementaiton of ITexture::Map() - virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; + virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData )override = 0; /// Base implementaiton of ITexture::Unmap() - virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) = 0; + virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override = 0; /// Creates default texture views. @@ -178,69 +177,11 @@ protected: } void CorrectTextureViewDesc( struct TextureViewDesc &ViewDesc ); - - // Corrects texture view format. For instance, if texture format is R32_TYPELESS, - // then for a depth-stencil view, the function will return D32_FLOAT, but for a shader resource - // view, it will return R32_FLOAT. - TEXTURE_FORMAT CorrectTextureViewFormat( TEXTURE_FORMAT Fmt, TEXTURE_VIEW_TYPE TexViewType ); }; -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -TEXTURE_FORMAT TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CorrectTextureViewFormat( TEXTURE_FORMAT Fmt, TEXTURE_VIEW_TYPE TexViewType ) -{ - // Correct texture view format for depth stencil view - if( TexViewType == TEXTURE_VIEW_DEPTH_STENCIL ) - { - if( Fmt == TEX_FORMAT_R32_FLOAT || Fmt == TEX_FORMAT_R32_TYPELESS ) - { - Fmt = TEX_FORMAT_D32_FLOAT; - } - else if( Fmt == TEX_FORMAT_R16_UNORM || Fmt == TEX_FORMAT_R16_TYPELESS ) - { - Fmt = TEX_FORMAT_D16_UNORM; - } - else if( Fmt == TEX_FORMAT_R24G8_TYPELESS || - Fmt == TEX_FORMAT_R24_UNORM_X8_TYPELESS || - Fmt == TEX_FORMAT_X24_TYPELESS_G8_UINT ) - { - Fmt = TEX_FORMAT_D24_UNORM_S8_UINT; - } - else if( Fmt == TEX_FORMAT_R32G8X24_TYPELESS || - Fmt == TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS || - Fmt == TEX_FORMAT_X32_TYPELESS_G8X24_UINT ) - { - Fmt = TEX_FORMAT_D32_FLOAT_S8X24_UINT; - } - } - else - { - // Correct texture view format for SR, RT or UA views - if( Fmt == TEX_FORMAT_D32_FLOAT || Fmt == TEX_FORMAT_R32_TYPELESS ) - { - Fmt = TEX_FORMAT_R32_FLOAT; - } - else if( Fmt == TEX_FORMAT_D16_UNORM || Fmt == TEX_FORMAT_R16_TYPELESS ) - { - Fmt = TEX_FORMAT_R16_UNORM; - } - else if( Fmt == TEX_FORMAT_D24_UNORM_S8_UINT || - Fmt == TEX_FORMAT_R24G8_TYPELESS ) - { - Fmt = TEX_FORMAT_R24_UNORM_X8_TYPELESS; - } - else if( Fmt == TEX_FORMAT_D32_FLOAT_S8X24_UINT || - Fmt == TEX_FORMAT_R32G8X24_TYPELESS ) - { - Fmt = TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS; - } - } - - return Fmt; -} - -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CorrectTextureViewDesc(struct TextureViewDesc &ViewDesc) +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexViewObjAllocator> :: CorrectTextureViewDesc(struct TextureViewDesc &ViewDesc) { #define TEX_VIEW_VALIDATION_ERROR(...) LOG_ERROR_AND_THROW( "Texture view \"", ViewDesc.Name ? ViewDesc.Name : "", "\": ", ##__VA_ARGS__ ); @@ -251,7 +192,7 @@ void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjA TEX_VIEW_VALIDATION_ERROR( "Most detailed mip (", ViewDesc.MostDetailedMip, ") and number of mip levels in the view (", ViewDesc.NumMipLevels, ") specify more levels than target texture has (", this->m_Desc.MipLevels, ")" ); if( ViewDesc.Format == TEX_FORMAT_UNKNOWN ) - ViewDesc.Format = CorrectTextureViewFormat( this->m_Desc.Format, ViewDesc.ViewType ); + ViewDesc.Format = GetDefaultTextureViewFormat( this->m_Desc.Format, ViewDesc.ViewType, this->m_Desc.BindFlags ); if( ViewDesc.TextureDim == RESOURCE_DIM_UNDEFINED ) { @@ -443,9 +384,16 @@ void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjA } } -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CreateDefaultViews() +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexViewObjAllocator> :: CreateDefaultViews() { + const auto& TexFmtAttribs = GetTextureFormatAttribs(this->m_Desc.Format); + if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_UNDEFINED) + { + // Cannot create default view for TYPELESS formats + return; + } + if(this->m_Desc.BindFlags & BIND_SHADER_RESOURCE ) { TextureViewDesc ViewDesc; @@ -489,14 +437,14 @@ void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjA } -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexViewObjAllocator> :: UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { ValidateUpdateDataParams( this->m_Desc, MipLevel, Slice, DstBox, SubresData ); } -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CopyData( IDeviceContext *pContext, +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexViewObjAllocator> :: CopyData( IDeviceContext *pContext, ITexture *pSrcTexture, Uint32 SrcMipLevel, Uint32 SrcSlice, @@ -513,13 +461,13 @@ void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjA this->GetDesc(), DstMipLevel, DstSlice, DstX, DstY, DstZ ); } -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexViewObjAllocator> :: Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData ) { } -template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> -void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) +template<class BaseInterface, class TTextureViewImpl, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexViewObjAllocator> :: Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags ) { } diff --git a/Graphics/GraphicsEngine/include/TextureViewBase.h b/Graphics/GraphicsEngine/include/TextureViewBase.h index f540340f..12974ef3 100644 --- a/Graphics/GraphicsEngine/include/TextureViewBase.h +++ b/Graphics/GraphicsEngine/include/TextureViewBase.h @@ -38,22 +38,21 @@ namespace Diligent /// \tparam BaseInterface - base interface that this class will inheret /// (Diligent::ITextureViewD3D11, Diligent::ITextureViewD3D12 or Diligent::ITextureViewGL). -/// \taparam TexViewObjAllocator - type of the allocator that is used to allocate memory for the texture view object instances -template<class BaseInterface, class TexViewObjAllocator> -class TextureViewBase : public DeviceObjectBase<BaseInterface, TextureViewDesc, TexViewObjAllocator> +template<class BaseInterface> +class TextureViewBase : public DeviceObjectBase<BaseInterface, TextureViewDesc> { public: - typedef DeviceObjectBase<BaseInterface, TextureViewDesc, TexViewObjAllocator> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, TextureViewDesc> TDeviceObjectBase; - /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the texture view object + /// \param pRefCounters - reference counters object that controls the lifetime of this texture view. /// \param pDevice - pointer to the render device. /// \param ViewDesc - texture view description. /// \param pTexture - pointer to the texture that the view is to be created for. /// \param bIsDefaultView - flag indicating if the view is default view, and is thus /// part of the texture object. In this case the view will attach /// to the texture's reference counters. - TextureViewBase( TexViewObjAllocator &ObjAllocator, + TextureViewBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const TextureViewDesc& ViewDesc, class ITexture *pTexture, @@ -61,7 +60,7 @@ public: // Default views are created as part of the texture, so we cannot not keep strong // reference to the texture to avoid cyclic links. Instead, we will attach to the // reference counters of the texture. - TDeviceObjectBase( ObjAllocator, pDevice, ViewDesc, bIsDefaultView ? pTexture : nullptr ), + TDeviceObjectBase( pRefCounters, pDevice, ViewDesc ), m_pTexture( pTexture ), // For non-default view, we will keep strong reference to texture m_spTexture(bIsDefaultView ? nullptr : pTexture) diff --git a/Graphics/GraphicsEngine/interface/BlendState.h b/Graphics/GraphicsEngine/interface/BlendState.h index 4bea7231..11c8ee41 100644 --- a/Graphics/GraphicsEngine/interface/BlendState.h +++ b/Graphics/GraphicsEngine/interface/BlendState.h @@ -40,7 +40,7 @@ namespace Diligent /// It generatlly mirrors [D3D11_BLEND][] and [D3D12_BLEND][] enumerations and is used by RenderTargetBlendDesc structure /// to define source and destination blend factors for color and alpha channels. /// \sa [D3D11_BLEND on MSDN][D3D11_BLEND], [D3D12_BLEND on MSDN][D3D12_BLEND], [glBlendFuncSeparate on OpenGL.org][glBlendFuncSeparate] -enum BLEND_FACTOR : Int32 +enum BLEND_FACTOR : Int8 { /// Undefined blend factor BLEND_FACTOR_UNDEFINED = 0, @@ -127,7 +127,7 @@ enum BLEND_FACTOR : Int32 /// [D3D11_BLEND_OP][] and [D3D12_BLEND_OP][] enums. It is used by RenderTargetBlendDesc structure to define RGB and Alpha /// blending operations /// \sa [D3D11_BLEND_OP on MSDN][D3D11_BLEND_OP], [D3D12_BLEND_OP on MSDN][D3D12_BLEND_OP], [glBlendEquationSeparate on OpenGL.org][glBlendEquationSeparate] -enum BLEND_OPERATION : Int32 +enum BLEND_OPERATION : Int8 { /// Undefined blend operation BLEND_OPERATION_UNDEFINED = 0, @@ -186,7 +186,7 @@ enum COLOR_MASK : Int32 /// It is used by RenderTargetBlendDesc structure to define logic operation. /// Only available on D3D12 engine /// \sa [D3D12_LOGIC_OP on MSDN][D3D12_LOGIC_OP] -enum LOGIC_OPERATION +enum LOGIC_OPERATION : Int8 { /// Clear the render target.\n /// Direct3D12 counterpart: D3D12_LOGIC_OP_CLEAR. diff --git a/Graphics/GraphicsEngine/interface/Buffer.h b/Graphics/GraphicsEngine/interface/Buffer.h index 5e5d107d..2e6b407e 100644 --- a/Graphics/GraphicsEngine/interface/Buffer.h +++ b/Graphics/GraphicsEngine/interface/Buffer.h @@ -44,7 +44,7 @@ enum BUFFER_MODE : Int32 BUFFER_MODE_UNDEFINED = 0, /// Formated buffer. - BUFFER_MODE_FORMATED, + BUFFER_MODE_FORMATTED, /// Structured buffer. BUFFER_MODE_STRUCTURED, @@ -107,17 +107,25 @@ struct BufferDesc : DeviceObjectAttribs NumComponents( 0 ), IsNormalized(True) {} + + /// Tests if two structures are equivalent + bool operator == (const BufferFormat& RHS)const + { + return ValueType == RHS.ValueType && + NumComponents == RHS.NumComponents && + IsNormalized == RHS.IsNormalized; + } }; /// Buffer format - /// For a formatted buffer (BufferDesc::Mode equals Diligent::BUFFER_MODE_FORMATED), this member describes the + /// For a formatted buffer (BufferDesc::Mode equals Diligent::BUFFER_MODE_FORMATTED), this member describes the /// buffer format, see BufferFormat. Ignored otherwise. BufferFormat Format; /// Buffer element stride, in bytes. For a structured buffer (BufferDesc::Mode /// equals Diligent::BUFFER_MODE_STRUCTURED), this member cannot be zero. For a formatted buffer - /// (BufferDesc::Mode equals Diligent::BUFFER_MODE_FORMATED), this member can either specify the stride, or + /// (BufferDesc::Mode equals Diligent::BUFFER_MODE_FORMATTED), this member can either specify the stride, or /// be 0. In the latter case, the stride is computed automatically based /// on the format size and assuming that elements are densely packed. Uint32 ElementByteStride; @@ -142,6 +150,26 @@ struct BufferDesc : DeviceObjectAttribs Mode( BUFFER_MODE_UNDEFINED ), ElementByteStride(0) {} + + + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures except for the Name are equal. + /// - False otherwise. + /// The operator ignores DeviceObjectAttribs::Name field as it does not affect + /// the buffer description. + bool operator == (const BufferDesc& RHS)const + { + return uiSizeInBytes == RHS.uiSizeInBytes && + BindFlags == RHS.BindFlags && + Usage == RHS.Usage && + CPUAccessFlags == RHS.CPUAccessFlags && + Mode == RHS.Mode && + Format == RHS.Format && + ElementByteStride == RHS.ElementByteStride; + } }; /// Describes the buffer initial data @@ -206,9 +234,11 @@ public: /// Unmaps the previously mapped buffer /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. - /// \param [in] MapType - Type of the map operation. This parameter must match to the type that was + /// \param [in] MapType - Type of the map operation. This parameter must match the type that was /// provided to the Map() method. - virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) = 0; + /// \param [in] MapFlags - Map flags. This parameter must match the flags that were provided to + /// the Map() method. + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags ) = 0; /// Creates a new buffer view @@ -231,6 +261,13 @@ public: /// \note The function does not increase the reference counter for the returned interface, so /// Release() must *NOT* be called. virtual IBufferView* GetDefaultView( BUFFER_VIEW_TYPE ViewType ) = 0; + + /// Returns native buffer handle specific to the underlying graphics API + + /// \return pointer to ID3D11Resource interface, for D3D11 implementation\n + /// pointer to ID3D12Resource interface, for D3D12 implementation\n + /// GL buffer handle, for GL implementation + virtual void* GetNativeHandle() = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/Constants.h b/Graphics/GraphicsEngine/interface/Constants.h index 7a392821..e5ac8c45 100644 --- a/Graphics/GraphicsEngine/interface/Constants.h +++ b/Graphics/GraphicsEngine/interface/Constants.h @@ -29,6 +29,7 @@ namespace Diligent { /// Maximum number of input buffer slots. + /// D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT == 32 static const Uint32 MaxBufferSlots = 32; /// Maximum number of simultaneous render targets. diff --git a/Graphics/GraphicsEngine/interface/DepthStencilState.h b/Graphics/GraphicsEngine/interface/DepthStencilState.h index 36feba55..c4734573 100644 --- a/Graphics/GraphicsEngine/interface/DepthStencilState.h +++ b/Graphics/GraphicsEngine/interface/DepthStencilState.h @@ -171,7 +171,7 @@ struct DepthStencilStateDesc /// Identify stencil operations for the back-facing triangles, see Diligent::StencilOpDesc. StencilOpDesc BackFace; - /// Initializes the structure members with default values + /// Initializes the structure members /// Default values: /// Member | Default value @@ -185,13 +185,18 @@ struct DepthStencilStateDesc /// /// Members of FrontFace and BackFace /// are initialized by StencilOpDesc::StencilOpDesc() - DepthStencilStateDesc() : - DepthEnable ( True ), - DepthWriteEnable( True ), - DepthFunc ( COMPARISON_FUNC_LESS ), - StencilEnable ( False ), - StencilReadMask ( 0xFF ), - StencilWriteMask( 0xFF ) + DepthStencilStateDesc(Bool _DepthEnable = True, + Bool _DepthWriteEnable = True, + COMPARISON_FUNCTION _DepthFunc = COMPARISON_FUNC_LESS, + Bool _StencilEnable = False, + Uint8 _StencilReadMask = 0xFF, + Uint8 _StencilWriteMask = 0xFF) : + DepthEnable ( _DepthEnable ), + DepthWriteEnable( _DepthWriteEnable ), + DepthFunc ( _DepthFunc ), + StencilEnable ( _StencilEnable ), + StencilReadMask ( _StencilReadMask ), + StencilWriteMask( _StencilWriteMask ) {} /// Tests if two structures are equivalent diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 70356296..67e346f5 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -41,6 +41,7 @@ #include "BlendState.h" #include "PipelineState.h" #include "CommandList.h" +#include "SwapChain.h" namespace Diligent { @@ -73,6 +74,134 @@ enum PRIMITIVE_TOPOLOGY : Int32 /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_LINELIST. OpenGL counterpart: GL_LINES. PRIMITIVE_TOPOLOGY_LINE_LIST, + /// Interpret the vertex data as a list of one control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of two control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of three control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of four control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of five control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of six control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of seven control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of eight control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of nine control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of ten control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 11 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 12 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 13 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 14 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 15 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 16 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 17 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 18 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 19 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 20 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 21 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 22 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 23 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 24 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 25 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 26 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 27 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 28 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 29 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 30 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 31 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, + + /// Interpret the vertex data as a list of 32 control point patches.\n + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST. OpenGL counterpart: GL_PATCHES. + PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST, + /// Helper value that stores the total number of topologies in the enumeration PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES }; @@ -395,8 +524,11 @@ public: Uint32 *pOffsets, Uint32 Flags) = 0; - /// Clears the context state. - virtual void ClearState() = 0; + /// Invalidates the cached context state. + + /// This method should be called by say Unity plugin before (or after) + /// issuing draw commands to invalidate cached states + virtual void InvalidateState() = 0; /// Binds an index buffer to the pipeline @@ -501,16 +633,33 @@ public: /// Finishes recording commands and generates a command list /// \param [out] ppCommandList - Memory location where pointer to the recorded command list will be written. - virtual void FinishCommandList(class ICommandList **ppCommandList) = 0; + virtual void FinishCommandList( ICommandList **ppCommandList) = 0; /// Executes recorded commands in a command list /// \param [in] pCommandList - Pointer to the command list to executre. /// \remarks After command list is executed, it is no longer valid and should be released. - virtual void ExecuteCommandList(class ICommandList *pCommandList) = 0; + virtual void ExecuteCommandList( ICommandList *pCommandList) = 0; /// Flushes the command buffer virtual void Flush() = 0; + + /// Sets the swap chain in the device context + + /// The swap chain is used by the device context to work with the + /// default framebuffer. Specifically, if the swap chain is set in the context, + /// the following commands can be used: + /// * SetRenderTargets(0, nullptr, nullptr) - to bind the default back buffer & depth buffer + /// * SetViewports(1, nullptr, 0, 0) - to set the viewport to match the size of the back buffer + /// * ClearRenderTarget(nullptr, color) - to clear the default back buffer + /// * ClearDepthStencil(nullptr, ...) - to clear the default depth buffer + /// The swap chain is automatically initialized for immediate and all deferred contexts + /// by factory functions EngineFactoryD3D11Impl::CreateSwapChainD3D11(), + /// EngineFactoryD3D12Impl::CreateSwapChainD3D12(), and EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(). + /// However, when the engine is initialized by attaching to existing d3d11/d3d12 device or OpenGL/GLES context, the + /// swap chain needs to be set manually if the device context will be using any of the commands above.\n + /// Device context keeps strong reference to the swap chain. + virtual void SetSwapChain( ISwapChain *pSwapChain) = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 3c0d3afd..c2af97ae 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -126,24 +126,15 @@ namespace Diligent { /// Resource is mapped for reading. \n /// D3D11 counterpart: D3D11_MAP_READ. OpenGL counterpart: GL_MAP_READ_BIT - MAP_READ = 0, + MAP_READ = 0x01, /// Resource is mapped for writing. \n /// D3D11 counterpart: D3D11_MAP_WRITE. OpenGL counterpart: GL_MAP_WRITE_BIT - MAP_WRITE, + MAP_WRITE = 0x02, /// Resource is mapped for reading and writing. \n /// D3D11 counterpart: D3D11_MAP_READ_WRITE. OpenGL counterpart: GL_MAP_WRITE_BIT | GL_MAP_READ_BIT - MAP_READ_WRITE, - - /// Resource is mapped for writing; the previous contents of the resource will be undefined. \n - /// D3D11 counterpart: D3D11_MAP_WRITE_DISCARD. OpenGL counterpart: GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT - /// \note OpenGL implementation may orphan a buffer instead - MAP_WRITE_DISCARD, - - /// Resource is mapped for writing; the existing contents of the resource cannot be overwritten. \n - /// D3D11 counterpart: D3D11_MAP_WRITE_NO_OVERWRITE. OpenGL counterpart: GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT - MAP_WRITE_NO_OVERWRITE + MAP_READ_WRITE = 0x03 }; /// Special map flags @@ -159,7 +150,18 @@ namespace Diligent /// is still in use.\n /// D3D11 counterpart: D3D11_MAP_FLAG_DO_NOT_WAIT /// \note: OpenGL does not have corresponding flag, so a buffer will always be mapped - MAP_FLAG_DO_NOT_WAIT = 0x001 + MAP_FLAG_DO_NOT_WAIT = 0x001, + + /// Previous contents of the resource will be undefined. This flag is only compatible with MAP_WRITE\n + /// D3D11 counterpart: D3D11_MAP_WRITE_DISCARD. OpenGL counterpart: GL_MAP_INVALIDATE_BUFFER_BIT + /// \note OpenGL implementation may orphan a buffer instead + MAP_FLAG_DISCARD = 0x002, + + /// The system will not synchronize pending operations before mapping the buffer. It is responsibility + /// of the application to make sure that the buffer contents is not overwritten while it is in use by + /// the GPU.\n + /// D3D11 counterpart: D3D11_MAP_WRITE_NO_OVERWRITE. OpenGL counterpart: GL_MAP_UNSYNCHRONIZED_BIT + MAP_FLAG_DO_NOT_SYNCHRONIZE = 0x004 }; /// Describes resource dimension diff --git a/Graphics/GraphicsEngine/interface/MapHelper.h b/Graphics/GraphicsEngine/interface/MapHelper.h index a0c25902..05c6d879 100644 --- a/Graphics/GraphicsEngine/interface/MapHelper.h +++ b/Graphics/GraphicsEngine/interface/MapHelper.h @@ -40,7 +40,7 @@ namespace Diligent /// Usage example: /// /// { -/// MapHelper<float> UniformData( pDeviceContext, pUniformBuff, MAP_WRITE_DISCARD, 0 ); +/// MapHelper<float> UniformData( pDeviceContext, pUniformBuff, MAP_WRITE, MAP_FLAG_DISCARD ); /// UniformData[0] = UniformData[1] = UniformData[2] = UniformData[3] = 1; /// } template<typename DataType, bool KeepStrongReferences = false> @@ -53,7 +53,8 @@ public: m_pMappedData(nullptr), m_pBuffer(nullptr), m_pContext(nullptr), - m_MapType(static_cast<MAP_TYPE>(-1)) + m_MapType(static_cast<MAP_TYPE>(-1)), + m_MapFlags(static_cast<Uint32>(-1)) { } @@ -70,12 +71,14 @@ public: m_pBuffer( std::move(Helper.m_pBuffer) ), m_pMappedData( std::move(Helper.m_pMappedData) ), m_pContext( std::move(Helper.m_pContext) ), - m_MapType( std::move(Helper.m_MapType) ) + m_MapType( std::move(Helper.m_MapType) ), + m_MapFlags( std::move(Helper.m_MapFlags) ) { Helper.m_pBuffer = nullptr; Helper.m_pContext = nullptr; Helper.m_pMappedData = nullptr; Helper.m_MapType = static_cast<MAP_TYPE>(-1); + Helper.m_MapFlags = static_cast<Uint32>(-1); } /// Move-assignement operator: takes over resource ownership from Helper @@ -85,10 +88,12 @@ public: m_pMappedData = std::move(Helper.m_pMappedData); m_pContext = std::move( Helper.m_pContext ); m_MapType = std::move(Helper.m_MapType); + m_MapFlags = std::move(Helper.m_MapFlags); Helper.m_pBuffer = nullptr; Helper.m_pContext = nullptr; Helper.m_pMappedData = nullptr; Helper.m_MapType = static_cast<MAP_TYPE>(-1); + Helper.m_MapFlags = static_cast<Uint32>(-1); return *this; } @@ -102,9 +107,14 @@ public: { VERIFY(!m_pBuffer && !m_pMappedData && !m_pContext, "Object already mapped"); Unmap(); +#ifdef _DEBUG + auto &BuffDesc = pBuffer->GetDesc(); + VERIFY(sizeof(DataType) <= BuffDesc.uiSizeInBytes, "Data type size exceeds buffer size") +#endif m_pContext = pContext; m_pBuffer = pBuffer; m_MapType = MapType; + m_MapFlags = MapFlags; m_pBuffer->Map(m_pContext, MapType, MapFlags, (PVoid&)m_pMappedData); VERIFY( m_pMappedData, "Map failed" ); } @@ -114,9 +124,10 @@ public: { if( m_pBuffer ) { - m_pBuffer->Unmap(m_pContext, m_MapType); + m_pBuffer->Unmap(m_pContext, m_MapType, m_MapFlags); m_pBuffer = nullptr; m_MapType = static_cast<MAP_TYPE>(-1); + m_MapFlags = static_cast<Uint32>(-1); } m_pContext = nullptr; m_pMappedData = nullptr; @@ -169,6 +180,8 @@ private: DataType *m_pMappedData; MAP_TYPE m_MapType; + + Uint32 m_MapFlags; }; } diff --git a/Graphics/GraphicsEngine/interface/RasterizerState.h b/Graphics/GraphicsEngine/interface/RasterizerState.h index c59075aa..e1668566 100644 --- a/Graphics/GraphicsEngine/interface/RasterizerState.h +++ b/Graphics/GraphicsEngine/interface/RasterizerState.h @@ -122,7 +122,7 @@ struct RasterizerStateDesc /// Specifies whether to enable line antialiasing. Bool AntialiasedLineEnable; - /// Initializes the structure members with default values + /// Initializes the structure members /// Member | Default value /// ----------------------|-------------- @@ -135,16 +135,24 @@ struct RasterizerStateDesc /// DepthClipEnable | True /// ScissorEnable | False /// AntialiasedLineEnable | False - RasterizerStateDesc() : - FillMode ( FILL_MODE_SOLID ), - CullMode ( CULL_MODE_BACK ), - FrontCounterClockwise( False ), - DepthBias ( 0 ), - DepthBiasClamp ( 0.f ), - SlopeScaledDepthBias ( 0.f ), - DepthClipEnable ( True ), - ScissorEnable ( False ), - AntialiasedLineEnable( False ) + RasterizerStateDesc(FILL_MODE _FillMode = FILL_MODE_SOLID, + CULL_MODE _CullMode = CULL_MODE_BACK, + Bool _FrontCounterClockwise = False, + Int32 _DepthBias = 0, + Float32 _DepthBiasClamp = 0.f, + Float32 _SlopeScaledDepthBias = 0.f, + Bool _DepthClipEnable = True, + Bool _ScissorEnable = False, + Bool _AntialiasedLineEnable = False) : + FillMode ( _FillMode ), + CullMode ( _CullMode ), + FrontCounterClockwise( _FrontCounterClockwise ), + DepthBias ( _DepthBias ), + DepthBiasClamp ( _DepthBiasClamp ), + SlopeScaledDepthBias ( _SlopeScaledDepthBias ), + DepthClipEnable ( _DepthClipEnable ), + ScissorEnable ( _ScissorEnable ), + AntialiasedLineEnable( _AntialiasedLineEnable ) { } diff --git a/Graphics/GraphicsEngine/interface/Sampler.h b/Graphics/GraphicsEngine/interface/Sampler.h index eb01b865..a36eeae0 100644 --- a/Graphics/GraphicsEngine/interface/Sampler.h +++ b/Graphics/GraphicsEngine/interface/Sampler.h @@ -93,7 +93,7 @@ struct SamplerDesc : DeviceObjectAttribs /// Must be greater than or equal to MinLOD. float MaxLOD; - /// Initializes the structure members with default values + /// Initializes the structure members /// Member | Default value /// --------------------|-------------- @@ -109,22 +109,37 @@ struct SamplerDesc : DeviceObjectAttribs /// BorderColor | (0,0,0,0) /// MinLOD | 0 /// MaxLOD | +FLT_MAX - SamplerDesc() : - MinFilter(FILTER_TYPE_LINEAR), - MagFilter(FILTER_TYPE_LINEAR), - MipFilter(FILTER_TYPE_LINEAR), - AddressU(TEXTURE_ADDRESS_CLAMP), - AddressV(TEXTURE_ADDRESS_CLAMP), - AddressW(TEXTURE_ADDRESS_CLAMP), - MipLODBias(0), - MaxAnisotropy(0), - ComparisonFunc(COMPARISON_FUNC_NEVER), - MinLOD(0), - MaxLOD(+FLT_MAX) + SamplerDesc(FILTER_TYPE _MinFilter = FILTER_TYPE_LINEAR, + FILTER_TYPE _MagFilter = FILTER_TYPE_LINEAR, + FILTER_TYPE _MipFilter = FILTER_TYPE_LINEAR, + TEXTURE_ADDRESS_MODE _AddressU = TEXTURE_ADDRESS_CLAMP, + TEXTURE_ADDRESS_MODE _AddressV = TEXTURE_ADDRESS_CLAMP, + TEXTURE_ADDRESS_MODE _AddressW = TEXTURE_ADDRESS_CLAMP, + Float32 _MipLODBias = 0, + Uint32 _MaxAnisotropy = 0, + COMPARISON_FUNCTION _ComparisonFunc = COMPARISON_FUNC_NEVER, + float _MinLOD = 0, + float _MaxLOD = +FLT_MAX) : + MinFilter(_MinFilter), + MagFilter(_MagFilter), + MipFilter(_MipFilter), + AddressU(_AddressU), + AddressV(_AddressV), + AddressW(_AddressW), + MipLODBias(_MipLODBias), + MaxAnisotropy(_MaxAnisotropy), + ComparisonFunc(_ComparisonFunc), + MinLOD(_MinLOD), + MaxLOD(_MaxLOD) { BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0; } + SamplerDesc(const SamplerDesc&) = default; + SamplerDesc(SamplerDesc&&) = default; + SamplerDesc& operator = (const SamplerDesc&) = default; + SamplerDesc& operator = (SamplerDesc&&) = default; + /// Tests if two structures are equivalent /// \param [in] RHS - reference to the structure to perform comparison with diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index 44864c3f..06381966 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -121,11 +121,11 @@ enum SHADER_VARIABLE_TYPE : Int32 struct ShaderVariableDesc { /// Shader variable name - const char *Name; + const Char *Name; /// Shader variable type. See Diligent::SHADER_VARIABLE_TYPE for a list of allowed types SHADER_VARIABLE_TYPE Type; - ShaderVariableDesc(const char *_Name = nullptr, SHADER_VARIABLE_TYPE _Type = SHADER_VARIABLE_TYPE_STATIC) : + ShaderVariableDesc(const Char *_Name = nullptr, SHADER_VARIABLE_TYPE _Type = SHADER_VARIABLE_TYPE_STATIC) : Name(_Name), Type(_Type) {} @@ -135,11 +135,17 @@ struct ShaderVariableDesc /// Static sampler description struct StaticSamplerDesc { + /// Name of the texture variable that static sampler will be assigned to + const Char* TextureName = nullptr; + /// Sampler description SamplerDesc Desc; - /// Name of the texture variable that static sampler will be assigned to - const char* TextureName = nullptr; + StaticSamplerDesc(){}; + StaticSamplerDesc(const Char* _TexName, const SamplerDesc &_Desc) : + TextureName(_TexName), + Desc(_Desc) + {} }; /// Shader description @@ -166,7 +172,7 @@ struct ShaderDesc : DeviceObjectAttribs Uint32 NumStaticSamplers; /// Array of static sampler descriptions - StaticSamplerDesc *StaticSamplers; + const StaticSamplerDesc *StaticSamplers; ShaderDesc() : ShaderType(SHADER_TYPE_VERTEX), @@ -205,15 +211,25 @@ struct ShaderCreationAttribs /// shader include files IShaderSourceInputStreamFactory *pShaderSourceStreamFactory; + /// HLSL->GLSL conversion stream + + /// If HLSL->GLSL converter is used to convert HLSL shader source to + /// GLSL, this member can provide pointer to the conversion stream. It is useful + /// when the same file is used to create a number of different shaders. If + /// ppConversionStream is null, the converter will parse the same file + /// every time new shader is converted. If ppConversionStream is not null, + /// the converter will write pointer to the conversion stream to *ppConversionStream + /// the first time and will use it in all subsequent times. + /// For all subsequent conversions, FilePath member must be the same, or + /// new stream will be crated and warning message will be displayed. + class IHLSL2GLSLConversionStream **ppConversionStream; + /// Shader source const Char* Source; /// Shader entry point const Char* EntryPoint; - /// Semicolon-separated list of include search directories. - const Char* SearchDirectories; - /// Shader macros const ShaderMacro *Macros; @@ -227,8 +243,8 @@ struct ShaderCreationAttribs FilePath( nullptr ), Source( nullptr ), pShaderSourceStreamFactory( nullptr ), + ppConversionStream( nullptr ), EntryPoint("main"), - SearchDirectories(nullptr), Macros(nullptr), SourceLanguage(SHADER_SOURCE_LANGUAGE_DEFAULT) {} diff --git a/Graphics/GraphicsEngine/interface/Texture.h b/Graphics/GraphicsEngine/interface/Texture.h index bfd9e344..1f751550 100644 --- a/Graphics/GraphicsEngine/interface/Texture.h +++ b/Graphics/GraphicsEngine/interface/Texture.h @@ -65,6 +65,17 @@ struct OptimizedClearValue Color[2] = 0; Color[3] = 0; } + + bool operator == (const OptimizedClearValue& rhs)const + { + return Format == rhs.Format && + Color[0] == rhs.Color[0] && + Color[1] == rhs.Color[1] && + Color[2] == rhs.Color[2] && + Color[3] == rhs.Color[3] && + DepthStencil.Depth == rhs.DepthStencil.Depth && + DepthStencil.Stencil == rhs.DepthStencil.Stencil; + } }; /// Texture description @@ -149,14 +160,46 @@ struct TextureDesc : DeviceObjectAttribs MiscFlags(0) { } + + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures except for the Name are equal. + /// - False otherwise. + /// The operator ignores DeviceObjectAttribs::Name field as it does not affect + /// the texture description state. + bool operator ==(const TextureDesc& RHS)const + { + // Name is primarily used for debug purposes and does not affect the state. + // It is ignored in comparison operation. + return // strcmp(Name, RHS.Name) == 0 && + Type == RHS.Type && + Width == RHS.Width && + Height == RHS.Height && + ArraySize == RHS.ArraySize && + Format == RHS.Format && + MipLevels == RHS.MipLevels && + SampleCount == RHS.SampleCount && + Usage == RHS.Usage && + BindFlags == RHS.BindFlags && + CPUAccessFlags == RHS.CPUAccessFlags && + MiscFlags == RHS.MiscFlags && + ClearValue == RHS.ClearValue; + } }; /// Describes data for one subresource struct TextureSubResData { - /// Pointer to the subresource data + /// Pointer to the subresource data in CPU memory. + /// If provided, pSrcBuffer must be null const void* pData; + /// Pointer to the GPU buffer that contains subresource data. + /// If provided, pData must be null + class IBuffer *pSrcBuffer; + /// For 2D and 3D textures, row stride in bytes Uint32 Stride; @@ -174,13 +217,23 @@ struct TextureSubResData /// DepthStride | 0 TextureSubResData(): pData(nullptr), + pSrcBuffer(nullptr), Stride(0), DepthStride(0) {} - /// Initializes the structure members with provided values - TextureSubResData(void *_pData, Uint32 _Stride, Uint32 _DepthStride=0): + /// Initializes the structure members to perform copy from the CPU memory + TextureSubResData(void *_pData, Uint32 _Stride, Uint32 _DepthStride=0) : pData(_pData), + pSrcBuffer(nullptr), + Stride(_Stride), + DepthStride(_DepthStride) + {} + + /// Initializes the structure members to perform copy from the GPU buffer + TextureSubResData(IBuffer *_pBuffer, Uint32 _Stride, Uint32 _DepthStride=0) : + pData(nullptr), + pSrcBuffer(_pBuffer), Stride(_Stride), DepthStride(_DepthStride) {} @@ -212,6 +265,13 @@ struct TextureData {} }; +struct MappedTextureSubresource +{ + PVoid pData = nullptr; + Uint32 Stride = 0; + Uint32 DepthStride = 0; +}; + /// Texture inteface class ITexture : public IDeviceObject { @@ -288,9 +348,16 @@ public: Uint32 DstZ) = 0; /// Map the texture - not implemented yet - virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; + virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData ) = 0; /// Unmap the textute - not implemented yet - virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) = 0; + virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags ) = 0; + + /// Returns native texture handle specific to the underlying graphics API + + /// \return pointer to ID3D11Resource interface, for D3D11 implementation\n + /// pointer to ID3D12Resource interface, for D3D12 implementation\n + /// GL buffer handle, for GL implementation + virtual void* GetNativeHandle() = 0; }; } diff --git a/Graphics/GraphicsEngine/src/EngineMemory.cpp b/Graphics/GraphicsEngine/src/EngineMemory.cpp index d96f6f78..0f8b3eb4 100644 --- a/Graphics/GraphicsEngine/src/EngineMemory.cpp +++ b/Graphics/GraphicsEngine/src/EngineMemory.cpp @@ -45,7 +45,7 @@ void SetRawAllocator(IMemoryAllocator *pRawAllocator) IMemoryAllocator& GetRawAllocator() { - return *g_pRawAllocator; + return g_pRawAllocator != nullptr ? *g_pRawAllocator : DefaultRawMemoryAllocator::GetAllocator(); } } diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp index 2cf31280..3057aea0 100644 --- a/Graphics/GraphicsEngine/src/Texture.cpp +++ b/Graphics/GraphicsEngine/src/Texture.cpp @@ -127,6 +127,7 @@ void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 S void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { + VERIFY((SubresData.pData != nullptr) ^ (SubresData.pSrcBuffer != nullptr), "Either CPU memory pointer or GPU buffer must be provided, exclusively") ValidateTextureRegion(TexDesc, MipLevel, Slice, DstBox); VERIFY_TEX_PARAMS( (SubresData.Stride & 0x03) == 0, "Texture data stride (", SubresData.Stride, ") must be at least 32-bit aligned" ); |
