diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-11-18 21:07:09 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-11-18 21:07:09 +0000 |
| commit | a55206ac29c47ca2765040a7339468f7b6a530c7 (patch) | |
| tree | 85ab32d391623c16bee8e19ad1cbb4f722f2f8d8 /Graphics/GraphicsEngine | |
| parent | Updated comment (diff) | |
| download | DiligentCore-a55206ac29c47ca2765040a7339468f7b6a530c7.tar.gz DiligentCore-a55206ac29c47ca2765040a7339468f7b6a530c7.zip | |
Added explicit resource state transitions to the API; implemented in D3D12
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/BufferBase.h | 25 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/include/TextureBase.h | 27 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/Buffer.h | 12 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/DeviceContext.h | 10 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/GraphicsTypes.h | 216 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/Texture.h | 12 |
6 files changed, 267 insertions, 35 deletions
diff --git a/Graphics/GraphicsEngine/include/BufferBase.h b/Graphics/GraphicsEngine/include/BufferBase.h index bc2d277b..93f752ef 100644 --- a/Graphics/GraphicsEngine/include/BufferBase.h +++ b/Graphics/GraphicsEngine/include/BufferBase.h @@ -27,6 +27,7 @@ /// Implementation of the Diligent::BufferBase template class #include "Buffer.h" +#include "GraphicsTypes.h" #include "DeviceObjectBase.h" #include "GraphicsAccessories.h" #include "STDAllocator.h" @@ -140,6 +141,28 @@ public: /// The function calls CreateViewInternal(). void CreateDefaultViews(); + virtual void SetState(RESOURCE_STATE State)override final + { + this->m_State = State; + } + + virtual RESOURCE_STATE GetState() const override final + { + return this->m_State; + } + + bool IsInKnownState() const + { + return this->m_State != RESOURCE_STATE_UNKNOWN; + } + + bool CheckState(RESOURCE_STATE State)const + { + VERIFY((State & (State-1)) == 0, "Single state is expected"); + VERIFY(IsInKnownState(), "Buffer state is unknown"); + return (this->m_State & State) == State; + } + protected: /// Pure virtual function that creates buffer view for the specific engine implementation. @@ -152,6 +175,8 @@ protected: TBuffViewObjAllocator& m_dbgBuffViewAllocator; #endif + RESOURCE_STATE m_State = RESOURCE_STATE_UNKNOWN; + /// Default UAV addressing the entire buffer std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator> > m_pDefaultUAV; diff --git a/Graphics/GraphicsEngine/include/TextureBase.h b/Graphics/GraphicsEngine/include/TextureBase.h index 81f57da1..234f2f0e 100644 --- a/Graphics/GraphicsEngine/include/TextureBase.h +++ b/Graphics/GraphicsEngine/include/TextureBase.h @@ -27,6 +27,7 @@ /// Implementation of the Diligent::TextureBase template class #include "Texture.h" +#include "GraphicsTypes.h" #include "DeviceObjectBase.h" #include "GraphicsAccessories.h" #include "STDAllocator.h" @@ -107,7 +108,7 @@ public: } else { - UNEXPECTED( "Unkwnown texture type" ); + UNEXPECTED( "Unknown texture type" ); } } @@ -178,6 +179,28 @@ public: /// The function calls CreateViewInternal(). void CreateDefaultViews(); + virtual void SetState(RESOURCE_STATE State)override final + { + this->m_State = State; + } + + virtual RESOURCE_STATE GetState() const override final + { + return this->m_State; + } + + bool IsInKnownState() const + { + return this->m_State != RESOURCE_STATE_UNKNOWN; + } + + bool CheckState(RESOURCE_STATE State)const + { + VERIFY((State & (State-1)) == 0, "Single state is expected"); + VERIFY(IsInKnownState(), "Texture state is unknown"); + return (this->m_State & State) == State; + } + protected: /// Pure virtual function that creates texture view for the specific engine implementation. @@ -210,6 +233,8 @@ protected: } void CorrectTextureViewDesc( struct TextureViewDesc& ViewDesc ); + + RESOURCE_STATE m_State = RESOURCE_STATE_UNKNOWN; }; diff --git a/Graphics/GraphicsEngine/interface/Buffer.h b/Graphics/GraphicsEngine/interface/Buffer.h index 4de1898c..6be6b2c6 100644 --- a/Graphics/GraphicsEngine/interface/Buffer.h +++ b/Graphics/GraphicsEngine/interface/Buffer.h @@ -218,6 +218,18 @@ public: /// pointer to ID3D12Resource interface, for D3D12 implementation\n /// GL buffer handle, for GL implementation virtual void* GetNativeHandle() = 0; + + /// Sets the buffer usage state. + + /// \note This method does not perform state transition, but + /// resets the internal buffer state to the given value. + /// This method should be used after the application finished + /// manually managing the buffer state and wants to hand over + /// state management back to the engine. + virtual void SetState(RESOURCE_STATE State) = 0; + + /// Returns the internal buffer state + virtual RESOURCE_STATE GetState() const = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 785efa63..6c5b0d85 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -519,6 +519,16 @@ public: /// have been executed through immediate context.\n /// The method does not Flush() the context. virtual void FinishFrame() = 0; + + + /// Transitions resource states + + /// \param [in] BarrierCount - Number of barriers in pResourceBarriers array + /// \param [in] pResourceBarriers - Pointer to the array of resource barriers + /// \remarks When both old and new states are RESOURCE_STATE_UNORDERED_ACCESS, the engine + /// executes UAV barrier on the resource. The barrier makes sure that all UAV accesses + /// (reads or writes) are complete before any future UAV accesses (read or write) can begin. + virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 2c37c0d5..384f1543 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -32,6 +32,9 @@ /// Graphics engine namespace namespace Diligent { + class ITexture; + class IBuffer; + /// Value type /// This enumeration describes value type. It is used by @@ -63,15 +66,15 @@ namespace Diligent { BIND_NONE = 0x0L, ///< Undefined binding BIND_VERTEX_BUFFER = 0x1L, ///< A buffer can be bound as a vertex buffer - BIND_INDEX_BUFFER = 0x2L, ///< A buffer can be bound as an index buffer - BIND_UNIFORM_BUFFER = 0x4L, ///< A buffer can be bound as a uniform buffer + BIND_INDEX_BUFFER = 0x2L, ///< A buffer can be bound as an index buffer + BIND_UNIFORM_BUFFER = 0x4L, ///< A buffer can be bound as a uniform buffer /// \warning This flag may not be combined with any other bind flag - BIND_SHADER_RESOURCE = 0x8L, ///< A buffer or a texture can be bound as a shader resource + BIND_SHADER_RESOURCE = 0x8L, ///< A buffer or a texture can be bound as a shader resource /// \warning This flag cannot be used with MAP_WRITE_NO_OVERWRITE flag - BIND_STREAM_OUTPUT = 0x10L,///< A buffer can be bound as a target for stream output stage - BIND_RENDER_TARGET = 0x20L,///< A texture can be bound as a render target - BIND_DEPTH_STENCIL = 0x40L,///< A texture can be bound as a depth-stencil target - BIND_UNORDERED_ACCESS = 0x80L,///< A buffer or a texture can be bound as an unordered access view + BIND_STREAM_OUTPUT = 0x10L,///< A buffer can be bound as a target for stream output stage + BIND_RENDER_TARGET = 0x20L,///< A texture can be bound as a render target + BIND_DEPTH_STENCIL = 0x40L,///< A texture can be bound as a depth-stencil target + BIND_UNORDERED_ACCESS = 0x80L,///< A buffer or a texture can be bound as an unordered access view BIND_INDIRECT_DRAW_ARGS = 0x100L///< A buffer can be bound as the source buffer for indirect draw commands }; @@ -125,17 +128,17 @@ namespace Diligent /// - ITexture::Map to describe texture mapping type enum MAP_TYPE : Uint8 { - /// Resource is mapped for reading. \n + /// The resource is mapped for reading. \n /// D3D11 counterpart: D3D11_MAP_READ. OpenGL counterpart: GL_MAP_READ_BIT MAP_READ = 0x01, - /// Resource is mapped for writing. \n + /// The resource is mapped for writing. \n /// D3D11 counterpart: D3D11_MAP_WRITE. OpenGL counterpart: GL_MAP_WRITE_BIT - MAP_WRITE = 0x02, + MAP_WRITE = 0x02, - /// Resource is mapped for reading and writing. \n + /// The 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 = 0x03 + MAP_READ_WRITE = 0x03 }; /// Special map flags @@ -156,13 +159,13 @@ namespace Diligent /// 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, + 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 + MAP_FLAG_DO_NOT_SYNCHRONIZE = 0x004 }; /// Describes resource dimension @@ -782,8 +785,8 @@ namespace Diligent { FILTER_TYPE_UNKNOWN = 0, ///< Unknown filter type FILTER_TYPE_POINT, ///< Point filtering - FILTER_TYPE_LINEAR, ///< Linear filtering - FILTER_TYPE_ANISOTROPIC, ///< Anisotropic filtering + FILTER_TYPE_LINEAR, ///< Linear filtering + FILTER_TYPE_ANISOTROPIC, ///< Anisotropic filtering FILTER_TYPE_COMPARISON_POINT, ///< Comparison-point filtering FILTER_TYPE_COMPARISON_LINEAR, ///< Comparison-linear filtering FILTER_TYPE_COMPARISON_ANISOTROPIC, ///< Comparison-anisotropic filtering @@ -814,24 +817,24 @@ namespace Diligent /// Flip the texture at every integer junction. \n /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR/D3D12_TEXTURE_ADDRESS_MODE_MIRROR. OpenGL counterpart: GL_MIRRORED_REPEAT - TEXTURE_ADDRESS_MIRROR = 2, + TEXTURE_ADDRESS_MIRROR = 2, /// Texture coordinates outside the range [0.0, 1.0] are set to the /// texture color at 0.0 or 1.0, respectively. \n /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_CLAMP/D3D12_TEXTURE_ADDRESS_MODE_CLAMP. OpenGL counterpart: GL_CLAMP_TO_EDGE - TEXTURE_ADDRESS_CLAMP = 3, + TEXTURE_ADDRESS_CLAMP = 3, /// Texture coordinates outside the range [0.0, 1.0] are set to the border color specified /// specified in SamplerDesc structure. \n /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_BORDER/D3D12_TEXTURE_ADDRESS_MODE_BORDER. OpenGL counterpart: GL_CLAMP_TO_BORDER - TEXTURE_ADDRESS_BORDER = 4, + TEXTURE_ADDRESS_BORDER = 4, /// Similar to TEXTURE_ADDRESS_MIRROR and TEXTURE_ADDRESS_CLAMP. Takes the absolute /// value of the texture coordinate (thus, mirroring around 0), and then clamps to /// the maximum value. \n /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR_ONCE/D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE. OpenGL counterpart: GL_MIRROR_CLAMP_TO_EDGE /// \note GL_MIRROR_CLAMP_TO_EDGE is only available in OpenGL4.4+, and is not available until at least OpenGLES3.1 - TEXTURE_ADDRESS_MIRROR_ONCE = 5, + TEXTURE_ADDRESS_MIRROR_ONCE = 5, /// Helper value that stores the total number of texture address modes in the enumeration TEXTURE_ADDRESS_NUM_MODES @@ -856,28 +859,28 @@ namespace Diligent /// Comparison passes if the source data is less than the destination data.\n /// Direct3D counterpart: D3D11_COMPARISON_LESS/D3D12_COMPARISON_FUNC_LESS. OpenGL counterpart: GL_LESS. - COMPARISON_FUNC_LESS, + COMPARISON_FUNC_LESS, /// Comparison passes if the source data is equal to the destination data.\n /// Direct3D counterpart: D3D11_COMPARISON_EQUAL/D3D12_COMPARISON_FUNC_EQUAL. OpenGL counterpart: GL_EQUAL. - COMPARISON_FUNC_EQUAL, + COMPARISON_FUNC_EQUAL, /// Comparison passes if the source data is less than or equal to the destination data.\n /// Direct3D counterpart: D3D11_COMPARISON_LESS_EQUAL/D3D12_COMPARISON_FUNC_LESS_EQUAL. OpenGL counterpart: GL_LEQUAL. - COMPARISON_FUNC_LESS_EQUAL, + COMPARISON_FUNC_LESS_EQUAL, /// Comparison passes if the source data is greater than the destination data.\n /// Direct3D counterpart: 3D11_COMPARISON_GREATER/D3D12_COMPARISON_FUNC_GREATER. OpenGL counterpart: GL_GREATER. - COMPARISON_FUNC_GREATER, + COMPARISON_FUNC_GREATER, /// Comparison passes if the source data is not equal to the destination data.\n /// Direct3D counterpart: D3D11_COMPARISON_NOT_EQUAL/D3D12_COMPARISON_FUNC_NOT_EQUAL. OpenGL counterpart: GL_NOTEQUAL. - COMPARISON_FUNC_NOT_EQUAL, + COMPARISON_FUNC_NOT_EQUAL, /// Comparison passes if the source data is greater than or equal to the destination data.\n /// Direct3D counterpart: D3D11_COMPARISON_GREATER_EQUAL/D3D12_COMPARISON_FUNC_GREATER_EQUAL. OpenGL counterpart: GL_GEQUAL. - COMPARISON_FUNC_GREATER_EQUAL, - + COMPARISON_FUNC_GREATER_EQUAL, + /// Comparison always passes. \n /// Direct3D counterpart: D3D11_COMPARISON_ALWAYS/D3D12_COMPARISON_FUNC_ALWAYS. OpenGL counterpart: GL_ALWAYS. COMPARISON_FUNC_ALWAYS, @@ -1257,13 +1260,13 @@ namespace Diligent 1024 // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER }; - /// This is the size of the chunk that dynamic descriptor allocations manager - /// request from the main GPU descriptor heap. - Uint32 DynamicDescriptorAllocationChunkSize[2] = - { - 256, // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV - 32 // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER - }; + /// This is the size of the chunk that dynamic descriptor allocations manager + /// request from the main GPU descriptor heap. + Uint32 DynamicDescriptorAllocationChunkSize[2] = + { + 256, // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + 32 // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + }; /// Number of commands to flush the command list. Only draw/dispatch commands count /// towards the limit. Command lists are only flushed when pipeline state is changed @@ -1579,4 +1582,149 @@ namespace Diligent /// If the format supports n samples, then (SampleCounts & n) != 0 Uint32 SampleCounts = 0; }; + + /// Resource usage state + enum RESOURCE_STATE : Uint32 + { + /// The resource state is not known to the engine and is managed by the application + RESOURCE_STATE_UNKNOWN = 0x0000, + + /// The resource state is known to the engine, but is undefined. A resource is typically in an undefined state right after initialization. + RESOURCE_STATE_UNDEFINED = 0x0001, + + /// The resource is accessed as vertex buffer + RESOURCE_STATE_VERTEX_BUFFER = 0x0002, + + /// The resource is accessed as constant (uniform) buffer + RESOURCE_STATE_CONSTANT_BUFFER = 0x0004, + + /// The resource is accessed as index buffer + RESOURCE_STATE_INDEX_BUFFER = 0x0008, + + /// The resource is accessed as render target + RESOURCE_STATE_RENDER_TARGET = 0x0010, + + /// The resource is used for unordered access + RESOURCE_STATE_UNORDERED_ACCESS = 0x0020, + + /// The resource is used in a writable depth-stencil view or in clear operation + RESOURCE_STATE_DEPTH_WRITE = 0x0040, + + /// The resource is used in a read-only depth-stencil view + RESOURCE_STATE_DEPTH_READ = 0x0080, + + /// The resource is accessed from a shader + RESOURCE_STATE_SHADER_RESOURCE = 0x0100, + + /// The resource is used as the destination for stream output + RESOURCE_STATE_STREAM_OUT = 0x0200, + + /// The resource is used as indirect draw/dispatch arguments buffer + RESOURCE_STATE_INDIRECT_ARGUMENT = 0x0400, + + /// The resource is used as the destination in a copy operation + RESOURCE_STATE_COPY_DEST = 0x0800, + + /// The resource is used as the source in a copy operation + RESOURCE_STATE_COPY_SOURCE = 0x1000, + + /// The resource is used as the destination in a resolve operation + RESOURCE_STATE_RESOLVE_DEST = 0x2000, + + /// The resource is used as the source in a resolve operation + RESOURCE_STATE_RESOLVE_SOURCE = 0x4000, + + /// The resource is used for present + RESOURCE_STATE_PRESENT = 0x8000, + + RESOURCE_STATE_MAX_BIT = 0x8000, + + RESOURCE_STATE_GENERIC_READ = RESOURCE_STATE_VERTEX_BUFFER | + RESOURCE_STATE_CONSTANT_BUFFER | + RESOURCE_STATE_INDEX_BUFFER | + RESOURCE_STATE_SHADER_RESOURCE | + RESOURCE_STATE_INDIRECT_ARGUMENT | + RESOURCE_STATE_COPY_SOURCE + }; + + + /// Resource state transition barrier description + struct StateTransitionDesc + { + static constexpr const Uint32 AllMipLevels = static_cast<Uint32>(-1); + static constexpr const Uint32 AllArraySlices = static_cast<Uint32>(-1); + + /// Texture to transition. + /// \note Exactly one of pTexture or pBuffer must be non-null. + ITexture* pTexture = nullptr; + + /// Buffer to transition. + /// \note Exactly one of pTexture or pBuffer must be non-null. + IBuffer* pBuffer = nullptr; + + /// When transitioning a texture, first mip level of the subresource range to transition. + Uint32 FirstMipLevel = 0; + + /// When transitioning a texture, number of mip levels of the subresource range to transition. + Uint32 MipLevelsCount = AllMipLevels; + + /// When transitioning a texture, first array slice of the subresource range to transition. + Uint32 FirstArraySlice = 0; + + /// When transitioning a texture, number of array slices of the subresource range to transition. + Uint32 ArraySliceCount = AllArraySlices; + + /// Resource state before transition. If this value is RESOURCE_STATE_UNKNOWN, + /// internal resource state will be used, which must be defined in this case. + RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN; + + /// Resource state after transition. + RESOURCE_STATE NewState = RESOURCE_STATE_UNKNOWN; + + /// If set to true, the internal resource state will be set to NewState and the engine + /// will be able to take the resource state management. In this case it is the + /// responsibility of the application to make sure that all subresources are indeed in + /// designated state. + /// If set to false, internal resource state will be set to RESOURCE_STATE_UNKNOWN, and the + /// engine will not manage or check the resource state in all further operations until the + /// state is set to a known value. + bool UpdateResourceState = false; + + StateTransitionDesc(){} + + StateTransitionDesc(ITexture* _pTexture, + RESOURCE_STATE _OldState, + RESOURCE_STATE _NewState, + Uint32 _FirstMipLevel = 0, + Uint32 _MipLevelsCount = AllMipLevels, + Uint32 _FirstArraySlice = 0, + Uint32 _ArraySliceCount = AllArraySlices, + bool _UpdateState = false) : + pTexture (_pTexture), + FirstMipLevel (_FirstMipLevel), + MipLevelsCount (_MipLevelsCount), + FirstArraySlice (_FirstArraySlice), + ArraySliceCount (_ArraySliceCount), + OldState (_OldState), + NewState (_NewState), + UpdateResourceState (_UpdateState) + {} + + StateTransitionDesc(ITexture* _pTexture, + RESOURCE_STATE _OldState, + RESOURCE_STATE _NewState, + bool _UpdateState) : + StateTransitionDesc(_pTexture, _OldState, _NewState, 0, AllMipLevels, 0, AllArraySlices, _UpdateState) + {} + + StateTransitionDesc(IBuffer* _pBuffer, + RESOURCE_STATE _OldState, + RESOURCE_STATE _NewState, + bool _UpdateState) : + pBuffer (_pBuffer), + OldState (_OldState), + NewState (_NewState), + UpdateResourceState (_UpdateState) + {} + }; } diff --git a/Graphics/GraphicsEngine/interface/Texture.h b/Graphics/GraphicsEngine/interface/Texture.h index d9da8c8f..e6dd2e9b 100644 --- a/Graphics/GraphicsEngine/interface/Texture.h +++ b/Graphics/GraphicsEngine/interface/Texture.h @@ -368,6 +368,18 @@ public: /// pointer to ID3D12Resource interface, for D3D12 implementation\n /// GL buffer handle, for GL implementation virtual void* GetNativeHandle() = 0; + + /// Sets the usage state for all texture subresources. + + /// \note This method does not perform state transition, but + /// resets the internal texture state to the given value. + /// This method should be used after the application finished + /// manually managing the texture state and wants to hand over + /// state management back to the engine. + virtual void SetState(RESOURCE_STATE State) = 0; + + /// Returns the internal texture state + virtual RESOURCE_STATE GetState() const = 0; }; } |
