From 7816066eaf654ff1e305a41113dd2691e1612208 Mon Sep 17 00:00:00 2001 From: wanghoi Date: Mon, 14 Oct 2024 09:33:31 +0800 Subject: [PATCH 1/2] IDeviceContextGL: OpenGL interop improvements. Add `PurgeCurrentContextCaches()` method; Remove `PurgeCaches` parameter of `UpdateCurrentGLContext()`. --- .../include/DeviceContextGLImpl.hpp | 5 ++++- .../GraphicsEngineOpenGL/include/FBOCache.hpp | 2 ++ .../GraphicsEngineOpenGL/include/VAOCache.hpp | 3 +++ .../interface/DeviceContextGL.h | 15 ++++++++------- .../src/DeviceContextGLImpl.cpp | 14 ++++++++------ Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp | 8 ++++++++ .../src/RenderDeviceGLImpl.cpp | 16 ++++++++++++++-- Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp | 9 +++++++++ 8 files changed, 56 insertions(+), 16 deletions(-) diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index 49603cd61..0a883d330 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -293,7 +293,10 @@ class DeviceContextGLImpl final : public DeviceContextBase virtual void DILIGENT_CALL_TYPE BindSparseResourceMemory(const BindSparseResourceMemoryAttribs& Attribs) override final; /// Implementation of IDeviceContextGL::UpdateCurrentGLContext(). - virtual bool DILIGENT_CALL_TYPE UpdateCurrentGLContext(bool PurgeCaches) override final; + virtual bool DILIGENT_CALL_TYPE UpdateCurrentGLContext() override final; + + /// Implementation of IDeviceContextGL::PurgeCurrentContextCaches(). + virtual void DILIGENT_CALL_TYPE PurgeCurrentContextCaches() override final; GLContextState& GetContextState() { return m_ContextState; } diff --git a/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp b/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp index a99eaf1ae..2a5bddb84 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp @@ -72,6 +72,8 @@ class FBOCache void OnReleaseTexture(ITexture* pTexture); + void Clear(); + private: // This structure is used as the key to find FBO struct FBOCacheKey diff --git a/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp b/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp index 815f38dc1..c80ab5a0d 100644 --- a/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp @@ -71,6 +71,9 @@ class VAOCache void OnDestroyBuffer(const BufferGLImpl& Buffer); void OnDestroyPSO(const PipelineStateGLImpl& PSO); + // Clears all cached objects + void Clear(); + private: // This structure is used as the key to find VAO struct VAOHashKey diff --git a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h index 1c091feb7..f533df525 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h @@ -58,14 +58,15 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContextGL, IDeviceContext) /// other command to let the engine update active context every time when control flow /// is passed over from the main application. /// - /// \param[in] PurgeCaches - Whether to purge context caches (e.g. VAO, FBO) before - /// updating the active context. An application should set this - /// flag to true if the last active context will not be used anymore - /// (e.g. it was destroyed) to avoid memory leaks. - /// /// \return false if there is no active GL context, and true otherwise. - VIRTUAL bool METHOD(UpdateCurrentGLContext)(THIS_ - bool PurgeCaches DEFAULT_INITIALIZER(false)) PURE; + VIRTUAL bool METHOD(UpdateCurrentGLContext)(THIS_) PURE; + + /// Purge current context caches (e.g. VAO, FBO). + + /// If an application uses multiple GL contexts, this method must be called + /// before the current context is about to be released, + /// to let the engine cleanup internal OpenGL object caches. + VIRTUAL void METHOD(PurgeCurrentContextCaches)(THIS_) PURE; /// Sets the swap in the device context. The swap chain is used by the device context /// to obtain the default FBO handle. diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index a6996d57c..5fa4defd3 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -1653,13 +1653,8 @@ void DeviceContextGLImpl::EndQuery(IQuery* pQuery) } } -bool DeviceContextGLImpl::UpdateCurrentGLContext(bool PurgeCaches) +bool DeviceContextGLImpl::UpdateCurrentGLContext() { - if (PurgeCaches) - { - m_pDevice->PurgeContextCaches(m_ContextState.GetCurrentGLContext()); - } - auto NativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); if (NativeGLContext == NULL) return false; @@ -1668,6 +1663,13 @@ bool DeviceContextGLImpl::UpdateCurrentGLContext(bool PurgeCaches) return true; } +void DeviceContextGLImpl::PurgeCurrentContextCaches() +{ + auto NativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); + if (NativeGLContext != NULL) + m_pDevice->PurgeContextCaches(NativeGLContext); +} + void DeviceContextGLImpl::UpdateBuffer(IBuffer* pBuffer, Uint64 Offset, Uint64 Size, diff --git a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp index 50d97689f..d78b00e43 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp @@ -115,6 +115,14 @@ void FBOCache::OnReleaseTexture(ITexture* pTexture) m_TexIdToKey.erase(EqualRange.first, EqualRange.second); } +void FBOCache::Clear() +{ + Threading::SpinLockGuard CacheGuard{m_CacheLock}; + + m_Cache.clear(); + m_TexIdToKey.clear(); +} + GLObjectWrappers::GLFrameBufferObj FBOCache::CreateFBO(GLContextState& ContextState, Uint32 NumRenderTargets, TextureViewGLImpl* ppRTVs[], diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index ab147404a..13d9fdd8d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -1687,11 +1687,23 @@ void RenderDeviceGLImpl::PurgeContextCaches(GLContext::NativeGLContextType Conte { { Threading::SpinLockGuard FBOCacheGuard{m_FBOCacheLock}; - m_FBOCache.erase(Context); + + auto it = m_FBOCache.find(Context); + if (it != m_FBOCache.end()) + { + it->second.Clear(); + m_FBOCache.erase(it); + } } { Threading::SpinLockGuard VAOCacheGuard{m_VAOCacheLock}; - m_VAOCache.erase(Context); + + auto it = m_VAOCache.find(Context); + if (it != m_VAOCache.end()) + { + it->second.Clear(); + m_VAOCache.erase(it); + } } } diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp index 7e6076653..909f5982d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp @@ -105,6 +105,15 @@ void VAOCache::OnDestroyPSO(const PipelineStateGLImpl& PSO) ClearStaleKeys(StaleKeys); } +void VAOCache::Clear() +{ + Threading::SpinLockGuard CacheGuard{m_CacheLock}; + + m_Cache.clear(); + m_PSOToKey.clear(); + m_BuffToKey.clear(); +} + void VAOCache::ClearStaleKeys(const std::vector& StaleKeys) { // Collect unique PSOs and buffers used in stale keys. From b54e515f4c6eef6a6484a99bf12453f5cdb52c47 Mon Sep 17 00:00:00 2001 From: wanghoi Date: Mon, 14 Oct 2024 10:12:00 +0800 Subject: [PATCH 2/2] IDeviceContextGL: fix include test --- .../GraphicsEngineOpenGL/interface/DeviceContextGL.h | 9 +++++---- .../GraphicsEngineOpenGL/DeviceContextGLH_test.c | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h index f533df525..892d2ffce 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h @@ -59,14 +59,14 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContextGL, IDeviceContext) /// is passed over from the main application. /// /// \return false if there is no active GL context, and true otherwise. - VIRTUAL bool METHOD(UpdateCurrentGLContext)(THIS_) PURE; + VIRTUAL Bool METHOD(UpdateCurrentGLContext)(THIS) PURE; /// Purge current context caches (e.g. VAO, FBO). /// If an application uses multiple GL contexts, this method must be called /// before the current context is about to be released, /// to let the engine cleanup internal OpenGL object caches. - VIRTUAL void METHOD(PurgeCurrentContextCaches)(THIS_) PURE; + VIRTUAL void METHOD(PurgeCurrentContextCaches)(THIS) PURE; /// Sets the swap in the device context. The swap chain is used by the device context /// to obtain the default FBO handle. @@ -81,8 +81,9 @@ DILIGENT_END_INTERFACE // clang-format off -# define IDeviceContextGL_UpdateCurrentGLContext(This, ...) CALL_IFACE_METHOD(DeviceContextGL, UpdateCurrentGLContext, This, __VA_ARGS__) -# define IDeviceContextGL_SetSwapChain(This, ...) CALL_IFACE_METHOD(DeviceContextGL, SetSwapChain, This, __VA_ARGS__) +# define IDeviceContextGL_UpdateCurrentGLContext(This) CALL_IFACE_METHOD(DeviceContextGL, UpdateCurrentGLContext, This) +# define IDeviceContextGL_PurgeCurrentContextCaches(This) CALL_IFACE_METHOD(DeviceContextGL, PurgeCurrentContextCaches, This) +# define IDeviceContextGL_SetSwapChain(This, ...) CALL_IFACE_METHOD(DeviceContextGL, SetSwapChain, This, __VA_ARGS__) // clang-format on diff --git a/Tests/IncludeTest/GraphicsEngineOpenGL/DeviceContextGLH_test.c b/Tests/IncludeTest/GraphicsEngineOpenGL/DeviceContextGLH_test.c index 4e9e00091..2f2c7e548 100644 --- a/Tests/IncludeTest/GraphicsEngineOpenGL/DeviceContextGLH_test.c +++ b/Tests/IncludeTest/GraphicsEngineOpenGL/DeviceContextGLH_test.c @@ -29,7 +29,8 @@ void TestDeviceContextGL_CInterface(IDeviceContextGL* pCtxGL) { - bool res = IDeviceContextGL_UpdateCurrentGLContext(pCtxGL, true); + bool res = IDeviceContextGL_UpdateCurrentGLContext(pCtxGL); (void)res; + IDeviceContextGL_PurgeCurrentContextCaches(pCtxGL); IDeviceContextGL_SetSwapChain(pCtxGL, (struct ISwapChainGL*)NULL); }