diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-07-22 02:46:57 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-07-22 02:46:57 +0000 |
| commit | 2dfbbae491090f3b0f0e622791515c59f3948ee0 (patch) | |
| tree | 898621085fe8253e7e52dc81ff03904931dcb36f /Graphics/GraphicsEngineOpenGL | |
| parent | Disabled D3D11 fence for now to fix build (diff) | |
| download | DiligentCore-2dfbbae491090f3b0f0e622791515c59f3948ee0.tar.gz DiligentCore-2dfbbae491090f3b0f0e622791515c59f3948ee0.zip | |
Implemented IFence interface in all backends
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
5 files changed, 89 insertions, 4 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 3a28312a..f757f771 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -79,6 +79,8 @@ public: virtual void ExecuteCommandList(class ICommandList *pCommandList)override final; + virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual bool UpdateCurrentGLContext()override final; void BindProgramResources( Uint32 &NewMemoryBarriers, IShaderResourceBinding *pResBinding ); diff --git a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h index 6756c467..e62a2a5c 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h @@ -26,9 +26,11 @@ /// \file /// Declaration of Diligent::FenceGLImpl class +#include <deque> #include "FenceGL.h" #include "RenderDeviceGL.h" #include "FenceBase.h" +#include "GLObjectWrapper.h" namespace Diligent { @@ -51,8 +53,15 @@ public: /// Resets the fence to the specified value. virtual void Reset(Uint64 Value)override final; -private: + void AddPendingFence(GLObjectWrappers::GLSyncObj&& Fence, Uint64 Value) + { + m_PendingFences.emplace_back(Value, std::move(Fence)); + } +private: + std::deque<std::pair<Uint64, GLObjectWrappers::GLSyncObj> > m_PendingFences; + volatile Uint64 m_LastCompletedFenceValue = 0; }; } + diff --git a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h index 4da5932d..2ae4e74d 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h @@ -261,4 +261,44 @@ public: }; typedef GLObjWrapper<GLRBOCreateReleaseHelper> GLRenderBufferObj; +struct GLSyncObj +{ + GLSyncObj() {} + GLSyncObj(GLsync _SyncHandle) : SyncHandle(_SyncHandle) {} + + GLSyncObj (const GLSyncObj&) = delete; + GLSyncObj& operator = (const GLSyncObj&) = delete; + + GLSyncObj(GLSyncObj&& rhs) + { + SyncHandle = rhs.SyncHandle; + rhs.SyncHandle = GLsync{}; + } + + GLSyncObj& operator = (GLSyncObj&& rhs) + { + Release(); + SyncHandle = rhs.SyncHandle; + rhs.SyncHandle = GLsync{}; + return *this; + } + + void Release() + { + if (SyncHandle != GLsync{}) + glDeleteSync(SyncHandle); + SyncHandle = GLsync{}; + } + + ~GLSyncObj() + { + Release(); + } + + operator GLsync()const{return SyncHandle;} + +private: + GLsync SyncHandle = {}; +}; + } diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index e07ce58f..a1509fbb 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -43,6 +43,7 @@ #include "GraphicsAccessories.h" #include "BufferViewGLImpl.h" #include "PipelineStateGLImpl.h" +#include "FenceGLImpl.h" #include "ShaderResourceBindingGLImpl.h" using namespace std; @@ -985,6 +986,19 @@ namespace Diligent LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); } + void DeviceContextGLImpl::SignalFence(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be signalled from immediate context"); + GLObjectWrappers::GLSyncObj GLFence( glFenceSync( + GL_SYNC_GPU_COMMANDS_COMPLETE, // Condition must always be GL_SYNC_GPU_COMMANDS_COMPLETE + 0 // Flags, must be 0 + ) + ); + CHECK_GL_ERROR( "Failed to create gl fence" ); + auto* pFenceGLImpl = ValidatedCast<FenceGLImpl>(pFence); + pFenceGLImpl->AddPendingFence(std::move(GLFence), Value); + }; + bool DeviceContextGLImpl::UpdateCurrentGLContext() { auto *pRenderDeviceGL = m_pDevice.RawPtr<RenderDeviceGLImpl>(); diff --git a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp index 5074e364..3c222b41 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp @@ -42,13 +42,33 @@ FenceGLImpl :: ~FenceGLImpl() Uint64 FenceGLImpl :: GetCompletedValue() { - UNSUPPORTED("Not yet implemented"); - return 0; + while (!m_PendingFences.empty()) + { + auto& val_fence = m_PendingFences.front(); + auto res = glClientWaitSync(val_fence.second, + 0, // Can be SYNC_FLUSH_COMMANDS_BIT + 0 // Timeout in nanoseconds + ); + if(res == GL_ALREADY_SIGNALED) + { + if (val_fence.first > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = val_fence.first; + m_PendingFences.pop_front(); + } + else + { + break; + } + } + + return m_LastCompletedFenceValue; } void FenceGLImpl :: Reset(Uint64 Value) { - UNSUPPORTED("Not yet implemented"); + DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")"); + if (Value > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = Value; } } |
