diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-11-24 20:13:26 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-11-24 20:13:26 +0000 |
| commit | f43e4c7e0be207d510b2ebd751f2e7ea5b1558af (patch) | |
| tree | ab4356128dac3db016c044bc165e673e263a54f7 /Graphics/GraphicsEngineOpenGL | |
| parent | Minor update to format validation script (diff) | |
| download | DiligentCore-f43e4c7e0be207d510b2ebd751f2e7ea5b1558af.tar.gz DiligentCore-f43e4c7e0be207d510b2ebd751f2e7ea5b1558af.zip | |
clang-formatted GraphicsEngineOpenGL project
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
89 files changed, 6426 insertions, 6030 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h b/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h index 851090bf..155eab1e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h +++ b/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h @@ -29,37 +29,37 @@ namespace Diligent class AsyncWritableResource { public: - AsyncWritableResource() : m_PendingMemoryBarriers( 0 ) {} - - void SetPendingMemoryBarriers( Uint32 Barriers ){ m_PendingMemoryBarriers |= Barriers; } - Uint32 GetPendingMemortBarriers(){ return m_PendingMemoryBarriers;} + AsyncWritableResource() noexcept {} + + void SetPendingMemoryBarriers(Uint32 Barriers) { m_PendingMemoryBarriers |= Barriers; } + Uint32 GetPendingMemortBarriers() { return m_PendingMemoryBarriers; } private: friend class GLContextState; - void ResetPendingMemoryBarriers( Uint32 Barriers ){ m_PendingMemoryBarriers = Barriers; } - void ClearPendingMemoryBarriers( Uint32 Barriers ){ m_PendingMemoryBarriers &= ~Barriers; } + void ResetPendingMemoryBarriers(Uint32 Barriers) { m_PendingMemoryBarriers = Barriers; } + void ClearPendingMemoryBarriers(Uint32 Barriers) { m_PendingMemoryBarriers &= ~Barriers; } // Buffer barriers: // GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT // GL_ELEMENT_ARRAY_BARRIER_BIT // GL_UNIFORM_BARRIER_BIT - // GL_BUFFER_UPDATE_BARRIER_BIT + // GL_BUFFER_UPDATE_BARRIER_BIT // GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT // GL_SHADER_STORAGE_BARRIER_BIT // Texture barriers: // GL_TEXTURE_FETCH_BARRIER_BIT // GL_SHADER_IMAGE_ACCESS_BARRIER_BIT - // GL_PIXEL_BUFFER_BARRIER_BIT - // GL_TEXTURE_UPDATE_BARRIER_BIT + // GL_PIXEL_BUFFER_BARRIER_BIT + // GL_TEXTURE_UPDATE_BARRIER_BIT // Misc barriers: - // GL_FRAMEBUFFER_BARRIER_BIT - // GL_TRANSFORM_FEEDBACK_BARRIER_BIT - // GL_ATOMIC_COUNTER_BARRIER_BIT + // GL_FRAMEBUFFER_BARRIER_BIT + // GL_TRANSFORM_FEEDBACK_BARRIER_BIT + // GL_ATOMIC_COUNTER_BARRIER_BIT // GL_QUERY_BUFFER_BARRIER_BIT - Uint32 m_PendingMemoryBarriers; + Uint32 m_PendingMemoryBarriers = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h index 68e86954..2747ff66 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h @@ -43,51 +43,51 @@ class BufferGLImpl final : public BufferBase<IBufferGL, RenderDeviceGLImpl, Buff public: using TBufferBase = BufferBase<IBufferGL, RenderDeviceGLImpl, BufferViewGLImpl, FixedBlockMemoryAllocator>; - BufferGLImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + BufferGLImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, RenderDeviceGLImpl* pDeviceGL, GLContextState& CtxState, - const BufferDesc& BuffDesc, + const BufferDesc& BuffDesc, const BufferData* pBuffData, bool bIsDeviceInternal); - BufferGLImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + BufferGLImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, class RenderDeviceGLImpl* pDeviceGL, GLContextState& CtxState, - const BufferDesc& BuffDesc, + const BufferDesc& BuffDesc, GLuint GLHandle, bool bIsDeviceInternal); ~BufferGLImpl(); - + /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; void UpdateData(GLContextState& CtxState, Uint32 Offset, Uint32 Size, const PVoid pData); void CopyData(GLContextState& CtxState, BufferGLImpl& SrcBufferGL, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); - void Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, PVoid& pMappedData ); + void Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, PVoid& pMappedData); void Unmap(GLContextState& CtxState); - void BufferMemoryBarrier( Uint32 RequiredBarriers, class GLContextState& GLContextState ); + void BufferMemoryBarrier(Uint32 RequiredBarriers, class GLContextState& GLContextState); - const GLObjectWrappers::GLBufferObj& GetGLHandle(){ return m_GlBuffer; } + const GLObjectWrappers::GLBufferObj& GetGLHandle() { return m_GlBuffer; } /// Implementation of IBufferGL::GetGLBufferHandle(). - virtual GLuint GetGLBufferHandle()override final { return GetGLHandle(); } + virtual GLuint GetGLBufferHandle() override final { return GetGLHandle(); } /// Implementation of IBuffer::GetNativeHandle() in OpenGL backend. - virtual void* GetNativeHandle()override final { return reinterpret_cast<void*>(static_cast<size_t>(GetGLBufferHandle())); } + virtual void* GetNativeHandle() override final { return reinterpret_cast<void*>(static_cast<size_t>(GetGLBufferHandle())); } private: - virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, class IBufferView **ppView, bool bIsDefaultView )override; + virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, class IBufferView** ppView, bool bIsDefaultView) override; friend class DeviceContextGLImpl; friend class VAOCache; GLObjectWrappers::GLBufferObj m_GlBuffer; - const Uint32 m_BindTarget; - const GLenum m_GLUsageHint; + const Uint32 m_BindTarget; + const GLenum m_GLUsageHint; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h index 1e93c850..4667f80a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h @@ -45,20 +45,20 @@ class BufferViewGLImpl final : public BufferViewBase<IBufferViewGL, RenderDevice public: using TBuffViewBase = BufferViewBase<IBufferViewGL, RenderDeviceGLImpl>; - BufferViewGLImpl( IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDevice, - IDeviceContext* pContext, - const BufferViewDesc& ViewDesc, - BufferGLImpl* pBuffer, - bool bIsDefaultView); - + BufferViewGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + IDeviceContext* pContext, + const BufferViewDesc& ViewDesc, + BufferGLImpl* pBuffer, + bool bIsDefaultView); + /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; - - const GLObjectWrappers::GLTextureObj& GetTexBufferHandle(){ return m_GLTexBuffer; } + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + const GLObjectWrappers::GLTextureObj& GetTexBufferHandle() { return m_GLTexBuffer; } private: GLObjectWrappers::GLTextureObj m_GLTexBuffer; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 70265a11..853ef602 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -54,22 +54,22 @@ public: DeviceContextGLImpl(IReferenceCounters* pRefCounters, RenderDeviceGLImpl* pDeviceGL, bool bIsDeferred); /// Queries the specific interface, see IObject::QueryInterface() for details. - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; /// Implementation of IDeviceContext::SetPipelineState() in OpenGL backend. - virtual void SetPipelineState(IPipelineState* pPipelineState)override final; + virtual void SetPipelineState(IPipelineState* pPipelineState) override final; /// Implementation of IDeviceContext::TransitionShaderResources() in OpenGL backend. - virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding)override final; + virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) override final; /// Implementation of IDeviceContext::CommitShaderResources() in OpenGL backend. - virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; + virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; /// Implementation of IDeviceContext::SetStencilRef() in OpenGL backend. - virtual void SetStencilRef(Uint32 StencilRef)override final; + virtual void SetStencilRef(Uint32 StencilRef) override final; /// Implementation of IDeviceContext::SetBlendFactors() in OpenGL backend. - virtual void SetBlendFactors(const float* pBlendFactors = nullptr)override final; + virtual void SetBlendFactors(const float* pBlendFactors = nullptr) override final; /// Implementation of IDeviceContext::SetVertexBuffers() in OpenGL backend. virtual void SetVertexBuffers(Uint32 StartSlot, @@ -77,56 +77,60 @@ public: IBuffer** ppBuffers, Uint32* pOffsets, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, - SET_VERTEX_BUFFERS_FLAGS Flags)override final; - + SET_VERTEX_BUFFERS_FLAGS Flags) override final; + /// Implementation of IDeviceContext::InvalidateState() in OpenGL backend. - virtual void InvalidateState()override final; + virtual void InvalidateState() override final; /// Implementation of IDeviceContext::SetIndexBuffer() in OpenGL backend. - virtual void SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; + virtual void SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; /// Implementation of IDeviceContext::SetViewports() in OpenGL backend. - virtual void SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight)override final; + virtual void SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) override final; /// Implementation of IDeviceContext::SetScissorRects() in OpenGL backend. - virtual void SetScissorRects(Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight)override final; + virtual void SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) override final; /// Implementation of IDeviceContext::SetRenderTargets() in OpenGL backend. virtual void SetRenderTargets(Uint32 NumRenderTargets, ITextureView* ppRenderTargets[], ITextureView* pDepthStencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + // clang-format off /// Implementation of IDeviceContext::Draw() in OpenGL backend. - virtual void Draw (const DrawAttribs& Attribs)override final; + virtual void Draw (const DrawAttribs& Attribs) override final; /// Implementation of IDeviceContext::DrawIndexed() in OpenGL backend. - virtual void DrawIndexed (const DrawIndexedAttribs& Attribs)override final; + virtual void DrawIndexed (const DrawIndexedAttribs& Attribs) override final; /// Implementation of IDeviceContext::DrawIndirect() in OpenGL backend. - virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)override final; + virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; /// Implementation of IDeviceContext::DrawIndexedIndirect() in OpenGL backend. - virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)override final; + virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; /// Implementation of IDeviceContext::DispatchCompute() in OpenGL backend. - virtual void DispatchCompute(const DispatchComputeAttribs& Attribs)override final; + virtual void DispatchCompute (const DispatchComputeAttribs& Attribs) override final; /// Implementation of IDeviceContext::DispatchComputeIndirect() in OpenGL backend. - virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)override final; + virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + + // clang-format on /// Implementation of IDeviceContext::ClearDepthStencil() in OpenGL backend. virtual void ClearDepthStencil(ITextureView* pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float fDepth, Uint8 Stencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; /// Implementation of IDeviceContext::ClearRenderTarget() in OpenGL backend. - virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; + virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; /// Implementation of IDeviceContext::UpdateBuffer() in OpenGL backend. virtual void UpdateBuffer(IBuffer* pBuffer, Uint32 Offset, Uint32 Size, const PVoid pData, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final; + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; /// Implementation of IDeviceContext::CopyBuffer() in OpenGL backend. virtual void CopyBuffer(IBuffer* pSrcBuffer, @@ -135,13 +139,13 @@ public: IBuffer* pDstBuffer, Uint32 DstOffset, Uint32 Size, - RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode)override final; + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) override final; /// Implementation of IDeviceContext::MapBuffer() in OpenGL backend. - virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData)override final; + virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) override final; /// Implementation of IDeviceContext::UnmapBuffer() in OpenGL backend. - virtual void UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType)override final; + virtual void UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) override final; /// Implementation of IDeviceContext::UpdateTexture() in OpenGL backend. virtual void UpdateTexture(ITexture* pTexture, @@ -150,10 +154,10 @@ public: const Box& DstBox, const TextureSubResData& SubresData, RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, - RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionMode)override final; + RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionMode) override final; /// Implementation of IDeviceContext::CopyTexture() in OpenGL backend. - virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs)override final; + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs) override final; /// Implementation of IDeviceContext::MapTextureSubresource() in OpenGL backend. virtual void MapTextureSubresource(ITexture* pTexture, @@ -162,50 +166,50 @@ public: MAP_TYPE MapType, MAP_FLAGS MapFlags, const Box* pMapRegion, - MappedTextureSubresource& MappedData)override final; + MappedTextureSubresource& MappedData) override final; /// Implementation of IDeviceContext::UnmapTextureSubresource() in OpenGL backend. - virtual void UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice)override final; + virtual void UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) override final; /// Implementation of IDeviceContext::GenerateMips() in OpenGL backend. - virtual void GenerateMips(ITextureView* pTexView)override; + virtual void GenerateMips(ITextureView* pTexView) override; /// Implementation of IDeviceContext::FinishFrame() in OpenGL backend. - virtual void FinishFrame()override final; + virtual void FinishFrame() override final; /// Implementation of IDeviceContext::TransitionResourceStates() in OpenGL backend. - virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final; + virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) override final; /// Implementation of IDeviceContext::ResolveTextureSubresource() in OpenGL backend. virtual void ResolveTextureSubresource(ITexture* pSrcTexture, ITexture* pDstTexture, - const ResolveTextureSubresourceAttribs& ResolveAttribs)override final; + const ResolveTextureSubresourceAttribs& ResolveAttribs) override final; /// Implementation of IDeviceContext::FinishCommandList() in OpenGL backend. - virtual void FinishCommandList(class ICommandList** ppCommandList)override final; + virtual void FinishCommandList(class ICommandList** ppCommandList) override final; /// Implementation of IDeviceContext::ExecuteCommandList() in OpenGL backend. - virtual void ExecuteCommandList(class ICommandList* pCommandList)override final; + virtual void ExecuteCommandList(class ICommandList* pCommandList) override final; /// Implementation of IDeviceContext::SignalFence() in OpenGL backend. - virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual void SignalFence(IFence* pFence, Uint64 Value) override final; /// Implementation of IDeviceContext::WaitForFence() in OpenGL backend. - virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext)override final; + virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) override final; /// Implementation of IDeviceContext::WaitForIdle() in OpenGL backend. - virtual void WaitForIdle()override final; + virtual void WaitForIdle() override final; /// Implementation of IDeviceContext::Flush() in OpenGL backend. - virtual void Flush()override final; + virtual void Flush() override final; /// Implementation of IDeviceContextGL::UpdateCurrentGLContext(). - virtual bool UpdateCurrentGLContext()override final; + virtual bool UpdateCurrentGLContext() override final; void BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding); - GLContextState& GetContextState(){return m_ContextState;} - + GLContextState& GetContextState() { return m_ContextState; } + void CommitRenderTargets(); protected: @@ -216,12 +220,12 @@ protected: GLContextState m_ContextState; private: - __forceinline void PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenum& GlTopology); - __forceinline void PrepareForIndexedDraw(VALUE_TYPE IndexType, Uint32 FirstIndexLocation, GLenum& GLIndexType, Uint32& FirstIndexByteOffset); + __forceinline void PrepareForIndexedDraw(VALUE_TYPE IndexType, Uint32 FirstIndexLocation, GLenum& GLIndexType, Uint32& FirstIndexByteOffset); __forceinline void PrepareForIndirectDraw(IBuffer* pAttribsBuffer); __forceinline void PostDraw(); - Uint32 m_CommitedResourcesTentativeBarriers; + + Uint32 m_CommitedResourcesTentativeBarriers = 0; std::vector<class TextureBaseGL*> m_BoundWritableTextures; std::vector<class BufferGLImpl*> m_BoundWritableBuffers; @@ -229,4 +233,4 @@ private: GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h index ddedcccc..546c972d 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h @@ -40,15 +40,18 @@ public: FBOCache(); ~FBOCache(); - FBOCache(const FBOCache&) = delete; - FBOCache( FBOCache&&) = delete; + // clang-format off + FBOCache (const FBOCache&) = delete; + FBOCache ( FBOCache&&) = delete; FBOCache& operator = (const FBOCache&) = delete; FBOCache& operator = ( FBOCache&&) = delete; + // clang-format on - const GLObjectWrappers::GLFrameBufferObj& GetFBO(Uint32 NumRenderTargets, - TextureViewGLImpl* ppRTVs[], + const GLObjectWrappers::GLFrameBufferObj& GetFBO(Uint32 NumRenderTargets, + TextureViewGLImpl* ppRTVs[], TextureViewGLImpl* pDSV, class GLContextState& ContextState); + void OnReleaseTexture(ITexture* pTexture); private: @@ -60,31 +63,31 @@ private: Uint32 NumRenderTargets = 0; // Unique IDs of textures bound as render targets - UniqueIdentifier RTIds [MaxRenderTargets] = {}; + UniqueIdentifier RTIds[MaxRenderTargets] = {}; TextureViewDesc RTVDescs[MaxRenderTargets]; // Unique IDs of texture bound as depth stencil - UniqueIdentifier DSId = 0; - TextureViewDesc DSVDesc = {}; + UniqueIdentifier DSId = 0; + TextureViewDesc DSVDesc = {}; - mutable size_t Hash = 0; + mutable size_t Hash = 0; - bool operator == (const FBOCacheKey &Key)const; + bool operator==(const FBOCacheKey& Key) const; }; struct FBOCacheKeyHashFunc { - std::size_t operator() ( const FBOCacheKey& Key )const; + std::size_t operator()(const FBOCacheKey& Key) const; }; friend class RenderDeviceGLImpl; - ThreadingTools::LockFlag m_CacheLockFlag; + ThreadingTools::LockFlag m_CacheLockFlag; std::unordered_map<FBOCacheKey, GLObjectWrappers::GLFrameBufferObj, FBOCacheKeyHashFunc> m_Cache; - + // Multimap that sets up correspondence between unique texture id and all // FBOs it is used in std::unordered_multimap<Diligent::UniqueIdentifier, FBOCacheKey> m_TexIdToKey; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h index 5c9dcd4e..5410ecaa 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h @@ -45,15 +45,15 @@ public: using TFenceBase = FenceBase<IFenceGL, RenderDeviceGLImpl>; FenceGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDevice, + RenderDeviceGLImpl* pDevice, const FenceDesc& Desc); ~FenceGLImpl(); /// Implementation of IFence::GetCompletedValue() in OpenGL backend. - virtual Uint64 GetCompletedValue()override final; + virtual Uint64 GetCompletedValue() override final; /// Implementation of IFence::Reset() in OpenGL backend. - virtual void Reset(Uint64 Value)override final; + virtual void Reset(Uint64 Value) override final; void AddPendingFence(GLObjectWrappers::GLSyncObj&& Fence, Uint64 Value) { @@ -63,9 +63,8 @@ public: void Wait(Uint64 Value, bool FlushCommands); private: - std::deque<std::pair<Uint64, GLObjectWrappers::GLSyncObj> > m_PendingFences; - volatile Uint64 m_LastCompletedFenceValue = 0; + std::deque<std::pair<Uint64, GLObjectWrappers::GLSyncObj>> m_PendingFences; + volatile Uint64 m_LastCompletedFenceValue = 0; }; -} - +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContext.h b/Graphics/GraphicsEngineOpenGL/include/GLContext.h index 64012d0a..9140c0bb 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContext.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContext.h @@ -24,15 +24,15 @@ #pragma once #if PLATFORM_WIN32 -# include "GLContextWindows.h" +# include "GLContextWindows.h" #elif PLATFORM_ANDROID -# include "GLContextAndroid.h" +# include "GLContextAndroid.h" #elif PLATFORM_LINUX -# include "GLContextLinux.h" +# include "GLContextLinux.h" #elif PLATFORM_MACOS -# include "GLContextMacOS.h" +# include "GLContextMacOS.h" #elif PLATFORM_IOS -# include "GLContextIOS.h" +# include "GLContextIOS.h" #else -# error Unsupported platform +# error Unsupported platform #endif diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h index 8f7e6956..e7d98d85 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h @@ -28,57 +28,60 @@ namespace Diligent { - class GLContext - { - public: - typedef EGLContext NativeGLContextType; - - GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); - ~GLContext(); - - bool Init( ANativeWindow* window ); - - void SwapBuffers(); - - void UpdateScreenSize(); - - bool Invalidate(); - - void Suspend(); - EGLint Resume( ANativeWindow* window ); - - NativeGLContextType GetCurrentNativeGLContext(); - int32_t GetScreenWidth()const{return screen_width_;} - int32_t GetScreenHeight()const{return screen_height_;} - - private: - //EGL configurations - ANativeWindow* window_ = nullptr; - EGLDisplay display_ = EGL_NO_DISPLAY; - EGLSurface surface_ = EGL_NO_SURFACE; - EGLContext context_ = EGL_NO_CONTEXT; - EGLConfig config_; - - //Screen parameters - int32_t color_size_ = 0; - int32_t depth_size_ = 0; - int32_t major_version_ = 0; - int32_t minor_version_ = 0; - int32_t screen_width_ = 0; - int32_t screen_height_ = 0; - - //Flags - bool gles_initialized_ = false; - bool egl_context_initialized_ = false; - bool context_valid_ = false; - - SwapChainDesc SwapChainAttribs_; - - void InitGLES(); - void Terminate(); - bool InitEGLSurface(); - bool InitEGLContext(); - void AttachToCurrentEGLContext(); - void FillDeviceCaps( DeviceCaps &DeviceCaps ); - }; -} + +class GLContext +{ +public: + using NativeGLContextType = EGLContext; + + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + ~GLContext(); + + bool Init(ANativeWindow* window); + + void SwapBuffers(); + + void UpdateScreenSize(); + + bool Invalidate(); + + void Suspend(); + EGLint Resume(ANativeWindow* window); + + NativeGLContextType GetCurrentNativeGLContext(); + + int32_t GetScreenWidth() const { return screen_width_; } + int32_t GetScreenHeight() const { return screen_height_; } + +private: + //EGL configurations + ANativeWindow* window_ = nullptr; + EGLDisplay display_ = EGL_NO_DISPLAY; + EGLSurface surface_ = EGL_NO_SURFACE; + EGLContext context_ = EGL_NO_CONTEXT; + EGLConfig config_; + + //Screen parameters + int32_t color_size_ = 0; + int32_t depth_size_ = 0; + int32_t major_version_ = 0; + int32_t minor_version_ = 0; + int32_t screen_width_ = 0; + int32_t screen_height_ = 0; + + //Flags + bool gles_initialized_ = false; + bool egl_context_initialized_ = false; + bool context_valid_ = false; + + SwapChainDesc SwapChainAttribs_; + + void InitGLES(); + void Terminate(); + bool InitEGLSurface(); + bool InitEGLContext(); + void AttachToCurrentEGLContext(); + void FillDeviceCaps(DeviceCaps& DeviceCaps); +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h b/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h index d1e5f571..53d80a87 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h @@ -25,13 +25,15 @@ namespace Diligent { - class GLContext - { - public: - typedef void* NativeGLContextType; // EAGLContext* - GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); +class GLContext +{ +public: + using NativeGLContextType = void*; // EAGLContext* + + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + + NativeGLContextType GetCurrentNativeGLContext(); +}; - NativeGLContextType GetCurrentNativeGLContext(); - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h b/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h index c5d9408e..2e30183f 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h @@ -25,20 +25,22 @@ namespace Diligent { - class GLContext - { - public: - typedef GLXContext NativeGLContextType; - GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); - ~GLContext(); - void SwapBuffers(); +class GLContext +{ +public: + using NativeGLContextType = GLXContext; + + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + ~GLContext(); + void SwapBuffers(); + + NativeGLContextType GetCurrentNativeGLContext(); - NativeGLContextType GetCurrentNativeGLContext(); +private: + void* m_pNativeWindow = nullptr; + void* m_pDisplay = nullptr; + NativeGLContextType m_Context; +}; - private: - void *m_pNativeWindow = nullptr; - void *m_pDisplay = nullptr; - NativeGLContextType m_Context; - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h b/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h index 8a279719..86dd685a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h @@ -25,13 +25,15 @@ namespace Diligent { - class GLContext - { - public: - typedef void* NativeGLContextType; // NSOpenGLContext* - GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); +class GLContext +{ +public: + using NativeGLContextType = void*; // NSOpenGLContext* + + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + + NativeGLContextType GetCurrentNativeGLContext(); +}; - NativeGLContextType GetCurrentNativeGLContext(); - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h index a11a2efa..33eb3c7b 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -34,7 +34,9 @@ namespace Diligent class GLContextState { public: - GLContextState(class RenderDeviceGLImpl *pDeviceGL); + GLContextState(class RenderDeviceGLImpl* pDeviceGL); + + // clang-format off void SetProgram (const GLObjectWrappers::GLProgramObj& GLProgram); void SetPipeline (const GLObjectWrappers::GLPipelineObj& GLPipeline); @@ -75,7 +77,9 @@ public: void GetColorWriteMask(Uint32 RTIndex, Uint32& WriteMask, Bool& bIsIndependent); void SetColorWriteMask(Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent); - void SetNumPatchVertices( Int32 NumVertices); + // clang-format on + + void SetNumPatchVertices(Int32 NumVertices); void Invalidate(); void InvalidateVAO() @@ -84,100 +88,109 @@ public: // Resetting VAO after that with BindVAO(GLVertexArrayObj::Null()) will still have the effect because // null VAO's ID is 0, not -1. } - + void InvalidateFBO() { m_FBOId = -1; } - bool IsValidVAOBound()const {return m_VAOId > 0;} + bool IsValidVAOBound() const { return m_VAOId > 0; } void SetCurrentGLContext(GLContext::NativeGLContextType Context) { m_CurrentGLContext = Context; } - GLContext::NativeGLContextType GetCurrentGLContext()const { return m_CurrentGLContext; } + + GLContext::NativeGLContextType GetCurrentGLContext() const { return m_CurrentGLContext; } struct ContextCaps { - bool bFillModeSelectionSupported = true; + bool bFillModeSelectionSupported = true; GLint m_iMaxCombinedTexUnits = 0; GLint m_iMaxDrawBuffers = 0; GLint m_iMaxUniformBufferBindings = 0; }; - const ContextCaps& GetContextCaps(){return m_Caps;} + const ContextCaps& GetContextCaps() { return m_Caps; } private: // It is unsafe to use GL handle to keep track of bound objects - // When an object is released, GL is free to reuse its handle for + // When an object is released, GL is free to reuse its handle for // the new created objects. // Even using pointers is not safe as when an object is created, // the system can reuse the same address // The safest way is to keep global unique ID for all objects - UniqueIdentifier m_GLProgId = -1; - UniqueIdentifier m_GLPipelineId = -1; - UniqueIdentifier m_VAOId = -1; - UniqueIdentifier m_FBOId = -1; - std::vector< UniqueIdentifier > m_BoundTextures; - std::vector< UniqueIdentifier > m_BoundSamplers; - std::vector< UniqueIdentifier > m_BoundUniformBuffers; - + UniqueIdentifier m_GLProgId = -1; + UniqueIdentifier m_GLPipelineId = -1; + UniqueIdentifier m_VAOId = -1; + UniqueIdentifier m_FBOId = -1; + std::vector<UniqueIdentifier> m_BoundTextures; + std::vector<UniqueIdentifier> m_BoundSamplers; + std::vector<UniqueIdentifier> m_BoundUniformBuffers; + struct BoundImageInfo { UniqueIdentifier InterfaceID = -1; - GLint MipLevel = 0; - GLboolean IsLayered = 0; - GLint Layer = 0; - GLenum Access = 0; - GLenum Format = 0; - - BoundImageInfo() {}; - - BoundImageInfo( UniqueIdentifier _UniqueID, - GLint _MipLevel, - GLboolean _IsLayered, - GLint _Layer, - GLenum _Access, - GLenum _Format) : - InterfaceID {_UniqueID }, - MipLevel {_MipLevel }, - IsLayered {_IsLayered}, - Layer {_Layer }, - Access {_Access }, - Format {_Format } + GLint MipLevel = 0; + GLboolean IsLayered = 0; + GLint Layer = 0; + GLenum Access = 0; + GLenum Format = 0; + + BoundImageInfo(){}; + + BoundImageInfo(UniqueIdentifier _UniqueID, + GLint _MipLevel, + GLboolean _IsLayered, + GLint _Layer, + GLenum _Access, + GLenum _Format) : + // clang-format off + InterfaceID{_UniqueID}, + MipLevel {_MipLevel}, + IsLayered {_IsLayered}, + Layer {_Layer}, + Access {_Access}, + Format {_Format} + // clang-format on {} - bool operator==(const BoundImageInfo &rhs)const + bool operator==(const BoundImageInfo& rhs) const { - return InterfaceID == rhs.InterfaceID && - MipLevel == rhs.MipLevel && - IsLayered == rhs.IsLayered && - Layer == rhs.Layer && - Access == rhs.Access && - Format == rhs.Format; + // clang-format off + return InterfaceID == rhs.InterfaceID && + MipLevel == rhs.MipLevel && + IsLayered == rhs.IsLayered && + Layer == rhs.Layer && + Access == rhs.Access && + Format == rhs.Format; + // clang-format on } }; - std::vector< BoundImageInfo > m_BoundImages; + std::vector<BoundImageInfo> m_BoundImages; struct BoundSSBOInfo { - BoundSSBOInfo(){} + BoundSSBOInfo() {} BoundSSBOInfo(UniqueIdentifier _BufferID, - GLintptr _Offset , + GLintptr _Offset, GLsizeiptr _Size) : + // clang-format off BufferID{_BufferID}, - Offset {_Offset }, - Size {_Size } + Offset {_Offset}, + Size {_Size} + // clang-format on {} UniqueIdentifier BufferID = -1; - GLintptr Offset = 0; - GLsizeiptr Size = 0; + GLintptr Offset = 0; + GLsizeiptr Size = 0; - bool operator==(const BoundSSBOInfo &rhs)const + bool operator==(const BoundSSBOInfo& rhs) const { - return BufferID == rhs.BufferID && - Offset == rhs.Offset && - Size == rhs.Size; + // clang-format off + return BufferID == rhs.BufferID && + Offset == rhs.Offset && + Size == rhs.Size; + // clang-format on } }; - std::vector< BoundSSBOInfo > m_BoundStorageBlocks; + std::vector<BoundSSBOInfo> m_BoundStorageBlocks; Uint32 m_PendingMemoryBarriers = 0; @@ -191,23 +204,23 @@ private: DISABLED }; - bool operator == (bool bEnabled)const + bool operator==(bool bEnabled) const { - return (bEnabled && m_EnableState == ENABLE_STATE::ENABLED) || - (!bEnabled && m_EnableState == ENABLE_STATE::DISABLED); + return (bEnabled && m_EnableState == ENABLE_STATE::ENABLED) || + (!bEnabled && m_EnableState == ENABLE_STATE::DISABLED); } - bool operator != (bool bEnabled) const + bool operator!=(bool bEnabled) const { return !(*this == bEnabled); } - const EnableStateHelper& operator = (bool bEnabled) + const EnableStateHelper& operator=(bool bEnabled) { m_EnableState = bEnabled ? ENABLE_STATE::ENABLED : ENABLE_STATE::DISABLED; return *this; } - operator bool()const + operator bool() const { return m_EnableState == ENABLE_STATE::ENABLED; } @@ -218,42 +231,42 @@ private: struct DepthStencilGLState { - EnableStateHelper m_DepthEnableState; - EnableStateHelper m_DepthWritesEnableState; + EnableStateHelper m_DepthEnableState; + EnableStateHelper m_DepthWritesEnableState; COMPARISON_FUNCTION m_DepthCmpFunc = COMPARISON_FUNC_UNKNOWN; - EnableStateHelper m_StencilTestEnableState; - Uint16 m_StencilReadMask = 0xFFFF; - Uint16 m_StencilWriteMask = 0xFFFF; + EnableStateHelper m_StencilTestEnableState; + Uint16 m_StencilReadMask = 0xFFFF; + Uint16 m_StencilWriteMask = 0xFFFF; struct StencilOpState { - COMPARISON_FUNCTION Func = COMPARISON_FUNC_UNKNOWN; - STENCIL_OP StencilFailOp = STENCIL_OP_UNDEFINED; - STENCIL_OP StencilDepthFailOp = STENCIL_OP_UNDEFINED; - STENCIL_OP StencilPassOp = STENCIL_OP_UNDEFINED; - Int32 Ref = std::numeric_limits<Int32>::min(); - Uint32 Mask = static_cast<Uint32>(-1); - }m_StencilOpState[2]; - }m_DSState; + COMPARISON_FUNCTION Func = COMPARISON_FUNC_UNKNOWN; + STENCIL_OP StencilFailOp = STENCIL_OP_UNDEFINED; + STENCIL_OP StencilDepthFailOp = STENCIL_OP_UNDEFINED; + STENCIL_OP StencilPassOp = STENCIL_OP_UNDEFINED; + Int32 Ref = std::numeric_limits<Int32>::min(); + Uint32 Mask = static_cast<Uint32>(-1); + } m_StencilOpState[2]; + } m_DSState; struct RasterizerGLState { - FILL_MODE FillMode = FILL_MODE_UNDEFINED; - CULL_MODE CullMode = CULL_MODE_UNDEFINED; + FILL_MODE FillMode = FILL_MODE_UNDEFINED; + CULL_MODE CullMode = CULL_MODE_UNDEFINED; EnableStateHelper FrontCounterClockwise; - float fDepthBias = std::numeric_limits<float>::max(); - float fSlopeScaledDepthBias = std::numeric_limits<float>::max(); + float fDepthBias = std::numeric_limits<float>::max(); + float fSlopeScaledDepthBias = std::numeric_limits<float>::max(); EnableStateHelper DepthClampEnable; EnableStateHelper ScissorTestEnable; - }m_RSState; + } m_RSState; ContextCaps m_Caps; - Uint32 m_ColorWriteMasks[MaxRenderTargets] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + Uint32 m_ColorWriteMasks[MaxRenderTargets] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; EnableStateHelper m_bIndependentWriteMasks; - Int32 m_iActiveTexture = -1; - Int32 m_NumPatchVertices = -1; - + Int32 m_iActiveTexture = -1; + Int32 m_NumPatchVertices = -1; + GLContext::NativeGLContextType m_CurrentGLContext = {}; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h index c9e16cf9..e2f974be 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h @@ -25,19 +25,21 @@ namespace Diligent { - class GLContext - { - public: - typedef HGLRC NativeGLContextType; - GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); - ~GLContext(); - void SwapBuffers(); +class GLContext +{ +public: + using NativeGLContextType = HGLRC; + + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + ~GLContext(); + void SwapBuffers(); + + NativeGLContextType GetCurrentNativeGLContext(); - NativeGLContextType GetCurrentNativeGLContext(); +private: + HGLRC m_Context = NULL; + HDC m_WindowHandleToDeviceContext = NULL; +}; - private: - HGLRC m_Context = NULL; - HDC m_WindowHandleToDeviceContext = NULL; - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h index 3b481aa1..0a26c1b9 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h @@ -28,18 +28,20 @@ namespace GLObjectWrappers { -template<class CreateReleaseHelperType> +template <class CreateReleaseHelperType> class GLObjWrapper { public: - explicit GLObjWrapper(bool CreateObject, CreateReleaseHelperType CreateReleaseHelper = CreateReleaseHelperType()) : + explicit GLObjWrapper(bool CreateObject, CreateReleaseHelperType CreateReleaseHelper = CreateReleaseHelperType()) : + // clang-format off m_uiHandle {0 }, m_CreateReleaseHelper{CreateReleaseHelper} + // clang-format on { - if( CreateObject ) + if (CreateObject) { Create(); - if(!m_uiHandle) + if (!m_uiHandle) { LOG_ERROR_AND_THROW("Failed to create ", m_CreateReleaseHelper.Name, " GL object"); } @@ -50,19 +52,23 @@ public: { Release(); } - - GLObjWrapper (const GLObjWrapper&) = delete; - GLObjWrapper& operator = (const GLObjWrapper&) = delete; - GLObjWrapper(GLObjWrapper&& Wrapper) : + // clang-format off + GLObjWrapper (const GLObjWrapper&) = delete; + GLObjWrapper& operator=(const GLObjWrapper&) = delete; + // clang-format on + + GLObjWrapper(GLObjWrapper&& Wrapper) : + // clang-format off m_uiHandle {Wrapper.m_uiHandle }, m_CreateReleaseHelper{std::move(Wrapper.m_CreateReleaseHelper)}, m_UniqueId {std::move(Wrapper.m_UniqueId) } + // clang-format on { Wrapper.m_uiHandle = 0; } - GLObjWrapper& operator = (GLObjWrapper&& Wrapper) + GLObjWrapper& operator=(GLObjWrapper&& Wrapper) { Release(); @@ -70,7 +76,7 @@ public: m_CreateReleaseHelper = std::move(Wrapper.m_CreateReleaseHelper); m_UniqueId = std::move(Wrapper.m_UniqueId); - Wrapper.m_uiHandle = 0; + Wrapper.m_uiHandle = 0; return *this; } @@ -80,7 +86,7 @@ public: VERIFY(m_uiHandle == 0, "GL object is already initialized"); Release(); m_CreateReleaseHelper.Create(m_uiHandle); - VERIFY(m_uiHandle, "Failed to initialize GL object" ); + VERIFY(m_uiHandle, "Failed to initialize GL object"); } void Release() @@ -92,7 +98,7 @@ public: } } - Diligent::UniqueIdentifier GetUniqueID()const + Diligent::UniqueIdentifier GetUniqueID() const { // This unique ID is used to unambiguously identify the object for // tracking purposes. @@ -101,7 +107,7 @@ public: return m_UniqueId.GetID(); } - operator GLuint()const{return m_uiHandle;} + operator GLuint() const { return m_uiHandle; } static GLObjWrapper Null() { @@ -109,7 +115,7 @@ public: } private: - GLuint m_uiHandle; + GLuint m_uiHandle; CreateReleaseHelperType m_CreateReleaseHelper; // Have separate counter for every type of wrappers @@ -120,25 +126,25 @@ class GLBufferObjCreateReleaseHelper { public: explicit GLBufferObjCreateReleaseHelper(GLuint ExternalGLBufferHandle = 0) : - m_ExternalGLBufferHandle(ExternalGLBufferHandle) + m_ExternalGLBufferHandle{ExternalGLBufferHandle} {} - void Create(GLuint &BuffObj) - { + void Create(GLuint& BuffObj) + { if (m_ExternalGLBufferHandle != 0) BuffObj = m_ExternalGLBufferHandle; // Attach to external GL buffer handle else - glGenBuffers(1, &BuffObj); + glGenBuffers(1, &BuffObj); } void Release(GLuint BuffObj) - { + { if (m_ExternalGLBufferHandle != 0) m_ExternalGLBufferHandle = 0; // Detach from external GL buffer. DO NOT delete the buffer else - glDeleteBuffers(1, &BuffObj); + glDeleteBuffers(1, &BuffObj); } - static const char *Name; + static const char* Name; private: GLuint m_ExternalGLBufferHandle; @@ -149,9 +155,10 @@ typedef GLObjWrapper<GLBufferObjCreateReleaseHelper> GLBufferObj; class GLProgramObjCreateReleaseHelper { public: - static void Create(GLuint &ProgObj){ ProgObj = glCreateProgram(); } - static void Release(GLuint ProgObj){ glDeleteProgram(ProgObj); } - static const char *Name; + static void Create(GLuint& ProgObj) { ProgObj = glCreateProgram(); } + static void Release(GLuint ProgObj) { glDeleteProgram(ProgObj); } + + static const char* Name; }; typedef GLObjWrapper<GLProgramObjCreateReleaseHelper> GLProgramObj; @@ -159,10 +166,13 @@ typedef GLObjWrapper<GLProgramObjCreateReleaseHelper> GLProgramObj; class GLShaderObjCreateReleaseHelper { public: - GLShaderObjCreateReleaseHelper(GLenum ShaderType) : m_ShaderType(ShaderType){} - void Create(GLuint &ShaderObj){ ShaderObj = glCreateShader(m_ShaderType); } - void Release(GLuint ShaderObj){ glDeleteShader(ShaderObj); } - static const char *Name; + GLShaderObjCreateReleaseHelper(GLenum ShaderType) : + m_ShaderType(ShaderType) {} + void Create(GLuint& ShaderObj) { ShaderObj = glCreateShader(m_ShaderType); } + void Release(GLuint ShaderObj) { glDeleteShader(ShaderObj); } + + static const char* Name; + private: GLenum m_ShaderType; }; @@ -172,9 +182,10 @@ typedef GLObjWrapper<GLShaderObjCreateReleaseHelper> GLShaderObj; class GLPipelineObjCreateReleaseHelper { public: - void Create(GLuint &Pipeline) { glGenProgramPipelines(1, &Pipeline); } + void Create(GLuint& Pipeline) { glGenProgramPipelines(1, &Pipeline); } void Release(GLuint Pipeline) { glDeleteProgramPipelines(1, &Pipeline); } - static const char *Name; + + static const char* Name; }; typedef GLObjWrapper<GLPipelineObjCreateReleaseHelper> GLPipelineObj; @@ -182,9 +193,10 @@ typedef GLObjWrapper<GLPipelineObjCreateReleaseHelper> GLPipelineObj; class GLVAOCreateReleaseHelper { public: - void Create(GLuint &VAO) { glGenVertexArrays(1, &VAO); } + void Create(GLuint& VAO) { glGenVertexArrays(1, &VAO); } void Release(GLuint VAO) { glDeleteVertexArrays(1, &VAO); } - static const char *Name; + + static const char* Name; }; typedef GLObjWrapper<GLVAOCreateReleaseHelper> GLVertexArrayObj; @@ -196,8 +208,8 @@ public: m_ExternalGLTextureHandle(ExternalGLTextureHandle) {} - void Create(GLuint &Tex) - { + void Create(GLuint& Tex) + { if (m_ExternalGLTextureHandle != 0) Tex = m_ExternalGLTextureHandle; // Attach to the external texture else @@ -205,14 +217,14 @@ public: } void Release(GLuint Tex) - { + { if (m_ExternalGLTextureHandle != 0) m_ExternalGLTextureHandle = 0; // Detach from the external texture. DO NOT delete it! else glDeleteTextures(1, &Tex); } - static const char *Name; + static const char* Name; private: GLuint m_ExternalGLTextureHandle; @@ -222,9 +234,10 @@ typedef GLObjWrapper<GLTextureCreateReleaseHelper> GLTextureObj; class GLSamplerCreateReleaseHelper { public: - void Create(GLuint &Sampler) { glGenSamplers(1, &Sampler); } + void Create(GLuint& Sampler) { glGenSamplers(1, &Sampler); } void Release(GLuint Sampler) { glDeleteSamplers(1, &Sampler); } - static const char *Name; + + static const char* Name; }; typedef GLObjWrapper<GLSamplerCreateReleaseHelper> GLSamplerObj; @@ -236,23 +249,23 @@ public: m_ExternalFBOHandle(ExternalFBOHandle) {} - void Create(GLuint &FBO) - { + void Create(GLuint& FBO) + { if (m_ExternalFBOHandle != 0) FBO = m_ExternalFBOHandle; // Attach to external FBO handle else - glGenFramebuffers(1, &FBO); + glGenFramebuffers(1, &FBO); } - void Release(GLuint FBO) - { + void Release(GLuint FBO) + { if (m_ExternalFBOHandle != 0) m_ExternalFBOHandle = 0; // DO NOT delete the FBO else - glDeleteFramebuffers(1, &FBO); + glDeleteFramebuffers(1, &FBO); } - static const char *Name; + static const char* Name; private: GLuint m_ExternalFBOHandle; @@ -263,27 +276,31 @@ typedef GLObjWrapper<GLFBOCreateReleaseHelper> GLFrameBufferObj; class GLRBOCreateReleaseHelper { public: - void Create(GLuint &RBO) { glGenRenderbuffers(1, &RBO); } + void Create(GLuint& RBO) { glGenRenderbuffers(1, &RBO); } void Release(GLuint RBO) { glDeleteRenderbuffers(1, &RBO); } - static const char *Name; + + static const char* Name; }; typedef GLObjWrapper<GLRBOCreateReleaseHelper> GLRenderBufferObj; - + struct GLSyncObj { GLSyncObj() {} - GLSyncObj(GLsync _SyncHandle) : SyncHandle(_SyncHandle) {} + GLSyncObj(GLsync _SyncHandle) : + SyncHandle{_SyncHandle} {} + // clang-format off GLSyncObj (const GLSyncObj&) = delete; GLSyncObj& operator = (const GLSyncObj&) = delete; - + // clang-format on + GLSyncObj(GLSyncObj&& rhs) { SyncHandle = rhs.SyncHandle; rhs.SyncHandle = GLsync{}; } - GLSyncObj& operator = (GLSyncObj&& rhs) + GLSyncObj& operator=(GLSyncObj&& rhs) { Release(); SyncHandle = rhs.SyncHandle; @@ -303,10 +320,10 @@ struct GLSyncObj Release(); } - operator GLsync()const{return SyncHandle;} + operator GLsync() const { return SyncHandle; } private: GLsync SyncHandle = {}; }; -} +} // namespace GLObjectWrappers diff --git a/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.h b/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.h index ddd79c38..9421d59c 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.h @@ -26,7 +26,7 @@ // GLPipelineResourceLayout class manages resource bindings for all stages in a pipeline // -// +// // To program resource cache // // A A A A A A A A @@ -78,16 +78,18 @@ class IMemoryAllocator; class GLPipelineResourceLayout { public: - GLPipelineResourceLayout(IObject& Owner) : + GLPipelineResourceLayout(IObject& Owner) : m_Owner(Owner) {} ~GLPipelineResourceLayout(); // No copies, only moves are allowed + // clang-format off GLPipelineResourceLayout (const GLPipelineResourceLayout&) = delete; GLPipelineResourceLayout& operator = (const GLPipelineResourceLayout&) = delete; GLPipelineResourceLayout ( GLPipelineResourceLayout&&) = default; GLPipelineResourceLayout& operator = ( GLPipelineResourceLayout&&) = delete; + // clang-format on void Initialize(GLProgramResources* ProgramResources, Uint32 NumPrograms, @@ -102,7 +104,7 @@ public: const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes); - void CopyResources(GLProgramResourceCache& DstCache)const; + void CopyResources(GLProgramResourceCache& DstCache) const; struct GLVariableBase : public ShaderVariableBase<GLPipelineResourceLayout> { @@ -110,26 +112,28 @@ public: GLVariableBase(const GLProgramResources::GLResourceAttribs& ResourceAttribs, GLPipelineResourceLayout& ParentLayout, SHADER_RESOURCE_VARIABLE_TYPE VariableType, - Int32 StaticSamplerIdx) : + Int32 StaticSamplerIdx) : + // clang-format off TBase {ParentLayout}, m_Attribs {ResourceAttribs }, m_VariableType {VariableType }, m_StaticSamplerIdx{StaticSamplerIdx} + // clang-format on { VERIFY_EXPR(StaticSamplerIdx < 0 || ResourceAttribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV); } - virtual SHADER_RESOURCE_VARIABLE_TYPE GetType()const override final + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final { return m_VariableType; } - virtual ShaderResourceDesc GetResourceDesc()const override final + virtual ShaderResourceDesc GetResourceDesc() const override final { return m_Attribs.GetResourceDesc(); } - virtual Uint32 GetIndex()const override final + virtual Uint32 GetIndex() const override final { return m_ParentResLayout.GetVariableIndex(*this); } @@ -150,19 +154,20 @@ public: // Non-virtual function void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - virtual void Set(IDeviceObject* pObject)override final + + virtual void Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); } - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.ArraySize, FirstElement, NumElements); - for(Uint32 elem=0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement+elem); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); } - virtual bool IsBound(Uint32 ArrayIndex)const override final + virtual bool IsBound(Uint32 ArrayIndex) const override final { VERIFY_EXPR(ArrayIndex < m_Attribs.ArraySize); return m_ParentResLayout.m_pResourceCache->IsUBBound(m_Attribs.Binding + ArrayIndex); @@ -176,24 +181,25 @@ public: GLPipelineResourceLayout& ParentResLayout, SHADER_RESOURCE_VARIABLE_TYPE VariableType, Int32 StaticSamplerIdx) : - GLVariableBase {ResourceAttribs, ParentResLayout, VariableType, StaticSamplerIdx} + GLVariableBase{ResourceAttribs, ParentResLayout, VariableType, StaticSamplerIdx} {} // Non-virtual function void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - virtual void Set(IDeviceObject* pObject)override final + + virtual void Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); } - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.ArraySize, FirstElement, NumElements); - for(Uint32 elem=0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement+elem); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); } - virtual bool IsBound(Uint32 ArrayIndex)const override final + virtual bool IsBound(Uint32 ArrayIndex) const override final { VERIFY_EXPR(ArrayIndex < m_Attribs.ArraySize); return m_ParentResLayout.m_pResourceCache->IsSamplerBound(m_Attribs.Binding + ArrayIndex, m_Attribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV); @@ -211,19 +217,20 @@ public: // Provide non-virtual function void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - virtual void Set(IDeviceObject* pObject)override final + + virtual void Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); } - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.ArraySize, FirstElement, NumElements); - for(Uint32 elem=0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement+elem); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); } - virtual bool IsBound(Uint32 ArrayIndex)const override final + virtual bool IsBound(Uint32 ArrayIndex) const override final { VERIFY_EXPR(ArrayIndex < m_Attribs.ArraySize); return m_ParentResLayout.m_pResourceCache->IsImageBound(m_Attribs.Binding + ArrayIndex, m_Attribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV); @@ -241,19 +248,20 @@ public: // Non-virtual function void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - virtual void Set(IDeviceObject* pObject)override final + + virtual void Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); } - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.ArraySize, FirstElement, NumElements); - for(Uint32 elem=0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement+elem); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); } - virtual bool IsBound(Uint32 ArrayIndex)const override final + virtual bool IsBound(Uint32 ArrayIndex) const override final { VERIFY_EXPR(ArrayIndex < m_Attribs.ArraySize); return m_ParentResLayout.m_pResourceCache->IsSSBOBound(m_Attribs.Binding + ArrayIndex); @@ -266,35 +274,37 @@ public: void BindResources(SHADER_TYPE ShaderStage, IResourceMapping* pResourceMapping, Uint32 Flags, const GLProgramResourceCache& dbgResourceCache); #ifdef DEVELOPMENT - bool dvpVerifyBindings(const GLProgramResourceCache& ResourceCache)const; + bool dvpVerifyBindings(const GLProgramResourceCache& ResourceCache) const; #endif - IShaderResourceVariable* GetShaderVariable( SHADER_TYPE ShaderStage, const Char* Name ); - IShaderResourceVariable* GetShaderVariable( SHADER_TYPE ShaderStage, Uint32 Index ); + IShaderResourceVariable* GetShaderVariable(SHADER_TYPE ShaderStage, const Char* Name); + IShaderResourceVariable* GetShaderVariable(SHADER_TYPE ShaderStage, Uint32 Index); - IObject& GetOwner(){return m_Owner;} + IObject& GetOwner() { return m_Owner; } - Uint32 GetNumVariables(SHADER_TYPE ShaderStage)const; + Uint32 GetNumVariables(SHADER_TYPE ShaderStage) const; + // clang-format off Uint32 GetNumUBs() const { return (m_SamplerOffset - m_UBOffset) / sizeof(UniformBuffBindInfo); } Uint32 GetNumSamplers() const { return (m_ImageOffset - m_SamplerOffset) / sizeof(SamplerBindInfo); } Uint32 GetNumImages() const { return (m_StorageBufferOffset - m_ImageOffset) / sizeof(ImageBindInfo) ; } Uint32 GetNumStorageBuffers() const { return (m_VariableEndOffset - m_StorageBufferOffset) / sizeof(StorageBufferBindInfo); } + // clang-format on - template<typename ResourceType> Uint32 GetNumResources()const; + template <typename ResourceType> Uint32 GetNumResources() const; - template<typename ResourceType> - const ResourceType& GetConstResource(Uint32 ResIndex)const + template <typename ResourceType> + const ResourceType& GetConstResource(Uint32 ResIndex) const { VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>(), ")"); auto Offset = GetResourceOffset<ResourceType>(); - return reinterpret_cast<const ResourceType*>( reinterpret_cast<const Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex]; + return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex]; } - Uint32 GetVariableIndex(const GLVariableBase& Var)const; + Uint32 GetVariableIndex(const GLVariableBase& Var) const; private: - + // clang-format off /* 0*/ IObject& m_Owner; // No need to use shared pointer, as the resource cache is either part of the same // ShaderGLImpl object, or ShaderResourceBindingGLImpl object @@ -311,36 +321,37 @@ private: /*40*/ std::array<Int8, 6> m_ProgramIndex = {{-1, -1, -1, -1, -1, -1}}; /*46*/ Uint8 m_NumPrograms = 0; /*48*/ + // clang-format on - template<typename ResourceType> OffsetType GetResourceOffset()const; + template <typename ResourceType> OffsetType GetResourceOffset() const; - template<typename ResourceType> + template <typename ResourceType> ResourceType& GetResource(Uint32 ResIndex) { - VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>()-1, ")"); + VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")"); auto Offset = GetResourceOffset<ResourceType>(); - return reinterpret_cast<ResourceType*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex]; + return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex]; } GLProgramResources::ResourceCounters& GetProgramVarEndOffsets(Uint32 prog) { VERIFY_EXPR(prog < m_NumPrograms); - return reinterpret_cast<GLProgramResources::ResourceCounters*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_VariableEndOffset)[prog]; + return reinterpret_cast<GLProgramResources::ResourceCounters*>(reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_VariableEndOffset)[prog]; } - const GLProgramResources::ResourceCounters& GetProgramVarEndOffsets(Uint32 prog)const + const GLProgramResources::ResourceCounters& GetProgramVarEndOffsets(Uint32 prog) const { VERIFY_EXPR(prog < m_NumPrograms); - return reinterpret_cast<GLProgramResources::ResourceCounters*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_VariableEndOffset)[prog]; + return reinterpret_cast<GLProgramResources::ResourceCounters*>(reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_VariableEndOffset)[prog]; } - template<typename ResourceType> + template <typename ResourceType> IShaderResourceVariable* GetResourceByName(SHADER_TYPE ShaderStage, const Char* Name); - template<typename THandleUB, - typename THandleSampler, - typename THandleImage, - typename THandleStorageBuffer> + template <typename THandleUB, + typename THandleSampler, + typename THandleImage, + typename THandleStorageBuffer> void HandleResources(THandleUB HandleUB, THandleSampler HandleSampler, THandleImage HandleImage, @@ -359,14 +370,14 @@ private: HandleStorageBuffer(GetResource<StorageBufferBindInfo>(s)); } - template<typename THandleUB, - typename THandleSampler, - typename THandleImage, - typename THandleStorageBuffer> + template <typename THandleUB, + typename THandleSampler, + typename THandleImage, + typename THandleStorageBuffer> void HandleConstResources(THandleUB HandleUB, THandleSampler HandleSampler, THandleImage HandleImage, - THandleStorageBuffer HandleStorageBuffer)const + THandleStorageBuffer HandleStorageBuffer) const { for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub) HandleUB(GetConstResource<UniformBuffBindInfo>(ub)); @@ -387,54 +398,58 @@ private: -template<> -inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::UniformBuffBindInfo>()const +template <> +inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::UniformBuffBindInfo>() const { return GetNumUBs(); } -template<> -inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::SamplerBindInfo>()const +template <> +inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::SamplerBindInfo>() const { return GetNumSamplers(); } -template<> -inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::ImageBindInfo>()const +template <> +inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::ImageBindInfo>() const { return GetNumImages(); } -template<> -inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::StorageBufferBindInfo>()const +template <> +inline Uint32 GLPipelineResourceLayout::GetNumResources<GLPipelineResourceLayout::StorageBufferBindInfo>() const { return GetNumStorageBuffers(); } -template<> -inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout::GetResourceOffset<GLPipelineResourceLayout::UniformBuffBindInfo>()const +template <> +inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout:: + GetResourceOffset<GLPipelineResourceLayout::UniformBuffBindInfo>() const { return m_UBOffset; } -template<> -inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout::GetResourceOffset<GLPipelineResourceLayout::SamplerBindInfo>()const +template <> +inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout:: + GetResourceOffset<GLPipelineResourceLayout::SamplerBindInfo>() const { return m_SamplerOffset; } -template<> -inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout::GetResourceOffset<GLPipelineResourceLayout::ImageBindInfo>()const +template <> +inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout:: + GetResourceOffset<GLPipelineResourceLayout::ImageBindInfo>() const { return m_ImageOffset; } -template<> -inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout::GetResourceOffset<GLPipelineResourceLayout::StorageBufferBindInfo>()const +template <> +inline GLPipelineResourceLayout::OffsetType GLPipelineResourceLayout:: + GetResourceOffset<GLPipelineResourceLayout::StorageBufferBindInfo>() const { return m_StorageBufferOffset; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.h b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.h index 08572f6c..865a7ade 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.h @@ -46,10 +46,12 @@ public: ~GLProgramResourceCache(); + // clang-format off GLProgramResourceCache (const GLProgramResourceCache&) = delete; GLProgramResourceCache& operator = (const GLProgramResourceCache&) = delete; GLProgramResourceCache (GLProgramResourceCache&&) = delete; GLProgramResourceCache& operator = (GLProgramResourceCache&&) = delete; + // clang-format on /// Describes a resource bound to a uniform buffer or a shader storage block slot struct CachedUB @@ -63,15 +65,16 @@ public: { /// We keep strong reference to the view instead of the reference /// to the texture or buffer because this is more efficient from - /// performance point of view: this avoids one pair of - /// AddStrongRef()/ReleaseStrongRef(). The view holds a strong reference + /// performance point of view: this avoids one pair of + /// AddStrongRef()/ReleaseStrongRef(). The view holds a strong reference /// to the texture or the buffer, so it makes no difference. RefCntAutoPtr<IDeviceObject> pView; - TextureBaseGL* pTexture = nullptr; + + TextureBaseGL* pTexture = nullptr; union { - BufferGLImpl* pBuffer = nullptr; // When pTexture == nullptr - SamplerGLImpl* pSampler; // When pTexture != nullptr + BufferGLImpl* pBuffer = nullptr; // When pTexture == nullptr + SamplerGLImpl* pSampler; // When pTexture != nullptr }; CachedResourceView() noexcept {} @@ -107,6 +110,7 @@ public: static size_t GetRequriedMemorySize(Uint32 UBCount, Uint32 SamplerCount, Uint32 ImageCount, Uint32 SSBOCount); + void Initialize(Uint32 UBCount, Uint32 SamplerCount, Uint32 ImageCount, Uint32 SSBOCount, class IMemoryAllocator& MemAllocator); void Destroy(class IMemoryAllocator& MemAllocator); @@ -155,7 +159,7 @@ public: GetSSBO(Binding).pBufferView = std::move(pBuffView); } - bool IsUBBound(Uint32 Binding)const + bool IsUBBound(Uint32 Binding) const { if (Binding >= GetUBCount()) return false; @@ -164,7 +168,7 @@ public: return UB.pBuffer; } - bool IsSamplerBound(Uint32 Binding, bool dbgIsTextureView)const + bool IsSamplerBound(Uint32 Binding, bool dbgIsTextureView) const { if (Binding >= GetSamplerCount()) return false; @@ -174,7 +178,7 @@ public: return Sampler.pView; } - bool IsImageBound(Uint32 Binding, bool dbgIsTextureView)const + bool IsImageBound(Uint32 Binding, bool dbgIsTextureView) const { if (Binding >= GetImageCount()) return false; @@ -184,7 +188,7 @@ public: return Image.pView; } - bool IsSSBOBound(Uint32 Binding)const + bool IsSSBOBound(Uint32 Binding) const { if (Binding >= GetSSBOCount()) return false; @@ -193,38 +197,40 @@ public: return SSBO.pBufferView; } + // clang-format off Uint32 GetUBCount() const { return (m_SmplrsOffset - m_UBsOffset) / sizeof(CachedUB); } Uint32 GetSamplerCount() const { return (m_ImgsOffset - m_SmplrsOffset) / sizeof(CachedResourceView); } Uint32 GetImageCount() const { return (m_SSBOsOffset - m_ImgsOffset) / sizeof(CachedResourceView); } Uint32 GetSSBOCount() const { return (m_MemoryEndOffset - m_SSBOsOffset) / sizeof(CachedSSBO); } + // clang-format on - const CachedUB& GetConstUB(Uint32 Binding)const + const CachedUB& GetConstUB(Uint32 Binding) const { VERIFY(Binding < GetUBCount(), "Uniform buffer binding (", Binding, ") is out of range"); return reinterpret_cast<CachedUB*>(m_pResourceData + m_UBsOffset)[Binding]; } - const CachedResourceView& GetConstSampler(Uint32 Binding)const + const CachedResourceView& GetConstSampler(Uint32 Binding) const { VERIFY(Binding < GetSamplerCount(), "Sampler binding (", Binding, ") is out of range"); return reinterpret_cast<CachedResourceView*>(m_pResourceData + m_SmplrsOffset)[Binding]; } - const CachedResourceView& GetConstImage(Uint32 Binding)const + const CachedResourceView& GetConstImage(Uint32 Binding) const { VERIFY(Binding < GetImageCount(), "Image buffer binding (", Binding, ") is out of range"); return reinterpret_cast<CachedResourceView*>(m_pResourceData + m_ImgsOffset)[Binding]; } - const CachedSSBO& GetConstSSBO(Uint32 Binding)const + const CachedSSBO& GetConstSSBO(Uint32 Binding) const { VERIFY(Binding < GetSSBOCount(), "Shader storage block binding (", Binding, ") is out of range"); return reinterpret_cast<CachedSSBO*>(m_pResourceData + m_SSBOsOffset)[Binding]; } - bool IsInitialized()const + bool IsInitialized() const { - return m_MemoryEndOffset != InvalidResourceOffset; + return m_MemoryEndOffset != InvalidResourceOffset; } private: @@ -249,7 +255,8 @@ private: } static constexpr const Uint16 InvalidResourceOffset = 0xFFFF; - static constexpr const Uint16 m_UBsOffset = 0; + static constexpr const Uint16 m_UBsOffset = 0; + Uint16 m_SmplrsOffset = InvalidResourceOffset; Uint16 m_ImgsOffset = InvalidResourceOffset; Uint16 m_SSBOsOffset = InvalidResourceOffset; @@ -260,7 +267,6 @@ private: #ifdef _DEBUG IMemoryAllocator* m_pdbgMemoryAllocator = nullptr; #endif - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h index 19947e96..a6085f80 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h @@ -26,7 +26,7 @@ // GLProgramResources class allocates single continuous chunk of memory to store all program resources, as follows: // // -// m_UniformBuffers m_Samplers m_Images m_StorageBlocks +// m_UniformBuffers m_Samplers m_Images m_StorageBlocks // | | | | | | // | UB[0] ... UB[Nu-1] | Sam[0] ... Sam[Ns-1] | Img[0] ... Img[Ni-1] | SB[0] ... SB[Nsb-1] | Resource Names | // @@ -44,443 +44,466 @@ namespace Diligent { - class GLProgramResources + +class GLProgramResources +{ +public: + GLProgramResources() {} + ~GLProgramResources(); + // clang-format off + GLProgramResources (GLProgramResources&& Program)noexcept; + + GLProgramResources (const GLProgramResources&) = delete; + GLProgramResources& operator = (const GLProgramResources&) = delete; + GLProgramResources& operator = ( GLProgramResources&&) = delete; + // clang-format on + + /// Loads program uniforms and assigns bindings + void LoadUniforms(SHADER_TYPE ShaderStages, + const GLObjectWrappers::GLProgramObj& GLProgram, + class GLContextState& State, + Uint32& UniformBufferBinding, + Uint32& SamplerBinding, + Uint32& ImageBinding, + Uint32& StorageBufferBinding); + + struct GLResourceAttribs { - public: - GLProgramResources(){} - ~GLProgramResources(); - GLProgramResources (GLProgramResources&& Program)noexcept; - - GLProgramResources (const GLProgramResources&) = delete; - GLProgramResources& operator = (const GLProgramResources&) = delete; - GLProgramResources& operator = ( GLProgramResources&&) = delete; - - /// Loads program uniforms and assigns bindings - void LoadUniforms(SHADER_TYPE ShaderStages, - const GLObjectWrappers::GLProgramObj& GLProgram, - class GLContextState& State, - Uint32& UniformBufferBinding, - Uint32& SamplerBinding, - Uint32& ImageBinding, - Uint32& StorageBufferBinding); - - struct GLResourceAttribs - { + // clang-format off /* 0 */ const Char* Name; /* 8 */ const SHADER_TYPE ShaderStages; /* 12 */ const SHADER_RESOURCE_TYPE ResourceType; /* 16 */ const Uint32 Binding; /* 20 */ Uint32 ArraySize; /* 24 */ // End of data - - GLResourceAttribs(const Char* _Name, - SHADER_TYPE _ShaderStages, - SHADER_RESOURCE_TYPE _ResourceType, - Uint32 _Binding, - Uint32 _ArraySize)noexcept : - Name {_Name }, - ShaderStages {_ShaderStages}, - ResourceType {_ResourceType}, - Binding {_Binding }, - ArraySize {_ArraySize } - { - VERIFY(_ShaderStages != SHADER_TYPE_UNKNOWN, "At least one shader stage must be specified"); - VERIFY(_ResourceType != SHADER_RESOURCE_TYPE_UNKNOWN, "Unknown shader resource type"); - VERIFY(_ArraySize >= 1, "Array size must be greater than 1"); - } - - GLResourceAttribs(const GLResourceAttribs& Attribs, - StringPool& NamesPool)noexcept : - GLResourceAttribs - { - NamesPool.CopyString(Attribs.Name), - Attribs.ShaderStages, - Attribs.ResourceType, - Attribs.Binding, - Attribs.ArraySize - } - { - } - - bool IsCompatibleWith(const GLResourceAttribs& Var)const - { - return ShaderStages == Var.ShaderStages && - ResourceType == Var.ResourceType && - Binding == Var.Binding && - ArraySize == Var.ArraySize; - } - - size_t GetHash()const - { - return ComputeHash(static_cast<Uint32>(ShaderStages), static_cast<Uint32>(ResourceType), Binding, ArraySize); - } - - String GetPrintName(Uint32 ArrayInd)const - { - VERIFY_EXPR(ArrayInd < ArraySize); - if (ArraySize > 1) - return String(Name) + '[' + std::to_string(ArrayInd) + ']'; - else - return Name; - } - - ShaderResourceDesc GetResourceDesc()const - { - ShaderResourceDesc ResourceDesc; - ResourceDesc.Name = Name; - ResourceDesc.ArraySize = ArraySize; - ResourceDesc.Type = ResourceType; - return ResourceDesc; - } - }; - - struct UniformBufferInfo final : GLResourceAttribs + // clang-format on + + GLResourceAttribs(const Char* _Name, + SHADER_TYPE _ShaderStages, + SHADER_RESOURCE_TYPE _ResourceType, + Uint32 _Binding, + Uint32 _ArraySize) noexcept : + // clang-format off + Name {_Name }, + ShaderStages {_ShaderStages}, + ResourceType {_ResourceType}, + Binding {_Binding }, + ArraySize {_ArraySize } + // clang-format on { - UniformBufferInfo (const UniformBufferInfo&) = delete; - UniformBufferInfo& operator= (const UniformBufferInfo&) = delete; - UniformBufferInfo ( UniformBufferInfo&&) = default; - UniformBufferInfo& operator= ( UniformBufferInfo&&) = delete; - - UniformBufferInfo(const Char* _Name, - SHADER_TYPE _ShaderStages, - SHADER_RESOURCE_TYPE _ResourceType, - Uint32 _Binding, - Uint32 _ArraySize, - GLuint _UBIndex)noexcept : - GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, - UBIndex {_UBIndex} - {} - - UniformBufferInfo(const UniformBufferInfo& UB, - StringPool& NamesPool)noexcept : - GLResourceAttribs{UB, NamesPool}, - UBIndex {UB.UBIndex } - {} - - bool IsCompatibleWith(const UniformBufferInfo& UB)const - { - return UBIndex == UB.UBIndex && - GLResourceAttribs::IsCompatibleWith(UB); - } + VERIFY(_ShaderStages != SHADER_TYPE_UNKNOWN, "At least one shader stage must be specified"); + VERIFY(_ResourceType != SHADER_RESOURCE_TYPE_UNKNOWN, "Unknown shader resource type"); + VERIFY(_ArraySize >= 1, "Array size must be greater than 1"); + } - size_t GetHash()const + GLResourceAttribs(const GLResourceAttribs& Attribs, + StringPool& NamesPool) noexcept : + // clang-format off + GLResourceAttribs { - return ComputeHash(UBIndex, GLResourceAttribs::GetHash()); + NamesPool.CopyString(Attribs.Name), + Attribs.ShaderStages, + Attribs.ResourceType, + Attribs.Binding, + Attribs.ArraySize } - - const GLuint UBIndex; - }; - static_assert((sizeof(UniformBufferInfo) % sizeof(void*)) == 0, "sizeof(UniformBufferInfo) must be multiple of sizeof(void*)"); - - - struct SamplerInfo final : GLResourceAttribs + // clang-format on { - SamplerInfo (const SamplerInfo&) = delete; - SamplerInfo& operator= (const SamplerInfo&) = delete; - SamplerInfo ( SamplerInfo&&) = default; - SamplerInfo& operator= ( SamplerInfo&&) = delete; - - SamplerInfo(const Char* _Name, - SHADER_TYPE _ShaderStages, - SHADER_RESOURCE_TYPE _ResourceType, - Uint32 _Binding, - Uint32 _ArraySize, - GLint _Location, - GLenum _SamplerType)noexcept : - GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, - Location {_Location }, - SamplerType {_SamplerType} - {} - - SamplerInfo(const SamplerInfo& Sam, - StringPool& NamesPool)noexcept : - GLResourceAttribs{Sam, NamesPool}, - Location {Sam.Location }, - SamplerType {Sam.SamplerType} - {} - - bool IsCompatibleWith(const SamplerInfo& Sam)const - { - return Location == Sam.Location && - SamplerType == Sam.SamplerType && - GLResourceAttribs::IsCompatibleWith(Sam); - } - - size_t GetHash()const - { - return ComputeHash(Location, SamplerType, GLResourceAttribs::GetHash()); - } - - const GLint Location; - const GLenum SamplerType; - }; - static_assert((sizeof(SamplerInfo) % sizeof(void*)) == 0, "sizeof(SamplerInfo) must be multiple of sizeof(void*)"); + } - - struct ImageInfo final : GLResourceAttribs + bool IsCompatibleWith(const GLResourceAttribs& Var)const { - ImageInfo (const ImageInfo&) = delete; - ImageInfo& operator= (const ImageInfo&) = delete; - ImageInfo ( ImageInfo&&) = default; - ImageInfo& operator= ( ImageInfo&&) = delete; - - ImageInfo(const Char* _Name, - SHADER_TYPE _ShaderStages, - SHADER_RESOURCE_TYPE _ResourceType, - Uint32 _Binding, - Uint32 _ArraySize, - GLint _Location, - GLenum _ImageType)noexcept : - GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, - Location {_Location }, - ImageType {_ImageType} - {} - - ImageInfo(const ImageInfo& Img, - StringPool& NamesPool)noexcept : - GLResourceAttribs{Img, NamesPool}, - Location {Img.Location }, - ImageType {Img.ImageType} - {} - - bool IsCompatibleWith(const ImageInfo& Img)const - { - return Location == Img.Location && - ImageType == Img.ImageType && - GLResourceAttribs::IsCompatibleWith(Img); - } - - size_t GetHash()const - { - return ComputeHash(Location, ImageType, GLResourceAttribs::GetHash()); - } - - const GLint Location; - const GLenum ImageType; - }; - static_assert((sizeof(ImageInfo) % sizeof(void*)) == 0, "sizeof(ImageInfo) must be multiple of sizeof(void*)"); - + // clang-format off + return ShaderStages == Var.ShaderStages && + ResourceType == Var.ResourceType && + Binding == Var.Binding && + ArraySize == Var.ArraySize; + // clang-format on + } - struct StorageBlockInfo final : GLResourceAttribs + size_t GetHash() const { - StorageBlockInfo (const StorageBlockInfo&) = delete; - StorageBlockInfo& operator= (const StorageBlockInfo&) = delete; - StorageBlockInfo ( StorageBlockInfo&&) = default; - StorageBlockInfo& operator= ( StorageBlockInfo&&) = delete; - - StorageBlockInfo(const Char* _Name, - SHADER_TYPE _ShaderStages, - SHADER_RESOURCE_TYPE _ResourceType, - Uint32 _Binding, - Uint32 _ArraySize, - GLint _SBIndex)noexcept : - GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, - SBIndex {_SBIndex} - {} - - StorageBlockInfo(const StorageBlockInfo& SB, - StringPool& NamesPool)noexcept : - GLResourceAttribs{SB, NamesPool}, - SBIndex {SB.SBIndex} - {} - - bool IsCompatibleWith(const StorageBlockInfo& SB)const - { - return SBIndex == SB.SBIndex && - GLResourceAttribs::IsCompatibleWith(SB); - } - - size_t GetHash()const - { - return ComputeHash(SBIndex, GLResourceAttribs::GetHash()); - } - - const GLint SBIndex; - }; - static_assert( (sizeof(StorageBlockInfo) % sizeof(void*)) == 0, "sizeof(StorageBlockInfo) must be multiple of sizeof(void*)"); - - - Uint32 GetNumUniformBuffers()const { return m_NumUniformBuffers; } - Uint32 GetNumSamplers() const { return m_NumSamplers; } - Uint32 GetNumImages() const { return m_NumImages; } - Uint32 GetNumStorageBlocks() const { return m_NumStorageBlocks; } + return ComputeHash(static_cast<Uint32>(ShaderStages), static_cast<Uint32>(ResourceType), Binding, ArraySize); + } - UniformBufferInfo& GetUniformBuffer(Uint32 Index) + String GetPrintName(Uint32 ArrayInd) const { - VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); - return m_UniformBuffers[Index]; + VERIFY_EXPR(ArrayInd < ArraySize); + if (ArraySize > 1) + return String(Name) + '[' + std::to_string(ArrayInd) + ']'; + else + return Name; } - SamplerInfo& GetSampler(Uint32 Index) + ShaderResourceDesc GetResourceDesc() const { - VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); - return m_Samplers[Index]; + ShaderResourceDesc ResourceDesc; + ResourceDesc.Name = Name; + ResourceDesc.ArraySize = ArraySize; + ResourceDesc.Type = ResourceType; + return ResourceDesc; } + }; - ImageInfo& GetImage(Uint32 Index) + struct UniformBufferInfo final : GLResourceAttribs + { + // clang-format off + UniformBufferInfo (const UniformBufferInfo&) = delete; + UniformBufferInfo& operator= (const UniformBufferInfo&) = delete; + UniformBufferInfo ( UniformBufferInfo&&) = default; + UniformBufferInfo& operator= ( UniformBufferInfo&&) = delete; + + UniformBufferInfo(const Char* _Name, + SHADER_TYPE _ShaderStages, + SHADER_RESOURCE_TYPE _ResourceType, + Uint32 _Binding, + Uint32 _ArraySize, + GLuint _UBIndex)noexcept : + GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, + UBIndex {_UBIndex} + {} + + UniformBufferInfo(const UniformBufferInfo& UB, + StringPool& NamesPool)noexcept : + GLResourceAttribs{UB, NamesPool}, + UBIndex {UB.UBIndex } + {} + // clang-format on + + bool IsCompatibleWith(const UniformBufferInfo& UB) const { - VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); - return m_Images[Index]; + return UBIndex == UB.UBIndex && + GLResourceAttribs::IsCompatibleWith(UB); } - StorageBlockInfo& GetStorageBlock(Uint32 Index) + size_t GetHash() const { - VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); - return m_StorageBlocks[Index]; + return ComputeHash(UBIndex, GLResourceAttribs::GetHash()); } + const GLuint UBIndex; + }; + static_assert((sizeof(UniformBufferInfo) % sizeof(void*)) == 0, "sizeof(UniformBufferInfo) must be multiple of sizeof(void*)"); - const UniformBufferInfo& GetUniformBuffer(Uint32 Index)const + + struct SamplerInfo final : GLResourceAttribs + { + // clang-format off + SamplerInfo (const SamplerInfo&) = delete; + SamplerInfo& operator= (const SamplerInfo&) = delete; + SamplerInfo ( SamplerInfo&&) = default; + SamplerInfo& operator= ( SamplerInfo&&) = delete; + + SamplerInfo(const Char* _Name, + SHADER_TYPE _ShaderStages, + SHADER_RESOURCE_TYPE _ResourceType, + Uint32 _Binding, + Uint32 _ArraySize, + GLint _Location, + GLenum _SamplerType)noexcept : + GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, + Location {_Location }, + SamplerType {_SamplerType} + {} + + SamplerInfo(const SamplerInfo& Sam, + StringPool& NamesPool)noexcept : + GLResourceAttribs{Sam, NamesPool}, + Location {Sam.Location }, + SamplerType {Sam.SamplerType} + {} + + bool IsCompatibleWith(const SamplerInfo& Sam)const { - VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); - return m_UniformBuffers[Index]; + return Location == Sam.Location && + SamplerType == Sam.SamplerType && + GLResourceAttribs::IsCompatibleWith(Sam); } + // clang-format on - const SamplerInfo& GetSampler(Uint32 Index)const + size_t GetHash() const { - VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); - return m_Samplers[Index]; + return ComputeHash(Location, SamplerType, GLResourceAttribs::GetHash()); } - const ImageInfo& GetImage(Uint32 Index)const + const GLint Location; + const GLenum SamplerType; + }; + static_assert((sizeof(SamplerInfo) % sizeof(void*)) == 0, "sizeof(SamplerInfo) must be multiple of sizeof(void*)"); + + + struct ImageInfo final : GLResourceAttribs + { + // clang-format off + ImageInfo (const ImageInfo&) = delete; + ImageInfo& operator= (const ImageInfo&) = delete; + ImageInfo ( ImageInfo&&) = default; + ImageInfo& operator= ( ImageInfo&&) = delete; + + ImageInfo(const Char* _Name, + SHADER_TYPE _ShaderStages, + SHADER_RESOURCE_TYPE _ResourceType, + Uint32 _Binding, + Uint32 _ArraySize, + GLint _Location, + GLenum _ImageType)noexcept : + GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, + Location {_Location }, + ImageType {_ImageType} + {} + + ImageInfo(const ImageInfo& Img, + StringPool& NamesPool)noexcept : + GLResourceAttribs{Img, NamesPool}, + Location {Img.Location }, + ImageType {Img.ImageType} + {} + + bool IsCompatibleWith(const ImageInfo& Img)const { - VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); - return m_Images[Index]; + return Location == Img.Location && + ImageType == Img.ImageType && + GLResourceAttribs::IsCompatibleWith(Img); } + // clang-format on - const StorageBlockInfo& GetStorageBlock(Uint32 Index)const + size_t GetHash() const { - VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); - return m_StorageBlocks[Index]; + return ComputeHash(Location, ImageType, GLResourceAttribs::GetHash()); } - Uint32 GetVariableCount()const + const GLint Location; + const GLenum ImageType; + }; + static_assert((sizeof(ImageInfo) % sizeof(void*)) == 0, "sizeof(ImageInfo) must be multiple of sizeof(void*)"); + + + struct StorageBlockInfo final : GLResourceAttribs + { + // clang-format off + StorageBlockInfo (const StorageBlockInfo&) = delete; + StorageBlockInfo& operator= (const StorageBlockInfo&) = delete; + StorageBlockInfo ( StorageBlockInfo&&) = default; + StorageBlockInfo& operator= ( StorageBlockInfo&&) = delete; + + StorageBlockInfo(const Char* _Name, + SHADER_TYPE _ShaderStages, + SHADER_RESOURCE_TYPE _ResourceType, + Uint32 _Binding, + Uint32 _ArraySize, + GLint _SBIndex)noexcept : + GLResourceAttribs{_Name, _ShaderStages, _ResourceType, _Binding, _ArraySize}, + SBIndex {_SBIndex} + {} + + StorageBlockInfo(const StorageBlockInfo& SB, + StringPool& NamesPool)noexcept : + GLResourceAttribs{SB, NamesPool}, + SBIndex {SB.SBIndex} + {} + + bool IsCompatibleWith(const StorageBlockInfo& SB)const { - return m_NumUniformBuffers + m_NumSamplers + m_NumImages + m_NumStorageBlocks; + return SBIndex == SB.SBIndex && + GLResourceAttribs::IsCompatibleWith(SB); } + // clang-format on - ShaderResourceDesc GetResourceDesc(Uint32 Index)const; + size_t GetHash() const + { + return ComputeHash(SBIndex, GLResourceAttribs::GetHash()); + } - bool IsCompatibleWith(const GLProgramResources& Res)const; - size_t GetHash()const; + const GLint SBIndex; + }; + static_assert((sizeof(StorageBlockInfo) % sizeof(void*)) == 0, "sizeof(StorageBlockInfo) must be multiple of sizeof(void*)"); - SHADER_TYPE GetShaderStages() const {return m_ShaderStages;} - template<typename THandleUB, - typename THandleSampler, - typename THandleImg, - typename THandleSB> - void ProcessConstResources(THandleUB HandleUB, - THandleSampler HandleSampler, - THandleImg HandleImg, - THandleSB HandleSB, - const PipelineResourceLayoutDesc* pResourceLayout = nullptr, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr, - Uint32 NumAllowedTypes = 0)const - { - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - auto CheckResourceType = [&](const char* Name) - { - if (pResourceLayout == nullptr) - return true; - else - { - auto VarType = GetShaderVariableType(m_ShaderStages, Name, *pResourceLayout); - return IsAllowedType(VarType, AllowedTypeBits); - } - }; - - for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) - { - const auto& UB = GetUniformBuffer(ub); - if (CheckResourceType(UB.Name)) - HandleUB(UB); - } + // clang-format off + Uint32 GetNumUniformBuffers()const { return m_NumUniformBuffers; } + Uint32 GetNumSamplers() const { return m_NumSamplers; } + Uint32 GetNumImages() const { return m_NumImages; } + Uint32 GetNumStorageBlocks() const { return m_NumStorageBlocks; } + // clang-format on - for (Uint32 s=0; s < m_NumSamplers; ++s) - { - const auto& Sam = GetSampler(s); - if (CheckResourceType(Sam.Name)) - HandleSampler(Sam); - } + UniformBufferInfo& GetUniformBuffer(Uint32 Index) + { + VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); + return m_UniformBuffers[Index]; + } - for (Uint32 img=0; img < m_NumImages; ++img) - { - const auto& Img = GetImage(img); - if (CheckResourceType(Img.Name)) - HandleImg(Img); - } + SamplerInfo& GetSampler(Uint32 Index) + { + VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); + return m_Samplers[Index]; + } - for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) - { - const auto& SB = GetStorageBlock(sb); - if (CheckResourceType(SB.Name)) - HandleSB(SB); - } - } + ImageInfo& GetImage(Uint32 Index) + { + VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); + return m_Images[Index]; + } - template<typename THandleUB, - typename THandleSampler, - typename THandleImg, - typename THandleSB> - void ProcessResources(THandleUB HandleUB, - THandleSampler HandleSampler, - THandleImg HandleImg, - THandleSB HandleSB) - { - for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) - HandleUB(GetUniformBuffer(ub)); + StorageBlockInfo& GetStorageBlock(Uint32 Index) + { + VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); + return m_StorageBlocks[Index]; + } - for (Uint32 s=0; s < m_NumSamplers; ++s) - HandleSampler(GetSampler(s)); - for (Uint32 img=0; img < m_NumImages; ++img) - HandleImg(GetImage(img)); + const UniformBufferInfo& GetUniformBuffer(Uint32 Index) const + { + VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); + return m_UniformBuffers[Index]; + } - for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) - HandleSB(GetStorageBlock(sb)); - } + const SamplerInfo& GetSampler(Uint32 Index) const + { + VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); + return m_Samplers[Index]; + } + + const ImageInfo& GetImage(Uint32 Index) const + { + VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); + return m_Images[Index]; + } + + const StorageBlockInfo& GetStorageBlock(Uint32 Index) const + { + VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); + return m_StorageBlocks[Index]; + } + + Uint32 GetVariableCount() const + { + return m_NumUniformBuffers + m_NumSamplers + m_NumImages + m_NumStorageBlocks; + } + + ShaderResourceDesc GetResourceDesc(Uint32 Index) const; + + bool IsCompatibleWith(const GLProgramResources& Res) const; + size_t GetHash() const; + + SHADER_TYPE GetShaderStages() const { return m_ShaderStages; } + + template <typename THandleUB, + typename THandleSampler, + typename THandleImg, + typename THandleSB> + void ProcessConstResources(THandleUB HandleUB, + THandleSampler HandleSampler, + THandleImg HandleImg, + THandleSB HandleSB, + const PipelineResourceLayoutDesc* pResourceLayout = nullptr, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr, + Uint32 NumAllowedTypes = 0) const + { + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - struct ResourceCounters + auto CheckResourceType = [&](const char* Name) // { - Uint32 NumUBs = 0; - Uint32 NumSamplers = 0; - Uint32 NumImages = 0; - Uint32 NumStorageBlocks = 0; + if (pResourceLayout == nullptr) + return true; + else + { + auto VarType = GetShaderVariableType(m_ShaderStages, Name, *pResourceLayout); + return IsAllowedType(VarType, AllowedTypeBits); + } }; - void CountResources(const PipelineResourceLayoutDesc& ResourceLayout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ResourceCounters& Counters)const; - - private: - void AllocateResources(std::vector<UniformBufferInfo>& UniformBlocks, - std::vector<SamplerInfo>& Samplers, - std::vector<ImageInfo>& Images, - std::vector<StorageBlockInfo>& StorageBlocks); + for (Uint32 ub = 0; ub < m_NumUniformBuffers; ++ub) + { + const auto& UB = GetUniformBuffer(ub); + if (CheckResourceType(UB.Name)) + HandleUB(UB); + } + for (Uint32 s = 0; s < m_NumSamplers; ++s) + { + const auto& Sam = GetSampler(s); + if (CheckResourceType(Sam.Name)) + HandleSampler(Sam); + } - // There could be more than one stage if using non-separable programs - SHADER_TYPE m_ShaderStages = SHADER_TYPE_UNKNOWN; + for (Uint32 img = 0; img < m_NumImages; ++img) + { + const auto& Img = GetImage(img); + if (CheckResourceType(Img.Name)) + HandleImg(Img); + } - // Memory layout: - // - // | Uniform buffers | Samplers | Images | Storage Blocks | String Pool Data | - // + for (Uint32 sb = 0; sb < m_NumStorageBlocks; ++sb) + { + const auto& SB = GetStorageBlock(sb); + if (CheckResourceType(SB.Name)) + HandleSB(SB); + } + } + + template <typename THandleUB, + typename THandleSampler, + typename THandleImg, + typename THandleSB> + void ProcessResources(THandleUB HandleUB, + THandleSampler HandleSampler, + THandleImg HandleImg, + THandleSB HandleSB) + { + for (Uint32 ub = 0; ub < m_NumUniformBuffers; ++ub) + HandleUB(GetUniformBuffer(ub)); - UniformBufferInfo* m_UniformBuffers = nullptr; - SamplerInfo* m_Samplers = nullptr; - ImageInfo* m_Images = nullptr; - StorageBlockInfo* m_StorageBlocks = nullptr; + for (Uint32 s = 0; s < m_NumSamplers; ++s) + HandleSampler(GetSampler(s)); - StringPool m_StringPool; + for (Uint32 img = 0; img < m_NumImages; ++img) + HandleImg(GetImage(img)); - Uint32 m_NumUniformBuffers = 0; - Uint32 m_NumSamplers = 0; - Uint32 m_NumImages = 0; - Uint32 m_NumStorageBlocks = 0; + for (Uint32 sb = 0; sb < m_NumStorageBlocks; ++sb) + HandleSB(GetStorageBlock(sb)); + } - // When adding new member DO NOT FORGET TO UPDATE GLProgramResources( GLProgramResources&& ProgramResources )!!! + struct ResourceCounters + { + Uint32 NumUBs = 0; + Uint32 NumSamplers = 0; + Uint32 NumImages = 0; + Uint32 NumStorageBlocks = 0; }; -} + void CountResources(const PipelineResourceLayoutDesc& ResourceLayout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ResourceCounters& Counters) const; + + +private: + void AllocateResources(std::vector<UniformBufferInfo>& UniformBlocks, + std::vector<SamplerInfo>& Samplers, + std::vector<ImageInfo>& Images, + std::vector<StorageBlockInfo>& StorageBlocks); + + // clang-format off + // There could be more than one stage if using non-separable programs + SHADER_TYPE m_ShaderStages = SHADER_TYPE_UNKNOWN; + + // Memory layout: + // + // | Uniform buffers | Samplers | Images | Storage Blocks | String Pool Data | + // + + UniformBufferInfo* m_UniformBuffers = nullptr; + SamplerInfo* m_Samplers = nullptr; + ImageInfo* m_Images = nullptr; + StorageBlockInfo* m_StorageBlocks = nullptr; + + StringPool m_StringPool; + + Uint32 m_NumUniformBuffers = 0; + Uint32 m_NumSamplers = 0; + Uint32 m_NumImages = 0; + Uint32 m_NumStorageBlocks = 0; + // clang-format on + // When adding new member DO NOT FORGET TO UPDATE GLProgramResources( GLProgramResources&& ProgramResources )!!! +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/GLStubsAndroid.h b/Graphics/GraphicsEngineOpenGL/include/GLStubsAndroid.h index 7a5f5571..2a09d40c 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLStubsAndroid.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLStubsAndroid.h @@ -25,6 +25,8 @@ #include "Errors.h" +// clang-format off + // Define unsupported formats for OpenGL ES #ifndef GL_RGBA16 # define GL_RGBA16 0x805B diff --git a/Graphics/GraphicsEngineOpenGL/include/GLStubsIOS.h b/Graphics/GraphicsEngineOpenGL/include/GLStubsIOS.h index 22f1fd8d..355c3135 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLStubsIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLStubsIOS.h @@ -25,18 +25,18 @@ #include "Errors.h" -#define glUseProgramStages glUseProgramStagesEXT -#define glActiveShaderProgram glActiveShaderProgramEXT -#define glCreateShaderProgramv glCreateShaderProgramvEXT -#define glBindProgramPipeline glBindProgramPipelineEXT -#define glDeleteProgramPipelines glDeleteProgramPipelinesEXT -#define glGenProgramPipelines glGenProgramPipelinesEXT -#define glIsProgramPipeline glIsProgramPipelineEXT -#define glProgramParameteri glProgramParameteriEXT -#define glGetProgramPipelineiv glGetProgramPipelineivEXT -#define glValidateProgramPipeline glValidateProgramPipelineEXT +#define glUseProgramStages glUseProgramStagesEXT +#define glActiveShaderProgram glActiveShaderProgramEXT +#define glCreateShaderProgramv glCreateShaderProgramvEXT +#define glBindProgramPipeline glBindProgramPipelineEXT +#define glDeleteProgramPipelines glDeleteProgramPipelinesEXT +#define glGenProgramPipelines glGenProgramPipelinesEXT +#define glIsProgramPipeline glIsProgramPipelineEXT +#define glProgramParameteri glProgramParameteriEXT +#define glGetProgramPipelineiv glGetProgramPipelineivEXT +#define glValidateProgramPipeline glValidateProgramPipelineEXT #define glGetProgramPipelineInfoLog glGetProgramPipelineInfoLogEXT -#define glProgramUniform1i glProgramUniform1iEXT +#define glProgramUniform1i glProgramUniform1iEXT #define GL_VERTEX_SHADER_BIT GL_VERTEX_SHADER_BIT_EXT #define GL_FRAGMENT_SHADER_BIT GL_FRAGMENT_SHADER_BIT_EXT @@ -45,14 +45,14 @@ #define GL_ACTIVE_PROGRAM GL_ACTIVE_PROGRAM_EXT #define GL_PROGRAM_PIPELINE_BINDING GL_PROGRAM_PIPELINE_BINDING_EXT -#define GL_ARB_shader_image_load_store 0 +#define GL_ARB_shader_image_load_store 0 #define GL_ARB_shader_storage_buffer_object 0 -#define GL_ARB_tessellation_shader 0 -#define GL_ARB_draw_indirect 0 -#define GL_ARB_compute_shader 0 -#define GL_ARB_program_interface_query 0 -#define GL_ARB_internalformat_query2 0 -#define GL_ARB_texture_storage_multisample 0 +#define GL_ARB_tessellation_shader 0 +#define GL_ARB_draw_indirect 0 +#define GL_ARB_compute_shader 0 +#define GL_ARB_program_interface_query 0 +#define GL_ARB_internalformat_query2 0 +#define GL_ARB_texture_storage_multisample 0 #ifndef GL_CLAMP_TO_BORDER # define GL_CLAMP_TO_BORDER GL_CLAMP_TO_EDGE @@ -77,353 +77,353 @@ #define glTexBuffer(...) 0 #ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER -# define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +# define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB #endif #ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER -# define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +# define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #endif #ifndef GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS -# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 #endif #ifndef GL_DRAW_INDIRECT_BUFFER -# define GL_DRAW_INDIRECT_BUFFER 0 +# define GL_DRAW_INDIRECT_BUFFER 0 #endif #ifndef GL_GEOMETRY_SHADER -# define GL_GEOMETRY_SHADER 0 +# define GL_GEOMETRY_SHADER 0 #endif #ifndef GL_TESS_CONTROL_SHADER -# define GL_TESS_CONTROL_SHADER 0 +# define GL_TESS_CONTROL_SHADER 0 #endif #ifndef GL_TESS_EVALUATION_SHADER -# define GL_TESS_EVALUATION_SHADER 0 +# define GL_TESS_EVALUATION_SHADER 0 #endif #ifndef GL_COMPUTE_SHADER -# define GL_COMPUTE_SHADER 0 +# define GL_COMPUTE_SHADER 0 #endif #ifndef GL_GEOMETRY_SHADER_BIT -# define GL_GEOMETRY_SHADER_BIT 0 +# define GL_GEOMETRY_SHADER_BIT 0 #endif #ifndef GL_TESS_CONTROL_SHADER_BIT -# define GL_TESS_CONTROL_SHADER_BIT 0 +# define GL_TESS_CONTROL_SHADER_BIT 0 #endif #ifndef GL_TESS_EVALUATION_SHADER_BIT -# define GL_TESS_EVALUATION_SHADER_BIT 0 +# define GL_TESS_EVALUATION_SHADER_BIT 0 #endif #ifndef GL_COMPUTE_SHADER_BIT -# define GL_COMPUTE_SHADER_BIT 0 +# define GL_COMPUTE_SHADER_BIT 0 #endif #ifndef GL_SAMPLER_BUFFER -# define GL_SAMPLER_BUFFER 0x8DC2 +# define GL_SAMPLER_BUFFER 0x8DC2 #endif #ifndef GL_INT_SAMPLER_BUFFER -# define GL_INT_SAMPLER_BUFFER 0x8DD0 +# define GL_INT_SAMPLER_BUFFER 0x8DD0 #endif #ifndef GL_UNSIGNED_INT_SAMPLER_BUFFER -# define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +# define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #endif // Polygon mode #ifndef GL_POINT -# define GL_POINT 0x1B00 +# define GL_POINT 0x1B00 #endif #ifndef GL_LINE -# define GL_LINE 0x1B01 +# define GL_LINE 0x1B01 #endif #ifndef GL_FILL -# define GL_FILL 0x1B02 +# define GL_FILL 0x1B02 #endif #ifndef GL_DEPTH_CLAMP -# define GL_DEPTH_CLAMP 0 +# define GL_DEPTH_CLAMP 0 #endif // Define unsupported formats for OpenGL ES #ifndef GL_RGBA16 -# define GL_RGBA16 0x805B +# define GL_RGBA16 0x805B #endif #ifndef GL_RGBA16_SNORM -# define GL_RGBA16_SNORM 0x8F9B +# define GL_RGBA16_SNORM 0x8F9B #endif #ifndef GL_RG16 -# define GL_RG16 0x822C +# define GL_RG16 0x822C #endif #ifndef GL_RG16_SNORM -# define GL_RG16_SNORM 0x8F99 +# define GL_RG16_SNORM 0x8F99 #endif #ifndef GL_R16 -# define GL_R16 0x822A +# define GL_R16 0x822A #endif #ifndef GL_R16_SNORM -# define GL_R16_SNORM 0x8F98 +# define GL_R16_SNORM 0x8F98 #endif #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT -# define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +# define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #endif #ifndef GL_COMPRESSED_SRGB_S3TC_DXT1_EXT -# define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +# define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C #endif #ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT -# define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +# define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #endif #ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT -# define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +# define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E #endif #ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT -# define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +# define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT -# define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +# define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F #endif #ifndef GL_COMPRESSED_RED_RGTC1 -# define GL_COMPRESSED_RED_RGTC1 0x8DBB +# define GL_COMPRESSED_RED_RGTC1 0x8DBB #endif #ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 -# define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +# define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #endif #ifndef GL_COMPRESSED_RG_RGTC2 -# define GL_COMPRESSED_RG_RGTC2 0x8DBD +# define GL_COMPRESSED_RG_RGTC2 0x8DBD #endif #ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 -# define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +# define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #endif #ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT -# define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +# define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F #endif #ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT -# define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +# define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E #endif #ifndef GL_COMPRESSED_RGBA_BPTC_UNORM -# define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +# define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C #endif #ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM -# define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +# define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D #endif #ifndef GL_UNSIGNED_SHORT_5_6_5_REV -# define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +# define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #endif #ifndef GL_UNSIGNED_INT_10_10_10_2 -# define GL_UNSIGNED_INT_10_10_10_2 0x8036 +# define GL_UNSIGNED_INT_10_10_10_2 0x8036 #endif #ifndef GL_UNSIGNED_SHORT_5_6_5_REV -# define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +# define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #endif #ifndef GL_UNSIGNED_SHORT_1_5_5_5_REV -# define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +# define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #endif // Define unsupported uniform data types #ifndef GL_SAMPLER_1D -# define GL_SAMPLER_1D 0x8B5D +# define GL_SAMPLER_1D 0x8B5D #endif #ifndef GL_SAMPLER_1D_SHADOW -# define GL_SAMPLER_1D_SHADOW 0x8B61 +# define GL_SAMPLER_1D_SHADOW 0x8B61 #endif #ifndef GL_SAMPLER_1D_ARRAY -# define GL_SAMPLER_1D_ARRAY 0x8DC0 +# define GL_SAMPLER_1D_ARRAY 0x8DC0 #endif #ifndef GL_SAMPLER_1D_ARRAY_SHADOW -# define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +# define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 #endif #ifndef GL_INT_SAMPLER_1D -# define GL_INT_SAMPLER_1D 0x8DC9 +# define GL_INT_SAMPLER_1D 0x8DC9 #endif #ifndef GL_INT_SAMPLER_1D_ARRAY -# define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +# define GL_INT_SAMPLER_1D_ARRAY 0x8DCE #endif #ifndef GL_UNSIGNED_INT_SAMPLER_1D -# define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +# define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 #endif #ifndef GL_UNSIGNED_INT_SAMPLER_1D_ARRAY -# define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +# define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 #endif #ifndef GL_SAMPLER_CUBE_MAP_ARRAY -# define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +# define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C #endif #ifndef GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW -# define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +# define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D #endif #ifndef GL_INT_SAMPLER_CUBE_MAP_ARRAY -# define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +# define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E #endif #ifndef GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY -# define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +# define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F #endif #ifndef GL_SAMPLER_BUFFER -# define GL_SAMPLER_BUFFER 0x8DC2 +# define GL_SAMPLER_BUFFER 0x8DC2 #endif #ifndef GL_INT_SAMPLER_BUFFER -# define GL_INT_SAMPLER_BUFFER 0x8DD0 +# define GL_INT_SAMPLER_BUFFER 0x8DD0 #endif #ifndef GL_UNSIGNED_INT_SAMPLER_BUFFER -# define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +# define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #endif #ifndef GL_SAMPLER_2D_MULTISAMPLE -# define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +# define GL_SAMPLER_2D_MULTISAMPLE 0x9108 #endif #ifndef GL_INT_SAMPLER_2D_MULTISAMPLE -# define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +# define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 #endif #ifndef GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE -# define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +# define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A #endif #ifndef GL_SAMPLER_2D_MULTISAMPLE_ARRAY -# define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +# define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B #endif #ifndef GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY -# define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +# define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C #endif #ifndef GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY -# define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +# define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D #endif // Blend functions #ifndef GL_SRC1_COLOR -# define GL_SRC1_COLOR 0x88F9 +# define GL_SRC1_COLOR 0x88F9 #endif #ifndef GL_ONE_MINUS_SRC1_COLOR -# define GL_ONE_MINUS_SRC1_COLOR 0x88FA +# define GL_ONE_MINUS_SRC1_COLOR 0x88FA #endif #ifndef GL_SOURCE1_ALPHA -# define GL_SOURCE1_ALPHA 0x8589 +# define GL_SOURCE1_ALPHA 0x8589 #endif #ifndef GL_SRC1_ALPHA -# define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +# define GL_SRC1_ALPHA GL_SOURCE1_ALPHA #endif #ifndef GL_ONE_MINUS_SRC1_ALPHA -# define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +# define GL_ONE_MINUS_SRC1_ALPHA 0x88FB #endif #ifndef GL_READ_ONLY -# define GL_READ_ONLY 0x88B8 +# define GL_READ_ONLY 0x88B8 #endif #ifndef GL_WRITE_ONLY -# define GL_WRITE_ONLY 0x88B9 +# define GL_WRITE_ONLY 0x88B9 #endif #ifndef GL_READ_WRITE -# define GL_READ_WRITE 0x88BA +# define GL_READ_WRITE 0x88BA #endif // Define unsupported sampler attributes #ifndef GL_TEXTURE_LOD_BIAS -# define GL_TEXTURE_LOD_BIAS 0 +# define GL_TEXTURE_LOD_BIAS 0 #endif #ifndef GL_TEXTURE_BORDER_COLOR -# define GL_TEXTURE_BORDER_COLOR 0 +# define GL_TEXTURE_BORDER_COLOR 0 #endif #ifndef GL_TEXTURE_1D -# define GL_TEXTURE_1D 0x0DE0 +# define GL_TEXTURE_1D 0x0DE0 #endif #ifndef GL_TEXTURE_1D_ARRAY -# define GL_TEXTURE_1D_ARRAY 0x8C18 +# define GL_TEXTURE_1D_ARRAY 0x8C18 #endif #ifndef GL_TEXTURE_BINDING_1D_ARRAY -# define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +# define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C #endif #ifndef GL_TEXTURE_BINDING_1D -# define GL_TEXTURE_BINDING_1D 0x8068 +# define GL_TEXTURE_BINDING_1D 0x8068 #endif #ifndef GL_TEXTURE_2D_MULTISAMPLE -# define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +# define GL_TEXTURE_2D_MULTISAMPLE 0x9100 #endif #ifndef GL_TEXTURE_BINDING_2D_MULTISAMPLE -# define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +# define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 #endif #ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY -# define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +# define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 #endif #ifndef GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY -# define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +# define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #endif #ifndef GL_TEXTURE_CUBE_MAP_ARRAY -# define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +# define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 #endif #ifndef GL_TEXTURE_BINDING_CUBE_MAP_ARRAY -# define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +# define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A #endif //#ifndef GL_TEXTURE_BUFFER @@ -432,103 +432,100 @@ #ifndef GL_TEXTURE_WIDTH -# define GL_TEXTURE_WIDTH 0 +# define GL_TEXTURE_WIDTH 0 #endif #ifndef GL_TEXTURE_HEIGHT -# define GL_TEXTURE_HEIGHT 0 +# define GL_TEXTURE_HEIGHT 0 #endif #ifndef GL_TEXTURE_DEPTH -# define GL_TEXTURE_DEPTH 0 +# define GL_TEXTURE_DEPTH 0 #endif #ifndef GL_TEXTURE_INTERNAL_FORMAT -# define GL_TEXTURE_INTERNAL_FORMAT 0 +# define GL_TEXTURE_INTERNAL_FORMAT 0 #endif #ifndef GL_TEXTURE_INTERNAL_FORMAT -# define GL_TEXTURE_INTERNAL_FORMAT 0 +# define GL_TEXTURE_INTERNAL_FORMAT 0 #endif #ifndef GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT -# define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +# define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 #endif #ifndef GL_ELEMENT_ARRAY_BARRIER_BIT -# define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +# define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 #endif #ifndef GL_UNIFORM_BARRIER_BIT -# define GL_UNIFORM_BARRIER_BIT 0x00000004 +# define GL_UNIFORM_BARRIER_BIT 0x00000004 #endif #ifndef GL_TEXTURE_FETCH_BARRIER_BIT -# define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +# define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 #endif #ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT -# define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +# define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 #endif #ifndef GL_COMMAND_BARRIER_BIT -# define GL_COMMAND_BARRIER_BIT 0x00000040 +# define GL_COMMAND_BARRIER_BIT 0x00000040 #endif #ifndef GL_PIXEL_BUFFER_BARRIER_BIT -# define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +# define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 #endif #ifndef GL_TEXTURE_UPDATE_BARRIER_BIT -# define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +# define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 #endif #ifndef GL_BUFFER_UPDATE_BARRIER_BIT -# define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +# define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 #endif #ifndef GL_FRAMEBUFFER_BARRIER_BIT -# define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +# define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 #endif #ifndef GL_TRANSFORM_FEEDBACK_BARRIER_BIT -# define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +# define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 #endif #ifndef GL_ATOMIC_COUNTER_BARRIER_BIT -# define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +# define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 #endif #ifndef GL_SHADER_STORAGE_BARRIER_BIT -# define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +# define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 #endif #ifndef GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT -# define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +# define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 #endif #ifndef GL_QUERY_BUFFER_BARRIER_BIT -# define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +# define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 #endif #ifndef GL_ALL_BARRIER_BITS -# define GL_ALL_BARRIER_BITS 0xFFFFFFFF +# define GL_ALL_BARRIER_BITS 0xFFFFFFFF #endif // Define unsupported GL function stubs -template<typename T> -void UnsupportedGLFunctionStub( const T &Name ) +template <typename T> +void UnsupportedGLFunctionStub(const T& Name) { - LOG_ERROR_MESSAGE( Name, "() is not supported on iOS!\n" ); + LOG_ERROR_MESSAGE(Name, "() is not supported on iOS!\n"); } #define glDrawElementsInstancedBaseVertexBaseInstance(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseVertexBaseInstance") -#define glDrawElementsInstancedBaseVertex(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseVertex") -#define glDrawElementsInstancedBaseInstance(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseInstance") -#define glDrawArraysInstancedBaseInstance(...) UnsupportedGLFunctionStub("glDrawArraysInstancedBaseInstance") -#define glDrawElementsBaseVertex(...) UnsupportedGLFunctionStub("glDrawElementsBaseVertex") -#define glTextureView(...) UnsupportedGLFunctionStub("glTextureView") -#define glTexStorage1D(...) UnsupportedGLFunctionStub("glTexStorage1D") -#define glTexSubImage1D(...) UnsupportedGLFunctionStub("glTexSubImage1D") -#define glTexStorage3DMultisample(...) UnsupportedGLFunctionStub("glTexStorage3DMultisample") -#define glViewportIndexedf(...) UnsupportedGLFunctionStub("glViewportIndexedf") -#define glScissorIndexed(...) UnsupportedGLFunctionStub("glScissorIndexed") -static void (*glPolygonMode) (GLenum face, GLenum mode) = nullptr; -#define glEnablei(...) UnsupportedGLFunctionStub("glEnablei") -#define glBlendFuncSeparatei(...) UnsupportedGLFunctionStub("glBlendFuncSeparatei") +#define glDrawElementsInstancedBaseVertex(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseVertex") +#define glDrawElementsInstancedBaseInstance(...) UnsupportedGLFunctionStub("glDrawElementsInstancedBaseInstance") +#define glDrawArraysInstancedBaseInstance(...) UnsupportedGLFunctionStub("glDrawArraysInstancedBaseInstance") +#define glDrawElementsBaseVertex(...) UnsupportedGLFunctionStub("glDrawElementsBaseVertex") +#define glTextureView(...) UnsupportedGLFunctionStub("glTextureView") +#define glTexStorage1D(...) UnsupportedGLFunctionStub("glTexStorage1D") +#define glTexSubImage1D(...) UnsupportedGLFunctionStub("glTexSubImage1D") +#define glTexStorage3DMultisample(...) UnsupportedGLFunctionStub("glTexStorage3DMultisample") +#define glViewportIndexedf(...) UnsupportedGLFunctionStub("glViewportIndexedf") +#define glScissorIndexed(...) UnsupportedGLFunctionStub("glScissorIndexed") +static void (*glPolygonMode)(GLenum face, GLenum mode) = nullptr; +#define glEnablei(...) UnsupportedGLFunctionStub("glEnablei") +#define glBlendFuncSeparatei(...) UnsupportedGLFunctionStub("glBlendFuncSeparatei") #define glBlendEquationSeparatei(...) UnsupportedGLFunctionStub("glBlendEquationSeparatei") -#define glDisablei(...) UnsupportedGLFunctionStub("glDisablei") -#define glColorMaski(...) UnsupportedGLFunctionStub("glColorMaski") -#define glFramebufferTexture(...) UnsupportedGLFunctionStub("glFramebufferTexture") -#define glFramebufferTexture1D(...) UnsupportedGLFunctionStub("glFramebufferTexture1D") - - - +#define glDisablei(...) UnsupportedGLFunctionStub("glDisablei") +#define glColorMaski(...) UnsupportedGLFunctionStub("glColorMaski") +#define glFramebufferTexture(...) UnsupportedGLFunctionStub("glFramebufferTexture") +#define glFramebufferTexture1D(...) UnsupportedGLFunctionStub("glFramebufferTexture1D") diff --git a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h index e3ba9ea5..60525d6e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h @@ -26,7 +26,8 @@ namespace Diligent { -static const GLenum PrimTopologyToGLTopologyMap[] = +// clang-format off +static const GLenum PrimTopologyToGLTopologyMap[] = { 0, //PRIMITIVE_TOPOLOGY_UNDEFINED = 0 GL_TRIANGLES, //PRIMITIVE_TOPOLOGY_TRIANGLE_LIST @@ -34,25 +35,29 @@ static const GLenum PrimTopologyToGLTopologyMap[] = GL_POINTS, //PRIMITIVE_TOPOLOGY_POINT_LIST GL_LINES //PRIMITIVE_TOPOLOGY_LINE_LIST }; +// clang-format on inline GLenum PrimitiveTopologyToGLTopology(PRIMITIVE_TOPOLOGY PrimTopology) { VERIFY_EXPR(PrimTopology < _countof(PrimTopologyToGLTopologyMap)); auto GLTopology = PrimTopologyToGLTopologyMap[PrimTopology]; #ifdef _DEBUG - switch(PrimTopology) + switch (PrimTopology) { + // clang-format off case PRIMITIVE_TOPOLOGY_UNDEFINED: VERIFY_EXPR(GLTopology == 0); break; case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: VERIFY_EXPR(GLTopology == GL_TRIANGLES); break; case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: VERIFY_EXPR(GLTopology == GL_TRIANGLE_STRIP); break; case PRIMITIVE_TOPOLOGY_POINT_LIST: VERIFY_EXPR(GLTopology == GL_POINTS); break; case PRIMITIVE_TOPOLOGY_LINE_LIST: VERIFY_EXPR(GLTopology == GL_LINES); break; default: UNEXPECTED("Unexpected primitive topology"); + // clang-format on } #endif return GLTopology; } +// clang-format off static const GLenum TypeToGLTypeMap[] = { 0, //VT_UNDEFINED = 0 @@ -65,14 +70,16 @@ static const GLenum TypeToGLTypeMap[] = 0, //VT_FLOAT16 GL_FLOAT //VT_FLOAT32 }; +// clang-format on inline GLenum TypeToGLType(VALUE_TYPE Value) { VERIFY_EXPR(Value < _countof(TypeToGLTypeMap)); auto GLType = TypeToGLTypeMap[Value]; #ifdef _DEBUG - switch(Value) + switch (Value) { + // clang-format off case VT_INT8: VERIFY_EXPR(GLType == GL_BYTE); break; case VT_INT16: VERIFY_EXPR(GLType == GL_SHORT); break; case VT_INT32: VERIFY_EXPR(GLType == GL_INT); break; @@ -81,6 +88,7 @@ inline GLenum TypeToGLType(VALUE_TYPE Value) case VT_UINT32: VERIFY_EXPR(GLType == GL_UNSIGNED_INT); break; case VT_FLOAT32: VERIFY_EXPR(GLType == GL_FLOAT); break; default: UNEXPECTED("Unexpected value type"); + // clang-format on } #endif return GLType; @@ -90,84 +98,87 @@ inline GLenum UsageToGLUsage(USAGE Usage) { // http://www.informit.com/articles/article.aspx?p=2033340&seqNum=2 // https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBufferData.xml - switch(Usage) + switch (Usage) { // STATIC: The data store contents will be modified once and used many times. // STREAM: The data store contents will be modified once and used at MOST a few times. // DYNAMIC: The data store contents will be modified repeatedly and used many times. + // clang-format off case USAGE_STATIC: return GL_STATIC_DRAW; case USAGE_DEFAULT: return GL_STATIC_DRAW; case USAGE_DYNAMIC: return GL_DYNAMIC_DRAW; case USAGE_STAGING: return GL_DYNAMIC_READ; default: UNEXPECTED( "Unknow usage" ); return 0; + // clang-format on } } -inline void FilterTypeToGLFilterType(FILTER_TYPE Filter, GLenum &GLFilter, Bool &bIsAnisotropic, Bool &bIsComparison) +inline void FilterTypeToGLFilterType(FILTER_TYPE Filter, GLenum& GLFilter, Bool& bIsAnisotropic, Bool& bIsComparison) { - switch(Filter) + switch (Filter) { case FILTER_TYPE_UNKNOWN: - UNEXPECTED( "Unspecified filter type" ); + UNEXPECTED("Unspecified filter type"); bIsAnisotropic = false; - bIsComparison = false; - GLFilter = GL_NEAREST; + bIsComparison = false; + GLFilter = GL_NEAREST; break; case FILTER_TYPE_POINT: bIsAnisotropic = false; - bIsComparison = false; - GLFilter = GL_NEAREST; + bIsComparison = false; + GLFilter = GL_NEAREST; break; case FILTER_TYPE_LINEAR: bIsAnisotropic = false; - bIsComparison = false; - GLFilter = GL_LINEAR; + bIsComparison = false; + GLFilter = GL_LINEAR; break; - case FILTER_TYPE_ANISOTROPIC: + case FILTER_TYPE_ANISOTROPIC: bIsAnisotropic = true; - bIsComparison = false; - GLFilter = GL_LINEAR; + bIsComparison = false; + GLFilter = GL_LINEAR; break; case FILTER_TYPE_COMPARISON_POINT: bIsAnisotropic = false; - bIsComparison = true; - GLFilter = GL_NEAREST; + bIsComparison = true; + GLFilter = GL_NEAREST; break; case FILTER_TYPE_COMPARISON_LINEAR: bIsAnisotropic = false; - bIsComparison = true; - GLFilter = GL_LINEAR; + bIsComparison = true; + GLFilter = GL_LINEAR; break; case FILTER_TYPE_COMPARISON_ANISOTROPIC: bIsAnisotropic = true; - bIsComparison = true; - GLFilter = GL_LINEAR; + bIsComparison = true; + GLFilter = GL_LINEAR; break; default: + UNEXPECTED("Unknown filter type"); bIsAnisotropic = false; - bIsComparison = false; - UNEXPECTED( "Unknown filter type" ); - GLFilter = GL_NEAREST; + bIsComparison = false; + GLFilter = GL_NEAREST; break; } } -GLenum TexFormatToGLInternalTexFormat(TEXTURE_FORMAT TexFormat, Uint32 BindFlags = 0); +GLenum TexFormatToGLInternalTexFormat(TEXTURE_FORMAT TexFormat, Uint32 BindFlags = 0); TEXTURE_FORMAT GLInternalTexFormatToTexFormat(GLenum GlFormat); -GLenum CorrectGLTexFormat(GLenum GLTexFormat, Uint32 BindFlags); +GLenum CorrectGLTexFormat(GLenum GLTexFormat, Uint32 BindFlags); inline GLenum TexAddressModeToGLAddressMode(TEXTURE_ADDRESS_MODE Mode) { - switch(Mode) + switch (Mode) { + // clang-format off case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED( "Texture address mode is not specified" ); return GL_CLAMP_TO_EDGE; case TEXTURE_ADDRESS_WRAP: return GL_REPEAT; case TEXTURE_ADDRESS_MIRROR: return GL_MIRRORED_REPEAT; @@ -180,13 +191,15 @@ inline GLenum TexAddressModeToGLAddressMode(TEXTURE_ADDRESS_MODE Mode) // GL_CLAMP_TO_EDGE except that it takes the absolute value of the texture // coordinates before clamping. default: UNEXPECTED( "Unknown texture address mode" ); return GL_CLAMP_TO_EDGE; + // clang-format on } } inline GLenum CompareFuncToGLCompareFunc(COMPARISON_FUNCTION Func) { - switch(Func) + switch (Func) { + // clang-format off case COMPARISON_FUNC_UNKNOWN: UNEXPECTED( "Comparison function is not specified" ); return GL_ALWAYS; case COMPARISON_FUNC_NEVER: return GL_NEVER; case COMPARISON_FUNC_LESS: return GL_LESS; @@ -197,24 +210,28 @@ inline GLenum CompareFuncToGLCompareFunc(COMPARISON_FUNCTION Func) case COMPARISON_FUNC_GREATER_EQUAL: return GL_GEQUAL; case COMPARISON_FUNC_ALWAYS: return GL_ALWAYS; default: UNEXPECTED( "Unknown comparison func" ); return GL_ALWAYS; + // clang-format on } } struct NativePixelAttribs { - GLenum PixelFormat; - GLenum DataType; - Bool IsCompressed; - explicit NativePixelAttribs(GLenum _PixelFormat = 0, GLenum _DataType = 0, Bool _IsCompressed = False) : - PixelFormat(_PixelFormat), - DataType(_DataType), - IsCompressed(_IsCompressed) + GLenum PixelFormat = 0; + GLenum DataType = 0; + Bool IsCompressed = 0; + + NativePixelAttribs() noexcept {} + + explicit NativePixelAttribs(GLenum _PixelFormat, GLenum _DataType, Bool _IsCompressed = False) noexcept : + PixelFormat{_PixelFormat}, + DataType{_DataType}, + IsCompressed{_IsCompressed} {} }; inline Uint32 GetNumPixelFormatComponents(GLenum Format) { - switch(Format) + switch (Format) { case GL_RGBA: case GL_RGBA_INTEGER: @@ -234,14 +251,15 @@ inline Uint32 GetNumPixelFormatComponents(GLenum Format) case GL_DEPTH_STENCIL: return 1; - default: UNEXPECTED( "Unknonw pixel format" ); return 0; + default: UNEXPECTED("Unknonw pixel format"); return 0; }; } inline Uint32 GetPixelTypeSize(GLenum Type) { - switch(Type) + switch (Type) { + // clang-format off case GL_FLOAT: return sizeof(GLfloat); case GL_UNSIGNED_INT_10_10_10_2: @@ -267,14 +285,15 @@ inline Uint32 GetPixelTypeSize(GLenum Type) case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:return sizeof(GLfloat) + sizeof(GLuint); default: UNEXPECTED( "Unknonw pixel type" ); return 0; + // clang-format on } } NativePixelAttribs GetNativePixelTransferAttribs(TEXTURE_FORMAT TexFormat); -GLenum AccessFlags2GLAccess( Uint32 UAVAccessFlags ); -GLenum TypeToGLTexFormat( VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized ); -GLenum StencilOp2GlStencilOp( STENCIL_OP StencilOp ); -GLenum BlendFactor2GLBlend( BLEND_FACTOR bf ); -GLenum BlendOperation2GLBlendOp( BLEND_OPERATION BlendOp ); +GLenum AccessFlags2GLAccess(Uint32 UAVAccessFlags); +GLenum TypeToGLTexFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized); +GLenum StencilOp2GlStencilOp(STENCIL_OP StencilOp); +GLenum BlendFactor2GLBlend(BLEND_FACTOR bf); +GLenum BlendOperation2GLBlendOp(BLEND_OPERATION BlendOp); -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h index 8cf7c8e0..cea2ceeb 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h @@ -50,13 +50,13 @@ public: const PipelineStateDesc& PipelineDesc, bool IsDeviceInternal = false); ~PipelineStateGLImpl(); - + /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; /// Implementation of IPipelineState::BindStaticResources() in OpenGL backend. - virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags)override final; - + virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final; + /// Implementation of IPipelineState::GetStaticVariableCount() in OpenGL backend. virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; @@ -67,22 +67,23 @@ public: virtual IShaderResourceVariable* GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; /// Implementation of IPipelineState::CreateShaderResourceBinding() in OpenGL backend. - virtual void CreateShaderResourceBinding( IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources )override final; + virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) override final; /// Implementation of IPipelineState::IsCompatibleWith() in OpenGL backend. - virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final; + virtual bool IsCompatibleWith(const IPipelineState* pPSO) const override final; void CommitProgram(GLContextState& State); - - void InitializeSRBResourceCache(GLProgramResourceCache& ResourceCache)const; - const GLPipelineResourceLayout& GetResourceLayout()const {return m_ResourceLayout;} - const GLPipelineResourceLayout& GetStaticResourceLayout()const {return m_StaticResourceLayout;} - const GLProgramResourceCache& GetStaticResourceCache()const {return m_StaticResourceCache;} + void InitializeSRBResourceCache(GLProgramResourceCache& ResourceCache) const; + + const GLPipelineResourceLayout& GetResourceLayout() const { return m_ResourceLayout; } + const GLPipelineResourceLayout& GetStaticResourceLayout() const { return m_StaticResourceLayout; } + const GLProgramResourceCache& GetStaticResourceCache() const { return m_StaticResourceCache; } private: GLObjectWrappers::GLPipelineObj& GetGLProgramPipeline(GLContext::NativeGLContextType Context); - void InitStaticSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache)const; + + void InitStaticSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache) const; // Linked GL programs for every shader stage. Every pipeline needs to have its own programs // because resource bindings assigned by GLProgramResources::LoadUniforms depend on other @@ -90,7 +91,8 @@ private: std::vector<GLObjectWrappers::GLProgramObj> m_GLPrograms; ThreadingTools::LockFlag m_ProgPipelineLockFlag; - std::vector< std::pair<GLContext::NativeGLContextType, GLObjectWrappers::GLPipelineObj > > m_GLProgPipelines; + + std::vector<std::pair<GLContext::NativeGLContextType, GLObjectWrappers::GLPipelineObj>> m_GLProgPipelines; // Resource layout that keeps variables of all types, but does not reference a // resource cache. @@ -101,17 +103,17 @@ private: // Resource layout that only keeps static variables GLPipelineResourceLayout m_StaticResourceLayout; // Resource cache for static resource variables only - GLProgramResourceCache m_StaticResourceCache; + GLProgramResourceCache m_StaticResourceCache; // Program resources for all shader stages in the pipeline std::vector<GLProgramResources> m_ProgramResources; - Uint32 m_TotalUniformBufferBindings = 0; - Uint32 m_TotalSamplerBindings = 0; - Uint32 m_TotalImageBindings = 0; - Uint32 m_TotalStorageBufferBindings = 0; + Uint32 m_TotalUniformBufferBindings = 0; + Uint32 m_TotalSamplerBindings = 0; + Uint32 m_TotalImageBindings = 0; + Uint32 m_TotalStorageBufferBindings = 0; std::vector<RefCntAutoPtr<ISampler>> m_StaticSamplers; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h index c8e23561..7971b979 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h @@ -31,19 +31,19 @@ namespace Diligent class RenderDeviceGLESImpl final : public RenderDeviceGLImpl { public: - RenderDeviceGLESImpl( IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - const EngineGLCreateInfo& InitAttribs, - const SwapChainDesc* pSCDesc = nullptr); - - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface ); + RenderDeviceGLESImpl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc* pSCDesc = nullptr); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface); virtual bool Invalidate(); virtual void Suspend(); - virtual EGLint Resume( ANativeWindow* window ); + virtual EGLint Resume(ANativeWindow* window); }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h index c9c232f8..d7d94679 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h @@ -33,7 +33,7 @@ enum class GPU_VENDOR { - UNKNOWN, + UNKNOWN, INTEL, ATI, NVIDIA, @@ -61,56 +61,56 @@ public: const EngineGLCreateInfo& InitAttribs, const SwapChainDesc* pSCDesc = nullptr); ~RenderDeviceGLImpl(); - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override; - + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; + /// Implementation of IRenderDevice::CreateBuffer() in OpenGL backend. - void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBufferLayout, bool bIsDeviceInternal); - virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* BuffData, IBuffer** ppBufferLayout)override final; + void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBufferLayout, bool bIsDeviceInternal); + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* BuffData, IBuffer** ppBufferLayout) override final; /// Implementation of IRenderDevice::CreateShader() in OpenGL backend. - void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader **ppShader, bool bIsDeviceInternal ); - virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader **ppShader)override final; + void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader, bool bIsDeviceInternal); + virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader) override final; /// Implementation of IRenderDevice::CreateTexture() in OpenGL backend. - void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture, bool bIsDeviceInternal); - virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* Data, ITexture** ppTexture)override final; - + void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture, bool bIsDeviceInternal); + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* Data, ITexture** ppTexture) override final; + /// Implementation of IRenderDevice::CreateSampler() in OpenGL backend. - void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler, bool bIsDeviceInternal); - virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler)override final; + void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler, bool bIsDeviceInternal); + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler) override final; /// Implementation of IRenderDevice::CreatePipelineState() in OpenGL backend. - void CreatePipelineState( const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState, bool bIsDeviceInternal); - virtual void CreatePipelineState( const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState )override final; - + void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState, bool bIsDeviceInternal); + virtual void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState) override final; + /// Implementation of IRenderDevice::CreateFence() in OpenGL backend. - virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence)override final; + virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence) override final; /// Implementation of IRenderDeviceGL::CreateTextureFromGLHandle(). - virtual void CreateTextureFromGLHandle(Uint32 GLHandle, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture)override final; + virtual void CreateTextureFromGLHandle(Uint32 GLHandle, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture) override final; /// Implementation of IRenderDeviceGL::CreateBufferFromGLHandle(). - virtual void CreateBufferFromGLHandle(Uint32 GLHandle, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer)override final; + virtual void CreateBufferFromGLHandle(Uint32 GLHandle, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; /// Implementation of IRenderDevice::ReleaseStaleResources() in OpenGL backend. - virtual void ReleaseStaleResources(bool ForceRelease = false)override final {} + virtual void ReleaseStaleResources(bool ForceRelease = false) override final {} /// Implementation of IRenderDevice::IdleGPU() in OpenGL backend. - virtual void IdleGPU()override final; + virtual void IdleGPU() override final; - const GPUInfo& GetGPUInfo(){ return m_GPUInfo; } + const GPUInfo& GetGPUInfo() { return m_GPUInfo; } FBOCache& GetFBOCache(GLContext::NativeGLContextType Context); - void OnReleaseTexture(ITexture* pTexture); + void OnReleaseTexture(ITexture* pTexture); VAOCache& GetVAOCache(GLContext::NativeGLContextType Context); - void OnDestroyPSO(IPipelineState* pPSO); - void OnDestroyBuffer(IBuffer* pBuffer); + void OnDestroyPSO(IPipelineState* pPSO); + void OnDestroyBuffer(IBuffer* pBuffer); void CreateDummyTexture(const TextureDesc& TexDesc, RESOURCE_STATE InitialState, class TextureBaseGL** ppTexture); - size_t GetCommandQueueCount()const { return 1; } - Uint64 GetCommandQueueMask()const { return Uint64{1};} + size_t GetCommandQueueCount() const { return 1; } + Uint64 GetCommandQueueMask() const { return Uint64{1}; } void InitTexRegionRender(); @@ -125,25 +125,25 @@ protected: friend class GLContextState; // Must be the first member because its constructor initializes OpenGL - GLContext m_GLContext; + GLContext m_GLContext; std::unordered_set<String> m_ExtensionStrings; - ThreadingTools::LockFlag m_VAOCacheLockFlag; + ThreadingTools::LockFlag m_VAOCacheLockFlag; std::unordered_map<GLContext::NativeGLContextType, VAOCache> m_VAOCache; - ThreadingTools::LockFlag m_FBOCacheLockFlag; + ThreadingTools::LockFlag m_FBOCacheLockFlag; std::unordered_map<GLContext::NativeGLContextType, FBOCache> m_FBOCache; GPUInfo m_GPUInfo; std::unique_ptr<TexRegionRender> m_pTexRegionRender; - + private: - virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final; - bool CheckExtension(const Char* ExtensionString); - void FlagSupportedTexFormats(); - void QueryDeviceCaps(); + virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; + bool CheckExtension(const Char* ExtensionString); + void FlagSupportedTexFormats(); + void QueryDeviceCaps(); }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h index ad096bbf..9ac52082 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h @@ -41,15 +41,15 @@ class SamplerGLImpl final : public SamplerBase<ISamplerGL, RenderDeviceGLImpl> public: using TSamplerBase = SamplerBase<ISamplerGL, RenderDeviceGLImpl>; - SamplerGLImpl( IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal = false ); + SamplerGLImpl(IReferenceCounters* pRefCounters, RenderDeviceGLImpl* pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal = false); ~SamplerGLImpl(); - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - const GLObjectWrappers::GLSamplerObj& GetHandle(){ return m_GlSampler; } + const GLObjectWrappers::GLSamplerObj& GetHandle() { return m_GlSampler; } private: GLObjectWrappers::GLSamplerObj m_GlSampler; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h index 900ce86f..cc69a1e8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h @@ -38,8 +38,9 @@ class FixedBlockMemoryAllocator; inline GLenum GetGLShaderType(SHADER_TYPE ShaderType) { - switch(ShaderType) + switch (ShaderType) { + // clang-format off case SHADER_TYPE_VERTEX: return GL_VERTEX_SHADER; break; case SHADER_TYPE_PIXEL: return GL_FRAGMENT_SHADER; break; case SHADER_TYPE_GEOMETRY: return GL_GEOMETRY_SHADER; break; @@ -47,13 +48,15 @@ inline GLenum GetGLShaderType(SHADER_TYPE ShaderType) case SHADER_TYPE_DOMAIN: return GL_TESS_EVALUATION_SHADER; break; case SHADER_TYPE_COMPUTE: return GL_COMPUTE_SHADER; break; default: return 0; + // clang-format on } } inline GLenum ShaderTypeToGLShaderBit(SHADER_TYPE ShaderType) { - switch(ShaderType) + switch (ShaderType) { + // clang-format off case SHADER_TYPE_VERTEX: return GL_VERTEX_SHADER_BIT; break; case SHADER_TYPE_PIXEL: return GL_FRAGMENT_SHADER_BIT; break; case SHADER_TYPE_GEOMETRY: return GL_GEOMETRY_SHADER_BIT; break; @@ -61,6 +64,7 @@ inline GLenum ShaderTypeToGLShaderBit(SHADER_TYPE ShaderType) case SHADER_TYPE_DOMAIN: return GL_TESS_EVALUATION_SHADER_BIT; break; case SHADER_TYPE_COMPUTE: return GL_COMPUTE_SHADER_BIT; break; default: return 0; + // clang-format on } } @@ -70,19 +74,19 @@ class ShaderGLImpl final : public ShaderBase<IShaderGL, RenderDeviceGLImpl> public: using TShaderBase = ShaderBase<IShaderGL, RenderDeviceGLImpl>; - ShaderGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDeviceGL, - const ShaderCreateInfo& ShaderCreateInfo, - bool bIsDeviceInternal = false); + ShaderGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDeviceGL, + const ShaderCreateInfo& ShaderCreateInfo, + bool bIsDeviceInternal = false); ~ShaderGLImpl(); - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; /// Implementation of IShader::GetResourceCount() in OpenGL backend. - virtual Uint32 GetResourceCount()const override final; + virtual Uint32 GetResourceCount() const override final; /// Implementation of IShader::GetResource() in OpenGL backend. - virtual ShaderResourceDesc GetResource(Uint32 Index)const override final; + virtual ShaderResourceDesc GetResource(Uint32 Index) const override final; static GLObjectWrappers::GLProgramObj LinkProgram(IShader** ppShaders, Uint32 NumShaders, bool IsSeparableProgram); @@ -91,4 +95,4 @@ private: GLProgramResources m_Resources; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h index 82110c44..5c5bc763 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h @@ -46,28 +46,28 @@ class ShaderResourceBindingGLImpl final : public ShaderResourceBindingBase<IShad public: using TBase = ShaderResourceBindingBase<IShaderResourceBindingGL>; - ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, - PipelineStateGLImpl* pPSO, - GLProgramResources* ProgramResources, - Uint32 NumPrograms); + ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, + PipelineStateGLImpl* pPSO, + GLProgramResources* ProgramResources, + Uint32 NumPrograms); ~ShaderResourceBindingGLImpl(); - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; /// Implementation of IShaderResourceBinding::BindResources() in OpenGL backend. - virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)override final; + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) override final; /// Implementation of IShaderResourceBinding::GetVariableByName() in OpenGL backend. - virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char *Name)override final; + virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override final; /// Implementation of IShaderResourceBinding::GetVariableCount() in OpenGL backend. virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; /// Implementation of IShaderResourceBinding::GetVariableByIndex() in OpenGL backend. - virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index)override final; + virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; /// Implementation of IShaderResourceBinding::InitializeStaticResources() in OpenGL backend. - virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; + virtual void InitializeStaticResources(const IPipelineState* pPipelineState) override final; const GLProgramResourceCache& GetResourceCache(PipelineStateGLImpl* pdbgPSO); @@ -76,9 +76,9 @@ private: GLPipelineResourceLayout m_ResourceLayout; // The resource cache holds resource bindings for all variables - GLProgramResourceCache m_ResourceCache; + GLProgramResourceCache m_ResourceCache; - bool m_bIsStaticResourcesBound = false; + bool m_bIsStaticResourcesBound = false; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h index db321e70..e82a2f75 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h @@ -32,40 +32,40 @@ namespace Diligent class IMemoryAllocator; /// Implementation of the Diligent::ISwapChainGL interface on IOS -class SwapChainGLIOS final : public SwapChainBase<ISwapChainGL> +class SwapChainGLIOS final : public SwapChainBase<ISwapChainGL> { public: typedef SwapChainBase<ISwapChainGL> TSwapChainBase; - - SwapChainGLIOS(IReferenceCounters* pRefCounters, - const EngineGLCreateInfo& InitAttribs, - const SwapChainDesc& SwapChainDesc, - class RenderDeviceGLImpl* pRenderDeviceGL, - class DeviceContextGLImpl* pImmediateContextGL); + + SwapChainGLIOS(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); SwapChainGLIOS(); - - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - - virtual void Present(Uint32 SyncInterval)override final; - - virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override final; - - virtual void SetFullscreenMode(const DisplayModeAttribs &DisplayMode)override final; - virtual void SetWindowedMode()override final; + virtual void QueryInterface(const Diligent::INTERFACE_ID& IID, IObject** ppInterface) override final; + + virtual void Present(Uint32 SyncInterval) override final; + + virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final; + + virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final; - virtual GLuint GetDefaultFBO()const override final; + virtual void SetWindowedMode() override final; + + virtual GLuint GetDefaultFBO() const override final; + + virtual ITextureView* GetCurrentBackBufferRTV() override final { return nullptr; } + virtual ITextureView* GetDepthBufferDSV() override final { return nullptr; } - virtual ITextureView* GetCurrentBackBufferRTV()override final{return nullptr;} - virtual ITextureView* GetDepthBufferDSV()override final{return nullptr;} - private: - void InitRenderBuffers(bool InitFromDrawable, Uint32 &Width, Uint32 &Height); - + void InitRenderBuffers(bool InitFromDrawable, Uint32& Width, Uint32& Height); + GLObjectWrappers::GLRenderBufferObj m_ColorRenderBuffer; GLObjectWrappers::GLRenderBufferObj m_DepthRenderBuffer; - GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; - void *m_CALayer; + GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; + void* m_CALayer; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h index f84a8f47..15608044 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h @@ -38,35 +38,35 @@ class SwapChainGLImpl final : public SwapChainBase<ISwapChainGL> public: using TSwapChainBase = SwapChainBase<ISwapChainGL>; - SwapChainGLImpl(IReferenceCounters* pRefCounters, - const EngineGLCreateInfo& InitAttribs, - const SwapChainDesc& SwapChainDesc, - class RenderDeviceGLImpl* pRenderDeviceGL, - class DeviceContextGLImpl* pImmediateContextGL); + SwapChainGLImpl(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); ~SwapChainGLImpl(); - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; /// Implementation of ISwapChain::Present() in OpenGL backend. - virtual void Present(Uint32 SyncInterval)override final; + virtual void Present(Uint32 SyncInterval) override final; /// Implementation of ISwapChain::Resize() in OpenGL backend. - virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override final; + virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final; /// Implementation of ISwapChain::SetFullscreenMode() in OpenGL backend. - virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode)override final; + virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final; /// Implementation of ISwapChain::SetWindowedMode() in OpenGL backend. - virtual void SetWindowedMode()override final; + virtual void SetWindowedMode() override final; /// Implementation of ISwapChainGL::GetDefaultFBO(). - virtual GLuint GetDefaultFBO()const override final{ return 0; } + virtual GLuint GetDefaultFBO() const override final { return 0; } /// Implementation of ISwapChain::GetCurrentBackBufferRTV() in OpenGL backend. - virtual ITextureView* GetCurrentBackBufferRTV()override final{return m_pRenderTargetView;} + virtual ITextureView* GetCurrentBackBufferRTV() override final { return m_pRenderTargetView; } /// Implementation of ISwapChain::GetDepthBufferDSV() in OpenGL backend. - virtual ITextureView* GetDepthBufferDSV()override final{return m_pDepthStencilView;} + virtual ITextureView* GetDepthBufferDSV() override final { return m_pDepthStencilView; } private: void CreateDummyBuffers(RenderDeviceGLImpl* pRenderDeviceGL); @@ -75,4 +75,4 @@ private: RefCntAutoPtr<TextureViewGLImpl> m_pDepthStencilView; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h index bdba9648..37594aca 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h +++ b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h @@ -30,33 +30,35 @@ namespace Diligent class TexRegionRender { public: - TexRegionRender(class RenderDeviceGLImpl* pDeviceGL); - void SetStates(class DeviceContextGLImpl* pCtxGL); - void RestoreStates(class DeviceContextGLImpl* pCtxGL); - void Render(class DeviceContextGLImpl* pCtxGL, - ITextureView* pSrcSRV, - RESOURCE_DIMENSION TexType, - TEXTURE_FORMAT TexFormat, - Int32 DstToSrcXOffset, - Int32 DstToSrcYOffset, - Int32 SrcZ, - Int32 SrcMipLevel); + TexRegionRender(class RenderDeviceGLImpl* pDeviceGL); + void SetStates(class DeviceContextGLImpl* pCtxGL); + void RestoreStates(class DeviceContextGLImpl* pCtxGL); + + void Render(class DeviceContextGLImpl* pCtxGL, + ITextureView* pSrcSRV, + RESOURCE_DIMENSION TexType, + TEXTURE_FORMAT TexFormat, + Int32 DstToSrcXOffset, + Int32 DstToSrcYOffset, + Int32 SrcZ, + Int32 SrcMipLevel); private: RefCntAutoPtr<IShader> m_pVertexShader; RefCntAutoPtr<IShader> m_pFragmentShaders[RESOURCE_DIM_NUM_DIMENSIONS * 3]; RefCntAutoPtr<IBuffer> m_pConstantBuffer; + RefCntAutoPtr<IPipelineState> m_pPSO[RESOURCE_DIM_NUM_DIMENSIONS * 3]; RefCntAutoPtr<IShaderResourceBinding> m_pSRB; IShaderResourceVariable* m_pSrcTexVar = nullptr; RefCntAutoPtr<IPipelineState> m_pOrigPSO; - Uint32 m_OrigStencilRef = 0; - float m_OrigBlendFactors[4] = {}; - Uint32 m_NumRenderTargets = 0; - ITextureView* m_pOrigRTVs[MaxRenderTargets] = {}; - RefCntAutoPtr<ITextureView> m_pOrigDSV; - std::vector<Viewport> m_OrigViewports; + Uint32 m_OrigStencilRef = 0; + float m_OrigBlendFactors[4] = {}; + Uint32 m_NumRenderTargets = 0; + ITextureView* m_pOrigRTVs[MaxRenderTargets] = {}; + RefCntAutoPtr<ITextureView> m_pOrigDSV; + std::vector<Viewport> m_OrigViewports; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h index 06b90fb2..1821097d 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h @@ -32,33 +32,33 @@ namespace Diligent class Texture1DArray_OGL final : public TextureBaseGL { public: - Texture1DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false); + Texture1DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - Texture1DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + Texture1DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); ~Texture1DArray_OGL(); /// Implementation of TextureBaseGL::UpdateData() for 1D texture array. - virtual void UpdateData( class GLContextState& CtxState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData )override final; + virtual void UpdateData(class GLContextState& CtxState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for 1D texture array. - virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint )override final; + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h index d08704eb..cc9d7893 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h @@ -32,33 +32,33 @@ namespace Diligent class Texture1D_OGL final : public TextureBaseGL { public: - Texture1D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false); + Texture1D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - Texture1D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + Texture1D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); ~Texture1D_OGL(); /// Implementation of TextureBaseGL::UpdateData() for 1D texture. - virtual void UpdateData( class GLContextState& CtxState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData )override final; + virtual void UpdateData(class GLContextState& CtxState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for 1D texture. - virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint )override final; + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h index 1acfc7e6..15d881a3 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h @@ -32,21 +32,21 @@ namespace Diligent class Texture2DArray_OGL final : public TextureBaseGL { public: - Texture2DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false ); + Texture2DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - Texture2DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + Texture2DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); ~Texture2DArray_OGL(); /// Implementation of TextureBaseGL::UpdateData() for 2D texture array. @@ -54,11 +54,11 @@ public: Uint32 MipLevel, Uint32 Slice, const Box& DstBox, - const TextureSubResData& SubresData)override final; + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for 2D texture array. - virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint )override final; + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h index b554fca9..841900fd 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h @@ -32,41 +32,41 @@ namespace Diligent class Texture2D_OGL final : public TextureBaseGL { public: - Texture2D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false); + Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - Texture2D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); /// This constructor is used to create a dummy texture object for the default framebuffer. - Texture2D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - const TextureDesc& TexDesc, - bool bIsDeviceInternal = false); + Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal = false); ~Texture2D_OGL(); /// Implementation of TextureBaseGL::UpdateData() for 2D texture. - virtual void UpdateData( class GLContextState& CtxState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData )override final; + virtual void UpdateData(class GLContextState& CtxState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for 2D texture. - virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint )override final; + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h index 4d00e365..7d9bb9ea 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h @@ -32,21 +32,21 @@ namespace Diligent class Texture3D_OGL final : public TextureBaseGL { public: - Texture3D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false); + Texture3D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - Texture3D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + Texture3D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); ~Texture3D_OGL(); /// Implementation of TextureBaseGL::UpdateData() for 3D texture. @@ -54,11 +54,11 @@ public: Uint32 MipLevel, Uint32 Slice, const Box& DstBox, - const TextureSubResData& SubresData)override final; + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for 3D texture. - virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint )override final; + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h index 59fb23f9..132ba912 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h @@ -44,73 +44,83 @@ public: using TTextureBase = TextureBase<ITextureGL, RenderDeviceGLImpl, TextureViewGLImpl, FixedBlockMemoryAllocator>; using ViewImplType = TextureViewGLImpl; - TextureBaseGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - const TextureDesc& TexDesc, - GLenum BindTarget, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false); - - TextureBaseGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - GLenum BindTarget, - bool bIsDeviceInternal); + TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + GLenum BindTarget, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); + + TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + GLenum BindTarget, + bool bIsDeviceInternal); /// Initializes a dummy texture (dummy textures are used by the swap chain to /// proxy default framebuffer). - TextureBaseGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - const TextureDesc& TexDesc, - bool bIsDeviceInternal); + TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal); ~TextureBaseGL(); - - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override; - const GLObjectWrappers::GLTextureObj& GetGLHandle()const{ return m_GlTexture; } + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; + + const GLObjectWrappers::GLTextureObj& GetGLHandle() const { return m_GlTexture; } /// Implementation of ITextureGL::GetBindTarget(). - virtual GLenum GetBindTarget()const override final{return m_BindTarget;} + virtual GLenum GetBindTarget() const override final { return m_BindTarget; } - GLenum GetGLTexFormat()const{ return m_GLTexFormat; } + GLenum GetGLTexFormat() const { return m_GLTexFormat; } - void TextureMemoryBarrier( Uint32 RequiredBarriers, class GLContextState &GLContextState); + void TextureMemoryBarrier(Uint32 RequiredBarriers, class GLContextState& GLContextState); virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint) = 0; - void CopyData(DeviceContextGLImpl* pDeviceCtxGL, - TextureBaseGL* pSrcTextureGL, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ); + void CopyData(DeviceContextGLImpl* pDeviceCtxGL, + TextureBaseGL* pSrcTextureGL, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box* pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ); /// Implementation of ITextureGL::GetGLTextureHandle(). - virtual GLuint GetGLTextureHandle()override final { return GetGLHandle(); } + virtual GLuint GetGLTextureHandle() override final { return GetGLHandle(); } /// Implementation of ITexture::GetNativeHandle() in OpenGL backend. - virtual void* GetNativeHandle()override final { return reinterpret_cast<void*>(static_cast<size_t>(GetGLTextureHandle())); } + virtual void* GetNativeHandle() override final + { + return reinterpret_cast<void*>(static_cast<size_t>(GetGLTextureHandle())); + } - virtual void UpdateData( class GLContextState& CtxState, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData ) = 0; + virtual void UpdateData(class GLContextState& CtxState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) = 0; protected: - virtual void CreateViewInternal( const struct TextureViewDesc& ViewDesc, class ITextureView** ppView, bool bIsDefaultView )override; + virtual void CreateViewInternal(const struct TextureViewDesc& ViewDesc, + class ITextureView** ppView, + bool bIsDefaultView) override; + void SetDefaultGLParameters(); GLObjectWrappers::GLTextureObj m_GlTexture; - const GLenum m_BindTarget; - const GLenum m_GLTexFormat; + const GLenum m_BindTarget; + const GLenum m_GLTexFormat; //Uint32 m_uiMapTarget; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h index 3e4042cb..8bda0a64 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h @@ -32,21 +32,21 @@ namespace Diligent class TextureCubeArray_OGL final : public TextureBaseGL { public: - TextureCubeArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false ); + TextureCubeArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - TextureCubeArray_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + TextureCubeArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); ~TextureCubeArray_OGL(); /// Implementation of TextureBaseGL::UpdateData() for cube texture array. @@ -54,11 +54,11 @@ public: Uint32 MipLevel, Uint32 Slice, const Box& DstBox, - const TextureSubResData& SubresData)override final; + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for cube texture array. - virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint )override final; + virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureCube_OGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureCube_OGL.h index 9836ad56..e56b949a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureCube_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureCube_OGL.h @@ -32,21 +32,21 @@ namespace Diligent class TextureCube_OGL final : public TextureBaseGL { public: - TextureCube_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr, - bool bIsDeviceInternal = false); + TextureCube_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr, + bool bIsDeviceInternal = false); - TextureCube_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - class GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal = false); + TextureCube_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + class GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal = false); ~TextureCube_OGL(); /// Implementation of TextureBaseGL::UpdateData() for cube texture. @@ -54,11 +54,11 @@ public: Uint32 MipLevel, Uint32 Slice, const Box& DstBox, - const TextureSubResData& SubresData)override final; + const TextureSubResData& SubresData) override final; /// Implementation of TextureBaseGL::AttachToFramebuffer() for cube texture. virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, - GLenum AttachmentPoint)override final; + GLenum AttachmentPoint) override final; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h index e98fae4e..91c10338 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h @@ -42,22 +42,23 @@ public: using TTextureViewBase = TextureViewBase<ITextureViewGL, RenderDeviceGLImpl>; TextureViewGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDevice, - const struct TextureViewDesc& ViewDesc, + RenderDeviceGLImpl* pDevice, + const struct TextureViewDesc& ViewDesc, class TextureBaseGL* pTexture, bool bCreateGLViewTex, bool bIsDefaultView); ~TextureViewGLImpl(); - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; const GLObjectWrappers::GLTextureObj& GetHandle(); + GLenum GetBindTarget(); - void SetBindTarget(GLenum ViewTexBindTarget) { m_ViewTexBindTarget = ViewTexBindTarget; } + void SetBindTarget(GLenum ViewTexBindTarget) { m_ViewTexBindTarget = ViewTexBindTarget; } protected: GLObjectWrappers::GLTextureObj m_ViewTexGLHandle; - GLenum m_ViewTexBindTarget; + GLenum m_ViewTexBindTarget; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h index 3b807029..d40e172a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h @@ -41,18 +41,18 @@ public: VAOCache(); ~VAOCache(); - VAOCache(const VAOCache&) = delete; - VAOCache( VAOCache&&) = delete; + // clang-format off + VAOCache (const VAOCache&) = delete; + VAOCache ( VAOCache&&) = delete; VAOCache& operator = (const VAOCache&) = delete; VAOCache& operator = ( VAOCache&&) = delete; - - - - const GLObjectWrappers::GLVertexArrayObj& GetVAO( IPipelineState* pPSO, - IBuffer* pIndexBuffer, - VertexStreamInfo<class BufferGLImpl> VertexStreams[], - Uint32 NumVertexStreams, - class GLContextState& GLContextState); + // clang-format on + + const GLObjectWrappers::GLVertexArrayObj& GetVAO(IPipelineState* pPSO, + IBuffer* pIndexBuffer, + VertexStreamInfo<class BufferGLImpl> VertexStreams[], + Uint32 NumVertexStreams, + class GLContextState& GLContextState); const GLObjectWrappers::GLVertexArrayObj& GetEmptyVAO(); void OnDestroyBuffer(IBuffer* pBuffer); @@ -62,10 +62,12 @@ private: // This structure is used as the key to find VAO struct VAOCacheKey { - VAOCacheKey(UniqueIdentifier pso_id, UniqueIdentifier ib_id) : + VAOCacheKey(UniqueIdentifier pso_id, UniqueIdentifier ib_id) : + // clang-format off PSOUId {pso_id}, IndexBufferUId {ib_id }, NumUsedSlots {0 } + // clang-format on {} // Note that using pointers is unsafe as they may (and will) be reused: @@ -84,22 +86,22 @@ private: UniqueIdentifier BufferUId; Uint32 Stride; Uint32 Offset; - }Streams[MaxBufferSlots]; - + } Streams[MaxBufferSlots]; + mutable size_t Hash = 0; - bool operator == (const VAOCacheKey &Key)const + bool operator==(const VAOCacheKey& Key) const { - return PSOUId == Key.PSOUId && - IndexBufferUId == Key.IndexBufferUId && - NumUsedSlots == Key.NumUsedSlots && - std::memcmp(Streams, Key.Streams, sizeof(StreamAttribs) * NumUsedSlots) == 0; + return PSOUId == Key.PSOUId && + IndexBufferUId == Key.IndexBufferUId && + NumUsedSlots == Key.NumUsedSlots && + std::memcmp(Streams, Key.Streams, sizeof(StreamAttribs) * NumUsedSlots) == 0; } }; struct VAOCacheKeyHashFunc { - std::size_t operator() ( const VAOCacheKey& Key )const + std::size_t operator()(const VAOCacheKey& Key) const { if (Key.Hash == 0) { @@ -107,7 +109,7 @@ private: HashCombine(Seed, Key.PSOUId, Key.IndexBufferUId, Key.NumUsedSlots); for (Uint32 slot = 0; slot < Key.NumUsedSlots; ++slot) { - auto &CurrStream = Key.Streams[slot]; + auto& CurrStream = Key.Streams[slot]; HashCombine(Seed, CurrStream.BufferUId); HashCombine(Seed, CurrStream.Offset); HashCombine(Seed, CurrStream.Stride); @@ -120,10 +122,11 @@ private: friend class RenderDeviceGLImpl; - ThreadingTools::LockFlag m_CacheLockFlag; + ThreadingTools::LockFlag m_CacheLockFlag; std::unordered_map<VAOCacheKey, GLObjectWrappers::GLVertexArrayObj, VAOCacheKeyHashFunc> m_Cache; + std::unordered_multimap<const IPipelineState*, VAOCacheKey> m_PSOToKey; - std::unordered_multimap<const IBuffer*, VAOCacheKey> m_BuffToKey; + std::unordered_multimap<const IBuffer*, VAOCacheKey> m_BuffToKey; // Any draw command fails if no VAO is bound. We will use this empty // VAO for draw commands with null input layout, such as these that @@ -131,4 +134,4 @@ private: GLObjectWrappers::GLVertexArrayObj m_EmptyVAO; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/pch.h b/Graphics/GraphicsEngineOpenGL/include/pch.h index 260ae5ae..19115f22 100644 --- a/Graphics/GraphicsEngineOpenGL/include/pch.h +++ b/Graphics/GraphicsEngineOpenGL/include/pch.h @@ -37,72 +37,72 @@ #if PLATFORM_WIN32 -# ifndef GLEW_STATIC -# define GLEW_STATIC // Must be defined to use static version of glew -# endif -# include "GL/glew.h" - // Glew includes <windows.h> -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include "GL/wglew.h" -# include <GL/GL.h> +# ifndef GLEW_STATIC +# define GLEW_STATIC // Must be defined to use static version of glew +# endif +# include "GL/glew.h" +// Glew includes <windows.h> +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include "GL/wglew.h" +# include <GL/GL.h> #elif PLATFORM_LINUX -# ifndef GLEW_STATIC -# define GLEW_STATIC // Must be defined to use static version of glew -# endif -# ifndef GLEW_NO_GLU -# define GLEW_NO_GLU -# endif +# ifndef GLEW_STATIC +# define GLEW_STATIC // Must be defined to use static version of glew +# endif +# ifndef GLEW_NO_GLU +# define GLEW_NO_GLU +# endif -# include "GL/glew.h" -# include <GL/glx.h> +# include "GL/glew.h" +# include <GL/glx.h> // Undefine beautiful defines from GL/glx.h -> X11/Xlib.h -# ifdef Bool -# undef Bool -# endif -# ifdef True -# undef True -# endif -# ifdef False -# undef False -# endif -# ifdef Status -# undef Status -# endif -# ifdef Success -# undef Success -# endif +# ifdef Bool +# undef Bool +# endif +# ifdef True +# undef True +# endif +# ifdef False +# undef False +# endif +# ifdef Status +# undef Status +# endif +# ifdef Success +# undef Success +# endif #elif PLATFORM_MACOS -# ifndef GLEW_STATIC -# define GLEW_STATIC // Must be defined to use static version of glew -# endif -# ifndef GLEW_NO_GLU -# define GLEW_NO_GLU -# endif +# ifndef GLEW_STATIC +# define GLEW_STATIC // Must be defined to use static version of glew +# endif +# ifndef GLEW_NO_GLU +# define GLEW_NO_GLU +# endif -# include "GL/glew.h" +# include "GL/glew.h" #elif PLATFORM_ANDROID -# include <GLES3/gl3.h> -# include <GLES3/gl3ext.h> - // GLStubs must be included after GLFeatures! -# include "GLStubsAndroid.h" +# include <GLES3/gl3.h> +# include <GLES3/gl3ext.h> +// GLStubs must be included after GLFeatures! +# include "GLStubsAndroid.h" #elif PLATFORM_IOS -# include <OpenGLES/ES3/gl.h> -# include <OpenGLES/ES3/glext.h> -# include "GLStubsIOS.h" +# include <OpenGLES/ES3/gl.h> +# include <OpenGLES/ES3/glext.h> +# include "GLStubsIOS.h" #else -# error Unsupported platform +# error Unsupported platform #endif #include "Errors.h" @@ -115,25 +115,30 @@ #include "RenderDevice.h" #include "BaseInterfacesGL.h" -#define CHECK_GL_ERROR(...)\ -{ \ - auto err = glGetError(); \ - if( err != GL_NO_ERROR ) \ - { \ - LogError<false>(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nGL Error Code: ", err); \ - UNEXPECTED("Error"); \ - } \ -} - -#define CHECK_GL_ERROR_AND_THROW(...)\ -{ \ - auto err = glGetError(); \ - if( err != GL_NO_ERROR ) \ - LogError<true>(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nGL Error Code: ", err); \ -} +#define CHECK_GL_ERROR(...) \ + do \ + { \ + auto err = glGetError(); \ + if (err != GL_NO_ERROR) \ + { \ + LogError<false>(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nGL Error Code: ", err); \ + UNEXPECTED("Error"); \ + } \ + } while (false) + +#define CHECK_GL_ERROR_AND_THROW(...) \ + do \ + { \ + auto err = glGetError(); \ + if (err != GL_NO_ERROR) \ + LogError<true>(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nGL Error Code: ", err); \ + } while (false) #ifdef DEVELOPMENT -# define DEV_CHECK_GL_ERROR CHECK_GL_ERROR +# define DEV_CHECK_GL_ERROR CHECK_GL_ERROR #else -# define DEV_CHECK_GL_ERROR(...) do{}while(false) +# define DEV_CHECK_GL_ERROR(...) \ + do \ + { \ + } while (false) #endif diff --git a/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h b/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h index 1dcade3a..6888ab5d 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h @@ -23,25 +23,33 @@ #pragma once +// clang-format off + #if PLATFORM_ANDROID - #include "RenderDeviceGLES.h" + +# include "RenderDeviceGLES.h" namespace Diligent { using IGLDeviceBaseInterface = IRenderDeviceGLES; } + #elif PLATFORM_WIN32 || PLATFORM_LINUX || PLATFORM_MACOS - #include "RenderDeviceGL.h" + +# include "RenderDeviceGL.h" namespace Diligent { using IGLDeviceBaseInterface = IRenderDeviceGL; } + #elif PLATFORM_IOS - #include "RenderDeviceGL.h" + +# include "RenderDeviceGL.h" namespace Diligent { using IGLDeviceBaseInterface = IRenderDeviceGL; } #else + # error Unsupported platform #endif diff --git a/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h b/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h index 5cee7cfc..350e2fa8 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h @@ -33,7 +33,7 @@ namespace Diligent // {08DF7319-F425-4EC7-8D2B-1B3FC0BDDBB4} static constexpr INTERFACE_ID IID_BufferGL = -{ 0x8df7319, 0xf425, 0x4ec7, { 0x8d, 0x2b, 0x1b, 0x3f, 0xc0, 0xbd, 0xdb, 0xb4 } }; + {0x8df7319, 0xf425, 0x4ec7, {0x8d, 0x2b, 0x1b, 0x3f, 0xc0, 0xbd, 0xdb, 0xb4}}; /// Exposes OpenGL-specific functionality of a buffer object. class IBufferGL : public IBuffer @@ -43,4 +43,4 @@ public: virtual GLuint GetGLBufferHandle() = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h b/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h index f4a868ae..9d618694 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h @@ -33,7 +33,7 @@ namespace Diligent // {927A865B-3CEB-4743-9A22-2A1397A73E6D} static constexpr INTERFACE_ID IID_BufferViewGL = -{ 0x927a865b, 0x3ceb, 0x4743, { 0x9a, 0x22, 0x2a, 0x13, 0x97, 0xa7, 0x3e, 0x6d } }; + {0x927a865b, 0x3ceb, 0x4743, {0x9a, 0x22, 0x2a, 0x13, 0x97, 0xa7, 0x3e, 0x6d}}; /// Exposes OpenGL-specific functionality of a buffer view object. class IBufferViewGL : public IBufferView @@ -42,4 +42,4 @@ public: //const GLObjectWrappers::GLTextureObj& GetTexBufferHandle(){ return m_GLTexBuffer; } }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h index 7964d6c5..ba0d5ddb 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h @@ -33,21 +33,20 @@ namespace Diligent // {3464FDF1-C548-4935-96C3-B454C9DF6F6A} static constexpr INTERFACE_ID IID_DeviceContextGL = -{ 0x3464fdf1, 0xc548, 0x4935, { 0x96, 0xc3, 0xb4, 0x54, 0xc9, 0xdf, 0x6f, 0x6a } }; + {0x3464fdf1, 0xc548, 0x4935, {0x96, 0xc3, 0xb4, 0x54, 0xc9, 0xdf, 0x6f, 0x6a}}; /// Exposes OpenGL-specific functionality of a device context. class IDeviceContextGL : public IDeviceContext { public: - /// Attaches to the active GL context in the thread. - /// If an application uses multiple GL contexts, this method must be called before any - /// other command to let the engine update active context every time when control flow + /// If an application uses multiple GL contexts, this method must be called before any + /// other command to let the engine update active context every time when control flow /// is passed over from the main application /// /// \return false if there is no active GL context, and true otherwise virtual bool UpdateCurrentGLContext() = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/EngineFactoryOpenGL.h b/Graphics/GraphicsEngineOpenGL/interface/EngineFactoryOpenGL.h index 322b49d4..7d06f16b 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/EngineFactoryOpenGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/EngineFactoryOpenGL.h @@ -38,12 +38,12 @@ #if PLATFORM_ANDROID || PLATFORM_LINUX || PLATFORM_MACOS || PLATFORM_IOS || (PLATFORM_WIN32 && !defined(_MSC_VER)) - // https://gcc.gnu.org/wiki/Visibility -# define API_QUALIFIER __attribute__((visibility("default"))) +// https://gcc.gnu.org/wiki/Visibility +# define API_QUALIFIER __attribute__((visibility("default"))) #elif PLATFORM_WIN32 -# define API_QUALIFIER +# define API_QUALIFIER #else # error Unsupported platform @@ -53,8 +53,8 @@ namespace Diligent { // {9BAAC767-02CC-4FFA-9E4B-E1340F572C49} -static const INTERFACE_ID IID_EngineFactoryOpenGL = -{ 0x9baac767, 0x2cc, 0x4ffa, { 0x9e, 0x4b, 0xe1, 0x34, 0xf, 0x57, 0x2c, 0x49 } }; +static const INTERFACE_ID IID_EngineFactoryOpenGL = + {0x9baac767, 0x2cc, 0x4ffa, {0x9e, 0x4b, 0xe1, 0x34, 0xf, 0x57, 0x2c, 0x49}}; class IEngineFactoryOpenGL : public IEngineFactory { @@ -63,66 +63,66 @@ public: IRenderDevice** ppDevice, IDeviceContext** ppImmediateContext, const SwapChainDesc& SCDesc, - ISwapChain** ppSwapChain ) = 0; - virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter) = 0; + ISwapChain** ppSwapChain) = 0; + virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter) = 0; virtual void AttachToActiveGLContext(const EngineGLCreateInfo& EngineCI, IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext) = 0; + IDeviceContext** ppImmediateContext) = 0; }; #if ENGINE_DLL && PLATFORM_WIN32 && defined(_MSC_VER) -# define EXPLICITLY_LOAD_ENGINE_GL_DLL 1 +# define EXPLICITLY_LOAD_ENGINE_GL_DLL 1 - typedef IEngineFactoryOpenGL* (*GetEngineFactoryOpenGLType)(); +typedef IEngineFactoryOpenGL* (*GetEngineFactoryOpenGLType)(); - static bool LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType& GetFactoryFunc) +static bool LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType& GetFactoryFunc) +{ + GetFactoryFunc = nullptr; + std::string LibName = "GraphicsEngineOpenGL_"; + +# if _WIN64 + LibName += "64"; +# else + LibName += "32"; +# endif + +# ifdef _DEBUG + LibName += "d"; +# else + LibName += "r"; +# endif + + LibName += ".dll"; + auto hModule = LoadLibraryA(LibName.c_str()); + if (hModule == NULL) + { + std::stringstream ss; + ss << "Failed to load " << LibName << " library.\n"; + OutputDebugStringA(ss.str().c_str()); + return false; + } + + GetFactoryFunc = reinterpret_cast<GetEngineFactoryOpenGLType>(GetProcAddress(hModule, "GetEngineFactoryOpenGL")); + if (GetFactoryFunc == NULL) { - GetFactoryFunc = nullptr; - std::string LibName = "GraphicsEngineOpenGL_"; - -# if _WIN64 - LibName += "64"; -# else - LibName += "32"; -# endif - -# ifdef _DEBUG - LibName += "d"; -# else - LibName += "r"; -# endif - - LibName += ".dll"; - auto hModule = LoadLibraryA( LibName.c_str() ); - if( hModule == NULL ) - { - std::stringstream ss; - ss << "Failed to load " << LibName << " library.\n"; - OutputDebugStringA(ss.str().c_str()); - return false; - } - - GetFactoryFunc = reinterpret_cast<GetEngineFactoryOpenGLType>( GetProcAddress(hModule, "GetEngineFactoryOpenGL") ); - if( GetFactoryFunc == NULL ) - { - std::stringstream ss; - ss << "Failed to load GetEngineFactoryOpenGL() from " << LibName << " library.\n"; - OutputDebugStringA(ss.str().c_str()); - FreeLibrary( hModule ); - return false; - } - return true; + std::stringstream ss; + ss << "Failed to load GetEngineFactoryOpenGL() from " << LibName << " library.\n"; + OutputDebugStringA(ss.str().c_str()); + FreeLibrary(hModule); + return false; } + return true; +} #else - // Do not forget to call System.loadLibrary("GraphicsEngineOpenGL") in Java on Android! - API_QUALIFIER - IEngineFactoryOpenGL* GetEngineFactoryOpenGL(); +// Do not forget to call System.loadLibrary("GraphicsEngineOpenGL") in Java on Android! +API_QUALIFIER +IEngineFactoryOpenGL* GetEngineFactoryOpenGL(); #endif -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/FenceGL.h b/Graphics/GraphicsEngineOpenGL/interface/FenceGL.h index 75b7e417..f4f6a771 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/FenceGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/FenceGL.h @@ -33,7 +33,7 @@ namespace Diligent // {8FEACBDA-89D6-4509-88E6-D55DD06220C5} static constexpr INTERFACE_ID IID_FenceGL = -{ 0x8feacbda, 0x89d6, 0x4509, { 0x88, 0xe6, 0xd5, 0x5d, 0xd0, 0x62, 0x20, 0xc5 } }; + {0x8feacbda, 0x89d6, 0x4509, {0x88, 0xe6, 0xd5, 0x5d, 0xd0, 0x62, 0x20, 0xc5}}; /// Exposes OpenGL-specific functionality of a fence object. @@ -44,4 +44,4 @@ public: //virtual IGLFence* GetGLFence() = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h index af71065f..25752140 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h @@ -33,13 +33,12 @@ namespace Diligent // {80666BE3-318A-4403-AEE1-6E61A5B7A0F9} static constexpr INTERFACE_ID IID_PipelineStateGL = -{ 0x80666be3, 0x318a, 0x4403, { 0xae, 0xe1, 0x6e, 0x61, 0xa5, 0xb7, 0xa0, 0xf9 } }; + {0x80666be3, 0x318a, 0x4403, {0xae, 0xe1, 0x6e, 0x61, 0xa5, 0xb7, 0xa0, 0xf9}}; /// Exposes OpenGL-specific functionality of a pipeline state object. class IPipelineStateGL : public IPipelineState { - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h index bb847d8b..85a815d0 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h @@ -34,25 +34,24 @@ namespace Diligent // {B4B395B9-AC99-4E8A-B7E1-9DCA0D485618} static constexpr INTERFACE_ID IID_RenderDeviceGL = -{ 0xb4b395b9, 0xac99, 0x4e8a, { 0xb7, 0xe1, 0x9d, 0xca, 0xd, 0x48, 0x56, 0x18 } }; + {0xb4b395b9, 0xac99, 0x4e8a, {0xb7, 0xe1, 0x9d, 0xca, 0xd, 0x48, 0x56, 0x18}}; /// Exposes OpenGL-specific functionality of a render device. class IRenderDeviceGL : public IRenderDevice { public: - /// Creates a texture from OpenGL handle /// \param [in] GLHandle - OpenGL texture handle - /// \param [in] TexDesc - Texture description. The engine can automatically + /// \param [in] TexDesc - Texture description. The engine can automatically /// set texture width, height, depth, mip levels count, and format. /// Remaining fields should be set up by the app. /// \param [in] InitialState - Initial texture state. See Diligent::RESOURCE_STATE. /// \param [out] ppTexture - Address of the memory location where the pointer to the - /// texture interface will be stored. - /// The function calls AddRef(), so that the new object will contain + /// texture interface will be stored. + /// The function calls AddRef(), so that the new object will contain /// one reference. - /// \note Diligent engine texture object does not take ownership of the GL resource, + /// \note Diligent engine texture object does not take ownership of the GL resource, /// and the application must not destroy it while it is in use by the engine. virtual void CreateTextureFromGLHandle(Uint32 GLHandle, const TextureDesc& TexDesc, @@ -62,15 +61,15 @@ public: /// Creates a buffer from OpenGL handle /// \param [in] GLHandle - OpenGL buffer handle - /// \param [in] BuffDesc - Buffer description. The engine can automatically - /// recover buffer size, but the rest of the fields need to + /// \param [in] BuffDesc - Buffer description. The engine can automatically + /// recover buffer size, but the rest of the fields need to /// be set by the client. /// \param [in] InitialState - Initial buffer state. See Diligent::RESOURCE_STATE. /// \param [out] ppBuffer - Address of the memory location where the pointer to the - /// texture interface will be stored. - /// The function calls AddRef(), so that the new object will contain + /// texture interface will be stored. + /// The function calls AddRef(), so that the new object will contain /// one reference. - /// \note Diligent engine buffer object does not take ownership of the GL resource, + /// \note Diligent engine buffer object does not take ownership of the GL resource, /// and the application must not destroy it while it is in use by the engine. virtual void CreateBufferFromGLHandle(Uint32 GLHandle, const BufferDesc& BuffDesc, @@ -78,4 +77,4 @@ public: IBuffer** ppBuffer) = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h index 4c45558c..bba2a652 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h @@ -35,7 +35,7 @@ namespace Diligent // {F705A0D9-2023-4DE1-8B3C-C56E4CEB8DB7} static const Diligent::INTERFACE_ID IID_RenderDeviceGLES = -{ 0xf705a0d9, 0x2023, 0x4de1, { 0x8b, 0x3c, 0xc5, 0x6e, 0x4c, 0xeb, 0x8d, 0xb7 } }; + {0xf705a0d9, 0x2023, 0x4de1, {0x8b, 0x3c, 0xc5, 0x6e, 0x4c, 0xeb, 0x8d, 0xb7}}; /// Interface to the render device object implemented in OpenGLES class IRenderDeviceGLES : public Diligent::IRenderDeviceGL @@ -45,7 +45,7 @@ public: virtual void Suspend() = 0; - virtual EGLint Resume( ANativeWindow* window ) = 0; + virtual EGLint Resume(ANativeWindow* window) = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h b/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h index f7f9a53a..62adc655 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h @@ -33,7 +33,7 @@ namespace Diligent // {3E9EB89E-E955-447A-9D13-92C10541F727} static constexpr INTERFACE_ID IID_SamplerGL = -{ 0x3e9eb89e, 0xe955, 0x447a, { 0x9d, 0x13, 0x92, 0xc1, 0x5, 0x41, 0xf7, 0x27 } }; + {0x3e9eb89e, 0xe955, 0x447a, {0x9d, 0x13, 0x92, 0xc1, 0x5, 0x41, 0xf7, 0x27}}; /// Exposes OpenGL-specific functionality of a sampler object. class ISamplerGL : public ISampler @@ -42,4 +42,4 @@ public: //const GLObjectWrappers::GLSamplerObj& GetHandle(){ return m_GlSampler; } }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h b/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h index 02dfd1e9..7265948f 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h @@ -30,16 +30,14 @@ namespace Diligent { - + // {2FF3C191-285B-4E6C-BD0B-D084DDEA6FCC} static constexpr INTERFACE_ID IID_ShaderGL = -{ 0x2ff3c191, 0x285b, 0x4e6c, { 0xbd, 0xb, 0xd0, 0x84, 0xdd, 0xea, 0x6f, 0xcc } }; + {0x2ff3c191, 0x285b, 0x4e6c, {0xbd, 0xb, 0xd0, 0x84, 0xdd, 0xea, 0x6f, 0xcc}}; /// Exposes OpenGL-specific functionality of a shader object. class IShaderGL : public IShader { -public: - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/ShaderResourceBindingGL.h b/Graphics/GraphicsEngineOpenGL/interface/ShaderResourceBindingGL.h index a3ae21ba..a94cbd3d 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/ShaderResourceBindingGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/ShaderResourceBindingGL.h @@ -33,13 +33,11 @@ namespace Diligent // {41DB0329-B6D2-4470-9A58-D44CF4695FC6} static constexpr INTERFACE_ID IID_ShaderResourceBindingGL = -{ 0x41db0329, 0xb6d2, 0x4470, { 0x9a, 0x58, 0xd4, 0x4c, 0xf4, 0x69, 0x5f, 0xc6 } }; + {0x41db0329, 0xb6d2, 0x4470, {0x9a, 0x58, 0xd4, 0x4c, 0xf4, 0x69, 0x5f, 0xc6}}; /// Exposes OpenGL-specific functionality of a shader resource binding object. class IShaderResourceBindingGL : public IShaderResourceBinding { -public: - }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h b/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h index 7c1e466a..494c1dc4 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h @@ -33,14 +33,14 @@ namespace Diligent // {F457BD7C-E725-4D3E-8607-A1F9BAE329EB} static constexpr INTERFACE_ID IID_SwapChainGL = -{ 0xf457bd7c, 0xe725, 0x4d3e, { 0x86, 0x7, 0xa1, 0xf9, 0xba, 0xe3, 0x29, 0xeb } }; + {0xf457bd7c, 0xe725, 0x4d3e, {0x86, 0x7, 0xa1, 0xf9, 0xba, 0xe3, 0x29, 0xeb}}; /// Exposes OpenGL-specific functionality of a swap chain. class ISwapChainGL : public ISwapChain { public: /// Returns the default framebuffer handle - virtual GLuint GetDefaultFBO()const = 0; + virtual GLuint GetDefaultFBO() const = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h b/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h index fd09d80e..906c4c75 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h @@ -33,7 +33,7 @@ namespace Diligent // {D7BC9FF0-28F0-4636-9732-710C204D1D63} static constexpr INTERFACE_ID IID_TextureGL = -{ 0xd7bc9ff0, 0x28f0, 0x4636, { 0x97, 0x32, 0x71, 0xc, 0x20, 0x4d, 0x1d, 0x63 } }; + {0xd7bc9ff0, 0x28f0, 0x4636, {0x97, 0x32, 0x71, 0xc, 0x20, 0x4d, 0x1d, 0x63}}; /// Exposes OpenGL-specific functionality of a texture object. class ITextureGL : public ITexture @@ -43,7 +43,7 @@ public: virtual GLuint GetGLTextureHandle() = 0; /// Returns bind target of the native OpenGL texture - virtual GLenum GetBindTarget()const = 0; + virtual GLenum GetBindTarget() const = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h b/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h index 1ad723c4..88d46db0 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h @@ -33,7 +33,7 @@ namespace Diligent // {15F93272-6135-414F-AB10-53FF9A5004AD} static constexpr INTERFACE_ID IID_TextureViewGL = -{ 0x15f93272, 0x6135, 0x414f, { 0xab, 0x10, 0x53, 0xff, 0x9a, 0x50, 0x4, 0xad } }; + {0x15f93272, 0x6135, 0x414f, {0xab, 0x10, 0x53, 0xff, 0x9a, 0x50, 0x4, 0xad}}; /// Exposes OpenGL-specific functionality of a texture view object. class ITextureViewGL : public ITextureView @@ -43,4 +43,4 @@ public: //GLenum GetBindTarget(); }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp index fc20afeb..e11f1765 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -38,34 +38,35 @@ static GLenum GetBufferBindTarget(const BufferDesc& Desc) GLenum Target = GL_ARRAY_BUFFER; if (Desc.BindFlags & BIND_VERTEX_BUFFER) Target = GL_ARRAY_BUFFER; - else if(Desc.BindFlags & BIND_INDEX_BUFFER) + else if (Desc.BindFlags & BIND_INDEX_BUFFER) Target = GL_ELEMENT_ARRAY_BUFFER; else if (Desc.BindFlags & BIND_UNIFORM_BUFFER) Target = GL_UNIFORM_BUFFER; - else if(Desc.BindFlags & BIND_INDIRECT_DRAW_ARGS) + else if (Desc.BindFlags & BIND_INDIRECT_DRAW_ARGS) { #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4127) // conditional expression is constant +# pragma warning(push) +# pragma warning(disable : 4127) // conditional expression is constant #endif - VERIFY(GL_DRAW_INDIRECT_BUFFER != 0, "Inidrect draw is not supported"); + VERIFY(GL_DRAW_INDIRECT_BUFFER != 0, "Inidrect draw is not supported"); #ifdef _MSC_VER -# pragma warning(pop) +# pragma warning(pop) #endif Target = GL_DRAW_INDIRECT_BUFFER; } else if (Desc.Usage == USAGE_STAGING && Desc.CPUAccessFlags == CPU_ACCESS_WRITE) Target = GL_PIXEL_UNPACK_BUFFER; - + return Target; } -BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const BufferDesc& BuffDesc, - const BufferData* pBuffData /*= nullptr*/, - bool bIsDeviceInternal) : +BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const BufferDesc& BuffDesc, + const BufferData* pBuffData /*= nullptr*/, + bool bIsDeviceInternal) : + // clang-format off TBufferBase { pRefCounters, @@ -74,11 +75,12 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, BuffDesc, bIsDeviceInternal }, - m_GlBuffer {true }, // Create buffer immediately - m_BindTarget {GetBufferBindTarget(BuffDesc) }, - m_GLUsageHint {UsageToGLUsage(BuffDesc.Usage)} + m_GlBuffer {true }, // Create buffer immediately + m_BindTarget {GetBufferBindTarget(BuffDesc) }, + m_GLUsageHint {UsageToGLUsage(BuffDesc.Usage)} +// clang-format on { - if( BuffDesc.Usage == USAGE_STATIC && (pBuffData == nullptr || pBuffData->pData == nullptr) ) + if (BuffDesc.Usage == USAGE_STATIC && (pBuffData == nullptr || pBuffData->pData == nullptr)) LOG_ERROR_AND_THROW("Static buffer must be initialized with data at creation time"); // TODO: find out if it affects performance if the buffer is originally bound to one target @@ -87,21 +89,21 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, // We must unbind VAO because otherwise we will break the bindings constexpr bool ResetVAO = true; GLState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO); - VERIFY(pBuffData == nullptr || pBuffData->pData == nullptr || pBuffData->DataSize >= BuffDesc.uiSizeInBytes, "Data pointer is null or data size is not consistent with buffer size" ); - GLsizeiptr DataSize = BuffDesc.uiSizeInBytes; - const GLvoid *pData = nullptr; - if( pBuffData != nullptr && pBuffData->pData != nullptr && pBuffData->DataSize >= BuffDesc.uiSizeInBytes ) + VERIFY(pBuffData == nullptr || pBuffData->pData == nullptr || pBuffData->DataSize >= BuffDesc.uiSizeInBytes, "Data pointer is null or data size is not consistent with buffer size"); + GLsizeiptr DataSize = BuffDesc.uiSizeInBytes; + const GLvoid* pData = nullptr; + if (pBuffData != nullptr && pBuffData->pData != nullptr && pBuffData->DataSize >= BuffDesc.uiSizeInBytes) { pData = pBuffData->pData; DataSize = pBuffData->DataSize; } // Create and initialize a buffer object's data store - // Target must be one of GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, - // GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER, + // Target must be one of GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, + // GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER, // GL_TRANSFORM_FEEDBACK_BUFFER, or GL_UNIFORM_BUFFER. - // Usage must be one of GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, + // Usage must be one of GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, // GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY. //The frequency of access may be one of these: @@ -115,30 +117,30 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, //DYNAMIC // The data store contents will be modified repeatedly and used many times. // - + //The nature of access may be one of these: // //DRAW - // The data store contents are modified by the application, and used as the source for GL + // The data store contents are modified by the application, and used as the source for GL // drawing and image specification commands. // //READ - // The data store contents are modified by reading data from the GL, and used to return that + // The data store contents are modified by reading data from the GL, and used to return that // data when queried by the application. // //COPY - // The data store contents are modified by reading data from the GL, and used as the source + // The data store contents are modified by reading data from the GL, and used as the source // for GL drawing and image specification commands. // See also http://www.informit.com/articles/article.aspx?p=2033340&seqNum=2 - // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same + // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same // kind of objects. As a result they are all equivalent from a transfer point of view. glBufferData(m_BindTarget, DataSize, pData, m_GLUsageHint); CHECK_GL_ERROR_AND_THROW("glBufferData() failed"); GLState.BindBuffer(m_BindTarget, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); } - + static BufferDesc GetBufferDescFromGLHandle(GLContextState& GLState, BufferDesc BuffDesc, GLuint BufferHandle) { // NOTE: the operations in this function are merely for debug purposes. @@ -159,8 +161,8 @@ static BufferDesc GetBufferDescFromGLHandle(GLContextState& GLState, BufferDesc VERIFY_EXPR(BufferSize > 0); VERIFY(BuffDesc.uiSizeInBytes == 0 || BuffDesc.uiSizeInBytes == static_cast<Uint32>(BufferSize), "Buffer size specified by the BufferDesc (", BuffDesc.uiSizeInBytes, ") does not match the size recovered from gl buffer object (", BufferSize, ")"); - if(BufferSize > 0) - BuffDesc.uiSizeInBytes = static_cast<Uint32>( BufferSize ); + if (BufferSize > 0) + BuffDesc.uiSizeInBytes = static_cast<Uint32>(BufferSize); glBindBuffer(BindTarget, 0); CHECK_GL_ERROR("Failed to unbind GL buffer"); @@ -168,13 +170,14 @@ static BufferDesc GetBufferDescFromGLHandle(GLContextState& GLState, BufferDesc return BuffDesc; } -BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& CtxState, - const BufferDesc& BuffDesc, - GLuint GLHandle, - bool bIsDeviceInternal) : +BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& CtxState, + const BufferDesc& BuffDesc, + GLuint GLHandle, + bool bIsDeviceInternal) : + // clang-format off TBufferBase { pRefCounters, @@ -184,32 +187,33 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, bIsDeviceInternal }, // Attach to external buffer handle - m_GlBuffer {true, GLObjectWrappers::GLBufferObjCreateReleaseHelper(GLHandle)}, - m_BindTarget {GetBufferBindTarget(m_Desc) }, - m_GLUsageHint {UsageToGLUsage(BuffDesc.Usage)} + m_GlBuffer {true, GLObjectWrappers::GLBufferObjCreateReleaseHelper(GLHandle)}, + m_BindTarget {GetBufferBindTarget(m_Desc) }, + m_GLUsageHint {UsageToGLUsage(BuffDesc.Usage)} +// clang-format on { } BufferGLImpl::~BufferGLImpl() { - static_cast<RenderDeviceGLImpl*>( GetDevice() )->OnDestroyBuffer(this); + static_cast<RenderDeviceGLImpl*>(GetDevice())->OnDestroyBuffer(this); } IMPLEMENT_QUERY_INTERFACE(BufferGLImpl, IID_BufferGL, TBufferBase) -void BufferGLImpl :: UpdateData(GLContextState& CtxState, Uint32 Offset, Uint32 Size, const PVoid pData) +void BufferGLImpl ::UpdateData(GLContextState& CtxState, Uint32 Offset, Uint32 Size, const PVoid pData) { BufferMemoryBarrier( - GL_BUFFER_UPDATE_BARRIER_BIT,// Reads or writes to buffer objects via any OpenGL API functions that allow - // modifying their contents will reflect data written by shaders prior to the barrier. - // Additionally, writes via these commands issued after the barrier will wait on - // the completion of any shader writes to the same memory initiated prior to the barrier. + GL_BUFFER_UPDATE_BARRIER_BIT, // Reads or writes to buffer objects via any OpenGL API functions that allow + // modifying their contents will reflect data written by shaders prior to the barrier. + // Additionally, writes via these commands issued after the barrier will wait on + // the completion of any shader writes to the same memory initiated prior to the barrier. CtxState); - + // We must unbind VAO because otherwise we will break the bindings constexpr bool ResetVAO = true; CtxState.BindBuffer(GL_ARRAY_BUFFER, m_GlBuffer, ResetVAO); - // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same + // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same // kind of objects. As a result they are all equivalent from a transfer point of view. glBufferSubData(GL_ARRAY_BUFFER, Offset, Size, pData); CHECK_GL_ERROR("glBufferSubData() failed"); @@ -217,22 +221,22 @@ void BufferGLImpl :: UpdateData(GLContextState& CtxState, Uint32 Offset, Uint32 } -void BufferGLImpl :: CopyData(GLContextState& CtxState, BufferGLImpl& SrcBufferGL, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size) +void BufferGLImpl ::CopyData(GLContextState& CtxState, BufferGLImpl& SrcBufferGL, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size) { BufferMemoryBarrier( - GL_BUFFER_UPDATE_BARRIER_BIT,// Reads or writes to buffer objects via any OpenGL API functions that allow - // modifying their contents will reflect data written by shaders prior to the barrier. - // Additionally, writes via these commands issued after the barrier will wait on - // the completion of any shader writes to the same memory initiated prior to the barrier. + GL_BUFFER_UPDATE_BARRIER_BIT, // Reads or writes to buffer objects via any OpenGL API functions that allow + // modifying their contents will reflect data written by shaders prior to the barrier. + // Additionally, writes via these commands issued after the barrier will wait on + // the completion of any shader writes to the same memory initiated prior to the barrier. CtxState); SrcBufferGL.BufferMemoryBarrier( GL_BUFFER_UPDATE_BARRIER_BIT, CtxState); - // Whilst glCopyBufferSubData() can be used to copy data between buffers bound to any two targets, - // the targets GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are provided specifically for this purpose. - // Neither target is used for anything else by OpenGL, and so you can safely bind buffers to them for - // the purposes of copying or staging data without disturbing OpenGL state or needing to keep track of + // Whilst glCopyBufferSubData() can be used to copy data between buffers bound to any two targets, + // the targets GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are provided specifically for this purpose. + // Neither target is used for anything else by OpenGL, and so you can safely bind buffers to them for + // the purposes of copying or staging data without disturbing OpenGL state or needing to keep track of // what was bound to the target before your copy. constexpr bool ResetVAO = false; // No need to reset VAO for READ/WRITE targets CtxState.BindBuffer(GL_COPY_WRITE_BUFFER, m_GlBuffer, ResetVAO); @@ -243,12 +247,12 @@ void BufferGLImpl :: CopyData(GLContextState& CtxState, BufferGLImpl& SrcBufferG CtxState.BindBuffer(GL_COPY_WRITE_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); } -void BufferGLImpl :: Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +void BufferGLImpl ::Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, PVoid& pMappedData) { BufferMemoryBarrier( - GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT,// Access by the client to persistent mapped regions of buffer - // objects will reflect data written by shaders prior to the barrier. - // Note that this may cause additional synchronization operations. + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT, // Access by the client to persistent mapped regions of buffer + // objects will reflect data written by shaders prior to the barrier. + // Note that this may cause additional synchronization operations. CtxState); // We must unbind VAO because otherwise we will break the bindings @@ -256,52 +260,52 @@ void BufferGLImpl :: Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapF CtxState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO); // !!!WARNING!!! GL_MAP_UNSYNCHRONIZED_BIT is not the same thing as MAP_FLAG_DO_NOT_WAIT. - // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize operations + // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize operations // on the buffer. This does not mean that map will fail if the buffer still in use. It is thus // what WRITE_NO_OVERWRITE does GLbitfield Access = 0; - switch(MapType) + switch (MapType) { - case MAP_READ: + case MAP_READ: Access |= GL_MAP_READ_BIT; - break; + break; case MAP_WRITE: Access |= GL_MAP_WRITE_BIT; - + if (MapFlags & MAP_FLAG_DISCARD) { // Use GL_MAP_INVALIDATE_BUFFER_BIT flag to discard previous buffer contents - // If GL_MAP_INVALIDATE_BUFFER_BIT is specified, the entire contents of the buffer may - // be discarded and considered invalid, regardless of the specified range. Any data - // lying outside the mapped range of the buffer object becomes undefined, as does any - // data within the range but not subsequently written by the application.This flag may + // If GL_MAP_INVALIDATE_BUFFER_BIT is specified, the entire contents of the buffer may + // be discarded and considered invalid, regardless of the specified range. Any data + // lying outside the mapped range of the buffer object becomes undefined, as does any + // data within the range but not subsequently written by the application.This flag may // not be used with GL_MAP_READ_BIT. Access |= GL_MAP_INVALIDATE_BUFFER_BIT; } if (MapFlags & MAP_FLAG_DO_NOT_SYNCHRONIZE) { - // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize - // operations on the buffer. + // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize + // operations on the buffer. Access |= GL_MAP_UNSYNCHRONIZED_BIT; } - break; - + break; + case MAP_READ_WRITE: Access |= GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; - break; + break; - default: UNEXPECTED( "Unknown map type" ); + default: UNEXPECTED("Unknown map type"); } - pMappedData = glMapBufferRange(m_BindTarget, 0, m_Desc.uiSizeInBytes, Access); + pMappedData = glMapBufferRange(m_BindTarget, 0, m_Desc.uiSizeInBytes, Access); CHECK_GL_ERROR("glMapBufferRange() failed"); - VERIFY( pMappedData, "Map failed" ); + VERIFY(pMappedData, "Map failed"); } void BufferGLImpl::Unmap(GLContextState& CtxState) @@ -317,14 +321,16 @@ void BufferGLImpl::Unmap(GLContextState& CtxState) // occur only during the periods that a buffer's data store is mapped. If such corruption // has occurred, glUnmapBuffer() returns FALSE, and the contents of the buffer's // data store become undefined. - VERIFY( Result != GL_FALSE, "Failed to unmap buffer. The data may have been corrupted" ); (void)Result; + VERIFY(Result != GL_FALSE, "Failed to unmap buffer. The data may have been corrupted"); + (void)Result; } -void BufferGLImpl::BufferMemoryBarrier( Uint32 RequiredBarriers, GLContextState &GLContextState ) +void BufferGLImpl::BufferMemoryBarrier(Uint32 RequiredBarriers, GLContextState& GLContextState) { #if GL_ARB_shader_image_load_store - #ifdef _DEBUG +# ifdef _DEBUG { + // clang-format off constexpr Uint32 BufferBarriers = GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | @@ -335,45 +341,46 @@ void BufferGLImpl::BufferMemoryBarrier( Uint32 RequiredBarriers, GLContextState GL_SHADER_STORAGE_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - VERIFY( (RequiredBarriers & BufferBarriers) !=0, "At least one buffer memory barrier flag should be set" ); - VERIFY( (RequiredBarriers & ~BufferBarriers) == 0, "Inappropriate buffer memory barrier flag" ); + // clang-format on + VERIFY((RequiredBarriers & BufferBarriers) != 0, "At least one buffer memory barrier flag should be set"); + VERIFY((RequiredBarriers & ~BufferBarriers) == 0, "Inappropriate buffer memory barrier flag"); } - #endif - - GLContextState.EnsureMemoryBarrier( RequiredBarriers, this ); +# endif + + GLContextState.EnsureMemoryBarrier(RequiredBarriers, this); #endif } void BufferGLImpl::CreateViewInternal(const BufferViewDesc& OrigViewDesc, class IBufferView** ppView, bool bIsDefaultView) { - VERIFY( ppView != nullptr, "Buffer view pointer address is null" ); - if( !ppView )return; - VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); - + VERIFY(ppView != nullptr, "Buffer view pointer address is null"); + if (!ppView) return; + VERIFY(*ppView == nullptr, "Overwriting reference to existing object may cause memory leaks"); + *ppView = nullptr; try { auto ViewDesc = OrigViewDesc; - CorrectBufferViewDesc( ViewDesc ); + CorrectBufferViewDesc(ViewDesc); - auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); - auto &BuffViewAllocator = pDeviceGLImpl->GetBuffViewObjAllocator(); - VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" ); + auto* pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); + auto& BuffViewAllocator = pDeviceGLImpl->GetBuffViewObjAllocator(); + VERIFY(&BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization"); auto pContext = pDeviceGLImpl->GetImmediateContext(); - VERIFY( pContext, "Immediate context has been released" ); - + VERIFY(pContext, "Immediate context has been released"); + *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewGLImpl instance", BufferViewGLImpl, bIsDefaultView ? this : nullptr)(pDeviceGLImpl, pContext, ViewDesc, this, bIsDefaultView); - - if( !bIsDefaultView ) + + if (!bIsDefaultView) (*ppView)->AddRef(); } - catch( const std::runtime_error & ) + catch (const std::runtime_error&) { - const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); + const auto* ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name ? m_Desc.Name : "", "\""); } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp index 1d0444a2..66a16b18 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp @@ -31,67 +31,72 @@ namespace Diligent { - BufferViewGLImpl::BufferViewGLImpl( IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDevice, - IDeviceContext* pContext, - const BufferViewDesc& ViewDesc, - BufferGLImpl* pBuffer, - bool bIsDefaultView) : - TBuffViewBase - { - pRefCounters, - pDevice, - ViewDesc, - pBuffer, - bIsDefaultView - }, - m_GLTexBuffer{false} +BufferViewGLImpl::BufferViewGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + IDeviceContext* pContext, + const BufferViewDesc& ViewDesc, + BufferGLImpl* pBuffer, + bool bIsDefaultView) : + // clang-format off + TBuffViewBase + { + pRefCounters, + pDevice, + ViewDesc, + pBuffer, + bIsDefaultView + }, + m_GLTexBuffer{false} +// clang-format on +{ + const auto& BuffDesc = pBuffer->GetDesc(); + if ((ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE || ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) && + (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_RAW)) { - const auto& BuffDesc = pBuffer->GetDesc(); - if ((ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE || ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) && - (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_RAW)) - { #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4127) // conditional expression is constant +# pragma warning(push) +# pragma warning(disable : 4127) // conditional expression is constant #endif - VERIFY( GL_TEXTURE_BUFFER != 0, "GL texture buffers are not supported"); + VERIFY(GL_TEXTURE_BUFFER != 0, "GL texture buffers are not supported"); #ifdef _MSC_VER -# pragma warning(pop) +# pragma warning(pop) #endif - auto* pContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); - auto& ContextState = pContextGL->GetContextState(); + auto* pContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); + auto& ContextState = pContextGL->GetContextState(); - m_GLTexBuffer.Create(); - ContextState.BindTexture(-1, GL_TEXTURE_BUFFER, m_GLTexBuffer); + m_GLTexBuffer.Create(); + ContextState.BindTexture(-1, GL_TEXTURE_BUFFER, m_GLTexBuffer); - const auto& BuffFmt = ViewDesc.Format; - GLenum GLFormat = 0; - if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffFmt.ValueType != VT_UNDEFINED) - GLFormat = TypeToGLTexFormat( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); - else - { - GLFormat = GL_R32UI; - } + const auto& BuffFmt = ViewDesc.Format; + GLenum GLFormat = 0; + if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffFmt.ValueType != VT_UNDEFINED) + { + GLFormat = TypeToGLTexFormat(BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized); + } + else + { + GLFormat = GL_R32UI; + } - if (ViewDesc.ByteOffset == 0 && ViewDesc.ByteWidth == BuffDesc.uiSizeInBytes) - glTexBuffer(GL_TEXTURE_BUFFER, GLFormat, pBuffer->GetGLHandle()); - else - { + if (ViewDesc.ByteOffset == 0 && ViewDesc.ByteWidth == BuffDesc.uiSizeInBytes) + glTexBuffer(GL_TEXTURE_BUFFER, GLFormat, pBuffer->GetGLHandle()); + else + { #if GL_ARB_texture_buffer_range - glTexBufferRange(GL_TEXTURE_BUFFER, GLFormat, pBuffer->GetGLHandle(), ViewDesc.ByteOffset, ViewDesc.ByteWidth); + glTexBufferRange(GL_TEXTURE_BUFFER, GLFormat, pBuffer->GetGLHandle(), ViewDesc.ByteOffset, ViewDesc.ByteWidth); #else - LOG_ERROR_AND_THROW("Unable to create view '", ViewDesc.Name, "' for buffer '", BuffDesc.Name, - "' because GL_ARB_texture_buffer_range extension is not available. " - "Only full-buffer views can be created on this device."); + LOG_ERROR_AND_THROW("Unable to create view '", ViewDesc.Name, "' for buffer '", BuffDesc.Name, + "' because GL_ARB_texture_buffer_range extension is not available. " + "Only full-buffer views can be created on this device."); #endif - } - CHECK_GL_ERROR_AND_THROW( "Failed to create texture buffer" ); - - ContextState.BindTexture(-1, GL_TEXTURE_BUFFER, GLObjectWrappers::GLTextureObj(false)); } - } + CHECK_GL_ERROR_AND_THROW("Failed to create texture buffer"); - IMPLEMENT_QUERY_INTERFACE( BufferViewGLImpl, IID_BufferViewGL, TBuffViewBase ) + ContextState.BindTexture(-1, GL_TEXTURE_BUFFER, GLObjectWrappers::GLTextureObj(false)); + } } + +IMPLEMENT_QUERY_INTERFACE(BufferViewGLImpl, IID_BufferViewGL, TBuffViewBase) + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index bdac5e7c..916c30a8 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -50,1189 +50,1192 @@ using namespace std; namespace Diligent { - DeviceContextGLImpl::DeviceContextGLImpl(IReferenceCounters* pRefCounters, class RenderDeviceGLImpl* pDeviceGL, bool bIsDeferred) : - TDeviceContextBase - { - pRefCounters, - pDeviceGL, - bIsDeferred - }, - m_ContextState {pDeviceGL}, - m_CommitedResourcesTentativeBarriers {0 }, - m_DefaultFBO {false } + +DeviceContextGLImpl::DeviceContextGLImpl(IReferenceCounters* pRefCounters, class RenderDeviceGLImpl* pDeviceGL, bool bIsDeferred) : + // clang-format off + TDeviceContextBase { - m_BoundWritableTextures.reserve( 16 ); - m_BoundWritableBuffers.reserve( 16 ); - } + pRefCounters, + pDeviceGL, + bIsDeferred + }, + m_ContextState {pDeviceGL}, + m_CommitedResourcesTentativeBarriers {0 }, + m_DefaultFBO {false } +// clang-format on +{ + m_BoundWritableTextures.reserve(16); + m_BoundWritableBuffers.reserve(16); +} - IMPLEMENT_QUERY_INTERFACE( DeviceContextGLImpl, IID_DeviceContextGL, TDeviceContextBase ) +IMPLEMENT_QUERY_INTERFACE(DeviceContextGLImpl, IID_DeviceContextGL, TDeviceContextBase) - void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) - { - auto* pPipelineStateGLImpl = ValidatedCast<PipelineStateGLImpl>(pPipelineState); - if (PipelineStateGLImpl::IsSameObject(m_pPipelineState, pPipelineStateGLImpl)) - return; +void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) +{ + auto* pPipelineStateGLImpl = ValidatedCast<PipelineStateGLImpl>(pPipelineState); + if (PipelineStateGLImpl::IsSameObject(m_pPipelineState, pPipelineStateGLImpl)) + return; - TDeviceContextBase::SetPipelineState(pPipelineStateGLImpl, 0 /*Dummy*/); + TDeviceContextBase::SetPipelineState(pPipelineStateGLImpl, 0 /*Dummy*/); - const auto& Desc = pPipelineStateGLImpl->GetDesc(); - if (Desc.IsComputePipeline) + const auto& Desc = pPipelineStateGLImpl->GetDesc(); + if (Desc.IsComputePipeline) + { + } + else + { + const auto& GraphicsPipeline = Desc.GraphicsPipeline; + // Set rasterizer state { + const auto& RasterizerDesc = GraphicsPipeline.RasterizerDesc; + + m_ContextState.SetFillMode(RasterizerDesc.FillMode); + m_ContextState.SetCullMode(RasterizerDesc.CullMode); + m_ContextState.SetFrontFace(RasterizerDesc.FrontCounterClockwise); + m_ContextState.SetDepthBias(static_cast<Float32>(RasterizerDesc.DepthBias), RasterizerDesc.SlopeScaledDepthBias); + if (RasterizerDesc.DepthBiasClamp != 0) + LOG_WARNING_MESSAGE("Depth bias clamp is not supported on OpenGL"); + + // Enabling depth clamping in GL is the same as disabling clipping in Direct3D. + // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc + // https://www.khronos.org/opengl/wiki/GLAPI/glEnable + m_ContextState.SetDepthClamp(!RasterizerDesc.DepthClipEnable); + + m_ContextState.EnableScissorTest(RasterizerDesc.ScissorEnable); + if (RasterizerDesc.AntialiasedLineEnable) + LOG_WARNING_MESSAGE("Line antialiasing is not supported on OpenGL"); } - else - { - const auto& GraphicsPipeline = Desc.GraphicsPipeline; - // Set rasterizer state - { - const auto& RasterizerDesc = GraphicsPipeline.RasterizerDesc; - - m_ContextState.SetFillMode(RasterizerDesc.FillMode); - m_ContextState.SetCullMode(RasterizerDesc.CullMode); - m_ContextState.SetFrontFace(RasterizerDesc.FrontCounterClockwise); - m_ContextState.SetDepthBias( static_cast<Float32>( RasterizerDesc.DepthBias ), RasterizerDesc.SlopeScaledDepthBias ); - if( RasterizerDesc.DepthBiasClamp != 0 ) - LOG_WARNING_MESSAGE( "Depth bias clamp is not supported on OpenGL" ); - - // Enabling depth clamping in GL is the same as disabling clipping in Direct3D. - // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc - // https://www.khronos.org/opengl/wiki/GLAPI/glEnable - m_ContextState.SetDepthClamp( !RasterizerDesc.DepthClipEnable ); - - m_ContextState.EnableScissorTest( RasterizerDesc.ScissorEnable ); - if( RasterizerDesc.AntialiasedLineEnable ) - LOG_WARNING_MESSAGE( "Line antialiasing is not supported on OpenGL" ); - } - // Set blend state - { - const auto& BSDsc = GraphicsPipeline.BlendDesc; - m_ContextState.SetBlendState(BSDsc, GraphicsPipeline.SampleMask); - } + // Set blend state + { + const auto& BSDsc = GraphicsPipeline.BlendDesc; + m_ContextState.SetBlendState(BSDsc, GraphicsPipeline.SampleMask); + } - // Set depth-stencil state - { - const auto& DepthStencilDesc = GraphicsPipeline.DepthStencilDesc; + // Set depth-stencil state + { + const auto& DepthStencilDesc = GraphicsPipeline.DepthStencilDesc; - m_ContextState.EnableDepthTest( DepthStencilDesc.DepthEnable ); - m_ContextState.EnableDepthWrites( DepthStencilDesc.DepthWriteEnable ); - m_ContextState.SetDepthFunc( DepthStencilDesc.DepthFunc ); + m_ContextState.EnableDepthTest(DepthStencilDesc.DepthEnable); + m_ContextState.EnableDepthWrites(DepthStencilDesc.DepthWriteEnable); + m_ContextState.SetDepthFunc(DepthStencilDesc.DepthFunc); - m_ContextState.EnableStencilTest( DepthStencilDesc.StencilEnable ); + m_ContextState.EnableStencilTest(DepthStencilDesc.StencilEnable); - m_ContextState.SetStencilWriteMask( DepthStencilDesc.StencilWriteMask ); + m_ContextState.SetStencilWriteMask(DepthStencilDesc.StencilWriteMask); - { - const auto& FrontFace = DepthStencilDesc.FrontFace; - m_ContextState.SetStencilFunc( GL_FRONT, FrontFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask ); - m_ContextState.SetStencilOp( GL_FRONT, FrontFace.StencilFailOp, FrontFace.StencilDepthFailOp, FrontFace.StencilPassOp ); - } + { + const auto& FrontFace = DepthStencilDesc.FrontFace; + m_ContextState.SetStencilFunc(GL_FRONT, FrontFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask); + m_ContextState.SetStencilOp(GL_FRONT, FrontFace.StencilFailOp, FrontFace.StencilDepthFailOp, FrontFace.StencilPassOp); + } - { - const auto& BackFace = DepthStencilDesc.BackFace; - m_ContextState.SetStencilFunc( GL_BACK, BackFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask ); - m_ContextState.SetStencilOp( GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp ); - } + { + const auto& BackFace = DepthStencilDesc.BackFace; + m_ContextState.SetStencilFunc(GL_BACK, BackFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask); + m_ContextState.SetStencilOp(GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp); } - m_ContextState.InvalidateVAO(); } + m_ContextState.InvalidateVAO(); } +} - void DeviceContextGLImpl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) - { - - } +void DeviceContextGLImpl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) +{ +} - void DeviceContextGLImpl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) - { - if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0)) - return; +void DeviceContextGLImpl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +{ + if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0)) + return; - if (m_CommitedResourcesTentativeBarriers != 0) - LOG_INFO_MESSAGE("Not all tentative resource barriers have been executed since the last call to CommitShaderResources(). Did you forget to call Draw()/DispatchCompute() ?"); + if (m_CommitedResourcesTentativeBarriers != 0) + LOG_INFO_MESSAGE("Not all tentative resource barriers have been executed since the last call to CommitShaderResources(). Did you forget to call Draw()/DispatchCompute() ?"); - m_CommitedResourcesTentativeBarriers = 0; - BindProgramResources(m_CommitedResourcesTentativeBarriers, pShaderResourceBinding); - // m_CommitedResourcesTentativeBarriers will contain memory barriers that will be required - // AFTER the actual draw/dispatch command is executed. Before that they have no meaning - } + m_CommitedResourcesTentativeBarriers = 0; + BindProgramResources(m_CommitedResourcesTentativeBarriers, pShaderResourceBinding); + // m_CommitedResourcesTentativeBarriers will contain memory barriers that will be required + // AFTER the actual draw/dispatch command is executed. Before that they have no meaning +} - void DeviceContextGLImpl::SetStencilRef(Uint32 StencilRef) +void DeviceContextGLImpl::SetStencilRef(Uint32 StencilRef) +{ + if (TDeviceContextBase::SetStencilRef(StencilRef, 0)) { - if (TDeviceContextBase::SetStencilRef(StencilRef, 0)) - { - m_ContextState.SetStencilRef(GL_FRONT, StencilRef); - m_ContextState.SetStencilRef(GL_BACK, StencilRef); - } + m_ContextState.SetStencilRef(GL_FRONT, StencilRef); + m_ContextState.SetStencilRef(GL_BACK, StencilRef); } +} - void DeviceContextGLImpl::SetBlendFactors(const float* pBlendFactors) +void DeviceContextGLImpl::SetBlendFactors(const float* pBlendFactors) +{ + if (TDeviceContextBase::SetBlendFactors(pBlendFactors, 0)) { - if (TDeviceContextBase::SetBlendFactors(pBlendFactors, 0)) - { - m_ContextState.SetBlendFactors(m_BlendFactors); - } + m_ContextState.SetBlendFactors(m_BlendFactors); } +} - void DeviceContextGLImpl::SetVertexBuffers(Uint32 StartSlot, - Uint32 NumBuffersSet, - IBuffer** ppBuffers, - Uint32* pOffsets, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, - SET_VERTEX_BUFFERS_FLAGS Flags) - { - TDeviceContextBase::SetVertexBuffers(StartSlot, NumBuffersSet, ppBuffers, pOffsets, StateTransitionMode, Flags); - m_ContextState.InvalidateVAO(); - } +void DeviceContextGLImpl::SetVertexBuffers(Uint32 StartSlot, + Uint32 NumBuffersSet, + IBuffer** ppBuffers, + Uint32* pOffsets, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, + SET_VERTEX_BUFFERS_FLAGS Flags) +{ + TDeviceContextBase::SetVertexBuffers(StartSlot, NumBuffersSet, ppBuffers, pOffsets, StateTransitionMode, Flags); + m_ContextState.InvalidateVAO(); +} - void DeviceContextGLImpl::InvalidateState() - { - TDeviceContextBase::InvalidateState(); +void DeviceContextGLImpl::InvalidateState() +{ + TDeviceContextBase::InvalidateState(); - m_ContextState.Invalidate(); - m_BoundWritableTextures.clear(); - m_BoundWritableBuffers.clear(); - } + m_ContextState.Invalidate(); + m_BoundWritableTextures.clear(); + m_BoundWritableBuffers.clear(); +} - void DeviceContextGLImpl::SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) - { - TDeviceContextBase::SetIndexBuffer(pIndexBuffer, ByteOffset, StateTransitionMode); - m_ContextState.InvalidateVAO(); - } +void DeviceContextGLImpl::SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +{ + TDeviceContextBase::SetIndexBuffer(pIndexBuffer, ByteOffset, StateTransitionMode); + m_ContextState.InvalidateVAO(); +} - void DeviceContextGLImpl::SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) - { - TDeviceContextBase::SetViewports(NumViewports, pViewports, RTWidth, RTHeight); +void DeviceContextGLImpl::SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) +{ + TDeviceContextBase::SetViewports(NumViewports, pViewports, RTWidth, RTHeight); - VERIFY(NumViewports == m_NumViewports, "Unexpected number of viewports"); - if (NumViewports == 1) + VERIFY(NumViewports == m_NumViewports, "Unexpected number of viewports"); + if (NumViewports == 1) + { + const auto& vp = m_Viewports[0]; + // Note that OpenGL and DirectX use different origin of + // the viewport in window coordinates: + // + // DirectX (0,0) + // \ ____________ + // | | + // | | + // | | + // | | + // |____________| + // / + // OpenGL (0,0) + // + float BottomLeftY = static_cast<float>(RTHeight) - (vp.TopLeftY + vp.Height); + float BottomLeftX = vp.TopLeftX; + + Int32 x = static_cast<int>(BottomLeftX); + Int32 y = static_cast<int>(BottomLeftY); + Int32 w = static_cast<int>(vp.Width); + Int32 h = static_cast<int>(vp.Height); + if (static_cast<float>(x) == BottomLeftX && + static_cast<float>(y) == BottomLeftY && + static_cast<float>(w) == vp.Width && + static_cast<float>(h) == vp.Height) { - const auto& vp = m_Viewports[0]; - // Note that OpenGL and DirectX use different origin of - // the viewport in window coordinates: - // - // DirectX (0,0) - // \ ____________ - // | | - // | | - // | | - // | | - // |____________| - // / - // OpenGL (0,0) - // - float BottomLeftY = static_cast<float>(RTHeight) - (vp.TopLeftY + vp.Height); - float BottomLeftX = vp.TopLeftX; - - Int32 x = static_cast<int>(BottomLeftX); - Int32 y = static_cast<int>(BottomLeftY); - Int32 w = static_cast<int>(vp.Width); - Int32 h = static_cast<int>(vp.Height); - if( static_cast<float>(x) == BottomLeftX && - static_cast<float>(y) == BottomLeftY && - static_cast<float>(w) == vp.Width && - static_cast<float>(h) == vp.Height ) - { - // GL_INVALID_VALUE is generated if either width or height is negative - // https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glViewport.xml - glViewport(x, y, w, h); - } - else - { - // GL_INVALID_VALUE is generated if either width or height is negative - // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewportIndexed.xhtml - glViewportIndexedf(0, BottomLeftX, BottomLeftY, vp.Width, vp.Height); - } - CHECK_GL_ERROR("Failed to set viewport"); - - glDepthRangef(vp.MinDepth, vp.MaxDepth); - CHECK_GL_ERROR("Failed to set depth range"); + // GL_INVALID_VALUE is generated if either width or height is negative + // https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glViewport.xml + glViewport(x, y, w, h); } else { - for (Uint32 i = 0; i < NumViewports; ++i) - { - const auto& vp = m_Viewports[i]; - float BottomLeftY = static_cast<float>(RTHeight) - (vp.TopLeftY + vp.Height); - float BottomLeftX = vp.TopLeftX; - glViewportIndexedf(i, BottomLeftX, BottomLeftY, vp.Width, vp.Height); - CHECK_GL_ERROR("Failed to set viewport #", i); - glDepthRangef(vp.MinDepth, vp.MaxDepth ); - CHECK_GL_ERROR("Failed to set depth range for viewport #", i); - } + // GL_INVALID_VALUE is generated if either width or height is negative + // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewportIndexed.xhtml + glViewportIndexedf(0, BottomLeftX, BottomLeftY, vp.Width, vp.Height); } - } + CHECK_GL_ERROR("Failed to set viewport"); - void DeviceContextGLImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) + glDepthRangef(vp.MinDepth, vp.MaxDepth); + CHECK_GL_ERROR("Failed to set depth range"); + } + else { - TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); - - VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); - if (NumRects == 1) + for (Uint32 i = 0; i < NumViewports; ++i) { - const auto& Rect = m_ScissorRects[0]; - // Note that OpenGL and DirectX use different origin - // of the viewport in window coordinates: - // - // DirectX (0,0) - // \ ____________ - // | | - // | | - // | | - // | | - // |____________| - // / - // OpenGL (0,0) - // - auto glBottom = RTHeight - Rect.bottom; - - auto width = Rect.right - Rect.left; - auto height = Rect.bottom - Rect.top; - glScissor( Rect.left, glBottom, width, height ); - CHECK_GL_ERROR( "Failed to set scissor rect" ); + const auto& vp = m_Viewports[i]; + float BottomLeftY = static_cast<float>(RTHeight) - (vp.TopLeftY + vp.Height); + float BottomLeftX = vp.TopLeftX; + glViewportIndexedf(i, BottomLeftX, BottomLeftY, vp.Width, vp.Height); + CHECK_GL_ERROR("Failed to set viewport #", i); + glDepthRangef(vp.MinDepth, vp.MaxDepth); + CHECK_GL_ERROR("Failed to set depth range for viewport #", i); } - else + } +} + +void DeviceContextGLImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) +{ + TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); + + VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); + if (NumRects == 1) + { + const auto& Rect = m_ScissorRects[0]; + // Note that OpenGL and DirectX use different origin + // of the viewport in window coordinates: + // + // DirectX (0,0) + // \ ____________ + // | | + // | | + // | | + // | | + // |____________| + // / + // OpenGL (0,0) + // + auto glBottom = RTHeight - Rect.bottom; + + auto width = Rect.right - Rect.left; + auto height = Rect.bottom - Rect.top; + glScissor(Rect.left, glBottom, width, height); + CHECK_GL_ERROR("Failed to set scissor rect"); + } + else + { + for (Uint32 sr = 0; sr < NumRects; ++sr) { - for (Uint32 sr = 0; sr < NumRects; ++sr) - { - const auto& Rect = m_ScissorRects[sr]; - auto glBottom = RTHeight - Rect.bottom; - auto width = Rect.right - Rect.left; - auto height = Rect.bottom - Rect.top; - glScissorIndexed(sr, Rect.left, glBottom, width, height ); - CHECK_GL_ERROR("Failed to set scissor rect #", sr); - } + const auto& Rect = m_ScissorRects[sr]; + auto glBottom = RTHeight - Rect.bottom; + auto width = Rect.right - Rect.left; + auto height = Rect.bottom - Rect.top; + glScissorIndexed(sr, Rect.left, glBottom, width, height); + CHECK_GL_ERROR("Failed to set scissor rect #", sr); } } +} - void DeviceContextGLImpl::CommitRenderTargets() +void DeviceContextGLImpl::CommitRenderTargets() +{ + if (m_IsDefaultFramebufferBound) { - if (m_IsDefaultFramebufferBound) + auto* pSwapChainGL = m_pSwapChain.RawPtr<ISwapChainGL>(); + GLuint DefaultFBOHandle = pSwapChainGL->GetDefaultFBO(); + if (m_DefaultFBO != DefaultFBOHandle) { - auto* pSwapChainGL = m_pSwapChain.RawPtr<ISwapChainGL>(); - GLuint DefaultFBOHandle = pSwapChainGL->GetDefaultFBO(); - if (m_DefaultFBO != DefaultFBOHandle) - { - m_DefaultFBO = GLObjectWrappers::GLFrameBufferObj(true, GLObjectWrappers::GLFBOCreateReleaseHelper(DefaultFBOHandle)); - } - m_ContextState.BindFBO(m_DefaultFBO); + m_DefaultFBO = GLObjectWrappers::GLFrameBufferObj(true, GLObjectWrappers::GLFBOCreateReleaseHelper(DefaultFBOHandle)); } - else - { - VERIFY(m_NumBoundRenderTargets != 0 || m_pBoundDepthStencil, "At least one render target or a depth stencil is expected"); - - Uint32 NumRenderTargets = m_NumBoundRenderTargets; - VERIFY(NumRenderTargets < MaxRenderTargets, "Too many render targets (", NumRenderTargets, ") are being set"); - NumRenderTargets = std::min(NumRenderTargets, MaxRenderTargets); + m_ContextState.BindFBO(m_DefaultFBO); + } + else + { + VERIFY(m_NumBoundRenderTargets != 0 || m_pBoundDepthStencil, "At least one render target or a depth stencil is expected"); - const auto& CtxCaps = m_ContextState.GetContextCaps(); - VERIFY(NumRenderTargets < static_cast<Uint32>(CtxCaps.m_iMaxDrawBuffers), "This device only supports ", CtxCaps.m_iMaxDrawBuffers, " draw buffers, but ", NumRenderTargets, " are being set"); - NumRenderTargets = std::min(NumRenderTargets, static_cast<Uint32>(CtxCaps.m_iMaxDrawBuffers)); + Uint32 NumRenderTargets = m_NumBoundRenderTargets; + VERIFY(NumRenderTargets < MaxRenderTargets, "Too many render targets (", NumRenderTargets, ") are being set"); + NumRenderTargets = std::min(NumRenderTargets, MaxRenderTargets); - TextureViewGLImpl* pBoundRTVs[MaxRenderTargets] = {}; - for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) - { - pBoundRTVs[rt] = m_pBoundRenderTargets[rt]; - DEV_CHECK_ERR(!pBoundRTVs[rt] || pBoundRTVs[rt]->GetTexture<TextureBaseGL>()->GetGLHandle(), - "Color buffer of the default framebuffer can only be bound with the default framebuffer's depth buffer " - "and cannot be combined with any other render target or depth buffer in OpenGL backend."); - } + const auto& CtxCaps = m_ContextState.GetContextCaps(); + VERIFY(NumRenderTargets < static_cast<Uint32>(CtxCaps.m_iMaxDrawBuffers), "This device only supports ", CtxCaps.m_iMaxDrawBuffers, " draw buffers, but ", NumRenderTargets, " are being set"); + NumRenderTargets = std::min(NumRenderTargets, static_cast<Uint32>(CtxCaps.m_iMaxDrawBuffers)); - DEV_CHECK_ERR(!m_pBoundDepthStencil || m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle(), - "Depth buffer of the default framebuffer can only be bound with the default framebuffer's color buffer " - "and cannot be combined with any other render target in OpenGL backend."); - - auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext(); - auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext); - const auto& FBO = FBOCache.GetFBO(NumRenderTargets, pBoundRTVs, m_pBoundDepthStencil, m_ContextState); - // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT - // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. - // Binding a new framebuffer will NOT affect the mask. - m_ContextState.BindFBO(FBO); + TextureViewGLImpl* pBoundRTVs[MaxRenderTargets] = {}; + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) + { + pBoundRTVs[rt] = m_pBoundRenderTargets[rt]; + DEV_CHECK_ERR(!pBoundRTVs[rt] || pBoundRTVs[rt]->GetTexture<TextureBaseGL>()->GetGLHandle(), + "Color buffer of the default framebuffer can only be bound with the default framebuffer's depth buffer " + "and cannot be combined with any other render target or depth buffer in OpenGL backend."); } - // Set the viewport to match the render target size - SetViewports(1, nullptr, 0, 0); + + DEV_CHECK_ERR(!m_pBoundDepthStencil || m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle(), + "Depth buffer of the default framebuffer can only be bound with the default framebuffer's color buffer " + "and cannot be combined with any other render target in OpenGL backend."); + + auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext(); + auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext); + const auto& FBO = FBOCache.GetFBO(NumRenderTargets, pBoundRTVs, m_pBoundDepthStencil, m_ContextState); + // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT + // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. + // Binding a new framebuffer will NOT affect the mask. + m_ContextState.BindFBO(FBO); } + // Set the viewport to match the render target size + SetViewports(1, nullptr, 0, 0); +} - void DeviceContextGLImpl::SetRenderTargets(Uint32 NumRenderTargets, - ITextureView* ppRenderTargets[], - ITextureView* pDepthStencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +void DeviceContextGLImpl::SetRenderTargets(Uint32 NumRenderTargets, + ITextureView* ppRenderTargets[], + ITextureView* pDepthStencil, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +{ + if (TDeviceContextBase::SetRenderTargets(NumRenderTargets, ppRenderTargets, pDepthStencil)) { - if (TDeviceContextBase::SetRenderTargets( NumRenderTargets, ppRenderTargets, pDepthStencil)) + if (!m_IsDefaultFramebufferBound) { - if (!m_IsDefaultFramebufferBound) + if (m_NumBoundRenderTargets == 1 && m_pBoundRenderTargets[0] && m_pBoundRenderTargets[0]->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) { - if (m_NumBoundRenderTargets == 1 && m_pBoundRenderTargets[0] && m_pBoundRenderTargets[0]->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) - { - DEV_CHECK_ERR(!m_pBoundDepthStencil || m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0, - "Attempting to bind texture '", m_pBoundDepthStencil->GetTexture()->GetDesc().Name, "' as depth buffer with the " - "default framebuffer's color buffer: color buffer of the default framebuffer can only be bound with the default " - "framebuffer's depth buffer and cannot be combined with any other depth buffer in OpenGL backend."); - m_IsDefaultFramebufferBound = true; - } - else if (m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) - { - m_IsDefaultFramebufferBound = true; - } + DEV_CHECK_ERR(!m_pBoundDepthStencil || m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0, + "Attempting to bind texture '", m_pBoundDepthStencil->GetTexture()->GetDesc().Name, + "' as depth buffer with the default framebuffer's color buffer: color buffer of the default framebuffer " + "can only be bound with the default framebuffer's depth buffer and cannot be combined with any other depth buffer in OpenGL backend."); + m_IsDefaultFramebufferBound = true; + } + else if (m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) + { + m_IsDefaultFramebufferBound = true; } - - CommitRenderTargets(); } + + CommitRenderTargets(); } +} - void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding) +void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding) +{ + if (!m_pPipelineState) { - if (!m_pPipelineState) - { - LOG_ERROR_MESSAGE("No pipeline state is bound"); - return; - } + LOG_ERROR_MESSAGE("No pipeline state is bound"); + return; + } - if (pResBinding == nullptr) - return; + if (pResBinding == nullptr) + return; - auto* pShaderResBindingGL = ValidatedCast<ShaderResourceBindingGLImpl>(pResBinding); - const auto& ResourceCache = pShaderResBindingGL->GetResourceCache(m_pPipelineState); + auto* pShaderResBindingGL = ValidatedCast<ShaderResourceBindingGLImpl>(pResBinding); + const auto& ResourceCache = pShaderResBindingGL->GetResourceCache(m_pPipelineState); #ifdef DEVELOPMENT - m_pPipelineState->GetResourceLayout().dvpVerifyBindings(ResourceCache); + m_pPipelineState->GetResourceLayout().dvpVerifyBindings(ResourceCache); #endif - VERIFY_EXPR(m_BoundWritableTextures.empty()); - VERIFY_EXPR(m_BoundWritableBuffers.empty()); + VERIFY_EXPR(m_BoundWritableTextures.empty()); + VERIFY_EXPR(m_BoundWritableBuffers.empty()); - for (Uint32 ub = 0; ub < ResourceCache.GetUBCount(); ++ub) - { - const auto& UB = ResourceCache.GetConstUB(ub); - if (!UB.pBuffer) - continue; + for (Uint32 ub = 0; ub < ResourceCache.GetUBCount(); ++ub) + { + const auto& UB = ResourceCache.GetConstUB(ub); + if (!UB.pBuffer) + continue; - auto* pBufferGL = UB.pBuffer.RawPtr<BufferGLImpl>(); - pBufferGL->BufferMemoryBarrier( - GL_UNIFORM_BARRIER_BIT,// Shader uniforms sourced from buffer objects after the barrier - // will reflect data written by shaders prior to the barrier - m_ContextState); + auto* pBufferGL = UB.pBuffer.RawPtr<BufferGLImpl>(); + pBufferGL->BufferMemoryBarrier( + GL_UNIFORM_BARRIER_BIT, // Shader uniforms sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier + m_ContextState); - m_ContextState.BindUniformBuffer(ub, pBufferGL->m_GlBuffer); - //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferGL->m_GlBuffer, 0, pBufferGL->GetDesc().uiSizeInBytes); - } + m_ContextState.BindUniformBuffer(ub, pBufferGL->m_GlBuffer); + //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferGL->m_GlBuffer, 0, pBufferGL->GetDesc().uiSizeInBytes); + } + + for (Uint32 s = 0; s < ResourceCache.GetSamplerCount(); ++s) + { + const auto& Sam = ResourceCache.GetConstSampler(s); + if (!Sam.pView) + continue; - for (Uint32 s = 0; s < ResourceCache.GetSamplerCount(); ++s) + // We must check 'pTexture' first as 'pBuffer' is in union with 'pSampler' + if (Sam.pTexture != nullptr) { - const auto& Sam = ResourceCache.GetConstSampler(s); - if (!Sam.pView) - continue; + auto* pTexViewGL = Sam.pView.RawPtr<TextureViewGLImpl>(); + auto* pTextureGL = ValidatedCast<TextureBaseGL>(Sam.pTexture); + VERIFY_EXPR(pTextureGL == pTexViewGL->GetTexture()); + m_ContextState.BindTexture(s, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle()); + + pTextureGL->TextureMemoryBarrier( + GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + m_ContextState); - // We must check 'pTexture' first as 'pBuffer' is in union with 'pSampler' - if (Sam.pTexture != nullptr) + if (Sam.pSampler) { - auto* pTexViewGL = Sam.pView.RawPtr<TextureViewGLImpl>(); - auto* pTextureGL = ValidatedCast<TextureBaseGL>(Sam.pTexture); - VERIFY_EXPR(pTextureGL == pTexViewGL->GetTexture()); - m_ContextState.BindTexture(s, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle()); - - pTextureGL->TextureMemoryBarrier( - GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object - // memory via buffer textures, after the barrier will reflect data - // written by shaders prior to the barrier - m_ContextState); - - if (Sam.pSampler) - { - m_ContextState.BindSampler(s, Sam.pSampler->GetHandle()); - } - else - { - m_ContextState.BindSampler(s, GLObjectWrappers::GLSamplerObj(false)); - } + m_ContextState.BindSampler(s, Sam.pSampler->GetHandle()); } - else if (Sam.pBuffer != nullptr) + else { - auto* pBufViewGL = Sam.pView.RawPtr<BufferViewGLImpl>(); - auto* pBufferGL = ValidatedCast<BufferGLImpl>(Sam.pBuffer); - VERIFY_EXPR(pBufferGL == pBufViewGL->GetBuffer()); + m_ContextState.BindSampler(s, GLObjectWrappers::GLSamplerObj(false)); + } + } + else if (Sam.pBuffer != nullptr) + { + auto* pBufViewGL = Sam.pView.RawPtr<BufferViewGLImpl>(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(Sam.pBuffer); + VERIFY_EXPR(pBufferGL == pBufViewGL->GetBuffer()); - m_ContextState.BindTexture(s, GL_TEXTURE_BUFFER, pBufViewGL->GetTexBufferHandle()); - m_ContextState.BindSampler(s, GLObjectWrappers::GLSamplerObj(false)); // Use default texture sampling parameters + m_ContextState.BindTexture(s, GL_TEXTURE_BUFFER, pBufViewGL->GetTexBufferHandle()); + m_ContextState.BindSampler(s, GLObjectWrappers::GLSamplerObj(false)); // Use default texture sampling parameters - pBufferGL->BufferMemoryBarrier( - GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object - // memory via buffer textures, after the barrier will reflect data - // written by shaders prior to the barrier - m_ContextState); - } + pBufferGL->BufferMemoryBarrier( + GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + m_ContextState); } + } #if GL_ARB_shader_image_load_store - for (Uint32 img = 0; img < ResourceCache.GetImageCount(); ++img) + for (Uint32 img = 0; img < ResourceCache.GetImageCount(); ++img) + { + const auto& Img = ResourceCache.GetConstImage(img); + if (!Img.pView) + continue; + + // We must check 'pTexture' first as 'pBuffer' is in union with 'pSampler' + if (Img.pTexture != nullptr) { - const auto& Img = ResourceCache.GetConstImage(img); - if (!Img.pView) - continue; + auto* pTexViewGL = Img.pView.RawPtr<TextureViewGLImpl>(); + auto* pTextureGL = ValidatedCast<TextureBaseGL>(Img.pTexture); + VERIFY_EXPR(pTextureGL == pTexViewGL->GetTexture()); - // We must check 'pTexture' first as 'pBuffer' is in union with 'pSampler' - if (Img.pTexture != nullptr) - { - auto* pTexViewGL = Img.pView.RawPtr<TextureViewGLImpl>(); - auto* pTextureGL = ValidatedCast<TextureBaseGL>(Img.pTexture); - VERIFY_EXPR(pTextureGL == pTexViewGL->GetTexture()); - - const auto& ViewDesc = pTexViewGL->GetDesc(); - VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Unexpected buffer view type" ); - - if (ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE) - { - pTextureGL->TextureMemoryBarrier( - GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in - // functions issued after the barrier will reflect data written by shaders - // prior to the barrier. Additionally, image stores and atomics issued after - // the barrier will not execute until all memory accesses (e.g., loads, - // stores, texture fetches, vertex fetches) initiated prior to the barrier - // complete. - m_ContextState); - // We cannot set pending memory barriers here, because - // if some texture is bound twice, the logic will fail - m_BoundWritableTextures.push_back( pTextureGL ); - } - -#ifdef _DEBUG - // Check that the texure being bound has immutable storage - { - m_ContextState.BindTexture(-1, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle()); - GLint IsImmutable = 0; - glGetTexParameteriv( pTexViewGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); - CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); - VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); - m_ContextState.BindTexture( -1, pTexViewGL->GetBindTarget(), GLObjectWrappers::GLTextureObj::Null() ); - } -#endif - auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); - // Note that if a format qulifier is specified in the shader, the format - // must match it - - GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; - // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this - // case. If "layered" is FALSE, only the single layer identified by "layer" will - // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. - GLint Layer = ViewDesc.FirstArraySlice; - - auto GLAccess = AccessFlags2GLAccess(ViewDesc.AccessFlags); - // WARNING: Texture being bound to the image unit must be complete - // That means that if an integer texture is being bound, its - // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, - // otherwise it will be incomplete - m_ContextState.BindImage(img, pTexViewGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat); - // Do not use binding points from reflection as they may not be initialized - } - else if (Img.pBuffer != nullptr) + const auto& ViewDesc = pTexViewGL->GetDesc(); + VERIFY(ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Unexpected buffer view type"); + + if (ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE) { - auto* pBuffViewGL = Img.pView.RawPtr<BufferViewGLImpl>(); - auto* pBufferGL = ValidatedCast<BufferGLImpl>(Img.pBuffer); - VERIFY_EXPR(pBufferGL == pBuffViewGL->GetBuffer()); - - const auto& ViewDesc = pBuffViewGL->GetDesc(); - VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected buffer view type" ); - - pBufferGL->BufferMemoryBarrier( - GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in - // functions issued after the barrier will reflect data written by shaders - // prior to the barrier. Additionally, image stores and atomics issued after - // the barrier will not execute until all memory accesses (e.g., loads, - // stores, texture fetches, vertex fetches) initiated prior to the barrier + pTextureGL->TextureMemoryBarrier( + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT, // Memory accesses using shader image load, store, and atomic built-in + // functions issued after the barrier will reflect data written by shaders + // prior to the barrier. Additionally, image stores and atomics issued after + // the barrier will not execute until all memory accesses (e.g., loads, + // stores, texture fetches, vertex fetches) initiated prior to the barrier // complete. m_ContextState); + // We cannot set pending memory barriers here, because + // if some texture is bound twice, the logic will fail + m_BoundWritableTextures.push_back(pTextureGL); + } - m_BoundWritableBuffers.push_back(pBufferGL); - - auto GlFormat = TypeToGLTexFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized); - m_ContextState.BindImage(img, pBuffViewGL, GL_READ_WRITE, GlFormat); +# ifdef _DEBUG + // Check that the texure being bound has immutable storage + { + m_ContextState.BindTexture(-1, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle()); + GLint IsImmutable = 0; + glGetTexParameteriv(pTexViewGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable); + CHECK_GL_ERROR("glGetTexParameteriv() failed"); + VERIFY(IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()"); + m_ContextState.BindTexture(-1, pTexViewGL->GetBindTarget(), GLObjectWrappers::GLTextureObj::Null()); } +# endif + auto GlTexFormat = TexFormatToGLInternalTexFormat(ViewDesc.Format); + // Note that if a format qulifier is specified in the shader, the format + // must match it + + GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; + // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this + // case. If "layered" is FALSE, only the single layer identified by "layer" will + // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. + GLint Layer = ViewDesc.FirstArraySlice; + + auto GLAccess = AccessFlags2GLAccess(ViewDesc.AccessFlags); + // WARNING: Texture being bound to the image unit must be complete + // That means that if an integer texture is being bound, its + // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, + // otherwise it will be incomplete + m_ContextState.BindImage(img, pTexViewGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat); + // Do not use binding points from reflection as they may not be initialized } -#endif + else if (Img.pBuffer != nullptr) + { + auto* pBuffViewGL = Img.pView.RawPtr<BufferViewGLImpl>(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(Img.pBuffer); + VERIFY_EXPR(pBufferGL == pBuffViewGL->GetBuffer()); + const auto& ViewDesc = pBuffViewGL->GetDesc(); + VERIFY(ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected buffer view type"); -#if GL_ARB_shader_storage_buffer_object - for (Uint32 ssbo = 0; ssbo < ResourceCache.GetSSBOCount(); ++ssbo) - { - const auto& SSBO = ResourceCache.GetConstSSBO(ssbo); - if (!SSBO.pBufferView) - return; - - auto* pBufferViewGL = SSBO.pBufferView.RawPtr<BufferViewGLImpl>(); - const auto& ViewDesc = pBufferViewGL->GetDesc(); - VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS || ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected buffer view type" ); - - auto* pBufferGL = pBufferViewGL->GetBuffer<BufferGLImpl>(); pBufferGL->BufferMemoryBarrier( - GL_SHADER_STORAGE_BARRIER_BIT,// Accesses to shader storage blocks after the barrier - // will reflect writes prior to the barrier + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT, // Memory accesses using shader image load, store, and atomic built-in + // functions issued after the barrier will reflect data written by shaders + // prior to the barrier. Additionally, image stores and atomics issued after + // the barrier will not execute until all memory accesses (e.g., loads, + // stores, texture fetches, vertex fetches) initiated prior to the barrier + // complete. m_ContextState); - m_ContextState.BindStorageBlock(ssbo, pBufferGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth); + m_BoundWritableBuffers.push_back(pBufferGL); - if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) - m_BoundWritableBuffers.push_back(pBufferGL); + auto GlFormat = TypeToGLTexFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized); + m_ContextState.BindImage(img, pBuffViewGL, GL_READ_WRITE, GlFormat); } + } +#endif + + +#if GL_ARB_shader_storage_buffer_object + for (Uint32 ssbo = 0; ssbo < ResourceCache.GetSSBOCount(); ++ssbo) + { + const auto& SSBO = ResourceCache.GetConstSSBO(ssbo); + if (!SSBO.pBufferView) + return; + + auto* pBufferViewGL = SSBO.pBufferView.RawPtr<BufferViewGLImpl>(); + const auto& ViewDesc = pBufferViewGL->GetDesc(); + VERIFY(ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS || ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected buffer view type"); + + auto* pBufferGL = pBufferViewGL->GetBuffer<BufferGLImpl>(); + pBufferGL->BufferMemoryBarrier( + GL_SHADER_STORAGE_BARRIER_BIT, // Accesses to shader storage blocks after the barrier + // will reflect writes prior to the barrier + m_ContextState); + + m_ContextState.BindStorageBlock(ssbo, pBufferGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth); + + if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) + m_BoundWritableBuffers.push_back(pBufferGL); + } #endif #if GL_ARB_shader_image_load_store - // Go through the list of textures bound as AUVs and set the required memory barriers - for (auto* pWritableTex : m_BoundWritableTextures) - { - Uint32 TextureMemBarriers = - GL_TEXTURE_UPDATE_BARRIER_BIT // Writes to a texture via glTex(Sub)Image*, glCopyTex(Sub)Image*, - // glClearTex*Image, glCompressedTex(Sub)Image*, and reads via - // glGetTexImage() after the barrier will reflect data written by - // shaders prior to the barrier - - | GL_TEXTURE_FETCH_BARRIER_BIT // Texture fetches from shaders, including fetches from buffer object - // memory via buffer textures, after the barrier will reflect data - // written by shaders prior to the barrier - - | GL_PIXEL_BUFFER_BARRIER_BIT // Reads and writes of buffer objects via the GL_PIXEL_PACK_BUFFER and - // GL_PIXEL_UNPACK_BUFFER bidnings after the barrier will reflect data - // written by shaders prior to the barrier + // Go through the list of textures bound as AUVs and set the required memory barriers + for (auto* pWritableTex : m_BoundWritableTextures) + { + Uint32 TextureMemBarriers = + GL_TEXTURE_UPDATE_BARRIER_BIT // Writes to a texture via glTex(Sub)Image*, glCopyTex(Sub)Image*, + // glClearTex*Image, glCompressedTex(Sub)Image*, and reads via + // glGetTexImage() after the barrier will reflect data written by + // shaders prior to the barrier - | GL_FRAMEBUFFER_BARRIER_BIT // Reads and writes via framebuffer object attachments after the - // barrier will reflect data written by shaders prior to the barrier. - // Additionally, framebuffer writes issued after the barrier will wait - // on the completion of all shader writes issued prior to the barrier. + | GL_TEXTURE_FETCH_BARRIER_BIT // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier - | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + | GL_PIXEL_BUFFER_BARRIER_BIT // Reads and writes of buffer objects via the GL_PIXEL_PACK_BUFFER and + // GL_PIXEL_UNPACK_BUFFER bidnings after the barrier will reflect data + // written by shaders prior to the barrier - NewMemoryBarriers |= TextureMemBarriers; + | GL_FRAMEBUFFER_BARRIER_BIT // Reads and writes via framebuffer object attachments after the + // barrier will reflect data written by shaders prior to the barrier. + // Additionally, framebuffer writes issued after the barrier will wait + // on the completion of all shader writes issued prior to the barrier. - // Set new required barriers for the time when texture is used next time - pWritableTex->SetPendingMemoryBarriers(TextureMemBarriers); - } - m_BoundWritableTextures.clear(); + | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - for (auto* pWritableBuff : m_BoundWritableBuffers) - { - Uint32 BufferMemoryBarriers = - GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | - GL_ELEMENT_ARRAY_BARRIER_BIT | - GL_UNIFORM_BARRIER_BIT | - GL_COMMAND_BARRIER_BIT | - GL_BUFFER_UPDATE_BARRIER_BIT | - GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | - GL_SHADER_STORAGE_BARRIER_BIT | - GL_TEXTURE_FETCH_BARRIER_BIT | - GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - - NewMemoryBarriers |= BufferMemoryBarriers; - // Set new required barriers for the time when buffer is used next time - pWritableBuff->SetPendingMemoryBarriers( BufferMemoryBarriers ); - } - m_BoundWritableBuffers.clear(); -#endif + NewMemoryBarriers |= TextureMemBarriers; + + // Set new required barriers for the time when texture is used next time + pWritableTex->SetPendingMemoryBarriers(TextureMemBarriers); } + m_BoundWritableTextures.clear(); - void DeviceContextGLImpl::PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenum& GlTopology) + for (auto* pWritableBuff : m_BoundWritableBuffers) { -#ifdef DEVELOPMENT - if ((Flags & DRAW_FLAG_VERIFY_RENDER_TARGETS) != 0) - DvpVerifyRenderTargets(); + // clang-format off + Uint32 BufferMemoryBarriers = + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | + GL_ELEMENT_ARRAY_BARRIER_BIT | + GL_UNIFORM_BARRIER_BIT | + GL_COMMAND_BARRIER_BIT | + GL_BUFFER_UPDATE_BARRIER_BIT | + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | + GL_SHADER_STORAGE_BARRIER_BIT | + GL_TEXTURE_FETCH_BARRIER_BIT | + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + // clang-format on + + NewMemoryBarriers |= BufferMemoryBarriers; + // Set new required barriers for the time when buffer is used next time + pWritableBuff->SetPendingMemoryBarriers(BufferMemoryBarriers); + } + m_BoundWritableBuffers.clear(); #endif +} - m_pPipelineState->CommitProgram(m_ContextState); +void DeviceContextGLImpl::PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenum& GlTopology) +{ +#ifdef DEVELOPMENT + if ((Flags & DRAW_FLAG_VERIFY_RENDER_TARGETS) != 0) + DvpVerifyRenderTargets(); +#endif - auto CurrNativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); - const auto& PipelineDesc = m_pPipelineState->GetDesc().GraphicsPipeline; - if (!m_ContextState.IsValidVAOBound()) - { - auto& VAOCache = m_pDevice->GetVAOCache(CurrNativeGLContext); - IBuffer* pIndexBuffer = IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr; - if (PipelineDesc.InputLayout.NumElements > 0 || pIndexBuffer != nullptr) - { - const auto& VAO = VAOCache.GetVAO( m_pPipelineState, pIndexBuffer, m_VertexStreams, m_NumVertexStreams, m_ContextState ); - m_ContextState.BindVAO( VAO ); - } - else - { - // Draw command will fail if no VAO is bound. If no vertex description is set - // (which is the case if, for instance, the command only inputs VertexID), - // use empty VAO - const auto& VAO = VAOCache.GetEmptyVAO(); - m_ContextState.BindVAO( VAO ); - } - } + m_pPipelineState->CommitProgram(m_ContextState); - auto Topology = PipelineDesc.PrimitiveTopology; - if (Topology >= PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) + auto CurrNativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); + const auto& PipelineDesc = m_pPipelineState->GetDesc().GraphicsPipeline; + if (!m_ContextState.IsValidVAOBound()) + { + auto& VAOCache = m_pDevice->GetVAOCache(CurrNativeGLContext); + IBuffer* pIndexBuffer = IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr; + if (PipelineDesc.InputLayout.NumElements > 0 || pIndexBuffer != nullptr) { -#if GL_ARB_tessellation_shader - GlTopology = GL_PATCHES; - auto NumVertices = static_cast<Int32>(Topology - PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1); - m_ContextState.SetNumPatchVertices(NumVertices); -#else - UNSUPPORTED("Tessellation is not supported"); -#endif + const auto& VAO = VAOCache.GetVAO(m_pPipelineState, pIndexBuffer, m_VertexStreams, m_NumVertexStreams, m_ContextState); + m_ContextState.BindVAO(VAO); } else { - GlTopology = PrimitiveTopologyToGLTopology( Topology ); + // Draw command will fail if no VAO is bound. If no vertex description is set + // (which is the case if, for instance, the command only inputs VertexID), + // use empty VAO + const auto& VAO = VAOCache.GetEmptyVAO(); + m_ContextState.BindVAO(VAO); } } - void DeviceContextGLImpl::PrepareForIndexedDraw(VALUE_TYPE IndexType, Uint32 FirstIndexLocation, GLenum& GLIndexType, Uint32& FirstIndexByteOffset) + auto Topology = PipelineDesc.PrimitiveTopology; + if (Topology >= PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) { - GLIndexType = TypeToGLType( IndexType ); - VERIFY( GLIndexType == GL_UNSIGNED_BYTE || GLIndexType == GL_UNSIGNED_SHORT || GLIndexType == GL_UNSIGNED_INT, - "Unsupported index type" ); - VERIFY( m_pIndexBuffer, "Index Buffer is not bound to the pipeline" ); - FirstIndexByteOffset = static_cast<Uint32>(GetValueSize( IndexType )) * FirstIndexLocation + m_IndexDataStartOffset; +#if GL_ARB_tessellation_shader + GlTopology = GL_PATCHES; + auto NumVertices = static_cast<Int32>(Topology - PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1); + m_ContextState.SetNumPatchVertices(NumVertices); +#else + UNSUPPORTED("Tessellation is not supported"); +#endif } - - void DeviceContextGLImpl::PostDraw() + else { - // IMPORTANT: new pending memory barriers in the context must be set - // after all previous barriers have been executed. - // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required - // AFTER the actual draw/dispatch command is executed. - m_ContextState.SetPendingMemoryBarriers( m_CommitedResourcesTentativeBarriers ); - m_CommitedResourcesTentativeBarriers = 0; + GlTopology = PrimitiveTopologyToGLTopology(Topology); } +} - void DeviceContextGLImpl::Draw(const DrawAttribs& Attribs) - { - if (!DvpVerifyDrawArguments(Attribs)) - return; +void DeviceContextGLImpl::PrepareForIndexedDraw(VALUE_TYPE IndexType, Uint32 FirstIndexLocation, GLenum& GLIndexType, Uint32& FirstIndexByteOffset) +{ + GLIndexType = TypeToGLType(IndexType); + VERIFY(GLIndexType == GL_UNSIGNED_BYTE || GLIndexType == GL_UNSIGNED_SHORT || GLIndexType == GL_UNSIGNED_INT, + "Unsupported index type"); + VERIFY(m_pIndexBuffer, "Index Buffer is not bound to the pipeline"); + FirstIndexByteOffset = static_cast<Uint32>(GetValueSize(IndexType)) * FirstIndexLocation + m_IndexDataStartOffset; +} - GLenum GlTopology; - PrepareForDraw(Attribs.Flags, false, GlTopology); +void DeviceContextGLImpl::PostDraw() +{ + // IMPORTANT: new pending memory barriers in the context must be set + // after all previous barriers have been executed. + // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required + // AFTER the actual draw/dispatch command is executed. + m_ContextState.SetPendingMemoryBarriers(m_CommitedResourcesTentativeBarriers); + m_CommitedResourcesTentativeBarriers = 0; +} - if (Attribs.NumInstances > 1 || Attribs.FirstInstanceLocation != 0) - { - if (Attribs.FirstInstanceLocation != 0) - glDrawArraysInstancedBaseInstance(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices, Attribs.NumInstances, Attribs.FirstInstanceLocation); - else - glDrawArraysInstanced(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices, Attribs.NumInstances); - } - else - { - glDrawArrays(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices); - } - DEV_CHECK_GL_ERROR( "OpenGL draw command failed" ); +void DeviceContextGLImpl::Draw(const DrawAttribs& Attribs) +{ + if (!DvpVerifyDrawArguments(Attribs)) + return; - PostDraw(); - } + GLenum GlTopology; + PrepareForDraw(Attribs.Flags, false, GlTopology); - void DeviceContextGLImpl::DrawIndexed(const DrawIndexedAttribs& Attribs) + if (Attribs.NumInstances > 1 || Attribs.FirstInstanceLocation != 0) { - if (!DvpVerifyDrawIndexedArguments(Attribs)) - return; + if (Attribs.FirstInstanceLocation != 0) + glDrawArraysInstancedBaseInstance(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices, Attribs.NumInstances, Attribs.FirstInstanceLocation); + else + glDrawArraysInstanced(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices, Attribs.NumInstances); + } + else + { + glDrawArrays(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices); + } + DEV_CHECK_GL_ERROR("OpenGL draw command failed"); + + PostDraw(); +} + +void DeviceContextGLImpl::DrawIndexed(const DrawIndexedAttribs& Attribs) +{ + if (!DvpVerifyDrawIndexedArguments(Attribs)) + return; - GLenum GlTopology; - PrepareForDraw(Attribs.Flags, true, GlTopology); - GLenum GLIndexType; - Uint32 FirstIndexByteOffset; - PrepareForIndexedDraw(Attribs.IndexType, Attribs.FirstIndexLocation, GLIndexType, FirstIndexByteOffset); + GLenum GlTopology; + PrepareForDraw(Attribs.Flags, true, GlTopology); + GLenum GLIndexType; + Uint32 FirstIndexByteOffset; + PrepareForIndexedDraw(Attribs.IndexType, Attribs.FirstIndexLocation, GLIndexType, FirstIndexByteOffset); - // NOTE: Base Vertex and Base Instance versions are not supported even in OpenGL ES 3.1 - // This functionality can be emulated by adjusting stream offsets. This, however may cause - // errors in case instance data is read from the same stream as vertex data. Thus handling - // such cases is left to the application + // NOTE: Base Vertex and Base Instance versions are not supported even in OpenGL ES 3.1 + // This functionality can be emulated by adjusting stream offsets. This, however may cause + // errors in case instance data is read from the same stream as vertex data. Thus handling + // such cases is left to the application - if (Attribs.NumInstances > 1 || Attribs.FirstInstanceLocation != 0) + if (Attribs.NumInstances > 1 || Attribs.FirstInstanceLocation != 0) + { + if (Attribs.BaseVertex > 0) { - if (Attribs.BaseVertex > 0) - { - if (Attribs.FirstInstanceLocation != 0) - glDrawElementsInstancedBaseVertexBaseInstance(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances, Attribs.BaseVertex, Attribs.FirstInstanceLocation); - else - glDrawElementsInstancedBaseVertex(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances, Attribs.BaseVertex); - } + if (Attribs.FirstInstanceLocation != 0) + glDrawElementsInstancedBaseVertexBaseInstance(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>(static_cast<size_t>(FirstIndexByteOffset)), Attribs.NumInstances, Attribs.BaseVertex, Attribs.FirstInstanceLocation); else - { - if (Attribs.FirstInstanceLocation != 0) - glDrawElementsInstancedBaseInstance(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances, Attribs.FirstInstanceLocation); - else - glDrawElementsInstanced(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances); - } + glDrawElementsInstancedBaseVertex(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>(static_cast<size_t>(FirstIndexByteOffset)), Attribs.NumInstances, Attribs.BaseVertex); } else { - if (Attribs.BaseVertex > 0) - glDrawElementsBaseVertex(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.BaseVertex); + if (Attribs.FirstInstanceLocation != 0) + glDrawElementsInstancedBaseInstance(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>(static_cast<size_t>(FirstIndexByteOffset)), Attribs.NumInstances, Attribs.FirstInstanceLocation); else - glDrawElements(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset))); + glDrawElementsInstanced(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>(static_cast<size_t>(FirstIndexByteOffset)), Attribs.NumInstances); } - DEV_CHECK_GL_ERROR( "OpenGL draw command failed" ); - - PostDraw(); } - - void DeviceContextGLImpl::PrepareForIndirectDraw(IBuffer* pAttribsBuffer) + else { + if (Attribs.BaseVertex > 0) + glDrawElementsBaseVertex(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>(static_cast<size_t>(FirstIndexByteOffset)), Attribs.BaseVertex); + else + glDrawElements(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>(static_cast<size_t>(FirstIndexByteOffset))); + } + DEV_CHECK_GL_ERROR("OpenGL draw command failed"); + + PostDraw(); +} + +void DeviceContextGLImpl::PrepareForIndirectDraw(IBuffer* pAttribsBuffer) +{ #if GL_ARB_draw_indirect - auto* pIndirectDrawAttribsGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer); - // The indirect rendering functions take their data from the buffer currently bound to the - // GL_DRAW_INDIRECT_BUFFER binding. Thus, any of indirect draw functions will fail if no buffer is - // bound to that binding. - pIndirectDrawAttribsGL->BufferMemoryBarrier( - GL_COMMAND_BARRIER_BIT,// Command data sourced from buffer objects by - // Draw*Indirect and DispatchComputeIndirect commands after the barrier - // will reflect data written by shaders prior to the barrier.The buffer - // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER - // and DISPATCH_INDIRECT_BUFFER bindings. - m_ContextState); - constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO - m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer, ResetVAO); + auto* pIndirectDrawAttribsGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer); + // The indirect rendering functions take their data from the buffer currently bound to the + // GL_DRAW_INDIRECT_BUFFER binding. Thus, any of indirect draw functions will fail if no buffer is + // bound to that binding. + pIndirectDrawAttribsGL->BufferMemoryBarrier( + GL_COMMAND_BARRIER_BIT, // Command data sourced from buffer objects by + // Draw*Indirect and DispatchComputeIndirect commands after the barrier + // will reflect data written by shaders prior to the barrier.The buffer + // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER + // and DISPATCH_INDIRECT_BUFFER bindings. + m_ContextState); + constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO + m_ContextState.BindBuffer(GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer, ResetVAO); #endif - } +} - void DeviceContextGLImpl::DrawIndirect(const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) - { - if (!DvpVerifyDrawIndirectArguments(Attribs, pAttribsBuffer)) - return; +void DeviceContextGLImpl::DrawIndirect(const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) +{ + if (!DvpVerifyDrawIndirectArguments(Attribs, pAttribsBuffer)) + return; #if GL_ARB_draw_indirect - GLenum GlTopology; - PrepareForDraw(Attribs.Flags, true, GlTopology); - - // http://www.opengl.org/wiki/Vertex_Rendering - PrepareForIndirectDraw(pAttribsBuffer); - - //typedef struct { - // GLuint count; - // GLuint instanceCount; - // GLuint first; - // GLuint baseInstance; - //} DrawArraysIndirectCommand; - glDrawArraysIndirect( GlTopology, reinterpret_cast<const void*>( static_cast<size_t>(Attribs.IndirectDrawArgsOffset) ) ); - // Note that on GLES 3.1, baseInstance is present but reserved and must be zero - DEV_CHECK_GL_ERROR( "glDrawArraysIndirect() failed" ); - - constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO - m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO ); - - PostDraw(); + GLenum GlTopology; + PrepareForDraw(Attribs.Flags, true, GlTopology); + + // http://www.opengl.org/wiki/Vertex_Rendering + PrepareForIndirectDraw(pAttribsBuffer); + + //typedef struct { + // GLuint count; + // GLuint instanceCount; + // GLuint first; + // GLuint baseInstance; + //} DrawArraysIndirectCommand; + glDrawArraysIndirect(GlTopology, reinterpret_cast<const void*>(static_cast<size_t>(Attribs.IndirectDrawArgsOffset))); + // Note that on GLES 3.1, baseInstance is present but reserved and must be zero + DEV_CHECK_GL_ERROR("glDrawArraysIndirect() failed"); + + constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO + m_ContextState.BindBuffer(GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); + + PostDraw(); #else - LOG_ERROR_MESSAGE("Indirect rendering is not supported"); + LOG_ERROR_MESSAGE("Indirect rendering is not supported"); #endif - } +} - void DeviceContextGLImpl::DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) - { - if (!DvpVerifyDrawIndexedIndirectArguments(Attribs, pAttribsBuffer)) - return; +void DeviceContextGLImpl::DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) +{ + if (!DvpVerifyDrawIndexedIndirectArguments(Attribs, pAttribsBuffer)) + return; #if GL_ARB_draw_indirect - GLenum GlTopology; - PrepareForDraw(Attribs.Flags, true, GlTopology); - GLenum GLIndexType; - Uint32 FirstIndexByteOffset; - PrepareForIndexedDraw(Attribs.IndexType, 0, GLIndexType, FirstIndexByteOffset); - - // http://www.opengl.org/wiki/Vertex_Rendering - PrepareForIndirectDraw(pAttribsBuffer); - - //typedef struct { - // GLuint count; - // GLuint instanceCount; - // GLuint firstIndex; - // GLuint baseVertex; - // GLuint baseInstance; - //} DrawElementsIndirectCommand; - glDrawElementsIndirect( GlTopology, GLIndexType, reinterpret_cast<const void*>( static_cast<size_t>(Attribs.IndirectDrawArgsOffset) ) ); - // Note that on GLES 3.1, baseInstance is present but reserved and must be zero - DEV_CHECK_GL_ERROR( "glDrawElementsIndirect() failed" ); - - constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO - m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO ); - - PostDraw(); + GLenum GlTopology; + PrepareForDraw(Attribs.Flags, true, GlTopology); + GLenum GLIndexType; + Uint32 FirstIndexByteOffset; + PrepareForIndexedDraw(Attribs.IndexType, 0, GLIndexType, FirstIndexByteOffset); + + // http://www.opengl.org/wiki/Vertex_Rendering + PrepareForIndirectDraw(pAttribsBuffer); + + //typedef struct { + // GLuint count; + // GLuint instanceCount; + // GLuint firstIndex; + // GLuint baseVertex; + // GLuint baseInstance; + //} DrawElementsIndirectCommand; + glDrawElementsIndirect(GlTopology, GLIndexType, reinterpret_cast<const void*>(static_cast<size_t>(Attribs.IndirectDrawArgsOffset))); + // Note that on GLES 3.1, baseInstance is present but reserved and must be zero + DEV_CHECK_GL_ERROR("glDrawElementsIndirect() failed"); + + constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO + m_ContextState.BindBuffer(GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); + + PostDraw(); #else - LOG_ERROR_MESSAGE("Indirect rendering is not supported"); + LOG_ERROR_MESSAGE("Indirect rendering is not supported"); #endif - } +} - void DeviceContextGLImpl::DispatchCompute(const DispatchComputeAttribs& Attribs) - { - if (!DvpVerifyDispatchArguments(Attribs)) - return; +void DeviceContextGLImpl::DispatchCompute(const DispatchComputeAttribs& Attribs) +{ + if (!DvpVerifyDispatchArguments(Attribs)) + return; #if GL_ARB_compute_shader - m_pPipelineState->CommitProgram(m_ContextState); - glDispatchCompute(Attribs.ThreadGroupCountX, Attribs.ThreadGroupCountY, Attribs.ThreadGroupCountZ); - CHECK_GL_ERROR("glDispatchCompute() failed"); + m_pPipelineState->CommitProgram(m_ContextState); + glDispatchCompute(Attribs.ThreadGroupCountX, Attribs.ThreadGroupCountY, Attribs.ThreadGroupCountZ); + CHECK_GL_ERROR("glDispatchCompute() failed"); - PostDraw(); + PostDraw(); #else - UNSUPPORTED("Compute shaders are not supported"); + UNSUPPORTED("Compute shaders are not supported"); #endif - } +} - void DeviceContextGLImpl::DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) - { - if (!DvpVerifyDispatchIndirectArguments(Attribs, pAttribsBuffer)) - return; +void DeviceContextGLImpl::DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) +{ + if (!DvpVerifyDispatchIndirectArguments(Attribs, pAttribsBuffer)) + return; #if GL_ARB_compute_shader - m_pPipelineState->CommitProgram(m_ContextState); + m_pPipelineState->CommitProgram(m_ContextState); - auto* pBufferGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer); - pBufferGL->BufferMemoryBarrier( - GL_COMMAND_BARRIER_BIT,// Command data sourced from buffer objects by - // Draw*Indirect and DispatchComputeIndirect commands after the barrier - // will reflect data written by shaders prior to the barrier.The buffer - // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER - // and DISPATCH_INDIRECT_BUFFER bindings. - m_ContextState); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer); + pBufferGL->BufferMemoryBarrier( + GL_COMMAND_BARRIER_BIT, // Command data sourced from buffer objects by + // Draw*Indirect and DispatchComputeIndirect commands after the barrier + // will reflect data written by shaders prior to the barrier.The buffer + // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER + // and DISPATCH_INDIRECT_BUFFER bindings. + m_ContextState); + + constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO + m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer, ResetVAO); + CHECK_GL_ERROR("Failed to bind a buffer for dispatch indirect command"); - constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO - m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer, ResetVAO); - CHECK_GL_ERROR( "Failed to bind a buffer for dispatch indirect command" ); + glDispatchComputeIndirect(Attribs.DispatchArgsByteOffset); + CHECK_GL_ERROR("glDispatchComputeIndirect() failed"); - glDispatchComputeIndirect(Attribs.DispatchArgsByteOffset); - CHECK_GL_ERROR("glDispatchComputeIndirect() failed"); + m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); - m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); - - PostDraw(); + PostDraw(); #else - UNSUPPORTED("Compute shaders are not supported"); + UNSUPPORTED("Compute shaders are not supported"); #endif - } +} - void DeviceContextGLImpl::ClearDepthStencil(ITextureView* pView, - CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, - float fDepth, - Uint8 Stencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +void DeviceContextGLImpl::ClearDepthStencil(ITextureView* pView, + CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, + float fDepth, + Uint8 Stencil, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +{ + // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied. + if (pView != nullptr) { - // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. - // Viewport and scissor settings are not applied. - if (pView != nullptr) + VERIFY(pView->GetDesc().ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected"); + CHECK_DYNAMIC_TYPE(TextureViewGLImpl, pView); + if (pView != m_pBoundDepthStencil) { - VERIFY( pView->GetDesc().ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); - CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pView ); - if (pView != m_pBoundDepthStencil) - { - UNEXPECTED( "Depth stencil buffer being cleared is not bound to the pipeline" ); - LOG_ERROR_MESSAGE( "Depth stencil buffer must be bound to the pipeline to be cleared" ); - } + UNEXPECTED("Depth stencil buffer being cleared is not bound to the pipeline"); + LOG_ERROR_MESSAGE("Depth stencil buffer must be bound to the pipeline to be cleared"); } - else + } + else + { + if (!m_IsDefaultFramebufferBound) { - if (!m_IsDefaultFramebufferBound) - { - UNEXPECTED( "Default depth stencil buffer being cleared is not bound to the pipeline" ); - LOG_ERROR_MESSAGE( "Default depth stencil buffer must be bound to the pipeline to be cleared" ); - } + UNEXPECTED("Default depth stencil buffer being cleared is not bound to the pipeline"); + LOG_ERROR_MESSAGE("Default depth stencil buffer must be bound to the pipeline to be cleared"); } - Uint32 glClearFlags = 0; - if( ClearFlags & CLEAR_DEPTH_FLAG ) glClearFlags |= GL_DEPTH_BUFFER_BIT; - if( ClearFlags & CLEAR_STENCIL_FLAG ) glClearFlags |= GL_STENCIL_BUFFER_BIT; - glClearDepthf( fDepth ); - glClearStencil( Stencil ); - // If depth writes are disabled, glClear() will not clear depth buffer! - bool DepthWritesEnabled = m_ContextState.GetDepthWritesEnabled(); - m_ContextState.EnableDepthWrites( True ); - bool ScissorTestEnabled = m_ContextState.GetScissorTestEnabled(); - m_ContextState.EnableScissorTest( False ); - // The pixel ownership test, the scissor test, dithering, and the buffer writemasks affect - // the operation of glClear. The scissor box bounds the cleared region. Alpha function, - // blend function, logical operation, stenciling, texture mapping, and depth-buffering - // are ignored by glClear. - glClear(glClearFlags); - CHECK_GL_ERROR( "glClear() failed" ); - m_ContextState.EnableDepthWrites( DepthWritesEnabled ); - m_ContextState.EnableScissorTest( ScissorTestEnabled ); } + Uint32 glClearFlags = 0; + if (ClearFlags & CLEAR_DEPTH_FLAG) glClearFlags |= GL_DEPTH_BUFFER_BIT; + if (ClearFlags & CLEAR_STENCIL_FLAG) glClearFlags |= GL_STENCIL_BUFFER_BIT; + glClearDepthf(fDepth); + glClearStencil(Stencil); + // If depth writes are disabled, glClear() will not clear depth buffer! + bool DepthWritesEnabled = m_ContextState.GetDepthWritesEnabled(); + m_ContextState.EnableDepthWrites(True); + bool ScissorTestEnabled = m_ContextState.GetScissorTestEnabled(); + m_ContextState.EnableScissorTest(False); + // The pixel ownership test, the scissor test, dithering, and the buffer writemasks affect + // the operation of glClear. The scissor box bounds the cleared region. Alpha function, + // blend function, logical operation, stenciling, texture mapping, and depth-buffering + // are ignored by glClear. + glClear(glClearFlags); + CHECK_GL_ERROR("glClear() failed"); + m_ContextState.EnableDepthWrites(DepthWritesEnabled); + m_ContextState.EnableScissorTest(ScissorTestEnabled); +} - void DeviceContextGLImpl::ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) - { - // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. - // Viewport and scissor settings are not applied. +void DeviceContextGLImpl::ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +{ + // Unlike OpenGL, in D3D10+, the full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied. - Int32 RTIndex = -1; - if (pView != nullptr) + Int32 RTIndex = -1; + if (pView != nullptr) + { + VERIFY(pView->GetDesc().ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected"); + CHECK_DYNAMIC_TYPE(TextureViewGLImpl, pView); + for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) { - VERIFY( pView->GetDesc().ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); - CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pView ); - for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) + if (m_pBoundRenderTargets[rt] == pView) { - if (m_pBoundRenderTargets[rt] == pView) - { - RTIndex = rt; - break; - } + RTIndex = rt; + break; } + } - if (RTIndex == -1) - { - UNEXPECTED( "Render target being cleared is not bound to the pipeline" ); - LOG_ERROR_MESSAGE( "Render target must be bound to the pipeline to be cleared" ); - } + if (RTIndex == -1) + { + UNEXPECTED("Render target being cleared is not bound to the pipeline"); + LOG_ERROR_MESSAGE("Render target must be bound to the pipeline to be cleared"); } + } + else + { + if (m_IsDefaultFramebufferBound) + RTIndex = 0; else { - if (m_IsDefaultFramebufferBound) - RTIndex = 0; - else - { - UNEXPECTED( "Default render target must be bound to the pipeline to be cleared" ); - LOG_ERROR_MESSAGE( "Default render target must be bound to the pipeline to be cleared" ); - } + UNEXPECTED("Default render target must be bound to the pipeline to be cleared"); + LOG_ERROR_MESSAGE("Default render target must be bound to the pipeline to be cleared"); } - - static const float Zero[4] = { 0, 0, 0, 0 }; - if( RGBA == nullptr ) - RGBA = Zero; - - // The pixel ownership test, the scissor test, dithering, and the buffer writemasks affect - // the operation of glClear. The scissor box bounds the cleared region. Alpha function, - // blend function, logical operation, stenciling, texture mapping, and depth-buffering - // are ignored by glClear. - - // Disable scissor test - bool ScissorTestEnabled = m_ContextState.GetScissorTestEnabled(); - m_ContextState.EnableScissorTest( False ); - - // Set write mask - Uint32 WriteMask = 0; - Bool bIndependentBlend = False; - m_ContextState.GetColorWriteMask( RTIndex, WriteMask, bIndependentBlend ); - m_ContextState.SetColorWriteMask( RTIndex, COLOR_MASK_ALL, bIndependentBlend ); - - glClearBufferfv( GL_COLOR, RTIndex, RGBA ); - CHECK_GL_ERROR( "glClearBufferfv() failed" ); - - m_ContextState.SetColorWriteMask( RTIndex, WriteMask, bIndependentBlend ); - m_ContextState.EnableScissorTest( ScissorTestEnabled ); } - void DeviceContextGLImpl::Flush() - { - glFlush(); - } + static const float Zero[4] = {0, 0, 0, 0}; + if (RGBA == nullptr) + RGBA = Zero; - void DeviceContextGLImpl::FinishFrame() - { - } + // The pixel ownership test, the scissor test, dithering, and the buffer writemasks affect + // the operation of glClear. The scissor box bounds the cleared region. Alpha function, + // blend function, logical operation, stenciling, texture mapping, and depth-buffering + // are ignored by glClear. - void DeviceContextGLImpl::FinishCommandList(class ICommandList** ppCommandList) - { - LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); - } + // Disable scissor test + bool ScissorTestEnabled = m_ContextState.GetScissorTestEnabled(); + m_ContextState.EnableScissorTest(False); - void DeviceContextGLImpl::ExecuteCommandList(class ICommandList* pCommandList) - { - LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); - } + // Set write mask + Uint32 WriteMask = 0; + Bool bIndependentBlend = False; + m_ContextState.GetColorWriteMask(RTIndex, WriteMask, bIndependentBlend); + m_ContextState.SetColorWriteMask(RTIndex, COLOR_MASK_ALL, bIndependentBlend); - void DeviceContextGLImpl::SignalFence(IFence* pFence, Uint64 Value) - { - VERIFY(!m_bIsDeferred, "Fence can only be signaled 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); - } + glClearBufferfv(GL_COLOR, RTIndex, RGBA); + CHECK_GL_ERROR("glClearBufferfv() failed"); - void DeviceContextGLImpl::WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) - { - VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); - auto* pFenceGLImpl = ValidatedCast<FenceGLImpl>(pFence); - pFenceGLImpl->Wait(Value, FlushContext); - } + m_ContextState.SetColorWriteMask(RTIndex, WriteMask, bIndependentBlend); + m_ContextState.EnableScissorTest(ScissorTestEnabled); +} - void DeviceContextGLImpl::WaitForIdle() - { - VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled"); - glFinish(); - } +void DeviceContextGLImpl::Flush() +{ + glFlush(); +} - bool DeviceContextGLImpl::UpdateCurrentGLContext() - { - auto NativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); - if (NativeGLContext == NULL) - return false; +void DeviceContextGLImpl::FinishFrame() +{ +} - m_ContextState.SetCurrentGLContext(NativeGLContext); - return true; - } +void DeviceContextGLImpl::FinishCommandList(class ICommandList** ppCommandList) +{ + LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); +} - void DeviceContextGLImpl::UpdateBuffer(IBuffer* pBuffer, - Uint32 Offset, - Uint32 Size, - const PVoid pData, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) - { - TDeviceContextBase::UpdateBuffer(pBuffer, Offset, Size, pData, StateTransitionMode); +void DeviceContextGLImpl::ExecuteCommandList(class ICommandList* pCommandList) +{ + LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); +} - auto* pBufferGL = ValidatedCast<BufferGLImpl>(pBuffer); - pBufferGL->UpdateData(m_ContextState, Offset, Size, pData); - } +void DeviceContextGLImpl::SignalFence(IFence* pFence, Uint64 Value) +{ + VERIFY(!m_bIsDeferred, "Fence can only be signaled 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); +} - void DeviceContextGLImpl::CopyBuffer(IBuffer* pSrcBuffer, - Uint32 SrcOffset, - RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, - IBuffer* pDstBuffer, - Uint32 DstOffset, - Uint32 Size, - RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) - { - TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, SrcBufferTransitionMode, pDstBuffer, DstOffset, Size, DstBufferTransitionMode); +void DeviceContextGLImpl::WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) +{ + VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + auto* pFenceGLImpl = ValidatedCast<FenceGLImpl>(pFence); + pFenceGLImpl->Wait(Value, FlushContext); +} - auto* pSrcBufferGL = ValidatedCast<BufferGLImpl>(pSrcBuffer); - auto* pDstBufferGL = ValidatedCast<BufferGLImpl>(pDstBuffer); - pDstBufferGL->CopyData(m_ContextState, *pSrcBufferGL, SrcOffset, DstOffset, Size); - } +void DeviceContextGLImpl::WaitForIdle() +{ + VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled"); + glFinish(); +} - void DeviceContextGLImpl::MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) - { - TDeviceContextBase::MapBuffer(pBuffer, MapType, MapFlags, pMappedData); - auto* pBufferGL = ValidatedCast<BufferGLImpl>(pBuffer); - pBufferGL->Map(m_ContextState, MapType, MapFlags, pMappedData); - } +bool DeviceContextGLImpl::UpdateCurrentGLContext() +{ + auto NativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); + if (NativeGLContext == NULL) + return false; - void DeviceContextGLImpl::UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) - { - TDeviceContextBase::UnmapBuffer(pBuffer, MapType); - auto* pBufferGL = ValidatedCast<BufferGLImpl>(pBuffer); - pBufferGL->Unmap(m_ContextState); - } + m_ContextState.SetCurrentGLContext(NativeGLContext); + return true; +} - void DeviceContextGLImpl::UpdateTexture(ITexture* pTexture, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData, - RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, - RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionMode) - { - TDeviceContextBase::UpdateTexture( pTexture, MipLevel, Slice, DstBox, SubresData, SrcBufferStateTransitionMode, TextureStateTransitionMode ); - auto* pTexGL = ValidatedCast<TextureBaseGL>(pTexture); - pTexGL->UpdateData(m_ContextState, MipLevel, Slice, DstBox, SubresData); - } +void DeviceContextGLImpl::UpdateBuffer(IBuffer* pBuffer, + Uint32 Offset, + Uint32 Size, + const PVoid pData, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) +{ + TDeviceContextBase::UpdateBuffer(pBuffer, Offset, Size, pData, StateTransitionMode); - void DeviceContextGLImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs) - { - TDeviceContextBase::CopyTexture( CopyAttribs ); - auto* pSrcTexGL = ValidatedCast<TextureBaseGL>(CopyAttribs.pSrcTexture); - auto* pDstTexGL = ValidatedCast<TextureBaseGL>(CopyAttribs.pDstTexture); - pDstTexGL->CopyData(this, pSrcTexGL, CopyAttribs.SrcMipLevel, CopyAttribs.SrcSlice, CopyAttribs.pSrcBox, - CopyAttribs.DstMipLevel, CopyAttribs.DstSlice, CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ); - } + auto* pBufferGL = ValidatedCast<BufferGLImpl>(pBuffer); + pBufferGL->UpdateData(m_ContextState, Offset, Size, pData); +} - void DeviceContextGLImpl::MapTextureSubresource(ITexture* pTexture, - Uint32 MipLevel, - Uint32 ArraySlice, - MAP_TYPE MapType, - MAP_FLAGS MapFlags, - const Box* pMapRegion, - MappedTextureSubresource& MappedData) - { - TDeviceContextBase::MapTextureSubresource(pTexture, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion, MappedData); - LOG_ERROR_MESSAGE("Texture mapping is not supported in OpenGL"); - MappedData = MappedTextureSubresource{}; - } +void DeviceContextGLImpl::CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) +{ + TDeviceContextBase::CopyBuffer(pSrcBuffer, SrcOffset, SrcBufferTransitionMode, pDstBuffer, DstOffset, Size, DstBufferTransitionMode); + auto* pSrcBufferGL = ValidatedCast<BufferGLImpl>(pSrcBuffer); + auto* pDstBufferGL = ValidatedCast<BufferGLImpl>(pDstBuffer); + pDstBufferGL->CopyData(m_ContextState, *pSrcBufferGL, SrcOffset, DstOffset, Size); +} - void DeviceContextGLImpl::UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) - { - TDeviceContextBase::UnmapTextureSubresource( pTexture, MipLevel, ArraySlice); - LOG_ERROR_MESSAGE("Texture mapping is not supported in OpenGL"); - } +void DeviceContextGLImpl::MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) +{ + TDeviceContextBase::MapBuffer(pBuffer, MapType, MapFlags, pMappedData); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(pBuffer); + pBufferGL->Map(m_ContextState, MapType, MapFlags, pMappedData); +} - void DeviceContextGLImpl::GenerateMips( ITextureView* pTexView ) - { - TDeviceContextBase::GenerateMips(pTexView); - auto* pTexViewGL = ValidatedCast<TextureViewGLImpl>(pTexView); - auto BindTarget = pTexViewGL->GetBindTarget(); - m_ContextState.BindTexture( -1, BindTarget, pTexViewGL->GetHandle() ); - glGenerateMipmap( BindTarget ); - CHECK_GL_ERROR( "Failed to generate mip maps" ); - m_ContextState.BindTexture( -1, BindTarget, GLObjectWrappers::GLTextureObj::Null() ); - } +void DeviceContextGLImpl::UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) +{ + TDeviceContextBase::UnmapBuffer(pBuffer, MapType); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(pBuffer); + pBufferGL->Unmap(m_ContextState); +} - void DeviceContextGLImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) - { +void DeviceContextGLImpl::UpdateTexture(ITexture* pTexture, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData, + RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, + RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionMode) +{ + TDeviceContextBase::UpdateTexture(pTexture, MipLevel, Slice, DstBox, SubresData, SrcBufferStateTransitionMode, TextureStateTransitionMode); + auto* pTexGL = ValidatedCast<TextureBaseGL>(pTexture); + pTexGL->UpdateData(m_ContextState, MipLevel, Slice, DstBox, SubresData); +} - } +void DeviceContextGLImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs) +{ + TDeviceContextBase::CopyTexture(CopyAttribs); + auto* pSrcTexGL = ValidatedCast<TextureBaseGL>(CopyAttribs.pSrcTexture); + auto* pDstTexGL = ValidatedCast<TextureBaseGL>(CopyAttribs.pDstTexture); + pDstTexGL->CopyData(this, pSrcTexGL, CopyAttribs.SrcMipLevel, CopyAttribs.SrcSlice, CopyAttribs.pSrcBox, + CopyAttribs.DstMipLevel, CopyAttribs.DstSlice, CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ); +} - void DeviceContextGLImpl::ResolveTextureSubresource(ITexture* pSrcTexture, - ITexture* pDstTexture, - const ResolveTextureSubresourceAttribs& ResolveAttribs) - { - TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); - auto* pSrcTexGl = ValidatedCast<TextureBaseGL>(pSrcTexture); - auto* pDstTexGl = ValidatedCast<TextureBaseGL>(pDstTexture); - const auto& SrcTexDesc = pSrcTexGl->GetDesc(); - //const auto& DstTexDesc = pDstTexGl->GetDesc(); +void DeviceContextGLImpl::MapTextureSubresource(ITexture* pTexture, + Uint32 MipLevel, + Uint32 ArraySlice, + MAP_TYPE MapType, + MAP_FLAGS MapFlags, + const Box* pMapRegion, + MappedTextureSubresource& MappedData) +{ + TDeviceContextBase::MapTextureSubresource(pTexture, MipLevel, ArraySlice, MapType, MapFlags, pMapRegion, MappedData); + LOG_ERROR_MESSAGE("Texture mapping is not supported in OpenGL"); + MappedData = MappedTextureSubresource{}; +} - auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext(); - auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext); - { - TextureViewDesc SrcTexViewDesc; - SrcTexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; - SrcTexViewDesc.MostDetailedMip = ResolveAttribs.SrcMipLevel; - SrcTexViewDesc.FirstArraySlice = ResolveAttribs.SrcSlice; - TextureViewGLImpl SrcTexView +void DeviceContextGLImpl::UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) +{ + TDeviceContextBase::UnmapTextureSubresource(pTexture, MipLevel, ArraySlice); + LOG_ERROR_MESSAGE("Texture mapping is not supported in OpenGL"); +} + +void DeviceContextGLImpl::GenerateMips(ITextureView* pTexView) +{ + TDeviceContextBase::GenerateMips(pTexView); + auto* pTexViewGL = ValidatedCast<TextureViewGLImpl>(pTexView); + auto BindTarget = pTexViewGL->GetBindTarget(); + m_ContextState.BindTexture(-1, BindTarget, pTexViewGL->GetHandle()); + glGenerateMipmap(BindTarget); + CHECK_GL_ERROR("Failed to generate mip maps"); + m_ContextState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null()); +} + +void DeviceContextGLImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) +{ +} + +void DeviceContextGLImpl::ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) +{ + TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + auto* pSrcTexGl = ValidatedCast<TextureBaseGL>(pSrcTexture); + auto* pDstTexGl = ValidatedCast<TextureBaseGL>(pDstTexture); + const auto& SrcTexDesc = pSrcTexGl->GetDesc(); + //const auto& DstTexDesc = pDstTexGl->GetDesc(); + + auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext(); + auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext); + + { + TextureViewDesc SrcTexViewDesc; + SrcTexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + SrcTexViewDesc.MostDetailedMip = ResolveAttribs.SrcMipLevel; + SrcTexViewDesc.FirstArraySlice = ResolveAttribs.SrcSlice; + TextureViewGLImpl SrcTexView // { - nullptr, // pRefCounters + nullptr, // pRefCounters m_pDevice, SrcTexViewDesc, pSrcTexGl, - false, // bCreateGLViewTex - false // bIsDefaultView + false, // bCreateGLViewTex + false // bIsDefaultView }; - TextureViewGLImpl* pSrcViews[] = {&SrcTexView}; - const auto& SrcFBO = FBOCache.GetFBO(1, pSrcViews, nullptr, m_ContextState); - glBindFramebuffer(GL_READ_FRAMEBUFFER, SrcFBO); - DEV_CHECK_GL_ERROR("Failed to bind FBO as read framebuffer"); - } + TextureViewGLImpl* pSrcViews[] = {&SrcTexView}; + const auto& SrcFBO = FBOCache.GetFBO(1, pSrcViews, nullptr, m_ContextState); + glBindFramebuffer(GL_READ_FRAMEBUFFER, SrcFBO); + DEV_CHECK_GL_ERROR("Failed to bind FBO as read framebuffer"); + } - if (pDstTexGl->GetGLHandle()) - { - TextureViewDesc DstTexViewDesc; - DstTexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; - DstTexViewDesc.MostDetailedMip = ResolveAttribs.DstMipLevel; - DstTexViewDesc.FirstArraySlice = ResolveAttribs.DstSlice; - TextureViewGLImpl DstTexView + if (pDstTexGl->GetGLHandle()) + { + TextureViewDesc DstTexViewDesc; + DstTexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + DstTexViewDesc.MostDetailedMip = ResolveAttribs.DstMipLevel; + DstTexViewDesc.FirstArraySlice = ResolveAttribs.DstSlice; + TextureViewGLImpl DstTexView // { - nullptr, // pRefCounters + nullptr, // pRefCounters m_pDevice, DstTexViewDesc, pDstTexGl, - false, // bCreateGLViewTex - false // bIsDefaultView + false, // bCreateGLViewTex + false // bIsDefaultView }; - TextureViewGLImpl* pDstViews[] = {&DstTexView}; - const auto& DstFBO = FBOCache.GetFBO(1, pDstViews, nullptr, m_ContextState); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, DstFBO); - DEV_CHECK_GL_ERROR("Failed to bind FBO as draw framebuffer"); - } - else - { - auto* pSwapChainGL = m_pSwapChain.RawPtr<ISwapChainGL>(); - GLuint DefaultFBOHandle = pSwapChainGL->GetDefaultFBO(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, DefaultFBOHandle); - DEV_CHECK_GL_ERROR("Failed to bind default FBO as draw framebuffer"); - } - - const auto& MipAttribs = GetMipLevelProperties(SrcTexDesc, ResolveAttribs.SrcMipLevel); - glBlitFramebuffer(0, 0, static_cast<GLint>(MipAttribs.LogicalWidth), static_cast<GLint>(MipAttribs.LogicalHeight), - 0, 0, static_cast<GLint>(MipAttribs.LogicalWidth), static_cast<GLint>(MipAttribs.LogicalHeight), - GL_COLOR_BUFFER_BIT, - GL_NEAREST // Filter is ignored - ); - DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled texture"); - - // Restore original FBO - m_ContextState.InvalidateFBO(); - CommitRenderTargets(); + TextureViewGLImpl* pDstViews[] = {&DstTexView}; + const auto& DstFBO = FBOCache.GetFBO(1, pDstViews, nullptr, m_ContextState); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, DstFBO); + DEV_CHECK_GL_ERROR("Failed to bind FBO as draw framebuffer"); + } + else + { + auto* pSwapChainGL = m_pSwapChain.RawPtr<ISwapChainGL>(); + GLuint DefaultFBOHandle = pSwapChainGL->GetDefaultFBO(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, DefaultFBOHandle); + DEV_CHECK_GL_ERROR("Failed to bind default FBO as draw framebuffer"); } + + const auto& MipAttribs = GetMipLevelProperties(SrcTexDesc, ResolveAttribs.SrcMipLevel); + glBlitFramebuffer(0, 0, static_cast<GLint>(MipAttribs.LogicalWidth), static_cast<GLint>(MipAttribs.LogicalHeight), + 0, 0, static_cast<GLint>(MipAttribs.LogicalWidth), static_cast<GLint>(MipAttribs.LogicalHeight), + GL_COLOR_BUFFER_BIT, + GL_NEAREST // Filter is ignored + ); + DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled texture"); + + // Restore original FBO + m_ContextState.InvalidateFBO(); + CommitRenderTargets(); } + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp index 5e314f28..c5544ce3 100644 --- a/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp @@ -33,37 +33,36 @@ #include "EngineFactoryBase.h" #if PLATFORM_IOS -# include "SwapChainGLIOS.h" +# include "SwapChainGLIOS.h" #else -# include "SwapChainGLImpl.h" +# include "SwapChainGLImpl.h" #endif #if PLATFORM_ANDROID -# include "RenderDeviceGLESImpl.h" -# include "FileStream.h" +# include "RenderDeviceGLESImpl.h" +# include "FileStream.h" #endif namespace Diligent { #if PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS || PLATFORM_LINUX || PLATFORM_MACOS - typedef RenderDeviceGLImpl TRenderDeviceGLImpl; - typedef SwapChainGLImpl TSwapChain; +using TRenderDeviceGLImpl = RenderDeviceGLImpl; +using TSwapChain = SwapChainGLImpl; #elif PLATFORM_ANDROID - typedef RenderDeviceGLESImpl TRenderDeviceGLImpl; - typedef SwapChainGLImpl TSwapChain; +using TRenderDeviceGLImpl = RenderDeviceGLESImpl; +using TSwapChain = SwapChainGLImpl; #elif PLATFORM_IOS - typedef RenderDeviceGLImpl TRenderDeviceGLImpl; - typedef SwapChainGLIOS TSwapChain; +using TRenderDeviceGLImpl = RenderDeviceGLImpl; +using TSwapChain = SwapChainGLIOS; #else -# error Unsupported platform +# error Unsupported platform #endif /// Engine factory for OpenGL implementation class EngineFactoryOpenGLImpl : public EngineFactoryBase<IEngineFactoryOpenGL> { public: - static EngineFactoryOpenGLImpl* GetInstance() { static EngineFactoryOpenGLImpl TheFactory; @@ -72,20 +71,20 @@ public: using TBase = EngineFactoryBase<IEngineFactoryOpenGL>; EngineFactoryOpenGLImpl() : - TBase(IID_EngineFactoryOpenGL) + TBase{IID_EngineFactoryOpenGL} {} virtual void CreateDeviceAndSwapChainGL(const EngineGLCreateInfo& EngineCI, IRenderDevice** ppDevice, IDeviceContext** ppImmediateContext, - const SwapChainDesc& SCDesc, - ISwapChain** ppSwapChain )override final; + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) override final; - virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter)override final; + virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter) override final; virtual void AttachToActiveGLContext(const EngineGLCreateInfo& EngineCI, IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext )override final; + IDeviceContext** ppImmediateContext) override final; #if PLATFORM_ANDROID virtual void InitAndroidFileSystem(void* Activity, const char* ActivityClassName) const override final; @@ -97,17 +96,17 @@ public: /// Creates render device, device context and swap chain for OpenGL/GLES-based engine implementation /// \param [in] EngineCI - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to +/// \param [out] ppDevice - Address of the memory location where pointer to /// the created device will be written. -/// \param [out] ppImmediateContext - Address of the memory location where pointers to +/// \param [out] ppImmediateContext - Address of the memory location where pointers to /// the immediate context will be written. /// \param [in] SCDesc - Swap chain description. -/// \param [out] ppSwapChain - Address of the memory location where pointer to the new +/// \param [out] ppSwapChain - Address of the memory location where pointer to the new /// swap chain will be written. void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInfo& EngineCI, IRenderDevice** ppDevice, IDeviceContext** ppImmediateContext, - const SwapChainDesc& SCDesc, + const SwapChainDesc& SCDesc, ISwapChain** ppSwapChain) { if (EngineCI.APIVersion != DILIGENT_API_VERSION) @@ -116,8 +115,8 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInf if (EngineCI.DebugMessageCallback != nullptr) SetDebugMessageCallback(EngineCI.DebugMessageCallback); - VERIFY( ppDevice && ppImmediateContext && ppSwapChain, "Null pointer provided" ); - if( !ppDevice || !ppImmediateContext || !ppSwapChain ) + VERIFY(ppDevice && ppImmediateContext && ppSwapChain, "Null pointer provided"); + if (!ppDevice || !ppImmediateContext || !ppSwapChain) return; if (EngineCI.NumDeferredContexts > 0) @@ -125,56 +124,56 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInf LOG_WARNING_MESSAGE("OpenGL back-end does not support deferred contexts"); } - *ppDevice = nullptr; + *ppDevice = nullptr; *ppImmediateContext = nullptr; - *ppSwapChain = nullptr; + *ppSwapChain = nullptr; try { SetRawAllocator(EngineCI.pRawMemAllocator); - auto &RawMemAllocator = GetRawAllocator(); + auto& RawMemAllocator = GetRawAllocator(); - RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, this, EngineCI, &SCDesc) ); - pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); + RenderDeviceGLImpl* pRenderDeviceOpenGL(NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, this, EngineCI, &SCDesc)); + pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice)); - DeviceContextGLImpl* pDeviceContextOpenGL( NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false ) ); + DeviceContextGLImpl* pDeviceContextOpenGL(NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false)); // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceOpenGL will // keep a weak reference to the context - pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); + pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext)); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); // Need to create immediate context first pRenderDeviceOpenGL->InitTexRegionRender(); - TSwapChain *pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", TSwapChain)(EngineCI, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); - pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); + TSwapChain* pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", TSwapChain)(EngineCI, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL); + pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain)); pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); // Bind default framebuffer and viewport - pDeviceContextOpenGL->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); - pDeviceContextOpenGL->SetViewports( 1, nullptr, 0, 0 ); + pDeviceContextOpenGL->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pDeviceContextOpenGL->SetViewports(1, nullptr, 0, 0); } - catch( const std::runtime_error & ) + catch (const std::runtime_error&) { - if( *ppDevice ) + if (*ppDevice) { (*ppDevice)->Release(); *ppDevice = nullptr; } - if( *ppImmediateContext ) + if (*ppImmediateContext) { (*ppImmediateContext)->Release(); *ppImmediateContext = nullptr; } - if( *ppSwapChain ) + if (*ppSwapChain) { (*ppSwapChain)->Release(); *ppSwapChain = nullptr; } - LOG_ERROR( "Failed to initialize OpenGL-based render device" ); + LOG_ERROR("Failed to initialize OpenGL-based render device"); } } @@ -182,13 +181,13 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInf /// Creates render device, device context and attaches to existing GL context /// \param [in] EngineCI - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to +/// \param [out] ppDevice - Address of the memory location where pointer to /// the created device will be written. -/// \param [out] ppImmediateContext - Address of the memory location where pointers to +/// \param [out] ppImmediateContext - Address of the memory location where pointers to /// the immediate context will be written. void EngineFactoryOpenGLImpl::AttachToActiveGLContext(const EngineGLCreateInfo& EngineCI, IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext ) + IDeviceContext** ppImmediateContext) { if (EngineCI.APIVersion != DILIGENT_API_VERSION) LOG_ERROR_AND_THROW("Diligent Engine runtime (", EngineCI.APIVersion, ") is not compatible with the client API version (", DILIGENT_API_VERSION, ")"); @@ -196,8 +195,8 @@ void EngineFactoryOpenGLImpl::AttachToActiveGLContext(const EngineGLCreateInfo& if (EngineCI.DebugMessageCallback != nullptr) SetDebugMessageCallback(EngineCI.DebugMessageCallback); - VERIFY( ppDevice && ppImmediateContext, "Null pointer provided" ); - if( !ppDevice || !ppImmediateContext ) + VERIFY(ppDevice && ppImmediateContext, "Null pointer provided"); + if (!ppDevice || !ppImmediateContext) return; if (EngineCI.NumDeferredContexts > 0) @@ -205,44 +204,44 @@ void EngineFactoryOpenGLImpl::AttachToActiveGLContext(const EngineGLCreateInfo& LOG_WARNING_MESSAGE("OpenGL back-end does not support deferred contexts"); } - *ppDevice = nullptr; + *ppDevice = nullptr; *ppImmediateContext = nullptr; try { SetRawAllocator(EngineCI.pRawMemAllocator); - auto &RawMemAllocator = GetRawAllocator(); + auto& RawMemAllocator = GetRawAllocator(); - RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, this, EngineCI) ); - pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); + RenderDeviceGLImpl* pRenderDeviceOpenGL(NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, this, EngineCI)); + pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice)); - DeviceContextGLImpl* pDeviceContextOpenGL( NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false ) ); + DeviceContextGLImpl* pDeviceContextOpenGL(NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false)); // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceOpenGL will // keep a weak reference to the context - pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); + pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext)); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); } - catch( const std::runtime_error & ) + catch (const std::runtime_error&) { - if( *ppDevice ) + if (*ppDevice) { (*ppDevice)->Release(); *ppDevice = nullptr; } - if( *ppImmediateContext ) + if (*ppImmediateContext) { (*ppImmediateContext)->Release(); *ppImmediateContext = nullptr; } - LOG_ERROR( "Failed to initialize OpenGL-based render device" ); + LOG_ERROR("Failed to initialize OpenGL-based render device"); } } #ifdef DOXYGEN /// Loads OpenGL-based engine implementation and exports factory functions -/// \param [out] GetFactoryFunc - Pointer to the function that returns pointer to the factory for +/// \param [out] GetFactoryFunc - Pointer to the function that returns pointer to the factory for /// the OpenGL engine implementation /// See EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(). /// \remarks Depending on the configuration and platform, the function loads different dll: @@ -252,17 +251,17 @@ void EngineFactoryOpenGLImpl::AttachToActiveGLContext(const EngineGLCreateInfo& /// Win32/x64 | GraphicsEngineOpenGL_64d.dll | GraphicsEngineOpenGL_64r.dll /// /// To load the library on Android, it is necessary to call System.loadLibrary("GraphicsEngineOpenGL") from Java. -void LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType &GetFactoryFunc) +void LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType& GetFactoryFunc) { - // This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO - #error This function must never be compiled; +// This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO +# error This function must never be compiled; } #endif void EngineFactoryOpenGLImpl::CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter) { - HLSL2GLSLConverterObject *pConverter( NEW_RC_OBJ(GetRawAllocator(), "HLSL2GLSLConverterObject instance", HLSL2GLSLConverterObject)() ); - pConverter->QueryInterface( IID_HLSL2GLSLConverter, reinterpret_cast<IObject**>(ppConverter) ); + HLSL2GLSLConverterObject* pConverter(NEW_RC_OBJ(GetRawAllocator(), "HLSL2GLSLConverterObject instance", HLSL2GLSLConverterObject)()); + pConverter->QueryInterface(IID_HLSL2GLSLConverter, reinterpret_cast<IObject**>(ppConverter)); } #if PLATFORM_ANDROID @@ -279,4 +278,4 @@ Diligent::IEngineFactoryOpenGL* GetEngineFactoryOpenGL() return Diligent::EngineFactoryOpenGLImpl::GetInstance(); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp index 4d4eb55a..79c3a730 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp @@ -31,49 +31,49 @@ namespace Diligent { -bool FBOCache::FBOCacheKey::operator == (const FBOCacheKey &Key)const +bool FBOCache::FBOCacheKey::operator==(const FBOCacheKey& Key) const { - if( Hash !=0 && Key.Hash !=0 && Hash != Key.Hash ) + if (Hash != 0 && Key.Hash != 0 && Hash != Key.Hash) return false; - if( NumRenderTargets != Key.NumRenderTargets ) + if (NumRenderTargets != Key.NumRenderTargets) return false; - for( Uint32 rt = 0; rt < NumRenderTargets;++rt ) - { - if( RTIds[rt] != Key.RTIds[rt] ) + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) + { + if (RTIds[rt] != Key.RTIds[rt]) return false; - if( RTIds[rt] ) + if (RTIds[rt]) { - if( !(RTVDescs[rt] == Key.RTVDescs[rt]) ) + if (!(RTVDescs[rt] == Key.RTVDescs[rt])) return false; } } - if( DSId != Key.DSId ) + if (DSId != Key.DSId) return false; - if( DSId ) + if (DSId) { - if( !(DSVDesc == Key.DSVDesc) ) + if (!(DSVDesc == Key.DSVDesc)) return false; } return true; } -std::size_t FBOCache::FBOCacheKeyHashFunc::operator() ( const FBOCacheKey& Key )const +std::size_t FBOCache::FBOCacheKeyHashFunc::operator()(const FBOCacheKey& Key) const { - if( Key.Hash == 0 ) + if (Key.Hash == 0) { std::hash<TextureViewDesc> TexViewDescHasher; Key.Hash = 0; - HashCombine( Key.Hash, Key.NumRenderTargets ); - for( Uint32 rt = 0; rt < Key.NumRenderTargets; ++rt ) + HashCombine(Key.Hash, Key.NumRenderTargets); + for (Uint32 rt = 0; rt < Key.NumRenderTargets; ++rt) { - HashCombine( Key.Hash, Key.RTIds[rt] ); - if( Key.RTIds[rt] ) - HashCombine( Key.Hash, TexViewDescHasher( Key.RTVDescs[rt] ) ); + HashCombine(Key.Hash, Key.RTIds[rt]); + if (Key.RTIds[rt]) + HashCombine(Key.Hash, TexViewDescHasher(Key.RTVDescs[rt])); } - HashCombine( Key.Hash, Key.DSId ); - if( Key.DSId ) - HashCombine( Key.Hash, TexViewDescHasher( Key.DSVDesc ) ); + HashCombine(Key.Hash, Key.DSId); + if (Key.DSId) + HashCombine(Key.Hash, TexViewDescHasher(Key.DSVDesc)); } return Key.Hash; } @@ -87,27 +87,28 @@ FBOCache::FBOCache() FBOCache::~FBOCache() { - VERIFY( m_Cache.empty(), "FBO cache is not empty. Are there any unreleased objects?" ); - VERIFY( m_TexIdToKey.empty(), "TexIdToKey cache is not empty."); + VERIFY(m_Cache.empty(), "FBO cache is not empty. Are there any unreleased objects?"); + VERIFY(m_TexIdToKey.empty(), "TexIdToKey cache is not empty."); } -void FBOCache::OnReleaseTexture(ITexture *pTexture) +void FBOCache::OnReleaseTexture(ITexture* pTexture) { ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); - auto *pTexGL = ValidatedCast<TextureBaseGL>( pTexture ); + + auto* pTexGL = ValidatedCast<TextureBaseGL>(pTexture); // Find all FBOs that this texture used in auto EqualRange = m_TexIdToKey.equal_range(pTexGL->GetUniqueID()); - for(auto It = EqualRange.first; It != EqualRange.second; ++It) + for (auto It = EqualRange.first; It != EqualRange.second; ++It) { m_Cache.erase(It->second); } m_TexIdToKey.erase(EqualRange.first, EqualRange.second); } -const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 NumRenderTargets, - TextureViewGLImpl* ppRTVs[], - TextureViewGLImpl* pDSV, - GLContextState& ContextState ) +const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 NumRenderTargets, + TextureViewGLImpl* ppRTVs[], + TextureViewGLImpl* pDSV, + GLContextState& ContextState) { // Pop null render targets from the end of the list while (NumRenderTargets > 0 && ppRTVs[NumRenderTargets - 1] == nullptr) @@ -117,11 +118,11 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 N // Lock the cache ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); - + // Construct the key FBOCacheKey Key; VERIFY(NumRenderTargets < MaxRenderTargets, "Too many render targets are being set"); - NumRenderTargets = std::min( NumRenderTargets, MaxRenderTargets ); + NumRenderTargets = std::min(NumRenderTargets, MaxRenderTargets); Key.NumRenderTargets = NumRenderTargets; for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) { @@ -131,10 +132,10 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 N auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>(); pColorTexGL->TextureMemoryBarrier( - GL_FRAMEBUFFER_BARRIER_BIT,// Reads and writes via framebuffer object attachments after the - // barrier will reflect data written by shaders prior to the barrier. - // Additionally, framebuffer writes issued after the barrier will wait - // on the completion of all shader writes issued prior to the barrier. + GL_FRAMEBUFFER_BARRIER_BIT, // Reads and writes via framebuffer object attachments after the + // barrier will reflect data written by shaders prior to the barrier. + // Additionally, framebuffer writes issued after the barrier will wait + // on the completion of all shader writes issued prior to the barrier. ContextState); Key.RTIds[rt] = pColorTexGL->GetUniqueID(); @@ -167,26 +168,26 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 N { if (auto* pRTView = ppRTVs[rt]) { - const auto& RTVDesc = pRTView->GetDesc(); - auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>(); - pColorTexGL->AttachToFramebuffer( RTVDesc, GL_COLOR_ATTACHMENT0 + rt ); + const auto& RTVDesc = pRTView->GetDesc(); + auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>(); + pColorTexGL->AttachToFramebuffer(RTVDesc, GL_COLOR_ATTACHMENT0 + rt); } } if (pDSV != nullptr) { - const auto& DSVDesc = pDSV->GetDesc(); - auto* pDepthTexGL = pDSV->GetTexture<TextureBaseGL>(); - GLenum AttachmentPoint = 0; - if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT || + const auto& DSVDesc = pDSV->GetDesc(); + auto* pDepthTexGL = pDSV->GetTexture<TextureBaseGL>(); + GLenum AttachmentPoint = 0; + if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT || DSVDesc.Format == TEX_FORMAT_D16_UNORM) { #ifdef _DEBUG { const auto GLTexFmt = pDepthTexGL->GetGLTexFormat(); - VERIFY( GLTexFmt == GL_DEPTH_COMPONENT32F || GLTexFmt == GL_DEPTH_COMPONENT16, - "Inappropriate internal texture format (", GLTexFmt, ") for depth attachment. " - "GL_DEPTH_COMPONENT32F or GL_DEPTH_COMPONENT16 is expected"); + VERIFY(GLTexFmt == GL_DEPTH_COMPONENT32F || GLTexFmt == GL_DEPTH_COMPONENT16, + "Inappropriate internal texture format (", GLTexFmt, + ") for depth attachment. GL_DEPTH_COMPONENT32F or GL_DEPTH_COMPONENT16 is expected"); } #endif AttachmentPoint = GL_DEPTH_ATTACHMENT; @@ -197,23 +198,24 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 N #ifdef _DEBUG { const auto GLTexFmt = pDepthTexGL->GetGLTexFormat(); - VERIFY( GLTexFmt == GL_DEPTH24_STENCIL8 || GLTexFmt == GL_DEPTH32F_STENCIL8, - "Inappropriate internal texture format (", GLTexFmt, ") for depth-stencil attachment. " - "GL_DEPTH24_STENCIL8 or GL_DEPTH32F_STENCIL8 is expected"); + VERIFY(GLTexFmt == GL_DEPTH24_STENCIL8 || GLTexFmt == GL_DEPTH32F_STENCIL8, + "Inappropriate internal texture format (", GLTexFmt, + ") for depth-stencil attachment. GL_DEPTH24_STENCIL8 or GL_DEPTH32F_STENCIL8 is expected"); } #endif AttachmentPoint = GL_DEPTH_STENCIL_ATTACHMENT; } else { - UNEXPECTED( GetTextureFormatAttribs(DSVDesc.Format).Name, " is not valid depth-stencil view format" ); + UNEXPECTED(GetTextureFormatAttribs(DSVDesc.Format).Name, " is not valid depth-stencil view format"); } pDepthTexGL->AttachToFramebuffer(DSVDesc, AttachmentPoint); } - // We now need to set mapping between shader outputs and + // We now need to set mapping between shader outputs and // color attachments. This largely redundant step is performed // by glDrawBuffers() + // clang-format off static const GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0, @@ -233,17 +235,20 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 N GL_COLOR_ATTACHMENT14, GL_COLOR_ATTACHMENT15 }; - // The state set by glDrawBuffers() is part of the state of the framebuffer. + // clang-format on + + // The state set by glDrawBuffers() is part of the state of the framebuffer. // So it can be set up once and left it set. glDrawBuffers(NumRenderTargets, DrawBuffers); - CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); + CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()"); GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (Status != GL_FRAMEBUFFER_COMPLETE) { const Char* StatusString = "Unknown"; - switch( Status ) + switch (Status) { + // clang-format off case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break; @@ -251,24 +256,25 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 N case GL_FRAMEBUFFER_UNSUPPORTED: StatusString = "GL_FRAMEBUFFER_UNSUPPORTED"; break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break; case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break; + // clang-format on } - LOG_ERROR( "Framebuffer is incomplete. FB status: ", StatusString ); - UNEXPECTED( "Framebuffer is incomplete" ); + LOG_ERROR("Framebuffer is incomplete. FB status: ", StatusString); + UNEXPECTED("Framebuffer is incomplete"); } - auto NewElems = m_Cache.emplace( std::make_pair(Key, std::move(NewFBO)) ); + auto NewElems = m_Cache.emplace(std::make_pair(Key, std::move(NewFBO))); // New element must be actually inserted - VERIFY( NewElems.second, "New element was not inserted" ); + VERIFY(NewElems.second, "New element was not inserted"); if (Key.DSId != 0) - m_TexIdToKey.insert( std::make_pair(Key.DSId, Key) ); + m_TexIdToKey.insert(std::make_pair(Key.DSId, Key)); for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) { if (Key.RTIds[rt] != 0) - m_TexIdToKey.insert( std::make_pair(Key.RTIds[rt], Key) ); + m_TexIdToKey.insert(std::make_pair(Key.RTIds[rt], Key)); } return NewElems.first->second; } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp index 41db445e..bb2ad414 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp @@ -28,33 +28,37 @@ namespace Diligent { - -FenceGLImpl :: FenceGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDevice, - const FenceDesc& Desc) : + +FenceGLImpl ::FenceGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + const FenceDesc& Desc) : + // clang-format off TFenceBase { pRefCounters, pDevice, Desc } +// clang-format on { } -FenceGLImpl :: ~FenceGLImpl() +FenceGLImpl ::~FenceGLImpl() { } -Uint64 FenceGLImpl :: GetCompletedValue() +Uint64 FenceGLImpl ::GetCompletedValue() { 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) + + 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; @@ -69,16 +73,17 @@ Uint64 FenceGLImpl :: GetCompletedValue() return m_LastCompletedFenceValue; } -void FenceGLImpl :: Wait(Uint64 Value, bool FlushCommands) +void FenceGLImpl ::Wait(Uint64 Value, bool FlushCommands) { while (!m_PendingFences.empty()) { - auto& val_fence = m_PendingFences.front(); + auto& val_fence = m_PendingFences.front(); if (val_fence.first > Value) break; auto res = glClientWaitSync(val_fence.second, FlushCommands ? GL_SYNC_FLUSH_COMMANDS_BIT : 0, std::numeric_limits<GLuint64>::max()); - VERIFY_EXPR(res == GL_ALREADY_SIGNALED || res == GL_CONDITION_SATISFIED); (void)res; + VERIFY_EXPR(res == GL_ALREADY_SIGNALED || res == GL_CONDITION_SATISFIED); + (void)res; if (val_fence.first > m_LastCompletedFenceValue) m_LastCompletedFenceValue = val_fence.first; @@ -86,11 +91,11 @@ void FenceGLImpl :: Wait(Uint64 Value, bool FlushCommands) } } -void FenceGLImpl :: Reset(Uint64 Value) +void FenceGLImpl ::Reset(Uint64 Value) { 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; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp index 3dbae218..bc61774a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp @@ -27,393 +27,394 @@ #include "GLContextAndroid.h" #ifndef EGL_CONTEXT_MINOR_VERSION_KHR -#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +# define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB #endif #ifndef EGL_CONTEXT_MAJOR_VERSION_KHR -#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION +# define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION #endif namespace Diligent { - bool GLContext::InitEGLSurface() + +bool GLContext::InitEGLSurface() +{ + display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (display_ == EGL_NO_DISPLAY) { - display_ = eglGetDisplay( EGL_DEFAULT_DISPLAY ); - if( display_ == EGL_NO_DISPLAY ) - { - LOG_ERROR_AND_THROW( "No EGL display found" ); - } + LOG_ERROR_AND_THROW("No EGL display found"); + } - auto success = eglInitialize( display_, 0, 0 ); - if( !success ) - { - LOG_ERROR_AND_THROW( "Failed to initialise EGL" ); - } + auto success = eglInitialize(display_, 0, 0); + if (!success) + { + LOG_ERROR_AND_THROW("Failed to initialise EGL"); + } - /* - * Here specify the attributes of the desired configuration. - * Below, we select an EGLConfig with at least 8 bits per color - * component compatible with on-screen windows - */ - color_size_ = 8; - depth_size_ = 24; - const EGLint attribs[] = - { + /* + * Here specify the attributes of the desired configuration. + * Below, we select an EGLConfig with at least 8 bits per color + * component compatible with on-screen windows + */ + color_size_ = 8; + depth_size_ = 24; + const EGLint attribs[] = + { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0 - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, //EGL_COLORSPACE, EGL_COLORSPACE_sRGB, // does not work - EGL_BLUE_SIZE, color_size_, + EGL_BLUE_SIZE, color_size_, EGL_GREEN_SIZE, color_size_, - EGL_RED_SIZE, color_size_, + EGL_RED_SIZE, color_size_, EGL_ALPHA_SIZE, color_size_, EGL_DEPTH_SIZE, depth_size_, //EGL_SAMPLE_BUFFERS , 1, //EGL_SAMPLES , 4, - EGL_NONE + EGL_NONE // }; - - // Get a list of EGL frame buffer configurations that match specified attributes - EGLint num_configs; - success = eglChooseConfig( display_, attribs, &config_, 1, &num_configs ); - if( !success ) - { - LOG_ERROR_AND_THROW( "Failed to choose config" ); - } - if( !num_configs ) - { - //Fall back to 16bit depth buffer - depth_size_ = 16; - const EGLint attribs[] = - { + // Get a list of EGL frame buffer configurations that match specified attributes + EGLint num_configs; + success = eglChooseConfig(display_, attribs, &config_, 1, &num_configs); + if (!success) + { + LOG_ERROR_AND_THROW("Failed to choose config"); + } + + if (!num_configs) + { + //Fall back to 16bit depth buffer + depth_size_ = 16; + const EGLint attribs[] = + { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0 - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_BLUE_SIZE, color_size_, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_BLUE_SIZE, color_size_, EGL_GREEN_SIZE, color_size_, - EGL_RED_SIZE, color_size_, + EGL_RED_SIZE, color_size_, EGL_ALPHA_SIZE, color_size_, - EGL_DEPTH_SIZE, depth_size_, - EGL_NONE + EGL_DEPTH_SIZE, depth_size_, + EGL_NONE // }; - success = eglChooseConfig( display_, attribs, &config_, 1, &num_configs ); - if( !success ) - { - LOG_ERROR_AND_THROW( "Failed to choose 16-bit depth config" ); - } - } - - if( !num_configs ) + success = eglChooseConfig(display_, attribs, &config_, 1, &num_configs); + if (!success) { - LOG_ERROR_AND_THROW( "Unable to retrieve EGL config" ); - } - - LOG_INFO_MESSAGE("Chosen EGL config: ", color_size_, " bit color, ", depth_size_, " bit depth"); - - surface_ = eglCreateWindowSurface( display_, config_, window_, NULL ); - if( surface_ == EGL_NO_SURFACE ) - { - LOG_ERROR_AND_THROW( "Failed to create EGLSurface" ); + LOG_ERROR_AND_THROW("Failed to choose 16-bit depth config"); } + } - eglQuerySurface( display_, surface_, EGL_WIDTH, &screen_width_ ); - eglQuerySurface( display_, surface_, EGL_HEIGHT, &screen_height_ ); + if (!num_configs) + { + LOG_ERROR_AND_THROW("Unable to retrieve EGL config"); + } - /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is - * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). - * As soon as we picked a EGLConfig, we can safely reconfigure the - * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ - EGLint format; - eglGetConfigAttrib( display_, config_, EGL_NATIVE_VISUAL_ID, &format ); - ANativeWindow_setBuffersGeometry( window_, 0, 0, format ); + LOG_INFO_MESSAGE("Chosen EGL config: ", color_size_, " bit color, ", depth_size_, " bit depth"); - return true; + surface_ = eglCreateWindowSurface(display_, config_, window_, NULL); + if (surface_ == EGL_NO_SURFACE) + { + LOG_ERROR_AND_THROW("Failed to create EGLSurface"); } - bool GLContext::InitEGLContext() - { - std::pair<int,int> es_versions[] = {{3,2}, {3,1}, {3,0}}; - for(size_t i=0; i < _countof(es_versions) && context_ == EGL_NO_CONTEXT; ++i) - { - const auto& version = es_versions[i]; - major_version_ = version.first; - minor_version_ = version.second; + eglQuerySurface(display_, surface_, EGL_WIDTH, &screen_width_); + eglQuerySurface(display_, surface_, EGL_HEIGHT, &screen_height_); - const EGLint context_attribs[] = - { - EGL_CONTEXT_CLIENT_VERSION, major_version_, - EGL_CONTEXT_MINOR_VERSION_KHR, minor_version_, - EGL_NONE - }; + /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is + * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). + * As soon as we picked a EGLConfig, we can safely reconfigure the + * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ + EGLint format; + eglGetConfigAttrib(display_, config_, EGL_NATIVE_VISUAL_ID, &format); + ANativeWindow_setBuffersGeometry(window_, 0, 0, format); - context_ = eglCreateContext( display_, config_, NULL, context_attribs ); - } + return true; +} - if (context_ == EGL_NO_CONTEXT) - { - LOG_ERROR_AND_THROW("Failed to create EGLContext"); - } +bool GLContext::InitEGLContext() +{ + std::pair<int, int> es_versions[] = {{3, 2}, {3, 1}, {3, 0}}; + for (size_t i = 0; i < _countof(es_versions) && context_ == EGL_NO_CONTEXT; ++i) + { + const auto& version = es_versions[i]; + major_version_ = version.first; + minor_version_ = version.second; - if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_FALSE ) - { - LOG_ERROR_AND_THROW( "Unable to eglMakeCurrent" ); - } + const EGLint context_attribs[] = + { + EGL_CONTEXT_CLIENT_VERSION, major_version_, + EGL_CONTEXT_MINOR_VERSION_KHR, minor_version_, + EGL_NONE}; - LOG_INFO_MESSAGE("Created OpenGLES Context ", major_version_, '.', minor_version_); - context_valid_ = true; - return true; + context_ = eglCreateContext(display_, config_, NULL, context_attribs); } - void GLContext::AttachToCurrentEGLContext() + if (context_ == EGL_NO_CONTEXT) { - if( eglGetCurrentContext() == EGL_NO_CONTEXT ) - { - LOG_ERROR_AND_THROW( "Failed to attach to EGLContext: no active context" ); - } - context_valid_ = true; - glGetIntegerv( GL_MAJOR_VERSION, &major_version_ ); - glGetIntegerv( GL_MINOR_VERSION, &minor_version_ ); + LOG_ERROR_AND_THROW("Failed to create EGLContext"); } - GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() + if (eglMakeCurrent(display_, surface_, surface_, context_) == EGL_FALSE) { - return eglGetCurrentContext(); + LOG_ERROR_AND_THROW("Unable to eglMakeCurrent"); } - void GLContext::InitGLES() + LOG_INFO_MESSAGE("Created OpenGLES Context ", major_version_, '.', minor_version_); + context_valid_ = true; + return true; +} + +void GLContext::AttachToCurrentEGLContext() +{ + if (eglGetCurrentContext() == EGL_NO_CONTEXT) { - if( gles_initialized_ ) - return; - // - //Initialize OpenGL ES 3 if available - // - const char* versionStr = (const char*)glGetString( GL_VERSION ); - LOG_INFO_MESSAGE( "GL Version: ", versionStr, '\n' ); - - LoadGLFunctions(); - - // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace - // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore - // convert the output from linear RGB to sRGB. - // Any writes to images that are not in the sRGB format should not be affected. - // Thus this setting should be just set once and left that way - glEnable(GL_FRAMEBUFFER_SRGB); - if( glGetError() != GL_NO_ERROR ) - LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); - - gles_initialized_ = true; + LOG_ERROR_AND_THROW("Failed to attach to EGLContext: no active context"); } + context_valid_ = true; + glGetIntegerv(GL_MAJOR_VERSION, &major_version_); + glGetIntegerv(GL_MINOR_VERSION, &minor_version_); +} - bool GLContext::Init( ANativeWindow* window ) - { - if( egl_context_initialized_ ) - return true; - - // - //Initialize EGL - // - window_ = window; - if (window != nullptr) - { - InitEGLSurface(); - InitEGLContext(); - } - else - { - AttachToCurrentEGLContext(); - } - InitGLES(); +GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() +{ + return eglGetCurrentContext(); +} - egl_context_initialized_ = true; +void GLContext::InitGLES() +{ + if (gles_initialized_) + return; + // + //Initialize OpenGL ES 3 if available + // + const char* versionStr = (const char*)glGetString(GL_VERSION); + LOG_INFO_MESSAGE("GL Version: ", versionStr, '\n'); + + LoadGLFunctions(); + + // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace + // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore + // convert the output from linear RGB to sRGB. + // Any writes to images that are not in the sRGB format should not be affected. + // Thus this setting should be just set once and left that way + glEnable(GL_FRAMEBUFFER_SRGB); + if (glGetError() != GL_NO_ERROR) + LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); + + gles_initialized_ = true; +} +bool GLContext::Init(ANativeWindow* window) +{ + if (egl_context_initialized_) return true; - } - GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : - display_( EGL_NO_DISPLAY ), - surface_( EGL_NO_SURFACE ), - context_( EGL_NO_CONTEXT ), - egl_context_initialized_( false ), - gles_initialized_( false ), - major_version_(0), - minor_version_(0) + // + //Initialize EGL + // + window_ = window; + if (window != nullptr) { - auto *NativeWindow = reinterpret_cast<ANativeWindow*>(InitAttribs.pNativeWndHandle); - Init( NativeWindow ); - - FillDeviceCaps(deviceCaps); + InitEGLSurface(); + InitEGLContext(); } - - GLContext::~GLContext() + else { - Terminate(); + AttachToCurrentEGLContext(); } + InitGLES(); - void GLContext::SwapBuffers() + egl_context_initialized_ = true; + + return true; +} + +GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : + display_(EGL_NO_DISPLAY), + surface_(EGL_NO_SURFACE), + context_(EGL_NO_CONTEXT), + egl_context_initialized_(false), + gles_initialized_(false), + major_version_(0), + minor_version_(0) +{ + auto* NativeWindow = reinterpret_cast<ANativeWindow*>(InitAttribs.pNativeWndHandle); + Init(NativeWindow); + + FillDeviceCaps(deviceCaps); +} + +GLContext::~GLContext() +{ + Terminate(); +} + +void GLContext::SwapBuffers() +{ + if (surface_ == EGL_NO_SURFACE) { - if(surface_ == EGL_NO_SURFACE) - { - LOG_WARNING_MESSAGE("No EGL surface when swapping buffers. This happens when SwapBuffers() is called after Suspend(). The operation will be ignored."); - return; - } + LOG_WARNING_MESSAGE("No EGL surface when swapping buffers. This happens when SwapBuffers() is called after Suspend(). The operation will be ignored."); + return; + } - bool b = eglSwapBuffers( display_, surface_ ); - if( !b ) + bool b = eglSwapBuffers(display_, surface_); + if (!b) + { + EGLint err = eglGetError(); + if (err == EGL_BAD_SURFACE) { - EGLint err = eglGetError(); - if( err == EGL_BAD_SURFACE ) + LOG_INFO_MESSAGE("EGL surface has been lost. Attempting to recreate"); + try { - LOG_INFO_MESSAGE("EGL surface has been lost. Attempting to recreate"); - try - { - InitEGLSurface(); - } - catch(std::runtime_error &) - { - LOG_ERROR_MESSAGE("Failed to recreate EGL surface"); - } - //return EGL_SUCCESS; //Still consider glContext is valid + InitEGLSurface(); } - else if( err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT ) + catch (std::runtime_error&) { - //Context has been lost!! - context_valid_ = false; - Terminate(); - InitEGLContext(); + LOG_ERROR_MESSAGE("Failed to recreate EGL surface"); } - //return err; + //return EGL_SUCCESS; //Still consider glContext is valid + } + else if (err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT) + { + //Context has been lost!! + context_valid_ = false; + Terminate(); + InitEGLContext(); } - //return EGL_SUCCESS; + //return err; } + //return EGL_SUCCESS; +} - void GLContext::Terminate() +void GLContext::Terminate() +{ + if (display_ != EGL_NO_DISPLAY) { - if( display_ != EGL_NO_DISPLAY ) + eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (context_ != EGL_NO_CONTEXT) { - eglMakeCurrent( display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); - if( context_ != EGL_NO_CONTEXT ) - { - eglDestroyContext( display_, context_ ); - } - - if( surface_ != EGL_NO_SURFACE ) - { - eglDestroySurface( display_, surface_ ); - } - eglTerminate( display_ ); + eglDestroyContext(display_, context_); } - display_ = EGL_NO_DISPLAY; - context_ = EGL_NO_CONTEXT; - surface_ = EGL_NO_SURFACE; - context_valid_ = false; + if (surface_ != EGL_NO_SURFACE) + { + eglDestroySurface(display_, surface_); + } + eglTerminate(display_); } + display_ = EGL_NO_DISPLAY; + context_ = EGL_NO_CONTEXT; + surface_ = EGL_NO_SURFACE; + context_valid_ = false; +} - void GLContext::UpdateScreenSize() - { - int32_t new_screen_width = 0; - int32_t new_screen_height = 0; - eglQuerySurface( display_, surface_, EGL_WIDTH, &new_screen_width ); - eglQuerySurface( display_, surface_, EGL_HEIGHT, &new_screen_height ); - if( new_screen_width != screen_width_ || new_screen_height != screen_height_ ) - { - screen_width_ = new_screen_width; - screen_height_ = new_screen_height; - //Screen resized - LOG_INFO_MESSAGE( "Window size changed to ", screen_width_, "x", screen_height_ ); - } - } +void GLContext::UpdateScreenSize() +{ + int32_t new_screen_width = 0; + int32_t new_screen_height = 0; + eglQuerySurface(display_, surface_, EGL_WIDTH, &new_screen_width); + eglQuerySurface(display_, surface_, EGL_HEIGHT, &new_screen_height); - EGLint GLContext::Resume( ANativeWindow* window ) + if (new_screen_width != screen_width_ || new_screen_height != screen_height_) { - LOG_INFO_MESSAGE( "Resuming gl context\n" ); + screen_width_ = new_screen_width; + screen_height_ = new_screen_height; + //Screen resized + LOG_INFO_MESSAGE("Window size changed to ", screen_width_, "x", screen_height_); + } +} - if( egl_context_initialized_ == false ) - { - Init( window ); - return EGL_SUCCESS; - } +EGLint GLContext::Resume(ANativeWindow* window) +{ + LOG_INFO_MESSAGE("Resuming gl context\n"); - //Create surface - window_ = window; - surface_ = eglCreateWindowSurface( display_, config_, window_, NULL ); - UpdateScreenSize(); + if (egl_context_initialized_ == false) + { + Init(window); + return EGL_SUCCESS; + } - if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_TRUE ) - return EGL_SUCCESS; + //Create surface + window_ = window; + surface_ = eglCreateWindowSurface(display_, config_, window_, NULL); + UpdateScreenSize(); - EGLint err = eglGetError(); - LOG_WARNING_MESSAGE( "Unable to eglMakeCurrent ", err, '\n' ); + if (eglMakeCurrent(display_, surface_, surface_, context_) == EGL_TRUE) + return EGL_SUCCESS; - if( err == EGL_CONTEXT_LOST ) - { - //Recreate context - LOG_INFO_MESSAGE( "Re-creating egl context\n" ); - InitEGLContext(); - } - else - { - //Recreate surface - LOG_INFO_MESSAGE( "Re-creating egl context and surface\n" ); - Terminate(); - InitEGLSurface(); - InitEGLContext(); - } - - return err; - } + EGLint err = eglGetError(); + LOG_WARNING_MESSAGE("Unable to eglMakeCurrent ", err, '\n'); - void GLContext::Suspend() + if (err == EGL_CONTEXT_LOST) { - LOG_INFO_MESSAGE( "Suspending gl context\n" ); - if( surface_ != EGL_NO_SURFACE ) - { - LOG_INFO_MESSAGE( "Destroying egl surface\n" ); - eglDestroySurface( display_, surface_ ); - surface_ = EGL_NO_SURFACE; - } + //Recreate context + LOG_INFO_MESSAGE("Re-creating egl context\n"); + InitEGLContext(); } - - bool GLContext::Invalidate() + else { - LOG_INFO_MESSAGE( "Invalidating gl context\n" ); + //Recreate surface + LOG_INFO_MESSAGE("Re-creating egl context and surface\n"); Terminate(); - - egl_context_initialized_ = false; - return true; + InitEGLSurface(); + InitEGLContext(); } - void GLContext::FillDeviceCaps( DeviceCaps& deviceCaps ) + return err; +} + +void GLContext::Suspend() +{ + LOG_INFO_MESSAGE("Suspending gl context\n"); + if (surface_ != EGL_NO_SURFACE) { - const auto* Extensions = (char*)glGetString(GL_EXTENSIONS); - LOG_INFO_MESSAGE( "Supported extensions: \n", Extensions); - - deviceCaps.DevType = DeviceType::OpenGLES; - deviceCaps.MajorVersion = major_version_; - deviceCaps.MinorVersion = minor_version_; - bool IsGLES31OrAbove = (major_version_ >= 4 || (major_version_ == 3 && minor_version_ >= 1) ); - bool IsGLES32OrAbove = (major_version_ >= 4 || (major_version_ == 3 && minor_version_ >= 2) ); - deviceCaps.bSeparableProgramSupported = IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects"); - deviceCaps.bIndirectRenderingSupported = IsGLES31OrAbove || strstr(Extensions, "draw_indirect"); - - deviceCaps.bComputeShadersSupported = IsGLES31OrAbove || strstr(Extensions, "compute_shader"); - deviceCaps.bGeometryShadersSupported = IsGLES32OrAbove || strstr(Extensions, "geometry_shader"); - deviceCaps.bTessellationSupported = IsGLES32OrAbove || strstr(Extensions, "tessellation_shader"); - - auto &SamCaps = deviceCaps.SamCaps; - SamCaps.bBorderSamplingModeSupported = GL_TEXTURE_BORDER_COLOR && (IsGLES32OrAbove || strstr(Extensions, "texture_border_clamp")); - SamCaps.bAnisotropicFilteringSupported = GL_TEXTURE_MAX_ANISOTROPY_EXT && (IsGLES31OrAbove || strstr(Extensions, "texture_filter_anisotropic")); - SamCaps.bLODBiasSupported = GL_TEXTURE_LOD_BIAS && IsGLES31OrAbove; - - auto &TexCaps = deviceCaps.TexCaps; - TexCaps.bTexture1DSupported = False; // Not supported in GLES 3.2 - TexCaps.bTexture1DArraySupported = False; // Not supported in GLES 3.2 - TexCaps.bTexture2DMSSupported = IsGLES31OrAbove || strstr(Extensions, "texture_storage_multisample"); - TexCaps.bTexture2DMSArraySupported = IsGLES32OrAbove || strstr(Extensions, "texture_storage_multisample_2d_array"); - TexCaps.bTextureViewSupported = IsGLES31OrAbove || strstr(Extensions, "texture_view"); - TexCaps.bCubemapArraysSupported = IsGLES32OrAbove || strstr(Extensions, "texture_cube_map_array"); - - deviceCaps.bMultithreadedResourceCreationSupported = False; + LOG_INFO_MESSAGE("Destroying egl surface\n"); + eglDestroySurface(display_, surface_); + surface_ = EGL_NO_SURFACE; } } + +bool GLContext::Invalidate() +{ + LOG_INFO_MESSAGE("Invalidating gl context\n"); + Terminate(); + + egl_context_initialized_ = false; + return true; +} + +void GLContext::FillDeviceCaps(DeviceCaps& deviceCaps) +{ + const auto* Extensions = (char*)glGetString(GL_EXTENSIONS); + LOG_INFO_MESSAGE("Supported extensions: \n", Extensions); + + deviceCaps.DevType = DeviceType::OpenGLES; + deviceCaps.MajorVersion = major_version_; + deviceCaps.MinorVersion = minor_version_; + bool IsGLES31OrAbove = (major_version_ >= 4 || (major_version_ == 3 && minor_version_ >= 1)); + bool IsGLES32OrAbove = (major_version_ >= 4 || (major_version_ == 3 && minor_version_ >= 2)); + deviceCaps.bSeparableProgramSupported = IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects"); + deviceCaps.bIndirectRenderingSupported = IsGLES31OrAbove || strstr(Extensions, "draw_indirect"); + + deviceCaps.bComputeShadersSupported = IsGLES31OrAbove || strstr(Extensions, "compute_shader"); + deviceCaps.bGeometryShadersSupported = IsGLES32OrAbove || strstr(Extensions, "geometry_shader"); + deviceCaps.bTessellationSupported = IsGLES32OrAbove || strstr(Extensions, "tessellation_shader"); + + auto& SamCaps = deviceCaps.SamCaps; + SamCaps.bBorderSamplingModeSupported = GL_TEXTURE_BORDER_COLOR && (IsGLES32OrAbove || strstr(Extensions, "texture_border_clamp")); + SamCaps.bAnisotropicFilteringSupported = GL_TEXTURE_MAX_ANISOTROPY_EXT && (IsGLES31OrAbove || strstr(Extensions, "texture_filter_anisotropic")); + SamCaps.bLODBiasSupported = GL_TEXTURE_LOD_BIAS && IsGLES31OrAbove; + + auto& TexCaps = deviceCaps.TexCaps; + TexCaps.bTexture1DSupported = False; // Not supported in GLES 3.2 + TexCaps.bTexture1DArraySupported = False; // Not supported in GLES 3.2 + TexCaps.bTexture2DMSSupported = IsGLES31OrAbove || strstr(Extensions, "texture_storage_multisample"); + TexCaps.bTexture2DMSArraySupported = IsGLES32OrAbove || strstr(Extensions, "texture_storage_multisample_2d_array"); + TexCaps.bTextureViewSupported = IsGLES31OrAbove || strstr(Extensions, "texture_view"); + TexCaps.bCubemapArraysSupported = IsGLES32OrAbove || strstr(Extensions, "texture_cube_map_array"); + + deviceCaps.bMultithreadedResourceCreationSupported = False; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp index ec0f710a..c67ec50b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp @@ -29,153 +29,156 @@ namespace Diligent { - void openglCallbackFunction( GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam ) - { - std::stringstream MessageSS; - - MessageSS << "OpenGL debug message ("; - switch( type ) - { - case GL_DEBUG_TYPE_ERROR: - MessageSS << "ERROR"; - break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: - MessageSS << "DEPRECATED_BEHAVIOR"; - break; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: - MessageSS << "UNDEFINED_BEHAVIOR"; - break; - case GL_DEBUG_TYPE_PORTABILITY: - MessageSS << "PORTABILITY"; - break; - case GL_DEBUG_TYPE_PERFORMANCE: - MessageSS << "PERFORMANCE"; - break; - case GL_DEBUG_TYPE_OTHER: - MessageSS << "OTHER"; - break; - } - switch( severity ) - { - case GL_DEBUG_SEVERITY_LOW: - MessageSS << ", low severity"; - break; - case GL_DEBUG_SEVERITY_MEDIUM: - MessageSS << ", medium severity"; - break; - case GL_DEBUG_SEVERITY_HIGH: - MessageSS << ", HIGH severity"; - break; - case GL_DEBUG_SEVERITY_NOTIFICATION: - MessageSS << ", notification"; - break; - } - - MessageSS << ")" << std::endl << message << std::endl; +void openglCallbackFunction(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) +{ + std::stringstream MessageSS; - LOG_INFO_MESSAGE( MessageSS.str().c_str() ); + MessageSS << "OpenGL debug message ("; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + MessageSS << "ERROR"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + MessageSS << "DEPRECATED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + MessageSS << "UNDEFINED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + MessageSS << "PORTABILITY"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + MessageSS << "PERFORMANCE"; + break; + case GL_DEBUG_TYPE_OTHER: + MessageSS << "OTHER"; + break; } - GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : - m_Context(0), - m_pNativeWindow(InitAttribs.pNativeWndHandle), - m_pDisplay(InitAttribs.pDisplay) + switch (severity) { - auto CurrentCtx = glXGetCurrentContext(); - if (CurrentCtx == 0) - { - LOG_ERROR_AND_THROW("No current GL context found!"); - } - - // Initialize GLEW - GLenum err = glewInit(); - if( GLEW_OK != err ) - LOG_ERROR_AND_THROW( "Failed to initialize GLEW" ); - - if(InitAttribs.pNativeWndHandle != nullptr && InitAttribs.pDisplay != nullptr) - { - //glXSwapIntervalEXT(0); - - if( glDebugMessageCallback ) - { - glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS ); - glDebugMessageCallback( openglCallbackFunction, nullptr ); - GLuint unusedIds = 0; - glDebugMessageControl( GL_DONT_CARE, - GL_DONT_CARE, - GL_DONT_CARE, - 0, - &unusedIds, - true ); - } - } - - //Checking GL version - const GLubyte *GLVersionString = glGetString( GL_VERSION ); - const GLubyte *GLRenderer = glGetString(GL_RENDERER); - - Int32 MajorVersion = 0, MinorVersion = 0; - //Or better yet, use the GL3 way to get the version number - glGetIntegerv( GL_MAJOR_VERSION, &MajorVersion ); - glGetIntegerv( GL_MINOR_VERSION, &MinorVersion ); - LOG_INFO_MESSAGE(InitAttribs.pNativeWndHandle != nullptr ? "Initialized OpenGL " : "Attached to OpenGL ", MajorVersion, '.', MinorVersion, " context (", GLVersionString, ", ", GLRenderer, ')'); - - // Under the standard filtering rules for cubemaps, filtering does not work across faces of the cubemap. - // This results in a seam across the faces of a cubemap. This was a hardware limitation in the past, but - // modern hardware is capable of interpolating across a cube face boundary. - // GL_TEXTURE_CUBE_MAP_SEAMLESS is not defined in OpenGLES - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - if( glGetError() != GL_NO_ERROR ) - LOG_ERROR_MESSAGE("Failed to enable seamless cubemap filtering"); - - // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace - // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore - // convert the output from linear RGB to sRGB. - // Any writes to images that are not in the sRGB format should not be affected. - // Thus this setting should be just set once and left that way - glEnable(GL_FRAMEBUFFER_SRGB); - if( glGetError() != GL_NO_ERROR ) - LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); - - deviceCaps.DevType = DeviceType::OpenGL; - deviceCaps.MajorVersion = MajorVersion; - deviceCaps.MinorVersion = MinorVersion; - bool IsGL43OrAbove = MajorVersion >= 5 || MajorVersion == 4 && MinorVersion >= 3; - auto &TexCaps = deviceCaps.TexCaps; - TexCaps.bTexture2DMSSupported = IsGL43OrAbove; - TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; - TexCaps.bTextureViewSupported = IsGL43OrAbove; - TexCaps.bCubemapArraysSupported = IsGL43OrAbove; - deviceCaps.bMultithreadedResourceCreationSupported = False; + case GL_DEBUG_SEVERITY_LOW: + MessageSS << ", low severity"; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + MessageSS << ", medium severity"; + break; + case GL_DEBUG_SEVERITY_HIGH: + MessageSS << ", HIGH severity"; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION: + MessageSS << ", notification"; + break; } - GLContext::~GLContext() + MessageSS << ")" << std::endl + << message << std::endl; + + LOG_INFO_MESSAGE(MessageSS.str().c_str()); +} + +GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : + m_Context(0), + m_pNativeWindow(InitAttribs.pNativeWndHandle), + m_pDisplay(InitAttribs.pDisplay) +{ + auto CurrentCtx = glXGetCurrentContext(); + if (CurrentCtx == 0) { + LOG_ERROR_AND_THROW("No current GL context found!"); } - void GLContext::SwapBuffers() + // Initialize GLEW + GLenum err = glewInit(); + if (GLEW_OK != err) + LOG_ERROR_AND_THROW("Failed to initialize GLEW"); + + if (InitAttribs.pNativeWndHandle != nullptr && InitAttribs.pDisplay != nullptr) { - if(m_pNativeWindow != nullptr && m_pDisplay != nullptr) - { - auto wnd = static_cast<Window>(reinterpret_cast<size_t>(m_pNativeWindow)); - auto display = reinterpret_cast<Display*>(m_pDisplay); - glXSwapBuffers(display, wnd); - } - else + //glXSwapIntervalEXT(0); + + if (glDebugMessageCallback) { - LOG_ERROR("Swap buffer failed because window and/or display handle is not initialized"); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(openglCallbackFunction, nullptr); + GLuint unusedIds = 0; + glDebugMessageControl(GL_DONT_CARE, + GL_DONT_CARE, + GL_DONT_CARE, + 0, + &unusedIds, + true); } } - GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() + //Checking GL version + const GLubyte* GLVersionString = glGetString(GL_VERSION); + const GLubyte* GLRenderer = glGetString(GL_RENDERER); + + Int32 MajorVersion = 0, MinorVersion = 0; + //Or better yet, use the GL3 way to get the version number + glGetIntegerv(GL_MAJOR_VERSION, &MajorVersion); + glGetIntegerv(GL_MINOR_VERSION, &MinorVersion); + LOG_INFO_MESSAGE(InitAttribs.pNativeWndHandle != nullptr ? "Initialized OpenGL " : "Attached to OpenGL ", MajorVersion, '.', MinorVersion, " context (", GLVersionString, ", ", GLRenderer, ')'); + + // Under the standard filtering rules for cubemaps, filtering does not work across faces of the cubemap. + // This results in a seam across the faces of a cubemap. This was a hardware limitation in the past, but + // modern hardware is capable of interpolating across a cube face boundary. + // GL_TEXTURE_CUBE_MAP_SEAMLESS is not defined in OpenGLES + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + if (glGetError() != GL_NO_ERROR) + LOG_ERROR_MESSAGE("Failed to enable seamless cubemap filtering"); + + // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace + // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore + // convert the output from linear RGB to sRGB. + // Any writes to images that are not in the sRGB format should not be affected. + // Thus this setting should be just set once and left that way + glEnable(GL_FRAMEBUFFER_SRGB); + if (glGetError() != GL_NO_ERROR) + LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); + + deviceCaps.DevType = DeviceType::OpenGL; + deviceCaps.MajorVersion = MajorVersion; + deviceCaps.MinorVersion = MinorVersion; + bool IsGL43OrAbove = MajorVersion >= 5 || MajorVersion == 4 && MinorVersion >= 3; + auto& TexCaps = deviceCaps.TexCaps; + TexCaps.bTexture2DMSSupported = IsGL43OrAbove; + TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; + TexCaps.bTextureViewSupported = IsGL43OrAbove; + TexCaps.bCubemapArraysSupported = IsGL43OrAbove; + deviceCaps.bMultithreadedResourceCreationSupported = False; +} + +GLContext::~GLContext() +{ +} + +void GLContext::SwapBuffers() +{ + if (m_pNativeWindow != nullptr && m_pDisplay != nullptr) + { + auto wnd = static_cast<Window>(reinterpret_cast<size_t>(m_pNativeWindow)); + auto display = reinterpret_cast<Display*>(m_pDisplay); + glXSwapBuffers(display, wnd); + } + else { - return glXGetCurrentContext(); + LOG_ERROR("Swap buffer failed because window and/or display handle is not initialized"); } } + +GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() +{ + return glXGetCurrentContext(); +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index 4afc6ea5..19b8197f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -35,788 +35,793 @@ using namespace GLObjectWrappers; namespace Diligent { - GLContextState::GLContextState(RenderDeviceGLImpl* pDeviceGL) - { - const DeviceCaps& DeviceCaps = pDeviceGL->GetDeviceCaps(); - m_Caps.bFillModeSelectionSupported = DeviceCaps.bWireframeFillSupported; - { - m_Caps.m_iMaxCombinedTexUnits = 0; - glGetIntegerv( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &m_Caps.m_iMaxCombinedTexUnits ); - CHECK_GL_ERROR( "Failed to get max combined tex image units count" ); - VERIFY_EXPR(m_Caps.m_iMaxCombinedTexUnits > 0); - - m_Caps.m_iMaxDrawBuffers = 0; - glGetIntegerv( GL_MAX_DRAW_BUFFERS, &m_Caps.m_iMaxDrawBuffers ); - CHECK_GL_ERROR( "Failed to get max draw buffers count" ); - VERIFY_EXPR(m_Caps.m_iMaxDrawBuffers > 0); - - glGetIntegerv( GL_MAX_UNIFORM_BUFFER_BINDINGS, &m_Caps.m_iMaxUniformBufferBindings ); - CHECK_GL_ERROR( "Failed to get uniform buffers count" ); - VERIFY_EXPR(m_Caps.m_iMaxUniformBufferBindings > 0); - } +GLContextState::GLContextState(RenderDeviceGLImpl* pDeviceGL) +{ + const DeviceCaps& DeviceCaps = pDeviceGL->GetDeviceCaps(); + m_Caps.bFillModeSelectionSupported = DeviceCaps.bWireframeFillSupported; - m_BoundTextures.reserve( m_Caps.m_iMaxCombinedTexUnits ); - m_BoundSamplers.reserve( 32 ); - m_BoundImages.reserve( 32 ); - m_BoundUniformBuffers.reserve( m_Caps.m_iMaxUniformBufferBindings ); - m_BoundStorageBlocks.reserve(16); + { + m_Caps.m_iMaxCombinedTexUnits = 0; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &m_Caps.m_iMaxCombinedTexUnits); + CHECK_GL_ERROR("Failed to get max combined tex image units count"); + VERIFY_EXPR(m_Caps.m_iMaxCombinedTexUnits > 0); - Invalidate(); + m_Caps.m_iMaxDrawBuffers = 0; + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &m_Caps.m_iMaxDrawBuffers); + CHECK_GL_ERROR("Failed to get max draw buffers count"); + VERIFY_EXPR(m_Caps.m_iMaxDrawBuffers > 0); - m_CurrentGLContext = pDeviceGL->m_GLContext.GetCurrentNativeGLContext(); + glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &m_Caps.m_iMaxUniformBufferBindings); + CHECK_GL_ERROR("Failed to get uniform buffers count"); + VERIFY_EXPR(m_Caps.m_iMaxUniformBufferBindings > 0); } - void GLContextState::Invalidate() - { + m_BoundTextures.reserve(m_Caps.m_iMaxCombinedTexUnits); + m_BoundSamplers.reserve(32); + m_BoundImages.reserve(32); + m_BoundUniformBuffers.reserve(m_Caps.m_iMaxUniformBufferBindings); + m_BoundStorageBlocks.reserve(16); + + Invalidate(); + + m_CurrentGLContext = pDeviceGL->m_GLContext.GetCurrentNativeGLContext(); +} + +void GLContextState::Invalidate() +{ #if !PLATFORM_ANDROID - // On Android this results in OpenGL error, so we will not - // clear the barriers. All the required barriers will be - // executed next frame when needed - if(m_PendingMemoryBarriers != 0) - EnsureMemoryBarrier(m_PendingMemoryBarriers); - m_PendingMemoryBarriers = 0; + // On Android this results in OpenGL error, so we will not + // clear the barriers. All the required barriers will be + // executed next frame when needed + if (m_PendingMemoryBarriers != 0) + EnsureMemoryBarrier(m_PendingMemoryBarriers); + m_PendingMemoryBarriers = 0; #endif - // Unity messes up at least VAO left in the context, - // so unbid what we bound - glUseProgram( 0 ); - glBindProgramPipeline( 0 ); - glBindVertexArray( 0 ); - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); - glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ); - DEV_CHECK_GL_ERROR( "Failed to reset GL context state" ); - - m_GLProgId = -1; - m_GLPipelineId = -1; - m_VAOId = -1; - m_FBOId = -1; - - m_BoundTextures.clear(); - m_BoundSamplers.clear(); - m_BoundImages.clear(); - m_BoundUniformBuffers.clear(); - m_BoundStorageBlocks.clear(); - - m_DSState = DepthStencilGLState(); - m_RSState = RasterizerGLState(); - - for( Uint32 rt = 0; rt < _countof( m_ColorWriteMasks ); ++rt ) - m_ColorWriteMasks[rt] = 0xFF; - - m_bIndependentWriteMasks = EnableStateHelper(); - - m_iActiveTexture = -1; - m_NumPatchVertices = -1; - } - - template<typename ObjectType> - bool UpdateBoundObject( UniqueIdentifier &CurrentObjectID, const ObjectType &NewObject, GLuint &NewGLHandle ) - { - NewGLHandle = static_cast<GLuint>(NewObject); - // Only ask for the ID if the object handle is non-zero - // to avoid ID generation for null objects - UniqueIdentifier NewObjectID = (NewGLHandle != 0) ? NewObject.GetUniqueID() : 0; - - // It is unsafe to use GL handle to keep track of bound textures - // When a texture is released, GL is free to reuse its handle for - // the new created textures - if( CurrentObjectID != NewObjectID ) - { - CurrentObjectID = NewObjectID; - return true; - } - return false; - } + // Unity messes up at least VAO left in the context, + // so unbid what we bound + glUseProgram(0); + glBindProgramPipeline(0); + glBindVertexArray(0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + DEV_CHECK_GL_ERROR("Failed to reset GL context state"); + + m_GLProgId = -1; + m_GLPipelineId = -1; + m_VAOId = -1; + m_FBOId = -1; + + m_BoundTextures.clear(); + m_BoundSamplers.clear(); + m_BoundImages.clear(); + m_BoundUniformBuffers.clear(); + m_BoundStorageBlocks.clear(); + + m_DSState = DepthStencilGLState(); + m_RSState = RasterizerGLState(); + + for (Uint32 rt = 0; rt < _countof(m_ColorWriteMasks); ++rt) + m_ColorWriteMasks[rt] = 0xFF; + + m_bIndependentWriteMasks = EnableStateHelper(); - void GLContextState::SetProgram( const GLProgramObj &GLProgram ) + m_iActiveTexture = -1; + m_NumPatchVertices = -1; +} + +template <typename ObjectType> +bool UpdateBoundObject(UniqueIdentifier& CurrentObjectID, const ObjectType& NewObject, GLuint& NewGLHandle) +{ + NewGLHandle = static_cast<GLuint>(NewObject); + // Only ask for the ID if the object handle is non-zero + // to avoid ID generation for null objects + UniqueIdentifier NewObjectID = (NewGLHandle != 0) ? NewObject.GetUniqueID() : 0; + + // It is unsafe to use GL handle to keep track of bound textures + // When a texture is released, GL is free to reuse its handle for + // the new created textures + if (CurrentObjectID != NewObjectID) { - GLuint GLProgHandle = 0; - if( UpdateBoundObject( m_GLProgId, GLProgram, GLProgHandle ) ) - { - glUseProgram( GLProgHandle ); - DEV_CHECK_GL_ERROR( "Failed to set GL program" ); - } + CurrentObjectID = NewObjectID; + return true; } + return false; +} - void GLContextState::SetPipeline( const GLPipelineObj &GLPipeline ) +void GLContextState::SetProgram(const GLProgramObj& GLProgram) +{ + GLuint GLProgHandle = 0; + if (UpdateBoundObject(m_GLProgId, GLProgram, GLProgHandle)) { - GLuint GLPipelineHandle = 0; - if( UpdateBoundObject( m_GLPipelineId, GLPipeline, GLPipelineHandle ) ) - { - glBindProgramPipeline( GLPipelineHandle ); - DEV_CHECK_GL_ERROR( "Failed to bind program pipeline" ); - } + glUseProgram(GLProgHandle); + DEV_CHECK_GL_ERROR("Failed to set GL program"); } +} - void GLContextState::BindVAO( const GLVertexArrayObj &VAO ) +void GLContextState::SetPipeline(const GLPipelineObj& GLPipeline) +{ + GLuint GLPipelineHandle = 0; + if (UpdateBoundObject(m_GLPipelineId, GLPipeline, GLPipelineHandle)) { - GLuint VAOHandle = 0; - if( UpdateBoundObject( m_VAOId, VAO, VAOHandle ) ) - { - glBindVertexArray( VAOHandle ); - DEV_CHECK_GL_ERROR( "Failed to set VAO" ); - } + glBindProgramPipeline(GLPipelineHandle); + DEV_CHECK_GL_ERROR("Failed to bind program pipeline"); } +} - void GLContextState::BindFBO( const GLFrameBufferObj &FBO ) +void GLContextState::BindVAO(const GLVertexArrayObj& VAO) +{ + GLuint VAOHandle = 0; + if (UpdateBoundObject(m_VAOId, VAO, VAOHandle)) { - GLuint FBOHandle = 0; - if( UpdateBoundObject( m_FBOId, FBO, FBOHandle ) ) - { - // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT - // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. - // Binding a new framebuffer will NOT affect the mask. - - // NOTE: if attachment image is a NON-immutable format texture and the selected - // level is NOT level_base, the texture MUST BE MIPMAP COMPLETE - // If image is part of a cubemap texture, the texture must also be mipmap cube complete. - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, FBOHandle ); - DEV_CHECK_GL_ERROR( "Failed to bind FBO as draw framebuffer" ); - glBindFramebuffer( GL_READ_FRAMEBUFFER, FBOHandle ); - DEV_CHECK_GL_ERROR( "Failed to bind FBO as read framebuffer" ); - } + glBindVertexArray(VAOHandle); + DEV_CHECK_GL_ERROR("Failed to set VAO"); } +} - template<class ObjectType> - bool UpdateBoundObjectsArr( std::vector< UniqueIdentifier >& BoundObjectIDs, Uint32 Index, const ObjectType &NewObject, GLuint &NewGLHandle ) +void GLContextState::BindFBO(const GLFrameBufferObj& FBO) +{ + GLuint FBOHandle = 0; + if (UpdateBoundObject(m_FBOId, FBO, FBOHandle)) { - if( Index >= BoundObjectIDs.size() ) - BoundObjectIDs.resize( Index + 1, -1 ); + // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT + // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. + // Binding a new framebuffer will NOT affect the mask. - return UpdateBoundObject( BoundObjectIDs[Index], NewObject, NewGLHandle ); + // NOTE: if attachment image is a NON-immutable format texture and the selected + // level is NOT level_base, the texture MUST BE MIPMAP COMPLETE + // If image is part of a cubemap texture, the texture must also be mipmap cube complete. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBOHandle); + DEV_CHECK_GL_ERROR("Failed to bind FBO as draw framebuffer"); + glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOHandle); + DEV_CHECK_GL_ERROR("Failed to bind FBO as read framebuffer"); } +} - void GLContextState::SetActiveTexture( Int32 Index ) +template <class ObjectType> +bool UpdateBoundObjectsArr(std::vector<UniqueIdentifier>& BoundObjectIDs, Uint32 Index, const ObjectType& NewObject, GLuint& NewGLHandle) +{ + if (Index >= BoundObjectIDs.size()) + BoundObjectIDs.resize(Index + 1, -1); + + return UpdateBoundObject(BoundObjectIDs[Index], NewObject, NewGLHandle); +} + +void GLContextState::SetActiveTexture(Int32 Index) +{ + if (Index < 0) { - if( Index < 0 ) - { - Index += m_Caps.m_iMaxCombinedTexUnits; - } - VERIFY( 0 <= Index && Index < m_Caps.m_iMaxCombinedTexUnits, "Texture unit is out of range" ); + Index += m_Caps.m_iMaxCombinedTexUnits; + } + VERIFY(0 <= Index && Index < m_Caps.m_iMaxCombinedTexUnits, "Texture unit is out of range"); - if( m_iActiveTexture != Index ) - { - glActiveTexture( GL_TEXTURE0 + Index ); - DEV_CHECK_GL_ERROR( "Failed to activate texture slot ", Index ); - m_iActiveTexture = Index; - } + if (m_iActiveTexture != Index) + { + glActiveTexture(GL_TEXTURE0 + Index); + DEV_CHECK_GL_ERROR("Failed to activate texture slot ", Index); + m_iActiveTexture = Index; } +} - void GLContextState::BindTexture( Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj &Tex) +void GLContextState::BindTexture(Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj& Tex) +{ + if (Index < 0) { - if( Index < 0 ) - { - Index += m_Caps.m_iMaxCombinedTexUnits; - } - VERIFY( 0 <= Index && Index < m_Caps.m_iMaxCombinedTexUnits, "Texture unit is out of range" ); + Index += m_Caps.m_iMaxCombinedTexUnits; + } + VERIFY(0 <= Index && Index < m_Caps.m_iMaxCombinedTexUnits, "Texture unit is out of range"); - // Always update active texture unit - SetActiveTexture( Index ); + // Always update active texture unit + SetActiveTexture(Index); - GLuint GLTexHandle = 0; - if( UpdateBoundObjectsArr( m_BoundTextures, Index, Tex, GLTexHandle ) ) - { - glBindTexture( BindTarget, GLTexHandle ); - DEV_CHECK_GL_ERROR( "Failed to bind texture to slot ", Index ); - } + GLuint GLTexHandle = 0; + if (UpdateBoundObjectsArr(m_BoundTextures, Index, Tex, GLTexHandle)) + { + glBindTexture(BindTarget, GLTexHandle); + DEV_CHECK_GL_ERROR("Failed to bind texture to slot ", Index); } +} - void GLContextState::BindSampler( Uint32 Index, const GLObjectWrappers::GLSamplerObj &GLSampler) +void GLContextState::BindSampler(Uint32 Index, const GLObjectWrappers::GLSamplerObj& GLSampler) +{ + GLuint GLSamplerHandle = 0; + if (UpdateBoundObjectsArr(m_BoundSamplers, Index, GLSampler, GLSamplerHandle)) { - GLuint GLSamplerHandle = 0; - if( UpdateBoundObjectsArr( m_BoundSamplers, Index, GLSampler, GLSamplerHandle ) ) - { - glBindSampler( Index, GLSamplerHandle ); - DEV_CHECK_GL_ERROR( "Failed to bind sampler to slot ", Index ); - } + glBindSampler(Index, GLSamplerHandle); + DEV_CHECK_GL_ERROR("Failed to bind sampler to slot ", Index); } +} - void GLContextState::BindImage( Uint32 Index, - TextureViewGLImpl *pTexView, - GLint MipLevel, - GLboolean IsLayered, - GLint Layer, - GLenum Access, - GLenum Format ) - { +void GLContextState::BindImage(Uint32 Index, + TextureViewGLImpl* pTexView, + GLint MipLevel, + GLboolean IsLayered, + GLint Layer, + GLenum Access, + GLenum Format) +{ #if GL_ARB_shader_image_load_store - BoundImageInfo NewImageInfo( + BoundImageInfo NewImageInfo // + { pTexView->GetUniqueID(), MipLevel, IsLayered, Layer, Access, - Format - ); - if( Index >= m_BoundImages.size() ) - m_BoundImages.resize( Index + 1 ); - if( !(m_BoundImages[Index] == NewImageInfo) ) - { - m_BoundImages[Index] = NewImageInfo; - GLint GLTexHandle = pTexView->GetHandle(); - glBindImageTexture( Index, GLTexHandle, MipLevel, IsLayered, Layer, Access, Format ); - DEV_CHECK_GL_ERROR( "glBindImageTexture() failed" ); - } + Format // + }; + if (Index >= m_BoundImages.size()) + m_BoundImages.resize(Index + 1); + if (!(m_BoundImages[Index] == NewImageInfo)) + { + m_BoundImages[Index] = NewImageInfo; + GLint GLTexHandle = pTexView->GetHandle(); + glBindImageTexture(Index, GLTexHandle, MipLevel, IsLayered, Layer, Access, Format); + DEV_CHECK_GL_ERROR("glBindImageTexture() failed"); + } #else - UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); + UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); #endif - } +} - void GLContextState::BindImage( Uint32 Index, BufferViewGLImpl* pBuffView, GLenum Access, GLenum Format ) - { +void GLContextState::BindImage(Uint32 Index, BufferViewGLImpl* pBuffView, GLenum Access, GLenum Format) +{ #if GL_ARB_shader_image_load_store - BoundImageInfo NewImageInfo( + BoundImageInfo NewImageInfo // + { pBuffView->GetUniqueID(), 0, GL_FALSE, 0, Access, - Format - ); - if( Index >= m_BoundImages.size() ) - m_BoundImages.resize( Index + 1 ); - if( !(m_BoundImages[Index] == NewImageInfo) ) - { - m_BoundImages[Index] = NewImageInfo; - GLint GLBuffHandle = pBuffView->GetTexBufferHandle(); - glBindImageTexture( Index, GLBuffHandle, 0, GL_FALSE, 0, Access, Format ); - DEV_CHECK_GL_ERROR( "glBindImageTexture() failed" ); - } + Format // + }; + if (Index >= m_BoundImages.size()) + m_BoundImages.resize(Index + 1); + if (!(m_BoundImages[Index] == NewImageInfo)) + { + m_BoundImages[Index] = NewImageInfo; + GLint GLBuffHandle = pBuffView->GetTexBufferHandle(); + glBindImageTexture(Index, GLBuffHandle, 0, GL_FALSE, 0, Access, Format); + DEV_CHECK_GL_ERROR("glBindImageTexture() failed"); + } #else - UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); + UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); #endif - } +} - void GLContextState::BindUniformBuffer( Int32 Index, const GLObjectWrappers::GLBufferObj &Buff) - { - VERIFY( 0 <= Index && Index < m_Caps.m_iMaxUniformBufferBindings, "Uniform buffer index is out of range" ); +void GLContextState::BindUniformBuffer(Int32 Index, const GLObjectWrappers::GLBufferObj& Buff) +{ + VERIFY(0 <= Index && Index < m_Caps.m_iMaxUniformBufferBindings, "Uniform buffer index is out of range"); - GLuint GLBufferHandle = Buff; - if( UpdateBoundObjectsArr( m_BoundUniformBuffers, Index, Buff, GLBufferHandle ) ) - { - // In addition to binding buffer to the indexed buffer binding target, glBindBufferBase also binds - // buffer to the generic buffer binding point specified by target. - glBindBufferBase(GL_UNIFORM_BUFFER, Index, GLBufferHandle); - DEV_CHECK_GL_ERROR("Failed to bind uniform buffer to slot ", Index); - } + GLuint GLBufferHandle = Buff; + if (UpdateBoundObjectsArr(m_BoundUniformBuffers, Index, Buff, GLBufferHandle)) + { + // In addition to binding buffer to the indexed buffer binding target, glBindBufferBase also binds + // buffer to the generic buffer binding point specified by target. + glBindBufferBase(GL_UNIFORM_BUFFER, Index, GLBufferHandle); + DEV_CHECK_GL_ERROR("Failed to bind uniform buffer to slot ", Index); } +} - void GLContextState::BindStorageBlock( Int32 Index, const GLObjectWrappers::GLBufferObj& Buff, GLintptr Offset, GLsizeiptr Size) - { +void GLContextState::BindStorageBlock(Int32 Index, const GLObjectWrappers::GLBufferObj& Buff, GLintptr Offset, GLsizeiptr Size) +{ #if GL_ARB_shader_storage_buffer_object - BoundSSBOInfo NewSSBOInfo {Buff.GetUniqueID(), Offset, Size}; - if (Index >= m_BoundStorageBlocks.size()) - m_BoundStorageBlocks.resize(Index + 1); + BoundSSBOInfo NewSSBOInfo{Buff.GetUniqueID(), Offset, Size}; + if (Index >= m_BoundStorageBlocks.size()) + m_BoundStorageBlocks.resize(Index + 1); - if( !(m_BoundStorageBlocks[Index] == NewSSBOInfo) ) - { - m_BoundStorageBlocks[Index] = NewSSBOInfo; - GLuint GLBufferHandle = Buff; - // In addition to binding buffer to the indexed buffer binding target, glBindBufferRange also binds - // buffer to the generic buffer binding point specified by target. - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, Index, GLBufferHandle, Offset, Size); - DEV_CHECK_GL_ERROR("Failed to bind shader storage block to slot ", Index); - } + if (!(m_BoundStorageBlocks[Index] == NewSSBOInfo)) + { + m_BoundStorageBlocks[Index] = NewSSBOInfo; + GLuint GLBufferHandle = Buff; + // In addition to binding buffer to the indexed buffer binding target, glBindBufferRange also binds + // buffer to the generic buffer binding point specified by target. + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, Index, GLBufferHandle, Offset, Size); + DEV_CHECK_GL_ERROR("Failed to bind shader storage block to slot ", Index); + } #else - UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); + UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); #endif - } +} - void GLContextState::BindBuffer(GLenum BindTarget, const GLObjectWrappers::GLBufferObj& Buff, bool ResetVAO) +void GLContextState::BindBuffer(GLenum BindTarget, const GLObjectWrappers::GLBufferObj& Buff, bool ResetVAO) +{ + // Binding ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER affects currently bound VAO + if (ResetVAO && (BindTarget == GL_ARRAY_BUFFER || BindTarget == GL_ELEMENT_ARRAY_BUFFER)) { - // Binding ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER affects currently bound VAO - if (ResetVAO && (BindTarget == GL_ARRAY_BUFFER || BindTarget == GL_ELEMENT_ARRAY_BUFFER)) - { - BindVAO(GLVertexArrayObj::Null()); - } + BindVAO(GLVertexArrayObj::Null()); + } - // Note that glBindBufferBase, glBindBufferRange etc. also bind the - // buffer to the generic buffer binding point specified by target. + // Note that glBindBufferBase, glBindBufferRange etc. also bind the + // buffer to the generic buffer binding point specified by target. - // GL_UNIFORM_BUFFER, GL_ATOMIC_COUNTER_BUFFER and GL_SHADER_STORAGE_BUFFER buffer binding points do not directly affect - // uniform buffer, atomic counter buffer or shader storage buffer state, respectively. glBindBufferBase or glBindBufferRange - // must be used to bind a buffer to an indexed uniform buffer, atomic counter buffer or shader storage buffer binding point. - glBindBuffer(BindTarget, Buff); - DEV_CHECK_GL_ERROR("Failed to bind buffer ", static_cast<GLint>(Buff), " to target ", BindTarget); - } + // GL_UNIFORM_BUFFER, GL_ATOMIC_COUNTER_BUFFER and GL_SHADER_STORAGE_BUFFER buffer binding points do not directly affect + // uniform buffer, atomic counter buffer or shader storage buffer state, respectively. glBindBufferBase or glBindBufferRange + // must be used to bind a buffer to an indexed uniform buffer, atomic counter buffer or shader storage buffer binding point. + glBindBuffer(BindTarget, Buff); + DEV_CHECK_GL_ERROR("Failed to bind buffer ", static_cast<GLint>(Buff), " to target ", BindTarget); +} - void GLContextState::EnsureMemoryBarrier( Uint32 RequiredBarriers, AsyncWritableResource *pRes/* = nullptr */ ) - { +void GLContextState::EnsureMemoryBarrier(Uint32 RequiredBarriers, AsyncWritableResource* pRes /* = nullptr */) +{ #if GL_ARB_shader_image_load_store - // Every resource tracks its own pending memory barriers. - // Device context also tracks which barriers have not been executed - // When a resource with pending memory barrier flag is bound to the context, - // the context checks if the same flag is set in its own pending barriers. - // Thus a memory barrier is only executed if some resource required that barrier - // and it has not been executed yet. This is almost optimal strategy, but slightly - // imperfect as the following scenario shows: - - // Draw 1: Barriers_A |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG - // Draw 2: Barriers_B |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG - // Draw 3: Bind B, execute BARRIER: Barriers_B = 0, Barrier_Ctx = 0 (Barriers_A == BARRIER_FLAG) - // Draw 4: Barriers_B |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG - // Draw 5: Bind A, execute BARRIER, Barriers_A = 0, Barrier_Ctx = 0 (Barriers_B == BARRIER_FLAG) - - // In the last draw call, barrier for resource A has already been executed when resource B was - // bound to the pipeline. Since Resource A has not been bound since then, its flag has not been - // cleared. - // This situation does not seem to be a problem though since a barier cannot be executed - // twice in any situation - - Uint32 ResourcePendingBarriers = 0; - if( pRes ) + // Every resource tracks its own pending memory barriers. + // Device context also tracks which barriers have not been executed + // When a resource with pending memory barrier flag is bound to the context, + // the context checks if the same flag is set in its own pending barriers. + // Thus a memory barrier is only executed if some resource required that barrier + // and it has not been executed yet. This is almost optimal strategy, but slightly + // imperfect as the following scenario shows: + + // Draw 1: Barriers_A |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG + // Draw 2: Barriers_B |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG + // Draw 3: Bind B, execute BARRIER: Barriers_B = 0, Barrier_Ctx = 0 (Barriers_A == BARRIER_FLAG) + // Draw 4: Barriers_B |= BARRIER_FLAG, Barrier_Ctx |= BARRIER_FLAG + // Draw 5: Bind A, execute BARRIER, Barriers_A = 0, Barrier_Ctx = 0 (Barriers_B == BARRIER_FLAG) + + // In the last draw call, barrier for resource A has already been executed when resource B was + // bound to the pipeline. Since Resource A has not been bound since then, its flag has not been + // cleared. + // This situation does not seem to be a problem though since a barier cannot be executed + // twice in any situation + + Uint32 ResourcePendingBarriers = 0; + if (pRes) + { + // If resource is specified, only set up memory barriers + // that are required by the resource + ResourcePendingBarriers = pRes->GetPendingMemortBarriers(); + RequiredBarriers &= ResourcePendingBarriers; + } + + // Leave only pending barriers + RequiredBarriers &= m_PendingMemoryBarriers; + if (RequiredBarriers) + { + glMemoryBarrier(RequiredBarriers); + DEV_CHECK_GL_ERROR("glMemoryBarrier() failed"); + m_PendingMemoryBarriers &= ~RequiredBarriers; + } + + // Leave only these barriers that are still pending + if (pRes) + pRes->ResetPendingMemoryBarriers(m_PendingMemoryBarriers & ResourcePendingBarriers); +#else + UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); +#endif +} + +void GLContextState::SetPendingMemoryBarriers(Uint32 PendingBarriers) +{ + m_PendingMemoryBarriers |= PendingBarriers; +} + +void GLContextState::EnableDepthTest(bool bEnable) +{ + if (m_DSState.m_DepthEnableState != bEnable) + { + if (bEnable) { - // If resource is specified, only set up memory barriers - // that are required by the resource - ResourcePendingBarriers = pRes->GetPendingMemortBarriers(); - RequiredBarriers &= ResourcePendingBarriers; + glEnable(GL_DEPTH_TEST); + DEV_CHECK_GL_ERROR("Failed to enable detph test"); } - - // Leave only pending barriers - RequiredBarriers &= m_PendingMemoryBarriers; - if( RequiredBarriers ) + else { - glMemoryBarrier( RequiredBarriers ); - DEV_CHECK_GL_ERROR( "glMemoryBarrier() failed" ); - m_PendingMemoryBarriers &= ~RequiredBarriers; + glDisable(GL_DEPTH_TEST); + DEV_CHECK_GL_ERROR("Failed to disable detph test"); } + m_DSState.m_DepthEnableState = bEnable; + } +} - // Leave only these barriers that are still pending - if( pRes ) - pRes->ResetPendingMemoryBarriers( m_PendingMemoryBarriers & ResourcePendingBarriers ); -#else - UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); -#endif +void GLContextState::EnableDepthWrites(bool bEnable) +{ + if (m_DSState.m_DepthWritesEnableState != bEnable) + { + // If mask is non-zero, the depth buffer is enabled for writing; otherwise, it is disabled. + glDepthMask(bEnable ? 1 : 0); + DEV_CHECK_GL_ERROR("Failed to enale/disable depth writes"); + m_DSState.m_DepthWritesEnableState = bEnable; } +} - void GLContextState::SetPendingMemoryBarriers( Uint32 PendingBarriers ) +void GLContextState::SetDepthFunc(COMPARISON_FUNCTION CmpFunc) +{ + if (m_DSState.m_DepthCmpFunc != CmpFunc) { - m_PendingMemoryBarriers |= PendingBarriers; + auto GlCmpFunc = CompareFuncToGLCompareFunc(CmpFunc); + glDepthFunc(GlCmpFunc); + DEV_CHECK_GL_ERROR("Failed to set GL comparison function"); + m_DSState.m_DepthCmpFunc = CmpFunc; } +} - void GLContextState::EnableDepthTest( bool bEnable ) +void GLContextState::EnableStencilTest(bool bEnable) +{ + if (m_DSState.m_StencilTestEnableState != bEnable) { - if( m_DSState.m_DepthEnableState != bEnable ) + if (bEnable) { - if( bEnable ) - { - glEnable( GL_DEPTH_TEST ); - DEV_CHECK_GL_ERROR( "Failed to enable detph test" ); - } - else - { - glDisable( GL_DEPTH_TEST ); - DEV_CHECK_GL_ERROR( "Failed to disable detph test" ); - } - m_DSState.m_DepthEnableState = bEnable; + glEnable(GL_STENCIL_TEST); + DEV_CHECK_GL_ERROR("Failed to enable stencil test"); + } + else + { + glDisable(GL_STENCIL_TEST); + DEV_CHECK_GL_ERROR("Failed to disable stencil test"); } + m_DSState.m_StencilTestEnableState = bEnable; } +} - void GLContextState::EnableDepthWrites( bool bEnable ) +void GLContextState::SetStencilWriteMask(Uint8 StencilWriteMask) +{ + if (m_DSState.m_StencilWriteMask != StencilWriteMask) { - if( m_DSState.m_DepthWritesEnableState != bEnable ) - { - // If mask is non-zero, the depth buffer is enabled for writing; otherwise, it is disabled. - glDepthMask( bEnable ? 1 : 0 ); - DEV_CHECK_GL_ERROR( "Failed to enale/disable depth writes" ); - m_DSState.m_DepthWritesEnableState = bEnable; - } + glStencilMask(StencilWriteMask); + m_DSState.m_StencilWriteMask = StencilWriteMask; } +} - void GLContextState::SetDepthFunc( COMPARISON_FUNCTION CmpFunc ) +void GLContextState::SetStencilRef(GLenum Face, Int32 Ref) +{ + auto& FaceStencilOp = m_DSState.m_StencilOpState[Face == GL_FRONT ? 0 : 1]; + auto GlStencilFunc = CompareFuncToGLCompareFunc(FaceStencilOp.Func); + glStencilFuncSeparate(Face, GlStencilFunc, Ref, FaceStencilOp.Mask); + DEV_CHECK_GL_ERROR("Failed to set stencil function"); +} + +void GLContextState::SetStencilFunc(GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask) +{ + auto& FaceStencilOp = m_DSState.m_StencilOpState[Face == GL_FRONT ? 0 : 1]; + if (FaceStencilOp.Func != Func || + FaceStencilOp.Ref != Ref || + FaceStencilOp.Mask != Mask) { - if( m_DSState.m_DepthCmpFunc != CmpFunc ) - { - auto GlCmpFunc = CompareFuncToGLCompareFunc( CmpFunc ); - glDepthFunc( GlCmpFunc ); - DEV_CHECK_GL_ERROR( "Failed to set GL comparison function" ); - m_DSState.m_DepthCmpFunc = CmpFunc; - } + FaceStencilOp.Func = Func; + FaceStencilOp.Ref = Ref; + FaceStencilOp.Mask = Mask; + + SetStencilRef(Face, Ref); } +} - void GLContextState::EnableStencilTest( bool bEnable ) +void GLContextState::SetStencilOp(GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp) +{ + auto& FaceStencilOp = m_DSState.m_StencilOpState[Face == GL_FRONT ? 0 : 1]; + if (FaceStencilOp.StencilFailOp != StencilFailOp || + FaceStencilOp.StencilDepthFailOp != StencilDepthFailOp || + FaceStencilOp.StencilPassOp != StencilPassOp) { - if( m_DSState.m_StencilTestEnableState != bEnable ) + auto glsfail = StencilOp2GlStencilOp(StencilFailOp); + auto dpfail = StencilOp2GlStencilOp(StencilDepthFailOp); + auto dppass = StencilOp2GlStencilOp(StencilPassOp); + + glStencilOpSeparate(Face, glsfail, dpfail, dppass); + DEV_CHECK_GL_ERROR("Failed to set stencil operation"); + + FaceStencilOp.StencilFailOp = StencilFailOp; + FaceStencilOp.StencilDepthFailOp = StencilDepthFailOp; + FaceStencilOp.StencilPassOp = StencilPassOp; + } +} + +void GLContextState::SetFillMode(FILL_MODE FillMode) +{ + if (m_Caps.bFillModeSelectionSupported) + { + if (m_RSState.FillMode != FillMode) { - if( bEnable ) + if (glPolygonMode != nullptr) { - glEnable( GL_STENCIL_TEST ); - DEV_CHECK_GL_ERROR( "Failed to enable stencil test" ); + auto PolygonMode = FillMode == FILL_MODE_WIREFRAME ? GL_LINE : GL_FILL; + glPolygonMode(GL_FRONT_AND_BACK, PolygonMode); + DEV_CHECK_GL_ERROR("Failed to set polygon mode"); } else { - glDisable( GL_STENCIL_TEST ); - DEV_CHECK_GL_ERROR( "Failed to disable stencil test" ); + if (FillMode != FILL_MODE_SOLID) + LOG_ERROR("This API/device only supports solid fill mode"); } - m_DSState.m_StencilTestEnableState = bEnable; + + m_RSState.FillMode = FillMode; } } + else + { + if (FillMode == FILL_MODE_WIREFRAME) + LOG_WARNING_MESSAGE("Wireframe fill mode is not supported on this device\n"); + } +} - void GLContextState::SetStencilWriteMask( Uint8 StencilWriteMask ) +void GLContextState::SetCullMode(CULL_MODE CullMode) +{ + if (m_RSState.CullMode != CullMode) { - if( m_DSState.m_StencilWriteMask != StencilWriteMask ) + if (CullMode == CULL_MODE_NONE) { - glStencilMask( StencilWriteMask ); - m_DSState.m_StencilWriteMask = StencilWriteMask; + glDisable(GL_CULL_FACE); + DEV_CHECK_GL_ERROR("Failed to disable face culling"); } + else + { + VERIFY(CullMode == CULL_MODE_FRONT || CullMode == CULL_MODE_BACK, "Unexpected cull mode"); + glEnable(GL_CULL_FACE); + DEV_CHECK_GL_ERROR("Failed to enable face culling"); + auto CullFace = CullMode == CULL_MODE_BACK ? GL_BACK : GL_FRONT; + glCullFace(CullFace); + DEV_CHECK_GL_ERROR("Failed to set cull face"); + } + + m_RSState.CullMode = CullMode; } +} - void GLContextState::SetStencilRef(GLenum Face, Int32 Ref) +void GLContextState::SetFrontFace(bool FrontCounterClockwise) +{ + if (m_RSState.FrontCounterClockwise != FrontCounterClockwise) { - auto& FaceStencilOp = m_DSState.m_StencilOpState[Face == GL_FRONT ? 0 : 1]; - auto GlStencilFunc = CompareFuncToGLCompareFunc( FaceStencilOp.Func ); - glStencilFuncSeparate( Face, GlStencilFunc, Ref, FaceStencilOp.Mask ); - DEV_CHECK_GL_ERROR( "Failed to set stencil function" ); + auto FrontFace = FrontCounterClockwise ? GL_CCW : GL_CW; + glFrontFace(FrontFace); + DEV_CHECK_GL_ERROR("Failed to set front face"); + m_RSState.FrontCounterClockwise = FrontCounterClockwise; } +} - void GLContextState::SetStencilFunc( GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask ) +void GLContextState::SetDepthBias(float fDepthBias, float fSlopeScaledDepthBias) +{ + if (m_RSState.fDepthBias != fDepthBias || + m_RSState.fSlopeScaledDepthBias != fSlopeScaledDepthBias) { - auto& FaceStencilOp = m_DSState.m_StencilOpState[Face == GL_FRONT ? 0 : 1]; - if( FaceStencilOp.Func != Func || - FaceStencilOp.Ref != Ref || - FaceStencilOp.Mask != Mask ) + if (fDepthBias != 0 || fSlopeScaledDepthBias != 0) { - FaceStencilOp.Func = Func; - FaceStencilOp.Ref = Ref; - FaceStencilOp.Mask = Mask; - - SetStencilRef(Face, Ref); + glEnable(GL_POLYGON_OFFSET_FILL); + DEV_CHECK_GL_ERROR("Failed to enable polygon offset fill"); } - } - - void GLContextState::SetStencilOp( GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp ) - { - auto& FaceStencilOp = m_DSState.m_StencilOpState[Face == GL_FRONT ? 0 : 1]; - if( FaceStencilOp.StencilFailOp != StencilFailOp || - FaceStencilOp.StencilDepthFailOp != StencilDepthFailOp || - FaceStencilOp.StencilPassOp != StencilPassOp ) + else { - auto glsfail = StencilOp2GlStencilOp( StencilFailOp ); - auto dpfail = StencilOp2GlStencilOp( StencilDepthFailOp ); - auto dppass = StencilOp2GlStencilOp( StencilPassOp ); + glDisable(GL_POLYGON_OFFSET_FILL); + DEV_CHECK_GL_ERROR("Failed to disable polygon offset fill"); + } - glStencilOpSeparate( Face, glsfail, dpfail, dppass ); - DEV_CHECK_GL_ERROR( "Failed to set stencil operation" ); + glPolygonOffset(fSlopeScaledDepthBias, fDepthBias); + DEV_CHECK_GL_ERROR("Failed to set polygon offset"); - FaceStencilOp.StencilFailOp = StencilFailOp; - FaceStencilOp.StencilDepthFailOp = StencilDepthFailOp; - FaceStencilOp.StencilPassOp = StencilPassOp; - } + m_RSState.fDepthBias = fDepthBias; + m_RSState.fSlopeScaledDepthBias = fSlopeScaledDepthBias; } +} - void GLContextState::SetFillMode( FILL_MODE FillMode ) +void GLContextState::SetDepthClamp(bool bEnableDepthClamp) +{ + if (m_RSState.DepthClampEnable != bEnableDepthClamp) { - if( m_Caps.bFillModeSelectionSupported ) + if (bEnableDepthClamp) { - if( m_RSState.FillMode != FillMode ) + // Note that enabling depth clamping in GL is the same as + // disabling clipping in Direct3D. + // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc + // https://www.khronos.org/opengl/wiki/GLAPI/glEnable +#pragma warning(push) +#pragma warning(disable : 4127) + if (GL_DEPTH_CLAMP) { - if(glPolygonMode != nullptr) - { - auto PolygonMode = FillMode == FILL_MODE_WIREFRAME ? GL_LINE : GL_FILL; - glPolygonMode( GL_FRONT_AND_BACK, PolygonMode ); - DEV_CHECK_GL_ERROR( "Failed to set polygon mode" ); - } - else - { - if(FillMode != FILL_MODE_SOLID) - LOG_ERROR("This API/device only supports solid fill mode"); - } - - m_RSState.FillMode = FillMode; + glEnable(GL_DEPTH_CLAMP); + DEV_CHECK_GL_ERROR("Failed to enable depth clamp"); } } else { - if( FillMode == FILL_MODE_WIREFRAME ) - LOG_WARNING_MESSAGE( "Wireframe fill mode is not supported on this device\n" ); - } - } - - void GLContextState::SetCullMode( CULL_MODE CullMode ) - { - if( m_RSState.CullMode != CullMode ) - { - if( CullMode == CULL_MODE_NONE ) + if (GL_DEPTH_CLAMP) { - glDisable( GL_CULL_FACE ); - DEV_CHECK_GL_ERROR( "Failed to disable face culling" ); + glDisable(GL_DEPTH_CLAMP); + DEV_CHECK_GL_ERROR("Failed to disable depth clamp"); } else { - VERIFY( CullMode == CULL_MODE_FRONT || CullMode == CULL_MODE_BACK, "Unexpected cull mode" ); - glEnable( GL_CULL_FACE ); - DEV_CHECK_GL_ERROR( "Failed to enable face culling" ); - auto CullFace = CullMode == CULL_MODE_BACK ? GL_BACK : GL_FRONT; - glCullFace( CullFace ); - DEV_CHECK_GL_ERROR( "Failed to set cull face" ); + LOG_WARNING_MESSAGE("Disabling depth clamp is not supported"); } - - m_RSState.CullMode = CullMode; +#pragma warning(pop) } + m_RSState.DepthClampEnable = bEnableDepthClamp; } +} - void GLContextState::SetFrontFace( bool FrontCounterClockwise ) +void GLContextState::EnableScissorTest(bool bEnableScissorTest) +{ + if (m_RSState.ScissorTestEnable != bEnableScissorTest) { - if( m_RSState.FrontCounterClockwise != FrontCounterClockwise ) + if (bEnableScissorTest) { - auto FrontFace = FrontCounterClockwise ? GL_CCW : GL_CW; - glFrontFace( FrontFace ); - DEV_CHECK_GL_ERROR( "Failed to set front face" ); - m_RSState.FrontCounterClockwise = FrontCounterClockwise; + glEnable(GL_SCISSOR_TEST); + DEV_CHECK_GL_ERROR("Failed to enable scissor test"); } - } - - void GLContextState::SetDepthBias( float fDepthBias, float fSlopeScaledDepthBias ) - { - if( m_RSState.fDepthBias != fDepthBias || - m_RSState.fSlopeScaledDepthBias != fSlopeScaledDepthBias ) + else { - if( fDepthBias != 0 || fSlopeScaledDepthBias != 0 ) - { - glEnable( GL_POLYGON_OFFSET_FILL ); - DEV_CHECK_GL_ERROR( "Failed to enable polygon offset fill" ); - } - else - { - glDisable( GL_POLYGON_OFFSET_FILL ); - DEV_CHECK_GL_ERROR( "Failed to disable polygon offset fill" ); - } - - glPolygonOffset( fSlopeScaledDepthBias, fDepthBias ); - DEV_CHECK_GL_ERROR( "Failed to set polygon offset" ); - - m_RSState.fDepthBias = fDepthBias; - m_RSState.fSlopeScaledDepthBias = fSlopeScaledDepthBias; + glDisable(GL_SCISSOR_TEST); + DEV_CHECK_GL_ERROR("Failed to disable scissor clamp"); } - } - void GLContextState::SetDepthClamp( bool bEnableDepthClamp ) - { - if( m_RSState.DepthClampEnable != bEnableDepthClamp ) - { - if( bEnableDepthClamp ) - { - // Note that enabling depth clamping in GL is the same as - // disabling clipping in Direct3D. - // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_rasterizer_desc - // https://www.khronos.org/opengl/wiki/GLAPI/glEnable -#pragma warning(push) -#pragma warning(disable : 4127) - if( GL_DEPTH_CLAMP ) - { - glEnable( GL_DEPTH_CLAMP ); - DEV_CHECK_GL_ERROR( "Failed to enable depth clamp" ); - } - } - else - { - if( GL_DEPTH_CLAMP ) - { - glDisable( GL_DEPTH_CLAMP ); - DEV_CHECK_GL_ERROR( "Failed to disable depth clamp" ); - } - else - { - LOG_WARNING_MESSAGE("Disabling depth clamp is not supported"); - } -#pragma warning(pop) - } - m_RSState.DepthClampEnable = bEnableDepthClamp; - } + m_RSState.ScissorTestEnable = bEnableScissorTest; } +} - void GLContextState::EnableScissorTest( bool bEnableScissorTest ) +void GLContextState::SetBlendFactors(const float* BlendFactors) +{ + glBlendColor(BlendFactors[0], BlendFactors[1], BlendFactors[2], BlendFactors[3]); + DEV_CHECK_GL_ERROR("Failed to set blend color"); +} + +void GLContextState::SetBlendState(const BlendStateDesc& BSDsc, Uint32 SampleMask) +{ + VERIFY(SampleMask == 0xFFFFFFFF, "Sample mask is not currently implemented in GL"); + + bool bEnableBlend = false; + if (BSDsc.IndependentBlendEnable) { - if( m_RSState.ScissorTestEnable != bEnableScissorTest ) + for (int i = 0; i < BSDsc.MaxRenderTargets; ++i) { - if( bEnableScissorTest ) + const auto& RT = BSDsc.RenderTargets[i]; + if (RT.BlendEnable) + bEnableBlend = true; + + if (i < m_Caps.m_iMaxDrawBuffers) { - glEnable( GL_SCISSOR_TEST ); - DEV_CHECK_GL_ERROR( "Failed to enable scissor test" ); + SetColorWriteMask(i, RT.RenderTargetWriteMask, True); } else { - glDisable( GL_SCISSOR_TEST ); - DEV_CHECK_GL_ERROR( "Failed to disable scissor clamp" ); + VERIFY(RT.RenderTargetWriteMask == RenderTargetBlendDesc().RenderTargetWriteMask, "Render target write mask is specified for buffer ", i, " but this device only supports ", m_Caps.m_iMaxDrawBuffers, " draw buffers"); } - - m_RSState.ScissorTestEnable = bEnableScissorTest; } } - - void GLContextState::SetBlendFactors(const float *BlendFactors) + else { - glBlendColor( BlendFactors[0], BlendFactors[1], BlendFactors[2], BlendFactors[3] ); - DEV_CHECK_GL_ERROR( "Failed to set blend color" ); + const auto& RT0 = BSDsc.RenderTargets[0]; + bEnableBlend = RT0.BlendEnable; + SetColorWriteMask(0, RT0.RenderTargetWriteMask, False); } - void GLContextState::SetBlendState( const BlendStateDesc &BSDsc, Uint32 SampleMask ) + if (bEnableBlend) { - VERIFY(SampleMask == 0xFFFFFFFF, "Sample mask is not currently implemented in GL"); + // Sets the blend enable flag for ALL color buffers. + glEnable(GL_BLEND); + DEV_CHECK_GL_ERROR("Failed to enable alpha blending"); - bool bEnableBlend = false; - if( BSDsc.IndependentBlendEnable ) + if (BSDsc.AlphaToCoverageEnable) { - for( int i = 0; i < BSDsc.MaxRenderTargets; ++i ) - { - const auto& RT = BSDsc.RenderTargets[i]; - if( RT.BlendEnable ) - bEnableBlend = true; - - if(i < m_Caps.m_iMaxDrawBuffers) - { - SetColorWriteMask(i, RT.RenderTargetWriteMask, True); - } - else - { - VERIFY(RT.RenderTargetWriteMask == RenderTargetBlendDesc().RenderTargetWriteMask, "Render target write mask is specified for buffer ", i, " but this device only supports ", m_Caps.m_iMaxDrawBuffers, " draw buffers"); - } - } + glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + DEV_CHECK_GL_ERROR("Failed to enable alpha to coverage"); } else { - const auto& RT0 = BSDsc.RenderTargets[0]; - bEnableBlend = RT0.BlendEnable; - SetColorWriteMask(0, RT0.RenderTargetWriteMask, False); + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + DEV_CHECK_GL_ERROR("Failed to disable alpha to coverage"); } - if( bEnableBlend ) + if (BSDsc.IndependentBlendEnable) { - // Sets the blend enable flag for ALL color buffers. - glEnable( GL_BLEND ); - DEV_CHECK_GL_ERROR( "Failed to enable alpha blending" ); - - if( BSDsc.AlphaToCoverageEnable ) + for (int i = 0; i < BSDsc.MaxRenderTargets; ++i) { - glEnable( GL_SAMPLE_ALPHA_TO_COVERAGE ); - DEV_CHECK_GL_ERROR( "Failed to enable alpha to coverage" ); - } - else - { - glDisable( GL_SAMPLE_ALPHA_TO_COVERAGE ); - DEV_CHECK_GL_ERROR( "Failed to disable alpha to coverage" ); - } + const auto& RT = BSDsc.RenderTargets[i]; - if( BSDsc.IndependentBlendEnable ) - { - for( int i = 0; i < BSDsc.MaxRenderTargets; ++i ) + if (i >= m_Caps.m_iMaxDrawBuffers) { - const auto& RT = BSDsc.RenderTargets[i]; - - if(i >= m_Caps.m_iMaxDrawBuffers) - { - if( RT.BlendEnable ) - LOG_ERROR_MESSAGE("Blend is enabled for render target ", i, " but this device only supports ", m_Caps.m_iMaxDrawBuffers, " draw buffers"); - continue; - } - - if( RT.BlendEnable ) - { - glEnablei( GL_BLEND, i ); - DEV_CHECK_GL_ERROR( "Failed to enable alpha blending" ); - - auto srcFactorRGB = BlendFactor2GLBlend( RT.SrcBlend ); - auto dstFactorRGB = BlendFactor2GLBlend( RT.DestBlend ); - auto srcFactorAlpha = BlendFactor2GLBlend( RT.SrcBlendAlpha ); - auto dstFactorAlpha = BlendFactor2GLBlend( RT.DestBlendAlpha ); - glBlendFuncSeparatei( i, srcFactorRGB, dstFactorRGB, srcFactorAlpha, dstFactorAlpha ); - DEV_CHECK_GL_ERROR( "Failed to set separate blending factors" ); - auto modeRGB = BlendOperation2GLBlendOp( RT.BlendOp ); - auto modeAlpha = BlendOperation2GLBlendOp( RT.BlendOpAlpha ); - glBlendEquationSeparatei( i, modeRGB, modeAlpha ); - DEV_CHECK_GL_ERROR( "Failed to set separate blending equations" ); - } - else - { - glDisablei( GL_BLEND, i ); - DEV_CHECK_GL_ERROR( "Failed to disable alpha blending" ); - } + if (RT.BlendEnable) + LOG_ERROR_MESSAGE("Blend is enabled for render target ", i, " but this device only supports ", m_Caps.m_iMaxDrawBuffers, " draw buffers"); + continue; + } + + if (RT.BlendEnable) + { + glEnablei(GL_BLEND, i); + DEV_CHECK_GL_ERROR("Failed to enable alpha blending"); + + auto srcFactorRGB = BlendFactor2GLBlend(RT.SrcBlend); + auto dstFactorRGB = BlendFactor2GLBlend(RT.DestBlend); + auto srcFactorAlpha = BlendFactor2GLBlend(RT.SrcBlendAlpha); + auto dstFactorAlpha = BlendFactor2GLBlend(RT.DestBlendAlpha); + glBlendFuncSeparatei(i, srcFactorRGB, dstFactorRGB, srcFactorAlpha, dstFactorAlpha); + DEV_CHECK_GL_ERROR("Failed to set separate blending factors"); + auto modeRGB = BlendOperation2GLBlendOp(RT.BlendOp); + auto modeAlpha = BlendOperation2GLBlendOp(RT.BlendOpAlpha); + glBlendEquationSeparatei(i, modeRGB, modeAlpha); + DEV_CHECK_GL_ERROR("Failed to set separate blending equations"); + } + else + { + glDisablei(GL_BLEND, i); + DEV_CHECK_GL_ERROR("Failed to disable alpha blending"); } - } - else - { - const auto& RT0 = BSDsc.RenderTargets[0]; - auto srcFactorRGB = BlendFactor2GLBlend( RT0.SrcBlend ); - auto dstFactorRGB = BlendFactor2GLBlend( RT0.DestBlend ); - auto srcFactorAlpha = BlendFactor2GLBlend( RT0.SrcBlendAlpha ); - auto dstFactorAlpha = BlendFactor2GLBlend( RT0.DestBlendAlpha ); - glBlendFuncSeparate( srcFactorRGB, dstFactorRGB, srcFactorAlpha, dstFactorAlpha ); - DEV_CHECK_GL_ERROR( "Failed to set blending factors" ); - - auto modeRGB = BlendOperation2GLBlendOp( RT0.BlendOp ); - auto modeAlpha = BlendOperation2GLBlendOp( RT0.BlendOpAlpha ); - glBlendEquationSeparate( modeRGB, modeAlpha ); - DEV_CHECK_GL_ERROR( "Failed to set blending equations" ); } } else { - // Sets the blend disable flag for ALL color buffers. - glDisable( GL_BLEND ); - DEV_CHECK_GL_ERROR( "Failed to disable alpha blending" ); + const auto& RT0 = BSDsc.RenderTargets[0]; + auto srcFactorRGB = BlendFactor2GLBlend(RT0.SrcBlend); + auto dstFactorRGB = BlendFactor2GLBlend(RT0.DestBlend); + auto srcFactorAlpha = BlendFactor2GLBlend(RT0.SrcBlendAlpha); + auto dstFactorAlpha = BlendFactor2GLBlend(RT0.DestBlendAlpha); + glBlendFuncSeparate(srcFactorRGB, dstFactorRGB, srcFactorAlpha, dstFactorAlpha); + DEV_CHECK_GL_ERROR("Failed to set blending factors"); + + auto modeRGB = BlendOperation2GLBlendOp(RT0.BlendOp); + auto modeAlpha = BlendOperation2GLBlendOp(RT0.BlendOpAlpha); + glBlendEquationSeparate(modeRGB, modeAlpha); + DEV_CHECK_GL_ERROR("Failed to set blending equations"); } } + else + { + // Sets the blend disable flag for ALL color buffers. + glDisable(GL_BLEND); + DEV_CHECK_GL_ERROR("Failed to disable alpha blending"); + } +} + +void GLContextState::SetColorWriteMask(Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent) +{ + // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT + // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. + // Binding a new framebuffer will NOT affect the mask. - void GLContextState::SetColorWriteMask( Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent ) + if (!bIsIndependent) + RTIndex = 0; + + if (m_ColorWriteMasks[RTIndex] != WriteMask || + m_bIndependentWriteMasks != bIsIndependent) { - // Even though the write mask only applies to writes to a framebuffer, the mask state is NOT - // Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer. - // Binding a new framebuffer will NOT affect the mask. - - if( !bIsIndependent ) - RTIndex = 0; + if (bIsIndependent) + { + // Note that glColorMaski() does not set color mask for the framebuffer + // attachment point RTIndex. Rather it sets the mask for what was set + // by the glDrawBuffers() function for the i-th output + glColorMaski(RTIndex, + (WriteMask & COLOR_MASK_RED) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_GREEN) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_BLUE) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_ALPHA) ? GL_TRUE : GL_FALSE); + DEV_CHECK_GL_ERROR("Failed to set GL color mask"); - if( m_ColorWriteMasks[RTIndex] != WriteMask || - m_bIndependentWriteMasks != bIsIndependent ) + m_ColorWriteMasks[RTIndex] = WriteMask; + } + else { - if( bIsIndependent ) - { - // Note that glColorMaski() does not set color mask for the framebuffer - // attachment point RTIndex. Rather it sets the mask for what was set - // by the glDrawBuffers() function for the i-th output - glColorMaski( RTIndex, - (WriteMask & COLOR_MASK_RED) ? GL_TRUE : GL_FALSE, - (WriteMask & COLOR_MASK_GREEN) ? GL_TRUE : GL_FALSE, - (WriteMask & COLOR_MASK_BLUE) ? GL_TRUE : GL_FALSE, - (WriteMask & COLOR_MASK_ALPHA) ? GL_TRUE : GL_FALSE ); - DEV_CHECK_GL_ERROR( "Failed to set GL color mask" ); - - m_ColorWriteMasks[RTIndex] = WriteMask; - } - else - { - // glColorMask() sets the mask for ALL draw buffers - glColorMask( (WriteMask & COLOR_MASK_RED) ? GL_TRUE : GL_FALSE, - (WriteMask & COLOR_MASK_GREEN) ? GL_TRUE : GL_FALSE, - (WriteMask & COLOR_MASK_BLUE) ? GL_TRUE : GL_FALSE, - (WriteMask & COLOR_MASK_ALPHA) ? GL_TRUE : GL_FALSE ); - DEV_CHECK_GL_ERROR( "Failed to set GL color mask" ); - - for( int rt = 0; rt < _countof( m_ColorWriteMasks ); ++rt ) - m_ColorWriteMasks[rt] = WriteMask; - } - m_bIndependentWriteMasks = bIsIndependent; + // glColorMask() sets the mask for ALL draw buffers + glColorMask( + (WriteMask & COLOR_MASK_RED) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_GREEN) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_BLUE) ? GL_TRUE : GL_FALSE, + (WriteMask & COLOR_MASK_ALPHA) ? GL_TRUE : GL_FALSE); + DEV_CHECK_GL_ERROR("Failed to set GL color mask"); + + for (int rt = 0; rt < _countof(m_ColorWriteMasks); ++rt) + m_ColorWriteMasks[rt] = WriteMask; } + m_bIndependentWriteMasks = bIsIndependent; } +} - void GLContextState::GetColorWriteMask( Uint32 RTIndex, Uint32 &WriteMask, Bool &bIsIndependent ) - { - if( !m_bIndependentWriteMasks ) - RTIndex = 0; - WriteMask = m_ColorWriteMasks[ RTIndex ]; - bIsIndependent = m_bIndependentWriteMasks; - } +void GLContextState::GetColorWriteMask(Uint32 RTIndex, Uint32& WriteMask, Bool& bIsIndependent) +{ + if (!m_bIndependentWriteMasks) + RTIndex = 0; + WriteMask = m_ColorWriteMasks[RTIndex]; + bIsIndependent = m_bIndependentWriteMasks; +} - void GLContextState::SetNumPatchVertices(Int32 NumVertices) - { +void GLContextState::SetNumPatchVertices(Int32 NumVertices) +{ #if GL_ARB_tessellation_shader - if (NumVertices != m_NumPatchVertices) - { - m_NumPatchVertices = NumVertices; - glPatchParameteri(GL_PATCH_VERTICES, static_cast<GLint>(NumVertices)); - DEV_CHECK_GL_ERROR( "Failed to set the number of patch vertices" ); - } -#endif + if (NumVertices != m_NumPatchVertices) + { + m_NumPatchVertices = NumVertices; + glPatchParameteri(GL_PATCH_VERTICES, static_cast<GLint>(NumVertices)); + DEV_CHECK_GL_ERROR("Failed to set the number of patch vertices"); } +#endif } + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp index a1b9a79a..5b50e52d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp @@ -31,289 +31,296 @@ namespace Diligent { - void APIENTRY openglCallbackFunction( GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam ) +void APIENTRY openglCallbackFunction(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) +{ + // Note: disabling flood of notifications through glDebugMessageControl() has no effect, + // so we have to filter them out here + if (id == 131185 || // Buffer detailed info: Buffer object <X> (bound to GL_XXXX ... , usage hint is GL_DYNAMIC_DRAW) + // will use VIDEO memory as the source for buffer object operations. + id == 131186 // Buffer object <X> (bound to GL_XXXX, usage hint is GL_DYNAMIC_DRAW) is being copied/moved from VIDEO memory to HOST memory. + ) + return; + + std::stringstream MessageSS; + + MessageSS << "OpenGL debug message " << id << " ("; + switch (source) { - // Note: disabling flood of notifications through glDebugMessageControl() has no effect, - // so we have to filter them out here - if (id == 131185 || // Buffer detailed info: Buffer object <X> (bound to GL_XXXX ... , usage hint is GL_DYNAMIC_DRAW) - // will use VIDEO memory as the source for buffer object operations. - id == 131186 // Buffer object <X> (bound to GL_XXXX, usage hint is GL_DYNAMIC_DRAW) is being copied/moved from VIDEO memory to HOST memory. - ) - return; - - std::stringstream MessageSS; - - MessageSS << "OpenGL debug message " << id << " ("; - switch (source) - { - case GL_DEBUG_SOURCE_API: MessageSS << "Source: API."; break; - case GL_DEBUG_SOURCE_WINDOW_SYSTEM: MessageSS << "Source: Window System."; break; - case GL_DEBUG_SOURCE_SHADER_COMPILER: MessageSS << "Source: Shader Compiler."; break; - case GL_DEBUG_SOURCE_THIRD_PARTY: MessageSS << "Source: Third Party."; break; - case GL_DEBUG_SOURCE_APPLICATION: MessageSS << "Source: Application."; break; - case GL_DEBUG_SOURCE_OTHER: MessageSS << "Source: Other."; break; - default: MessageSS << "Source: Unknown (" << source << ")."; - } + // clang-format off + case GL_DEBUG_SOURCE_API: MessageSS << "Source: API."; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: MessageSS << "Source: Window System."; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: MessageSS << "Source: Shader Compiler."; break; + case GL_DEBUG_SOURCE_THIRD_PARTY: MessageSS << "Source: Third Party."; break; + case GL_DEBUG_SOURCE_APPLICATION: MessageSS << "Source: Application."; break; + case GL_DEBUG_SOURCE_OTHER: MessageSS << "Source: Other."; break; + default: MessageSS << "Source: Unknown (" << source << ")."; + // clang-format on + } - switch (type) - { - case GL_DEBUG_TYPE_ERROR: MessageSS << " Type: ERROR."; break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: MessageSS << " Type: Deprecated Behaviour."; break; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: MessageSS << " Type: UNDEFINED BEHAVIOUR."; break; - case GL_DEBUG_TYPE_PORTABILITY: MessageSS << " Type: Portability."; break; - case GL_DEBUG_TYPE_PERFORMANCE: MessageSS << " Type: PERFORMANCE."; break; - case GL_DEBUG_TYPE_MARKER: MessageSS << " Type: Marker."; break; - case GL_DEBUG_TYPE_PUSH_GROUP: MessageSS << " Type: Push Group."; break; - case GL_DEBUG_TYPE_POP_GROUP: MessageSS << " Type: Pop Group."; break; - case GL_DEBUG_TYPE_OTHER: MessageSS << " Type: Other."; break; - default: MessageSS << " Type: Unknown (" << type << ")."; - } + switch (type) + { + // clang-format off + case GL_DEBUG_TYPE_ERROR: MessageSS << " Type: ERROR."; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: MessageSS << " Type: Deprecated Behaviour."; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: MessageSS << " Type: UNDEFINED BEHAVIOUR."; break; + case GL_DEBUG_TYPE_PORTABILITY: MessageSS << " Type: Portability."; break; + case GL_DEBUG_TYPE_PERFORMANCE: MessageSS << " Type: PERFORMANCE."; break; + case GL_DEBUG_TYPE_MARKER: MessageSS << " Type: Marker."; break; + case GL_DEBUG_TYPE_PUSH_GROUP: MessageSS << " Type: Push Group."; break; + case GL_DEBUG_TYPE_POP_GROUP: MessageSS << " Type: Pop Group."; break; + case GL_DEBUG_TYPE_OTHER: MessageSS << " Type: Other."; break; + default: MessageSS << " Type: Unknown (" << type << ")."; + // clang-format on + } - switch (severity) - { - case GL_DEBUG_SEVERITY_HIGH: MessageSS << " Severity: HIGH"; break; - case GL_DEBUG_SEVERITY_MEDIUM: MessageSS << " Severity: Medium"; break; - case GL_DEBUG_SEVERITY_LOW: MessageSS << " Severity: Low"; break; - case GL_DEBUG_SEVERITY_NOTIFICATION: MessageSS << " Severity: Notification"; break; - default: MessageSS << " Severity: Unknown (" << severity << ")"; break; - } + switch (severity) + { + // clang-format off + case GL_DEBUG_SEVERITY_HIGH: MessageSS << " Severity: HIGH"; break; + case GL_DEBUG_SEVERITY_MEDIUM: MessageSS << " Severity: Medium"; break; + case GL_DEBUG_SEVERITY_LOW: MessageSS << " Severity: Low"; break; + case GL_DEBUG_SEVERITY_NOTIFICATION: MessageSS << " Severity: Notification"; break; + default: MessageSS << " Severity: Unknown (" << severity << ")"; break; + // clang-format on + } - MessageSS << "): " << message; + MessageSS << "): " << message; - LOG_INFO_MESSAGE( MessageSS.str().c_str() ); - } + LOG_INFO_MESSAGE(MessageSS.str().c_str()); +} - GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const SwapChainDesc* pSCDesc) : - m_Context {0}, - m_WindowHandleToDeviceContext{0} +GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const SwapChainDesc* pSCDesc) : + m_Context{0}, + m_WindowHandleToDeviceContext{0} +{ + Int32 MajorVersion = 0, MinorVersion = 0; + if (InitAttribs.pNativeWndHandle != nullptr) { - Int32 MajorVersion = 0, MinorVersion = 0; - if(InitAttribs.pNativeWndHandle != nullptr) - { - HWND hWnd = reinterpret_cast<HWND>(InitAttribs.pNativeWndHandle); - - // See http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_(C%2B%2B/Win) - // http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL) - PIXELFORMATDESCRIPTOR pfd; - memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) ); - pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; - pfd.iPixelType = PFD_TYPE_RGBA; - if (pSCDesc != nullptr) + HWND hWnd = reinterpret_cast<HWND>(InitAttribs.pNativeWndHandle); + + // See http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_(C%2B%2B/Win) + // http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL) + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + pfd.iPixelType = PFD_TYPE_RGBA; + if (pSCDesc != nullptr) + { + auto ColorFmt = pSCDesc->ColorBufferFormat; + if (ColorFmt == TEX_FORMAT_RGBA8_UNORM || ColorFmt == TEX_FORMAT_RGBA8_UNORM_SRGB || + ColorFmt == TEX_FORMAT_BGRA8_UNORM || ColorFmt == TEX_FORMAT_BGRA8_UNORM_SRGB) + { + pfd.cColorBits = 32; + } + else { - auto ColorFmt = pSCDesc->ColorBufferFormat; - if (ColorFmt == TEX_FORMAT_RGBA8_UNORM || ColorFmt == TEX_FORMAT_RGBA8_UNORM_SRGB || - ColorFmt == TEX_FORMAT_BGRA8_UNORM || ColorFmt == TEX_FORMAT_BGRA8_UNORM_SRGB) - { - pfd.cColorBits = 32; - } - else - { - LOG_WARNING_MESSAGE("Unsupported color buffer format ", GetTextureFormatAttribs(ColorFmt).Name, ". " - "OpenGL only supports 32-bit UNORM color buffer formats."); - pfd.cColorBits = 32; - } - - auto DepthFmt = pSCDesc->DepthBufferFormat; - switch(DepthFmt) - { - case TEX_FORMAT_UNKNOWN: - pfd.cDepthBits = 0; - pfd.cStencilBits = 0; + LOG_WARNING_MESSAGE("Unsupported color buffer format ", GetTextureFormatAttribs(ColorFmt).Name, ". " + "OpenGL only supports 32-bit UNORM color buffer formats."); + pfd.cColorBits = 32; + } + + auto DepthFmt = pSCDesc->DepthBufferFormat; + switch (DepthFmt) + { + case TEX_FORMAT_UNKNOWN: + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; break; - case TEX_FORMAT_D32_FLOAT_S8X24_UINT: - pfd.cDepthBits = 32; - pfd.cStencilBits = 8; + case TEX_FORMAT_D32_FLOAT_S8X24_UINT: + pfd.cDepthBits = 32; + pfd.cStencilBits = 8; break; - case TEX_FORMAT_D32_FLOAT: - pfd.cDepthBits = 32; + case TEX_FORMAT_D32_FLOAT: + pfd.cDepthBits = 32; break; - case TEX_FORMAT_D24_UNORM_S8_UINT: - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; + case TEX_FORMAT_D24_UNORM_S8_UINT: + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; break; - case TEX_FORMAT_D16_UNORM: - pfd.cDepthBits = 16; + case TEX_FORMAT_D16_UNORM: + pfd.cDepthBits = 16; break; - default: - LOG_ERROR_MESSAGE("Unsupported depth buffer format ", GetTextureFormatAttribs(DepthFmt).Name); - pfd.cDepthBits = 32; - } + default: + LOG_ERROR_MESSAGE("Unsupported depth buffer format ", GetTextureFormatAttribs(DepthFmt).Name); + pfd.cDepthBits = 32; } - else + } + else + { + pfd.cColorBits = 32; + pfd.cDepthBits = 32; + } + pfd.iLayerType = PFD_MAIN_PLANE; + + m_WindowHandleToDeviceContext = GetDC(hWnd); + int nPixelFormat = ChoosePixelFormat(m_WindowHandleToDeviceContext, &pfd); + + if (nPixelFormat == 0) + LOG_ERROR_AND_THROW("Invalid Pixel Format"); + + BOOL bResult = SetPixelFormat(m_WindowHandleToDeviceContext, nPixelFormat, &pfd); + if (!bResult) + LOG_ERROR_AND_THROW("Failed to set Pixel Format"); + + // Create standard OpenGL (2.1) rendering context which will be used only temporarily, + HGLRC tempContext = wglCreateContext(m_WindowHandleToDeviceContext); + // and make it current + wglMakeCurrent(m_WindowHandleToDeviceContext, tempContext); + + // Initialize GLEW + GLenum err = glewInit(); + if (GLEW_OK != err) + LOG_ERROR_AND_THROW("Failed to initialize GLEW"); + + if (wglewIsSupported("WGL_ARB_create_context") == 1) + { + std::pair<int, int> gl_versions[] = {{4, 4}, {4, 3}, {4, 2}}; + for (size_t i = 0; i < _countof(gl_versions) && m_Context == NULL; ++i) { - pfd.cColorBits = 32; - pfd.cDepthBits = 32; - } - pfd.iLayerType = PFD_MAIN_PLANE; - - m_WindowHandleToDeviceContext = GetDC( hWnd ); - int nPixelFormat = ChoosePixelFormat( m_WindowHandleToDeviceContext, &pfd ); - - if( nPixelFormat == 0 ) - LOG_ERROR_AND_THROW( "Invalid Pixel Format" ); - - BOOL bResult = SetPixelFormat( m_WindowHandleToDeviceContext, nPixelFormat, &pfd ); - if( !bResult ) - LOG_ERROR_AND_THROW( "Failed to set Pixel Format" ); - - // Create standard OpenGL (2.1) rendering context which will be used only temporarily, - HGLRC tempContext = wglCreateContext( m_WindowHandleToDeviceContext ); - // and make it current - wglMakeCurrent( m_WindowHandleToDeviceContext, tempContext ); - - // Initialize GLEW - GLenum err = glewInit(); - if( GLEW_OK != err ) - LOG_ERROR_AND_THROW( "Failed to initialize GLEW" ); - - if (wglewIsSupported( "WGL_ARB_create_context" ) == 1) - { - std::pair<int,int> gl_versions[] = {{4,4}, {4,3}, {4,2}}; - for(size_t i=0; i < _countof(gl_versions) && m_Context == NULL; ++i) - { - const auto& version = gl_versions[i]; - MajorVersion = version.first; - MinorVersion = version.second; - // Setup attributes for a new OpenGL rendering context - int attribs[] = - { - WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion, - WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion, - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_CORE_PROFILE_BIT, - 0, 0 - }; + const auto& version = gl_versions[i]; + MajorVersion = version.first; + MinorVersion = version.second; + // Setup attributes for a new OpenGL rendering context + int attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion, + WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_CORE_PROFILE_BIT, + 0, 0 // + }; #ifdef _DEBUG - attribs[5] |= WGL_CONTEXT_DEBUG_BIT_ARB; -#endif - - // Create new rendering context - // In order to create new OpenGL rendering context we have to call function wglCreateContextAttribsARB(), - // which is an OpenGL function and requires OpenGL to be active when it is called. - // The only way is to create an old context, activate it, and while it is active create a new one. - // Very inconsistent, but we have to live with it! - m_Context = wglCreateContextAttribsARB( m_WindowHandleToDeviceContext, 0, attribs ); - } - - if (m_Context == NULL) - { - LOG_ERROR_AND_THROW("Failed to initialize OpenGL context."); - } - - // Delete tempContext - wglMakeCurrent( NULL, NULL ); - wglDeleteContext( tempContext ); - // Make new context current - wglMakeCurrent( m_WindowHandleToDeviceContext, m_Context ); - wglSwapIntervalEXT( 0 ); - } - else - { //It's not possible to make a GL 4.x context. Use the old style context (GL 2.1 and before) - m_Context = tempContext; - } - - if( glDebugMessageCallback ) + attribs[5] |= WGL_CONTEXT_DEBUG_BIT_ARB; +#endif + + // Create new rendering context + // In order to create new OpenGL rendering context we have to call function wglCreateContextAttribsARB(), + // which is an OpenGL function and requires OpenGL to be active when it is called. + // The only way is to create an old context, activate it, and while it is active create a new one. + // Very inconsistent, but we have to live with it! + m_Context = wglCreateContextAttribsARB(m_WindowHandleToDeviceContext, 0, attribs); + } + + if (m_Context == NULL) { - glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS ); - glDebugMessageCallback( openglCallbackFunction, nullptr ); - GLuint unusedIds = 0; - glDebugMessageControl( - GL_DONT_CARE, // Source of debug messages to enable or disable - GL_DONT_CARE, // Type of debug messages to enable or disable - GL_DONT_CARE, // Severity of debug messages to enable or disable - 0, // The length of the array ids - &unusedIds, // Array of unsigned integers contianing the ids of the messages to enable or disable - GL_TRUE // Flag determining whether the selected messages should be enabled or disabled - ); - if( glGetError() != GL_NO_ERROR ) - LOG_ERROR_MESSAGE("Failed to enable debug messages"); + LOG_ERROR_AND_THROW("Failed to initialize OpenGL context."); } - } - else - { - auto CurrentCtx = wglGetCurrentContext(); - if (CurrentCtx == 0) - { - LOG_ERROR_AND_THROW("No current GL context found! Provide non-null handle to a native Window to create a GL context"); - } - - // Initialize GLEW - GLenum err = glewInit(); - if( GLEW_OK != err ) - LOG_ERROR_AND_THROW( "Failed to initialize GLEW" ); - } - - //Checking GL version - const GLubyte *GLVersionString = glGetString( GL_VERSION ); - - //Or better yet, use the GL3 way to get the version number - glGetIntegerv( GL_MAJOR_VERSION, &MajorVersion ); - glGetIntegerv( GL_MINOR_VERSION, &MinorVersion ); - LOG_INFO_MESSAGE(InitAttribs.pNativeWndHandle != nullptr ? "Initialized OpenGL " : "Attached to OpenGL ", MajorVersion, '.', MinorVersion, " context (", GLVersionString, ')'); - - // Under the standard filtering rules for cubemaps, filtering does not work across faces of the cubemap. - // This results in a seam across the faces of a cubemap. This was a hardware limitation in the past, but - // modern hardware is capable of interpolating across a cube face boundary. - // GL_TEXTURE_CUBE_MAP_SEAMLESS is not defined in OpenGLES - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - if( glGetError() != GL_NO_ERROR ) - LOG_ERROR_MESSAGE("Failed to enable seamless cubemap filtering"); - - // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace - // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore - // convert the output from linear RGB to sRGB. - // Any writes to images that are not in the sRGB format should not be affected. - // Thus this setting should be just set once and left that way - glEnable(GL_FRAMEBUFFER_SRGB); - if( glGetError() != GL_NO_ERROR ) - LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); - - deviceCaps.DevType = DeviceType::OpenGL; - deviceCaps.MajorVersion = MajorVersion; - deviceCaps.MinorVersion = MinorVersion; - bool IsGL43OrAbove = MajorVersion >= 5 || MajorVersion == 4 && MinorVersion >= 3; - auto &TexCaps = deviceCaps.TexCaps; - TexCaps.bTexture2DMSSupported = IsGL43OrAbove; - TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; - TexCaps.bTextureViewSupported = IsGL43OrAbove; - TexCaps.bCubemapArraysSupported = IsGL43OrAbove; - deviceCaps.bMultithreadedResourceCreationSupported = False; - } - GLContext::~GLContext() - { - // Do not destroy context if it was created by the app. - if( m_Context ) - { - wglMakeCurrent( m_WindowHandleToDeviceContext, 0 ); - wglDeleteContext( m_Context ); - } - } + // Delete tempContext + wglMakeCurrent(NULL, NULL); + wglDeleteContext(tempContext); + // Make new context current + wglMakeCurrent(m_WindowHandleToDeviceContext, m_Context); + wglSwapIntervalEXT(0); + } + else + { //It's not possible to make a GL 4.x context. Use the old style context (GL 2.1 and before) + m_Context = tempContext; + } - void GLContext::SwapBuffers() + if (glDebugMessageCallback) + { + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(openglCallbackFunction, nullptr); + GLuint unusedIds = 0; + glDebugMessageControl( + GL_DONT_CARE, // Source of debug messages to enable or disable + GL_DONT_CARE, // Type of debug messages to enable or disable + GL_DONT_CARE, // Severity of debug messages to enable or disable + 0, // The length of the array ids + &unusedIds, // Array of unsigned integers contianing the ids of the messages to enable or disable + GL_TRUE // Flag determining whether the selected messages should be enabled or disabled + ); + if (glGetError() != GL_NO_ERROR) + LOG_ERROR_MESSAGE("Failed to enable debug messages"); + } + } + else { - if (m_WindowHandleToDeviceContext) - ::SwapBuffers(m_WindowHandleToDeviceContext); - else - LOG_ERROR("Swap buffer failed because window handle to device context is not initialized"); + auto CurrentCtx = wglGetCurrentContext(); + if (CurrentCtx == 0) + { + LOG_ERROR_AND_THROW("No current GL context found! Provide non-null handle to a native Window to create a GL context"); + } + + // Initialize GLEW + GLenum err = glewInit(); + if (GLEW_OK != err) + LOG_ERROR_AND_THROW("Failed to initialize GLEW"); } - GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() + //Checking GL version + const GLubyte* GLVersionString = glGetString(GL_VERSION); + + //Or better yet, use the GL3 way to get the version number + glGetIntegerv(GL_MAJOR_VERSION, &MajorVersion); + glGetIntegerv(GL_MINOR_VERSION, &MinorVersion); + LOG_INFO_MESSAGE(InitAttribs.pNativeWndHandle != nullptr ? "Initialized OpenGL " : "Attached to OpenGL ", MajorVersion, '.', MinorVersion, " context (", GLVersionString, ')'); + + // Under the standard filtering rules for cubemaps, filtering does not work across faces of the cubemap. + // This results in a seam across the faces of a cubemap. This was a hardware limitation in the past, but + // modern hardware is capable of interpolating across a cube face boundary. + // GL_TEXTURE_CUBE_MAP_SEAMLESS is not defined in OpenGLES + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + if (glGetError() != GL_NO_ERROR) + LOG_ERROR_MESSAGE("Failed to enable seamless cubemap filtering"); + + // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace + // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore + // convert the output from linear RGB to sRGB. + // Any writes to images that are not in the sRGB format should not be affected. + // Thus this setting should be just set once and left that way + glEnable(GL_FRAMEBUFFER_SRGB); + if (glGetError() != GL_NO_ERROR) + LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); + + deviceCaps.DevType = DeviceType::OpenGL; + deviceCaps.MajorVersion = MajorVersion; + deviceCaps.MinorVersion = MinorVersion; + bool IsGL43OrAbove = MajorVersion >= 5 || MajorVersion == 4 && MinorVersion >= 3; + auto& TexCaps = deviceCaps.TexCaps; + TexCaps.bTexture2DMSSupported = IsGL43OrAbove; + TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; + TexCaps.bTextureViewSupported = IsGL43OrAbove; + TexCaps.bCubemapArraysSupported = IsGL43OrAbove; + deviceCaps.bMultithreadedResourceCreationSupported = False; +} + +GLContext::~GLContext() +{ + // Do not destroy context if it was created by the app. + if (m_Context) { - return wglGetCurrentContext(); + wglMakeCurrent(m_WindowHandleToDeviceContext, 0); + wglDeleteContext(m_Context); } } + +void GLContext::SwapBuffers() +{ + if (m_WindowHandleToDeviceContext) + ::SwapBuffers(m_WindowHandleToDeviceContext); + else + LOG_ERROR("Swap buffer failed because window handle to device context is not initialized"); +} + +GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() +{ + return wglGetCurrentContext(); +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp index 8d56792c..fa07d9bb 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp @@ -26,13 +26,17 @@ namespace GLObjectWrappers { - const char *GLBufferObjCreateReleaseHelper :: Name = "buffer"; - const char *GLProgramObjCreateReleaseHelper :: Name = "program"; - const char *GLShaderObjCreateReleaseHelper :: Name = "shader"; - const char *GLPipelineObjCreateReleaseHelper:: Name = "pipeline"; - const char *GLVAOCreateReleaseHelper :: Name = "vertex array"; - const char *GLTextureCreateReleaseHelper :: Name = "texture"; - const char *GLSamplerCreateReleaseHelper :: Name = "sampler"; - const char *GLFBOCreateReleaseHelper :: Name = "framebuffer"; - const char *GLRBOCreateReleaseHelper :: Name = "renderbuffer"; -} + +// clang-format off +const char *GLBufferObjCreateReleaseHelper :: Name = "buffer"; +const char *GLProgramObjCreateReleaseHelper :: Name = "program"; +const char *GLShaderObjCreateReleaseHelper :: Name = "shader"; +const char *GLPipelineObjCreateReleaseHelper:: Name = "pipeline"; +const char *GLVAOCreateReleaseHelper :: Name = "vertex array"; +const char *GLTextureCreateReleaseHelper :: Name = "texture"; +const char *GLSamplerCreateReleaseHelper :: Name = "sampler"; +const char *GLFBOCreateReleaseHelper :: Name = "framebuffer"; +const char *GLRBOCreateReleaseHelper :: Name = "renderbuffer"; +// clang-format on + +} // namespace GLObjectWrappers diff --git a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp index e99f7921..a2841321 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp @@ -39,16 +39,18 @@ size_t GLPipelineResourceLayout::GetRequiredMemorySize(GLProgramResources* Uint32 NumAllowedTypes) { GLProgramResources::ResourceCounters Counters; - for(Uint32 prog = 0; prog < NumPrograms; ++prog) + for (Uint32 prog = 0; prog < NumPrograms; ++prog) { ProgramResources[prog].CountResources(ResourceLayout, AllowedVarTypes, NumAllowedTypes, Counters); } + // clang-format off size_t RequiredSize = Counters.NumUBs * sizeof(UniformBuffBindInfo) + Counters.NumSamplers * sizeof(SamplerBindInfo) + Counters.NumImages * sizeof(ImageBindInfo) + Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo) + NumPrograms * sizeof(GLProgramResources::ResourceCounters); + // clang-format on return RequiredSize; } @@ -61,27 +63,31 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P { GLProgramResources::ResourceCounters Counters; - for(Uint32 prog = 0; prog < NumPrograms; ++prog) + for (Uint32 prog = 0; prog < NumPrograms; ++prog) { ProgramResources[prog].CountResources(ResourceLayout, AllowedVarTypes, NumAllowedTypes, Counters); } // Initialize offsets size_t CurrentOffset = 0; - auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) + + auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) // { constexpr size_t MaxOffset = std::numeric_limits<OffsetType>::max(); - VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");(void)MaxOffset; + VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")"); + (void)MaxOffset; auto Offset = static_cast<OffsetType>(CurrentOffset); CurrentOffset += NumBytes; return Offset; }; + // clang-format off auto UBOffset = AdvanceOffset(Counters.NumUBs * sizeof(UniformBuffBindInfo) ); (void)UBOffset; // To suppress warning m_SamplerOffset = AdvanceOffset(Counters.NumSamplers * sizeof(SamplerBindInfo) ); m_ImageOffset = AdvanceOffset(Counters.NumImages * sizeof(ImageBindInfo) ); m_StorageBufferOffset = AdvanceOffset(Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo)); m_VariableEndOffset = AdvanceOffset(0); + // clang-format off m_NumPrograms = static_cast<Uint8>(NumPrograms); VERIFY_EXPR(m_NumPrograms == NumPrograms); auto TotalMemorySize = m_VariableEndOffset + m_NumPrograms * sizeof(GLProgramResources::ResourceCounters); @@ -94,10 +100,12 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void> >(pRawMem, ResLayoutDataAllocator); } + // clang-format off VERIFY_EXPR(Counters.NumUBs == GetNumUBs() ); VERIFY_EXPR(Counters.NumSamplers == GetNumSamplers() ); VERIFY_EXPR(Counters.NumImages == GetNumImages() ); VERIFY_EXPR(Counters.NumStorageBlocks == GetNumStorageBuffers()); + // clang-format on // Current resource index for every resource type GLProgramResources::ResourceCounters VarCounters = {}; @@ -110,24 +118,25 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P #ifdef _DEBUG const Uint32 DbgAllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); #endif - for(Uint32 prog = 0; prog < NumPrograms; ++prog) + for (Uint32 prog = 0; prog < NumPrograms; ++prog) { - const auto& Resources = ProgramResources[prog]; - auto ShaderStages = Resources.GetShaderStages(); + const auto& Resources = ProgramResources[prog]; + auto ShaderStages = Resources.GetShaderStages(); Resources.ProcessConstResources( - [&](const GLProgramResources::UniformBufferInfo& UB) + [&](const GLProgramResources::UniformBufferInfo& UB) // { auto VarType = GetShaderVariableType(ShaderStages, UB.Name, ResourceLayout); VERIFY_EXPR(IsAllowedType(VarType, DbgAllowedTypeBits)); - auto* pUBVar = new (&GetResource<UniformBuffBindInfo>(VarCounters.NumUBs++)) UniformBuffBindInfo - { - UB, - *this, - VarType - }; + auto* pUBVar = new (&GetResource<UniformBuffBindInfo>(VarCounters.NumUBs++)) + UniformBuffBindInfo // + { + UB, + *this, + VarType // + }; UniformBindingSlots = std::max(UniformBindingSlots, pUBVar->m_Attribs.Binding + pUBVar->m_Attribs.ArraySize); }, - [&](const GLProgramResources::SamplerInfo& Sam) + [&](const GLProgramResources::SamplerInfo& Sam) // { auto VarType = GetShaderVariableType(ShaderStages, Sam.Name, ResourceLayout); VERIFY_EXPR(IsAllowedType(VarType, DbgAllowedTypeBits)); @@ -137,58 +146,63 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P StaticSamplerIdx = FindStaticSampler(ResourceLayout.StaticSamplers, ResourceLayout.NumStaticSamplers, ShaderStages, Sam.Name, nullptr); } - auto* pSamVar = new (&GetResource<SamplerBindInfo>(VarCounters.NumSamplers++)) SamplerBindInfo - { - Sam, - *this, - VarType, - StaticSamplerIdx - }; + auto* pSamVar = new (&GetResource<SamplerBindInfo>(VarCounters.NumSamplers++)) + SamplerBindInfo // + { + Sam, + *this, + VarType, + StaticSamplerIdx // + }; SamplerBindingSlots = std::max(SamplerBindingSlots, pSamVar->m_Attribs.Binding + pSamVar->m_Attribs.ArraySize); }, - [&](const GLProgramResources::ImageInfo& Img) + [&](const GLProgramResources::ImageInfo& Img) // { auto VarType = GetShaderVariableType(ShaderStages, Img.Name, ResourceLayout); VERIFY_EXPR(IsAllowedType(VarType, DbgAllowedTypeBits)); - auto* pImgVar = new (&GetResource<ImageBindInfo>(VarCounters.NumImages++)) ImageBindInfo - { - Img, - *this, - VarType - }; + auto* pImgVar = new (&GetResource<ImageBindInfo>(VarCounters.NumImages++)) + ImageBindInfo // + { + Img, + *this, + VarType // + }; ImageBindingSlots = std::max(ImageBindingSlots, pImgVar->m_Attribs.Binding + pImgVar->m_Attribs.ArraySize); }, - [&](const GLProgramResources::StorageBlockInfo& SB) + [&](const GLProgramResources::StorageBlockInfo& SB) // { auto VarType = GetShaderVariableType(ShaderStages, SB.Name, ResourceLayout); VERIFY_EXPR(IsAllowedType(VarType, DbgAllowedTypeBits)); - auto* pSSBOVar = new (&GetResource<StorageBufferBindInfo>(VarCounters.NumStorageBlocks++)) StorageBufferBindInfo - { - SB, - *this, - VarType - }; + auto* pSSBOVar = new (&GetResource<StorageBufferBindInfo>(VarCounters.NumStorageBlocks++)) + StorageBufferBindInfo // + { + SB, + *this, + VarType // + }; SSBOBindingSlots = std::max(SSBOBindingSlots, pSSBOVar->m_Attribs.Binding + pSSBOVar->m_Attribs.ArraySize); }, &ResourceLayout, AllowedVarTypes, - NumAllowedTypes + NumAllowedTypes // ); new (&GetProgramVarEndOffsets(prog)) GLProgramResources::ResourceCounters{VarCounters}; while (ShaderStages != SHADER_TYPE_UNKNOWN) { - auto Stage = static_cast<SHADER_TYPE>(Uint32{ShaderStages} & ~(Uint32{ShaderStages}-1)); - auto ShaderInd = GetShaderTypeIndex(Stage); + auto Stage = static_cast<SHADER_TYPE>(Uint32{ShaderStages} & ~(Uint32{ShaderStages} - 1)); + auto ShaderInd = GetShaderTypeIndex(Stage); m_ProgramIndex[ShaderInd] = static_cast<Int8>(prog); - ShaderStages = static_cast<SHADER_TYPE>(Uint32{ShaderStages} & ~Stage); + ShaderStages = static_cast<SHADER_TYPE>(Uint32{ShaderStages} & ~Stage); } } - + + // clang-format off VERIFY(VarCounters.NumUBs == GetNumUBs(), "Not all UBs are initialized which will cause a crash when dtor is called"); VERIFY(VarCounters.NumSamplers == GetNumSamplers(), "Not all Samplers are initialized which will cause a crash when dtor is called"); VERIFY(VarCounters.NumImages == GetNumImages(), "Not all Images are initialized which will cause a crash when dtor is called"); VERIFY(VarCounters.NumStorageBlocks == GetNumStorageBuffers(), "Not all SSBOs are initialized which will cause a crash when dtor is called"); + // clang-format on m_pResourceCache = pResourceCache; if (m_pResourceCache != nullptr && !m_pResourceCache->IsInitialized()) @@ -200,6 +214,7 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P GLPipelineResourceLayout::~GLPipelineResourceLayout() { + // clang-format off HandleResources( [&](UniformBuffBindInfo& ub) { @@ -221,13 +236,14 @@ GLPipelineResourceLayout::~GLPipelineResourceLayout() ssbo.~StorageBufferBindInfo(); } ); + // clang-format on } void GLPipelineResourceLayout::UniformBuffBindInfo::BindResource(IDeviceObject* pBuffer, Uint32 ArrayIndex) { - DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize-1); + DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize - 1); VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is not initialized"); auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; @@ -251,7 +267,7 @@ void GLPipelineResourceLayout::UniformBuffBindInfo::BindResource(IDeviceObject* void GLPipelineResourceLayout::SamplerBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize-1); + DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize - 1); VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is not initialized"); auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; @@ -298,7 +314,7 @@ void GLPipelineResourceLayout::SamplerBindInfo::BindResource(IDeviceObject* pVie void GLPipelineResourceLayout::ImageBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize-1); + DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize - 1); VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is not initialized"); auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; @@ -339,7 +355,7 @@ void GLPipelineResourceLayout::ImageBindInfo::BindResource(IDeviceObject* pView, void GLPipelineResourceLayout::StorageBufferBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize-1); + DEV_CHECK_ERR(ArrayIndex < m_Attribs.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.ArraySize - 1); VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is not initialized"); auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; VERIFY_EXPR(m_Attribs.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV); @@ -364,29 +380,31 @@ class BindResourceHelper { public: BindResourceHelper(IResourceMapping& RM, SHADER_TYPE SS, Uint32 Fl) : + // clang-format off ResourceMapping {RM}, ShaderStage {SS}, Flags {Fl} + // clang-format on { } - template<typename ResourceType> - void Bind( ResourceType& Res) + template <typename ResourceType> + void Bind(ResourceType& Res) { - if ( (Flags & (1 << Res.GetType())) == 0 ) + if ((Flags & (1 << Res.GetType())) == 0) return; - for (Uint16 elem=0; elem < Res.m_Attribs.ArraySize; ++elem) + for (Uint16 elem = 0; elem < Res.m_Attribs.ArraySize; ++elem) { if ((Res.m_Attribs.ShaderStages & ShaderStage) == 0) continue; - if ( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(elem) ) + if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(elem)) continue; - const auto* VarName = Res.m_Attribs.Name; + const auto* VarName = Res.m_Attribs.Name; RefCntAutoPtr<IDeviceObject> pRes; - ResourceMapping.GetResource( VarName, &pRes, elem ); + ResourceMapping.GetResource(VarName, &pRes, elem); if (pRes) { // Call non-virtual function @@ -394,8 +412,8 @@ public: } else { - if ( (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(elem) ) - LOG_ERROR_MESSAGE( "Unable to bind resource to shader variable '", VarName, "': resource is not found in the resource mapping" ); + if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(elem)) + LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", VarName, "': resource is not found in the resource mapping"); } } } @@ -413,15 +431,16 @@ void GLPipelineResourceLayout::BindResources(SHADER_TYPE ShaderStage, IResourceM if (pResourceMapping == nullptr) { - LOG_ERROR_MESSAGE( "Failed to bind resources: resource mapping is null" ); + LOG_ERROR_MESSAGE("Failed to bind resources: resource mapping is null"); return; } - - if ( (Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0 ) + + if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0) Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL; BindResourceHelper BindResHelper(*pResourceMapping, ShaderStage, Flags); + // clang-format off HandleResources( [&](UniformBuffBindInfo& ub) { @@ -443,17 +462,18 @@ void GLPipelineResourceLayout::BindResources(SHADER_TYPE ShaderStage, IResourceM BindResHelper.Bind(ssbo); } ); + // clang-format on } -template<typename ResourceType> +template <typename ResourceType> IShaderResourceVariable* GLPipelineResourceLayout::GetResourceByName(SHADER_TYPE ShaderStage, const Char* Name) { auto NumResources = GetNumResources<ResourceType>(); for (Uint32 res = 0; res < NumResources; ++res) { auto& Resource = GetResource<ResourceType>(res); - if ( (Resource.m_Attribs.ShaderStages & ShaderStage) != 0 && strcmp(Resource.m_Attribs.Name, Name) == 0) + if ((Resource.m_Attribs.ShaderStages & ShaderStage) != 0 && strcmp(Resource.m_Attribs.Name, Name) == 0) return &Resource; } @@ -478,27 +498,29 @@ IShaderResourceVariable* GLPipelineResourceLayout::GetShaderVariable(SHADER_TYPE return nullptr; } -Uint32 GLPipelineResourceLayout::GetNumVariables(SHADER_TYPE ShaderStage)const +Uint32 GLPipelineResourceLayout::GetNumVariables(SHADER_TYPE ShaderStage) const { VERIFY(IsPowerOfTwo(Uint32{ShaderStage}), "Only one shader stage must be specified"); auto ShaderInd = GetShaderTypeIndex(ShaderStage); - auto ProgIdx = m_ProgramIndex[ShaderInd]; + auto ProgIdx = m_ProgramIndex[ShaderInd]; if (ProgIdx < 0) return 0; const auto& VariableEndOffset = GetProgramVarEndOffsets(ProgIdx); - const auto& VariableStartOffset = ProgIdx > 0 ? GetProgramVarEndOffsets(ProgIdx-1) : GLProgramResources::ResourceCounters{}; + const auto& VariableStartOffset = ProgIdx > 0 ? GetProgramVarEndOffsets(ProgIdx - 1) : GLProgramResources::ResourceCounters{}; + // clang-format off Uint32 NumVars = VariableEndOffset.NumUBs - VariableStartOffset.NumUBs + VariableEndOffset.NumSamplers - VariableStartOffset.NumSamplers + VariableEndOffset.NumImages - VariableStartOffset.NumImages + VariableEndOffset.NumStorageBlocks - VariableStartOffset.NumStorageBlocks; + // clang-format on + #ifdef _DEBUG { Uint32 DbgNumVars = 0; - auto CountVar = [&](const GLVariableBase& Var) - { + auto CountVar = [&](const GLVariableBase& Var) { DbgNumVars += ((Var.m_Attribs.ShaderStages & ShaderStage) != 0) ? 1 : 0; }; HandleConstResources(CountVar, CountVar, CountVar, CountVar); @@ -512,14 +534,16 @@ Uint32 GLPipelineResourceLayout::GetNumVariables(SHADER_TYPE ShaderStage)const class ShaderVariableLocator { public: - ShaderVariableLocator(GLPipelineResourceLayout& _Layout, - Uint32 _Index) : + ShaderVariableLocator(GLPipelineResourceLayout& _Layout, + Uint32 _Index) : + // clang-format off Layout {_Layout}, Index {_Index} + // clang-format on { } - template<typename ResourceType> + template <typename ResourceType> IShaderResourceVariable* TryResource(Uint32 StartVarOffset, Uint32 EndVarOffset) { auto NumResources = EndVarOffset - StartVarOffset; @@ -533,8 +557,8 @@ public: } private: - GLPipelineResourceLayout& Layout; - Uint32 Index; + GLPipelineResourceLayout& Layout; + Uint32 Index; }; @@ -542,26 +566,26 @@ IShaderResourceVariable* GLPipelineResourceLayout::GetShaderVariable(SHADER_TYPE { VERIFY(IsPowerOfTwo(Uint32{ShaderStage}), "Only one shader stage must be specified"); auto ShaderInd = GetShaderTypeIndex(ShaderStage); - auto ProgIdx = m_ProgramIndex[ShaderInd]; + auto ProgIdx = m_ProgramIndex[ShaderInd]; if (ProgIdx < 0) return nullptr; const auto& VariableEndOffset = GetProgramVarEndOffsets(ProgIdx); - const auto& VariableStartOffset = ProgIdx > 0 ? GetProgramVarEndOffsets(ProgIdx-1) : GLProgramResources::ResourceCounters{}; + const auto& VariableStartOffset = ProgIdx > 0 ? GetProgramVarEndOffsets(ProgIdx - 1) : GLProgramResources::ResourceCounters{}; ShaderVariableLocator VarLocator(*this, Index); - if(auto* pUB = VarLocator.TryResource<UniformBuffBindInfo>(VariableStartOffset.NumUBs, VariableEndOffset.NumUBs)) + if (auto* pUB = VarLocator.TryResource<UniformBuffBindInfo>(VariableStartOffset.NumUBs, VariableEndOffset.NumUBs)) return pUB; - if(auto* pSampler = VarLocator.TryResource<SamplerBindInfo>(VariableStartOffset.NumSamplers, VariableEndOffset.NumSamplers)) + if (auto* pSampler = VarLocator.TryResource<SamplerBindInfo>(VariableStartOffset.NumSamplers, VariableEndOffset.NumSamplers)) return pSampler; - if(auto* pImage = VarLocator.TryResource<ImageBindInfo>(VariableStartOffset.NumImages, VariableEndOffset.NumImages)) + if (auto* pImage = VarLocator.TryResource<ImageBindInfo>(VariableStartOffset.NumImages, VariableEndOffset.NumImages)) return pImage; - if(auto* pSSBO = VarLocator.TryResource<StorageBufferBindInfo>(VariableStartOffset.NumStorageBlocks, VariableEndOffset.NumStorageBlocks)) + if (auto* pSSBO = VarLocator.TryResource<StorageBufferBindInfo>(VariableStartOffset.NumStorageBlocks, VariableEndOffset.NumStorageBlocks)) return pSSBO; LOG_ERROR(Index, " is not a valid variable index."); @@ -573,18 +597,20 @@ IShaderResourceVariable* GLPipelineResourceLayout::GetShaderVariable(SHADER_TYPE class ShaderVariableIndexLocator { public: - ShaderVariableIndexLocator(const GLPipelineResourceLayout& _Layout, const GLPipelineResourceLayout::GLVariableBase& Variable) : - Layout (_Layout), + ShaderVariableIndexLocator(const GLPipelineResourceLayout& _Layout, const GLPipelineResourceLayout::GLVariableBase& Variable) : + // clang-format off + Layout {_Layout}, VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer.get())) + // clang-format on {} - template<typename ResourceType> + template <typename ResourceType> bool TryResource(Uint32 NextResourceTypeOffset, Uint32 FirstVarOffset, Uint32 LastVarOffset) { if (VarOffset < NextResourceTypeOffset) { auto RelativeOffset = VarOffset - Layout.GetResourceOffset<ResourceType>(); - DEV_CHECK_ERR( RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")"); + DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")"); RelativeOffset /= sizeof(ResourceType); VERIFY(RelativeOffset >= FirstVarOffset && RelativeOffset < LastVarOffset, "Relative offset is out of bounds which either means the variable does not belong to this SRB or " @@ -599,29 +625,29 @@ public: } } - Uint32 GetIndex() const {return Index;} + Uint32 GetIndex() const { return Index; } private: const GLPipelineResourceLayout& Layout; - const size_t VarOffset; - Uint32 Index = 0; + const size_t VarOffset; + Uint32 Index = 0; }; -Uint32 GLPipelineResourceLayout::GetVariableIndex(const GLVariableBase& Var)const +Uint32 GLPipelineResourceLayout::GetVariableIndex(const GLVariableBase& Var) const { if (!m_ResourceBuffer) { LOG_ERROR("This shader resource layout does not have resources"); return static_cast<Uint32>(-1); } - - auto FirstStage = static_cast<SHADER_TYPE>(Uint32{Var.m_Attribs.ShaderStages} & ~(Uint32{Var.m_Attribs.ShaderStages}-1)); - auto ProgIdx = m_ProgramIndex[GetShaderTypeIndex(FirstStage)]; + + auto FirstStage = static_cast<SHADER_TYPE>(Uint32{Var.m_Attribs.ShaderStages} & ~(Uint32{Var.m_Attribs.ShaderStages} - 1)); + auto ProgIdx = m_ProgramIndex[GetShaderTypeIndex(FirstStage)]; VERIFY(ProgIdx >= 0, "This shader stage is not initialized in the resource layout"); const auto& VariableEndOffset = GetProgramVarEndOffsets(ProgIdx); - const auto& VariableStartOffset = ProgIdx > 0 ? GetProgramVarEndOffsets(ProgIdx-1) : GLProgramResources::ResourceCounters{}; + const auto& VariableStartOffset = ProgIdx > 0 ? GetProgramVarEndOffsets(ProgIdx - 1) : GLProgramResources::ResourceCounters{}; ShaderVariableIndexLocator IdxLocator(*this, Var); @@ -641,17 +667,19 @@ Uint32 GLPipelineResourceLayout::GetVariableIndex(const GLVariableBase& Var)cons return static_cast<Uint32>(-1); } -void GLPipelineResourceLayout::CopyResources(GLProgramResourceCache& DstCache)const +void GLPipelineResourceLayout::CopyResources(GLProgramResourceCache& DstCache) const { VERIFY_EXPR(m_pResourceCache != nullptr); const auto& SrcCache = *m_pResourceCache; + // clang-format off VERIFY( DstCache.GetUBCount() >= SrcCache.GetUBCount(), "Dst cache is not large enough to contain all CBs" ); VERIFY( DstCache.GetSamplerCount() >= SrcCache.GetSamplerCount(), "Dst cache is not large enough to contain all SRVs" ); VERIFY( DstCache.GetImageCount() >= SrcCache.GetImageCount(), "Dst cache is not large enough to contain all samplers" ); VERIFY( DstCache.GetSSBOCount() >= SrcCache.GetSSBOCount(), "Dst cache is not large enough to contain all UAVs" ); + // clang-format on HandleConstResources( - [&](const UniformBuffBindInfo& UB) + [&](const UniformBuffBindInfo& UB) // { for (auto binding = UB.m_Attribs.Binding; binding < UB.m_Attribs.Binding + UB.m_Attribs.ArraySize; ++binding) { @@ -660,7 +688,7 @@ void GLPipelineResourceLayout::CopyResources(GLProgramResourceCache& DstCache)co } }, - [&](const SamplerBindInfo& Sam) + [&](const SamplerBindInfo& Sam) // { for (auto binding = Sam.m_Attribs.Binding; binding < Sam.m_Attribs.Binding + Sam.m_Attribs.ArraySize; ++binding) { @@ -669,7 +697,7 @@ void GLPipelineResourceLayout::CopyResources(GLProgramResourceCache& DstCache)co } }, - [&](const ImageBindInfo& Img) + [&](const ImageBindInfo& Img) // { for (auto binding = Img.m_Attribs.Binding; binding < Img.m_Attribs.Binding + Img.m_Attribs.ArraySize; ++binding) { @@ -678,37 +706,37 @@ void GLPipelineResourceLayout::CopyResources(GLProgramResourceCache& DstCache)co } }, - [&](const StorageBufferBindInfo& SSBO) + [&](const StorageBufferBindInfo& SSBO) // { for (auto binding = SSBO.m_Attribs.Binding; binding < SSBO.m_Attribs.Binding + SSBO.m_Attribs.ArraySize; ++binding) { auto pBufferView = SrcCache.GetConstSSBO(binding).pBufferView; DstCache.SetSSBO(binding, std::move(pBufferView)); } - } + } // ); } #ifdef DEVELOPMENT -bool GLPipelineResourceLayout::dvpVerifyBindings(const GLProgramResourceCache& ResourceCache)const +bool GLPipelineResourceLayout::dvpVerifyBindings(const GLProgramResourceCache& ResourceCache) const { -#define LOG_MISSING_BINDING(VarType, BindInfo, BindPt) LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", BindInfo.m_Attribs.GetPrintName(BindPt - BindInfo.m_Attribs.Binding), "'") +# define LOG_MISSING_BINDING(VarType, BindInfo, BindPt) LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", BindInfo.m_Attribs.GetPrintName(BindPt - BindInfo.m_Attribs.Binding), "'") bool BindingsOK = true; HandleConstResources( - [&](const UniformBuffBindInfo& ub) + [&](const UniformBuffBindInfo& ub) // { for (Uint32 BindPoint = ub.m_Attribs.Binding; BindPoint < Uint32{ub.m_Attribs.Binding} + ub.m_Attribs.ArraySize; ++BindPoint) { if (!ResourceCache.IsUBBound(BindPoint)) { LOG_MISSING_BINDING("constant buffer", ub, BindPoint); - BindingsOK = false; + BindingsOK = false; } } }, - [&](const SamplerBindInfo& sam) + [&](const SamplerBindInfo& sam) // { for (Uint32 BindPoint = sam.m_Attribs.Binding; BindPoint < Uint32{sam.m_Attribs.Binding} + sam.m_Attribs.ArraySize; ++BindPoint) { @@ -717,7 +745,7 @@ bool GLPipelineResourceLayout::dvpVerifyBindings(const GLProgramResourceCache& R if (!ResourceCache.IsSamplerBound(BindPoint, sam.m_Attribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV)) { LOG_MISSING_BINDING("texture", sam, BindPoint); - BindingsOK = false; + BindingsOK = false; } else { @@ -725,13 +753,13 @@ bool GLPipelineResourceLayout::dvpVerifyBindings(const GLProgramResourceCache& R if (sam.m_StaticSamplerIdx >= 0 && CachedSampler.pSampler == nullptr) { LOG_ERROR_MESSAGE("Static sampler is not initialized for texture '", sam.m_Attribs.Name, "'"); - BindingsOK = false; + BindingsOK = false; } } } }, - [&](const ImageBindInfo& img) + [&](const ImageBindInfo& img) // { for (Uint32 BindPoint = img.m_Attribs.Binding; BindPoint < Uint32{img.m_Attribs.Binding} + img.m_Attribs.ArraySize; ++BindPoint) { @@ -740,28 +768,27 @@ bool GLPipelineResourceLayout::dvpVerifyBindings(const GLProgramResourceCache& R if (!ResourceCache.IsImageBound(BindPoint, img.m_Attribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV)) { LOG_MISSING_BINDING("texture UAV", img, BindPoint); - BindingsOK = false; + BindingsOK = false; } } }, - [&](const StorageBufferBindInfo& ssbo) + [&](const StorageBufferBindInfo& ssbo) // { for (Uint32 BindPoint = ssbo.m_Attribs.Binding; BindPoint < Uint32{ssbo.m_Attribs.Binding} + ssbo.m_Attribs.ArraySize; ++BindPoint) { if (!ResourceCache.IsSSBOBound(BindPoint)) { LOG_MISSING_BINDING("buffer", ssbo, BindPoint); - BindingsOK = false; + BindingsOK = false; } } - } - ); -#undef LOG_MISSING_BINDING + }); +# undef LOG_MISSING_BINDING return BindingsOK; } #endif -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp index f8b73d8d..819757da 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp @@ -29,16 +29,19 @@ namespace Diligent size_t GLProgramResourceCache::GetRequriedMemorySize(Uint32 UBCount, Uint32 SamplerCount, Uint32 ImageCount, Uint32 SSBOCount) { + // clang-format off auto MemSize = sizeof(CachedUB) * UBCount + sizeof(CachedResourceView) * SamplerCount + sizeof(CachedResourceView) * ImageCount + sizeof(CachedSSBO) * SSBOCount; + // clang-format on return MemSize; } void GLProgramResourceCache::Initialize(Uint32 UBCount, Uint32 SamplerCount, Uint32 ImageCount, Uint32 SSBOCount, class IMemoryAllocator& MemAllocator) { + // clang-format off m_SmplrsOffset = static_cast<Uint16>(m_UBsOffset + sizeof(CachedUB) * UBCount); m_ImgsOffset = static_cast<Uint16>(m_SmplrsOffset + sizeof(CachedResourceView) * SamplerCount); m_SSBOsOffset = static_cast<Uint16>(m_ImgsOffset + sizeof(CachedResourceView) * ImageCount); @@ -48,16 +51,17 @@ void GLProgramResourceCache::Initialize(Uint32 UBCount, Uint32 SamplerCount, Uin VERIFY_EXPR(GetSamplerCount() == static_cast<Uint32>(SamplerCount)); VERIFY_EXPR(GetImageCount() == static_cast<Uint32>(ImageCount)); VERIFY_EXPR(GetSSBOCount() == static_cast<Uint32>(SSBOCount)); + // clang-format on VERIFY_EXPR(m_pResourceData == nullptr); - size_t BufferSize = m_MemoryEndOffset; + size_t BufferSize = m_MemoryEndOffset; VERIFY_EXPR(BufferSize == GetRequriedMemorySize(UBCount, SamplerCount, ImageCount, SSBOCount)); #ifdef _DEBUG m_pdbgMemoryAllocator = &MemAllocator; #endif - if( BufferSize > 0 ) + if (BufferSize > 0) { m_pResourceData = ALLOCATE(MemAllocator, "Shader resource cache data buffer", Uint8, BufferSize); memset(m_pResourceData, 0, BufferSize); @@ -65,27 +69,27 @@ void GLProgramResourceCache::Initialize(Uint32 UBCount, Uint32 SamplerCount, Uin // Explicitly construct all objects for (Uint32 cb = 0; cb < UBCount; ++cb) - new(&GetUB(cb)) CachedUB; + new (&GetUB(cb)) CachedUB; for (Uint32 s = 0; s < SamplerCount; ++s) - new(&GetSampler(s)) CachedResourceView; + new (&GetSampler(s)) CachedResourceView; for (Uint32 i = 0; i < ImageCount; ++i) - new(&GetImage(i)) CachedResourceView; - + new (&GetImage(i)) CachedResourceView; + for (Uint32 s = 0; s < SSBOCount; ++s) - new(&GetSSBO(s)) CachedSSBO; + new (&GetSSBO(s)) CachedSSBO; } GLProgramResourceCache::~GLProgramResourceCache() { - VERIFY( !IsInitialized(), "Shader resource cache memory must be released with GLProgramResourceCache::Destroy()" ); + VERIFY(!IsInitialized(), "Shader resource cache memory must be released with GLProgramResourceCache::Destroy()"); } void GLProgramResourceCache::Destroy(class IMemoryAllocator& MemAllocator) { - VERIFY( IsInitialized(), "Resource cache is not initialized"); - VERIFY( m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources"); + VERIFY(IsInitialized(), "Resource cache is not initialized"); + VERIFY(m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources"); for (Uint32 cb = 0; cb < GetUBCount(); ++cb) GetUB(cb).~CachedUB(); @@ -95,18 +99,18 @@ void GLProgramResourceCache::Destroy(class IMemoryAllocator& MemAllocator) for (Uint32 i = 0; i < GetImageCount(); ++i) GetImage(i).~CachedResourceView(); - + for (Uint32 s = 0; s < GetSSBOCount(); ++s) GetSSBO(s).~CachedSSBO(); if (m_pResourceData != nullptr) MemAllocator.Free(m_pResourceData); - m_pResourceData = nullptr; + m_pResourceData = nullptr; m_SmplrsOffset = InvalidResourceOffset; m_ImgsOffset = InvalidResourceOffset; m_SSBOsOffset = InvalidResourceOffset; m_MemoryEndOffset = InvalidResourceOffset; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp index dc8d5aec..d9b36154 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp @@ -33,7 +33,8 @@ namespace Diligent { -GLProgramResources::GLProgramResources(GLProgramResources&& Program)noexcept : +GLProgramResources::GLProgramResources(GLProgramResources&& Program) noexcept : + // clang-format off m_ShaderStages {Program.m_ShaderStages }, m_UniformBuffers {Program.m_UniformBuffers }, m_Samplers {Program.m_Samplers }, @@ -44,6 +45,7 @@ GLProgramResources::GLProgramResources(GLProgramResources&& Program)noexcept : m_NumSamplers {Program.m_NumSamplers }, m_NumImages {Program.m_NumImages }, m_NumStorageBlocks {Program.m_NumStorageBlocks } +// clang-format on { Program.m_UniformBuffers = nullptr; Program.m_Samplers = nullptr; @@ -56,7 +58,7 @@ GLProgramResources::GLProgramResources(GLProgramResources&& Program)noexcept : Program.m_NumStorageBlocks = 0; } -inline void RemoveArrayBrackets(char *Str) +inline void RemoveArrayBrackets(char* Str) { auto* OpenBacketPtr = strchr(Str, '['); if (OpenBacketPtr != nullptr) @@ -98,12 +100,14 @@ void GLProgramResources::AllocateResources(std::vector<UniformBufferInfo>& Unifo auto AlignedStringPoolDataSize = Align(StringPoolDataSize, sizeof(void*)); + // clang-format off size_t TotalMemorySize = m_NumUniformBuffers * sizeof(UniformBufferInfo) + m_NumSamplers * sizeof(SamplerInfo) + m_NumImages * sizeof(ImageInfo) + m_NumStorageBlocks * sizeof(StorageBlockInfo); - + // clang-format on + if (TotalMemorySize == 0) { m_UniformBuffers = nullptr; @@ -122,36 +126,38 @@ void GLProgramResources::AllocateResources(std::vector<UniformBufferInfo>& Unifo TotalMemorySize += AlignedStringPoolDataSize * sizeof(Char); auto& MemAllocator = GetRawAllocator(); - void* RawMemory = ALLOCATE_RAW(MemAllocator, "Memory buffer for GLProgramResources", TotalMemorySize); + void* RawMemory = ALLOCATE_RAW(MemAllocator, "Memory buffer for GLProgramResources", TotalMemorySize); + // clang-format off m_UniformBuffers = reinterpret_cast<UniformBufferInfo*>(RawMemory); m_Samplers = reinterpret_cast<SamplerInfo*> (m_UniformBuffers + m_NumUniformBuffers); m_Images = reinterpret_cast<ImageInfo*> (m_Samplers + m_NumSamplers); m_StorageBlocks = reinterpret_cast<StorageBlockInfo*>(m_Images + m_NumImages); void* EndOfResourceData = m_StorageBlocks + m_NumStorageBlocks; Char* StringPoolData = reinterpret_cast<Char*>(EndOfResourceData); + // clang-format on m_StringPool.AssignMemory(StringPoolData, StringPoolDataSize); - for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) + for (Uint32 ub = 0; ub < m_NumUniformBuffers; ++ub) { auto& SrcUB = UniformBlocks[ub]; new (m_UniformBuffers + ub) UniformBufferInfo{SrcUB, m_StringPool}; } - for (Uint32 s=0; s < m_NumSamplers; ++s) + for (Uint32 s = 0; s < m_NumSamplers; ++s) { auto& SrcSam = Samplers[s]; new (m_Samplers + s) SamplerInfo{SrcSam, m_StringPool}; } - for (Uint32 img=0; img < m_NumImages; ++img) + for (Uint32 img = 0; img < m_NumImages; ++img) { auto& SrcImg = Images[img]; new (m_Images + img) ImageInfo{SrcImg, m_StringPool}; } - for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) + for (Uint32 sb = 0; sb < m_NumStorageBlocks; ++sb) { auto& SrcSB = StorageBlocks[sb]; new (m_StorageBlocks + sb) StorageBlockInfo{SrcSB, m_StringPool}; @@ -162,6 +168,7 @@ void GLProgramResources::AllocateResources(std::vector<UniformBufferInfo>& Unifo GLProgramResources::~GLProgramResources() { + // clang-format off ProcessResources( [&](UniformBufferInfo& UB) { @@ -180,6 +187,7 @@ GLProgramResources::~GLProgramResources() SB.~StorageBlockInfo(); } ); + // clang-format on void* RawMemory = m_UniformBuffers; if (RawMemory != nullptr) @@ -233,7 +241,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad //CHECK_GL_ERROR_AND_THROW("Unable to get the maximum uniform block name length\n"); if (glGetError() != GL_NO_ERROR) { - LOG_WARNING_MESSAGE( "Unable to get the maximum uniform block name length. Using 1024 as a workaround\n" ); + LOG_WARNING_MESSAGE("Unable to get the maximum uniform block name length. Using 1024 as a workaround\n"); activeUniformBlockMaxLength = 1024; } @@ -244,33 +252,33 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad if (glGetProgramInterfaceiv) { glGetProgramInterfaceiv(GLProgram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numActiveShaderStorageBlocks); - CHECK_GL_ERROR_AND_THROW( "Unable to get the number of shader storage blocks blocks\n" ); + CHECK_GL_ERROR_AND_THROW("Unable to get the number of shader storage blocks blocks\n"); // Query the maximum name length of the active shader storage block (including null terminator) GLint MaxShaderStorageBlockNameLen = 0; glGetProgramInterfaceiv(GLProgram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &MaxShaderStorageBlockNameLen); - CHECK_GL_ERROR_AND_THROW( "Unable to get the maximum shader storage block name length\n" ); - MaxNameLength = std::max( MaxNameLength, MaxShaderStorageBlockNameLen ); + CHECK_GL_ERROR_AND_THROW("Unable to get the maximum shader storage block name length\n"); + MaxNameLength = std::max(MaxNameLength, MaxShaderStorageBlockNameLen); } #endif MaxNameLength = std::max(MaxNameLength, 512); std::vector<GLchar> Name(MaxNameLength + 1); - for (int i = 0; i < numActiveUniforms; i++) + for (int i = 0; i < numActiveUniforms; i++) { - GLenum dataType = 0; - GLint size = 0; - GLint NameLen = 0; - // If one or more elements of an array are active, the name of the array is returned in 'name', - // the type is returned in 'type', and the 'size' parameter returns the highest array element index used, - // plus one, as determined by the compiler and/or linker. + GLenum dataType = 0; + GLint size = 0; + GLint NameLen = 0; + // If one or more elements of an array are active, the name of the array is returned in 'name', + // the type is returned in 'type', and the 'size' parameter returns the highest array element index used, + // plus one, as determined by the compiler and/or linker. // Only one active uniform variable will be reported for a uniform array. // Uniform variables other than arrays will have a size of 1 glGetActiveUniform(GLProgram, i, MaxNameLength, &NameLen, &size, &dataType, Name.data()); CHECK_GL_ERROR_AND_THROW("Unable to get active uniform\n"); - VERIFY(NameLen < MaxNameLength && static_cast<size_t>(NameLen) == strlen( Name.data() ), "Incorrect uniform name"); + VERIFY(NameLen < MaxNameLength && static_cast<size_t>(NameLen) == strlen(Name.data()), "Incorrect uniform name"); VERIFY(size >= 1, "Size is expected to be at least 1"); - // Note that + // Note that // glGetActiveUniform( program, index, bufSize, length, size, type, name ); // // is equivalent to @@ -280,7 +288,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[0], 1, NULL, size ); // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[1], 1, NULL, (int *)type ); // - // The latter is only available in GL 4.4 and GLES 3.1 + // The latter is only available in GL 4.4 and GLES 3.1 switch (dataType) { @@ -327,25 +335,29 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad case GL_UNSIGNED_INT_SAMPLER_BUFFER: { auto UniformLocation = glGetUniformLocation(GLProgram, Name.data()); - // Note that glGetUniformLocation(program, name) is equivalent to + // Note that glGetUniformLocation(program, name) is equivalent to // glGetProgramResourceLocation(program, GL_UNIFORM, name); // The latter is only available in GL 4.4 and GLES 3.1 - const auto ResourceType = dataType == GL_SAMPLER_BUFFER || - dataType == GL_INT_SAMPLER_BUFFER || - dataType == GL_UNSIGNED_INT_SAMPLER_BUFFER ? - SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV; + // clang-format off + const auto ResourceType = + dataType == GL_SAMPLER_BUFFER || + dataType == GL_INT_SAMPLER_BUFFER || + dataType == GL_UNSIGNED_INT_SAMPLER_BUFFER ? + SHADER_RESOURCE_TYPE_BUFFER_SRV : + SHADER_RESOURCE_TYPE_TEXTURE_SRV; + // clang-format on RemoveArrayBrackets(Name.data()); - + Samplers.emplace_back( NamesPool.emplace(Name.data()).first->c_str(), ShaderStages, ResourceType, SamplerBinding, static_cast<Uint32>(size), - UniformLocation, - dataType + UniformLocation, + dataType // ); for (GLint arr_ind = 0; arr_ind < size; ++arr_ind) @@ -393,12 +405,16 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: { - auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); + auto UniformLocation = glGetUniformLocation(GLProgram, Name.data()); - const auto ResourceType = dataType == GL_IMAGE_BUFFER || - dataType == GL_INT_IMAGE_BUFFER || - dataType == GL_UNSIGNED_INT_IMAGE_BUFFER ? - SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV; + // clang-format off + const auto ResourceType = + dataType == GL_IMAGE_BUFFER || + dataType == GL_INT_IMAGE_BUFFER || + dataType == GL_UNSIGNED_INT_IMAGE_BUFFER ? + SHADER_RESOURCE_TYPE_BUFFER_UAV : + SHADER_RESOURCE_TYPE_TEXTURE_UAV; + // clang-format on RemoveArrayBrackets(Name.data()); @@ -409,7 +425,8 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad ImageBinding, static_cast<Uint32>(size), UniformLocation, - dataType ); + dataType // + ); for (GLint arr_ind = 0; arr_ind < size; ++arr_ind) { @@ -421,8 +438,8 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad if (size > 1) { LOG_WARNING_MESSAGE("Failed to set binding for image uniform '", Name.data(), "'[", arr_ind, - "]. Expected binding: ", ImageBinding, "." - " Make sure that this binding is explicitly assigned in shader source code." + "]. Expected binding: ", ImageBinding, + ". Make sure that this binding is explicitly assigned in shader source code." " Note that if the source code is converted from HLSL and if images are only used" " by a single shader stage, then bindings automatically assigned by HLSL->GLSL" " converter will work fine."); @@ -430,8 +447,9 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad else { LOG_WARNING_MESSAGE("Failed to set binding for image uniform '", Name.data(), "'." - " Expected binding: ", ImageBinding, "." - " Make sure that this binding is explicitly assigned in shader source code." + " Expected binding: ", + ImageBinding, + ". Make sure that this binding is explicitly assigned in shader source code." " Note that if the source code is converted from HLSL and if images are only used" " by a single shader stage, then bindings automatically assigned by HLSL->GLSL" " converter will work fine."); @@ -455,7 +473,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad GLsizei NameLen = 0; glGetActiveUniformBlockName(GLProgram, i, MaxNameLength, &NameLen, Name.data()); CHECK_GL_ERROR_AND_THROW("Unable to get active uniform block name\n"); - VERIFY(NameLen < MaxNameLength && static_cast<size_t>(NameLen) == strlen( Name.data() ), "Incorrect uniform block name"); + VERIFY(NameLen < MaxNameLength && static_cast<size_t>(NameLen) == strlen(Name.data()), "Incorrect uniform block name"); // glGetActiveUniformBlockName( program, uniformBlockIndex, bufSize, length, uniformBlockName ); // is equivalent to @@ -469,12 +487,12 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad bool IsNewBlock = true; - GLint ArraySize = 1; + GLint ArraySize = 1; auto* OpenBacketPtr = strchr(Name.data(), '['); if (OpenBacketPtr != nullptr) { - auto Ind = atoi(OpenBacketPtr+1); - ArraySize = std::max(ArraySize, Ind+1); + auto Ind = atoi(OpenBacketPtr + 1); + ArraySize = std::max(ArraySize, Ind + 1); *OpenBacketPtr = 0; if (!UniformBlocks.empty()) { @@ -485,7 +503,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad ArraySize = std::max(ArraySize, static_cast<GLint>(LastBlock.ArraySize)); VERIFY(UniformBlockIndex == LastBlock.UBIndex + Ind, "Uniform block indices are expected to be continuous"); LastBlock.ArraySize = ArraySize; - IsNewBlock = false; + IsNewBlock = false; } else { @@ -505,7 +523,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, UniformBufferBinding, static_cast<Uint32>(ArraySize), - UniformBlockIndex + UniformBlockIndex // ); } @@ -519,18 +537,18 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad GLsizei Length = 0; glGetProgramResourceName(GLProgram, GL_SHADER_STORAGE_BLOCK, i, MaxNameLength, &Length, Name.data()); CHECK_GL_ERROR_AND_THROW("Unable to get shader storage block name\n"); - VERIFY( Length < MaxNameLength && static_cast<size_t>(Length) == strlen( Name.data() ), "Incorrect shader storage block name" ); + VERIFY(Length < MaxNameLength && static_cast<size_t>(Length) == strlen(Name.data()), "Incorrect shader storage block name"); auto SBIndex = glGetProgramResourceIndex(GLProgram, GL_SHADER_STORAGE_BLOCK, Name.data()); CHECK_GL_ERROR_AND_THROW("Unable to get shader storage block index\n"); - bool IsNewBlock = true; - Int32 ArraySize = 1; + bool IsNewBlock = true; + Int32 ArraySize = 1; auto* OpenBacketPtr = strchr(Name.data(), '['); if (OpenBacketPtr != nullptr) { - auto Ind = atoi(OpenBacketPtr+1); - ArraySize = std::max(ArraySize, Ind+1); + auto Ind = atoi(OpenBacketPtr + 1); + ArraySize = std::max(ArraySize, Ind + 1); *OpenBacketPtr = 0; if (!StorageBlocks.empty()) { @@ -541,14 +559,14 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad ArraySize = std::max(ArraySize, static_cast<GLint>(LastBlock.ArraySize)); VERIFY(static_cast<GLint>(SBIndex) == LastBlock.SBIndex + Ind, "Storage block indices are expected to be continuous"); LastBlock.ArraySize = ArraySize; - IsNewBlock = false; + IsNewBlock = false; } else { -#ifdef _DEBUG +# ifdef _DEBUG for (const auto& sb : StorageBlocks) VERIFY(strcmp(sb.Name, Name.data()) != 0, "Storage block with the name \"", sb.Name, "\" has already been enumerated"); -#endif +# endif } } } @@ -560,8 +578,8 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad ShaderStages, SHADER_RESOURCE_TYPE_BUFFER_UAV, StorageBufferBinding, - static_cast<Uint32>(ArraySize), - SBIndex + static_cast<Uint32>(ArraySize), + SBIndex // ); } @@ -574,8 +592,8 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad { LOG_WARNING_MESSAGE("glShaderStorageBlockBinding is not available on this device and " "the engine is unable to automatically assign shader storage block bindindg for '", - Name.data(), "' variable. Expected binding: ", StorageBufferBinding, "." - " Make sure that this binding is explicitly assigned in shader source code." + Name.data(), "' variable. Expected binding: ", StorageBufferBinding, + ". Make sure that this binding is explicitly assigned in shader source code." " Note that if the source code is converted from HLSL and if storage blocks are only used" " by a single shader stage, then bindings automatically assigned by HLSL->GLSL" " converter will work fine."); @@ -589,7 +607,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad AllocateResources(UniformBlocks, Samplers, Images, StorageBlocks); } -ShaderResourceDesc GLProgramResources::GetResourceDesc(Uint32 Index)const +ShaderResourceDesc GLProgramResources::GetResourceDesc(Uint32 Index) const { if (Index < m_NumUniformBuffers) return GetUniformBuffer(Index).GetResourceDesc(); @@ -618,8 +636,9 @@ ShaderResourceDesc GLProgramResources::GetResourceDesc(Uint32 Index)const void GLProgramResources::CountResources(const PipelineResourceLayoutDesc& ResourceLayout, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes, - ResourceCounters& Counters)const + ResourceCounters& Counters) const { + // clang-format off ProcessConstResources( [&](const GLProgramResources::UniformBufferInfo& UB) { @@ -641,15 +660,18 @@ void GLProgramResources::CountResources(const PipelineResourceLayoutDesc& Res AllowedVarTypes, NumAllowedTypes ); + // clang-format on } -bool GLProgramResources::IsCompatibleWith(const GLProgramResources& Res)const +bool GLProgramResources::IsCompatibleWith(const GLProgramResources& Res) const { + // clang-format off if (GetNumUniformBuffers() != Res.GetNumUniformBuffers() || GetNumSamplers() != Res.GetNumSamplers() || GetNumImages() != Res.GetNumImages() || GetNumStorageBlocks() != Res.GetNumStorageBlocks()) return false; + // clang-format on for (Uint32 ub = 0; ub < GetNumUniformBuffers(); ++ub) { @@ -687,10 +709,11 @@ bool GLProgramResources::IsCompatibleWith(const GLProgramResources& Res)const } -size_t GLProgramResources::GetHash()const +size_t GLProgramResources::GetHash() const { size_t hash = ComputeHash(GetNumUniformBuffers(), GetNumSamplers(), GetNumImages(), GetNumStorageBlocks()); + // clang-format off ProcessConstResources( [&](const UniformBufferInfo& UB) { @@ -709,8 +732,9 @@ size_t GLProgramResources::GetHash()const HashCombine(hash, SB.GetHash()); } ); + // clang-format on return hash; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLStubsAndroid.cpp b/Graphics/GraphicsEngineOpenGL/src/GLStubsAndroid.cpp index 1744afab..ea598f4c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLStubsAndroid.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLStubsAndroid.cpp @@ -25,6 +25,8 @@ #include "GLStubsAndroid.h" #include <EGL/egl.h> +// clang-format off + #define DECLARE_GL_FUNCTION(Func, FuncType, ...)\ FuncType Func = nullptr; \ void Func##Stub(__VA_ARGS__) \ diff --git a/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp b/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp index bfc22978..e0695410 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp @@ -33,128 +33,130 @@ class FormatToGLInternalTexFormatMap public: FormatToGLInternalTexFormatMap() { + // clang-format off // http://www.opengl.org/wiki/Image_Format - m_FmtToGLFmtMap[ TEX_FORMAT_UNKNOWN ] = 0; - - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA32_TYPELESS ] = GL_RGBA32F; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA32_FLOAT ] = GL_RGBA32F; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA32_UINT ] = GL_RGBA32UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA32_SINT ] = GL_RGBA32I; - - m_FmtToGLFmtMap[ TEX_FORMAT_RGB32_TYPELESS ] = GL_RGB32F; - m_FmtToGLFmtMap[ TEX_FORMAT_RGB32_FLOAT ] = GL_RGB32F; - m_FmtToGLFmtMap[ TEX_FORMAT_RGB32_UINT ] = GL_RGB32UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RGB32_SINT ] = GL_RGB32I; - - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA16_TYPELESS ] = GL_RGBA16F; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA16_FLOAT ] = GL_RGBA16F; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA16_UNORM ] = GL_RGBA16; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA16_UINT ] = GL_RGBA16UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA16_SNORM ] = GL_RGBA16_SNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA16_SINT ] = GL_RGBA16I; - - m_FmtToGLFmtMap[ TEX_FORMAT_RG32_TYPELESS ] = GL_RG32F; - m_FmtToGLFmtMap[ TEX_FORMAT_RG32_FLOAT ] = GL_RG32F; - m_FmtToGLFmtMap[ TEX_FORMAT_RG32_UINT ] = GL_RG32UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RG32_SINT ] = GL_RG32I; - - m_FmtToGLFmtMap[ TEX_FORMAT_R32G8X24_TYPELESS ] = GL_DEPTH32F_STENCIL8; - m_FmtToGLFmtMap[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = GL_DEPTH32F_STENCIL8; - m_FmtToGLFmtMap[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]=GL_DEPTH32F_STENCIL8; - m_FmtToGLFmtMap[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= 0;//GL_DEPTH32F_STENCIL8; - - m_FmtToGLFmtMap[ TEX_FORMAT_RGB10A2_TYPELESS ] = GL_RGB10_A2; - m_FmtToGLFmtMap[ TEX_FORMAT_RGB10A2_UNORM ] = GL_RGB10_A2; - m_FmtToGLFmtMap[ TEX_FORMAT_RGB10A2_UINT ] = GL_RGB10_A2UI; - m_FmtToGLFmtMap[ TEX_FORMAT_R11G11B10_FLOAT ] = GL_R11F_G11F_B10F; - - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA8_TYPELESS ] = GL_RGBA8; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA8_UNORM ] = GL_RGBA8; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = GL_SRGB8_ALPHA8; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA8_UINT ] = GL_RGBA8UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA8_SNORM ] = GL_RGBA8_SNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_RGBA8_SINT ] = GL_RGBA8I; - - m_FmtToGLFmtMap[ TEX_FORMAT_RG16_TYPELESS ] = GL_RG16F; - m_FmtToGLFmtMap[ TEX_FORMAT_RG16_FLOAT ] = GL_RG16F; - m_FmtToGLFmtMap[ TEX_FORMAT_RG16_UNORM ] = GL_RG16; - m_FmtToGLFmtMap[ TEX_FORMAT_RG16_UINT ] = GL_RG16UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RG16_SNORM ] = GL_RG16_SNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_RG16_SINT ] = GL_RG16I; - - m_FmtToGLFmtMap[ TEX_FORMAT_R32_TYPELESS ] = GL_R32F; - m_FmtToGLFmtMap[ TEX_FORMAT_D32_FLOAT ] = GL_DEPTH_COMPONENT32F; - m_FmtToGLFmtMap[ TEX_FORMAT_R32_FLOAT ] = GL_R32F; - m_FmtToGLFmtMap[ TEX_FORMAT_R32_UINT ] = GL_R32UI; - m_FmtToGLFmtMap[ TEX_FORMAT_R32_SINT ] = GL_R32I; - - m_FmtToGLFmtMap[ TEX_FORMAT_R24G8_TYPELESS ] = GL_DEPTH24_STENCIL8; - m_FmtToGLFmtMap[ TEX_FORMAT_D24_UNORM_S8_UINT ] = GL_DEPTH24_STENCIL8; - m_FmtToGLFmtMap[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = GL_DEPTH24_STENCIL8; - m_FmtToGLFmtMap[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = 0;//GL_DEPTH24_STENCIL8; - - m_FmtToGLFmtMap[ TEX_FORMAT_RG8_TYPELESS ] = GL_RG8; - m_FmtToGLFmtMap[ TEX_FORMAT_RG8_UNORM ] = GL_RG8; - m_FmtToGLFmtMap[ TEX_FORMAT_RG8_UINT ] = GL_RG8UI; - m_FmtToGLFmtMap[ TEX_FORMAT_RG8_SNORM ] = GL_RG8_SNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_RG8_SINT ] = GL_RG8I; - - m_FmtToGLFmtMap[ TEX_FORMAT_R16_TYPELESS ] = GL_R16F; - m_FmtToGLFmtMap[ TEX_FORMAT_R16_FLOAT ] = GL_R16F; - m_FmtToGLFmtMap[ TEX_FORMAT_D16_UNORM ] = GL_DEPTH_COMPONENT16; - m_FmtToGLFmtMap[ TEX_FORMAT_R16_UNORM ] = GL_R16; - m_FmtToGLFmtMap[ TEX_FORMAT_R16_UINT ] = GL_R16UI; - m_FmtToGLFmtMap[ TEX_FORMAT_R16_SNORM ] = GL_R16_SNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_R16_SINT ] = GL_R16I; - - m_FmtToGLFmtMap[ TEX_FORMAT_R8_TYPELESS ] = GL_R8; - m_FmtToGLFmtMap[ TEX_FORMAT_R8_UNORM ] = GL_R8; - m_FmtToGLFmtMap[ TEX_FORMAT_R8_UINT ] = GL_R8UI; - m_FmtToGLFmtMap[ TEX_FORMAT_R8_SNORM ] = GL_R8_SNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_R8_SINT ] = GL_R8I; - m_FmtToGLFmtMap[ TEX_FORMAT_A8_UNORM ] = 0; - - m_FmtToGLFmtMap[ TEX_FORMAT_R1_UNORM ] = 0; - - m_FmtToGLFmtMap[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = GL_RGB9_E5; - m_FmtToGLFmtMap[ TEX_FORMAT_RG8_B8G8_UNORM ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_G8R8_G8B8_UNORM ] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_UNKNOWN] = 0; + + m_FmtToGLFmtMap[TEX_FORMAT_RGBA32_TYPELESS] = GL_RGBA32F; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA32_FLOAT] = GL_RGBA32F; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA32_UINT] = GL_RGBA32UI; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA32_SINT] = GL_RGBA32I; + + m_FmtToGLFmtMap[TEX_FORMAT_RGB32_TYPELESS] = GL_RGB32F; + m_FmtToGLFmtMap[TEX_FORMAT_RGB32_FLOAT] = GL_RGB32F; + m_FmtToGLFmtMap[TEX_FORMAT_RGB32_UINT] = GL_RGB32UI; + m_FmtToGLFmtMap[TEX_FORMAT_RGB32_SINT] = GL_RGB32I; + + m_FmtToGLFmtMap[TEX_FORMAT_RGBA16_TYPELESS] = GL_RGBA16F; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA16_FLOAT] = GL_RGBA16F; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA16_UNORM] = GL_RGBA16; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA16_UINT] = GL_RGBA16UI; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA16_SNORM] = GL_RGBA16_SNORM; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA16_SINT] = GL_RGBA16I; + + m_FmtToGLFmtMap[TEX_FORMAT_RG32_TYPELESS] = GL_RG32F; + m_FmtToGLFmtMap[TEX_FORMAT_RG32_FLOAT] = GL_RG32F; + m_FmtToGLFmtMap[TEX_FORMAT_RG32_UINT] = GL_RG32UI; + m_FmtToGLFmtMap[TEX_FORMAT_RG32_SINT] = GL_RG32I; + + m_FmtToGLFmtMap[TEX_FORMAT_R32G8X24_TYPELESS] = GL_DEPTH32F_STENCIL8; + m_FmtToGLFmtMap[TEX_FORMAT_D32_FLOAT_S8X24_UINT] = GL_DEPTH32F_STENCIL8; + m_FmtToGLFmtMap[TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS]=GL_DEPTH32F_STENCIL8; + m_FmtToGLFmtMap[TEX_FORMAT_X32_TYPELESS_G8X24_UINT]= 0;//GL_DEPTH32F_STENCIL8; + + m_FmtToGLFmtMap[TEX_FORMAT_RGB10A2_TYPELESS] = GL_RGB10_A2; + m_FmtToGLFmtMap[TEX_FORMAT_RGB10A2_UNORM] = GL_RGB10_A2; + m_FmtToGLFmtMap[TEX_FORMAT_RGB10A2_UINT] = GL_RGB10_A2UI; + m_FmtToGLFmtMap[TEX_FORMAT_R11G11B10_FLOAT] = GL_R11F_G11F_B10F; + + m_FmtToGLFmtMap[TEX_FORMAT_RGBA8_TYPELESS] = GL_RGBA8; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA8_UNORM] = GL_RGBA8; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA8_UNORM_SRGB] = GL_SRGB8_ALPHA8; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA8_UINT] = GL_RGBA8UI; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA8_SNORM] = GL_RGBA8_SNORM; + m_FmtToGLFmtMap[TEX_FORMAT_RGBA8_SINT] = GL_RGBA8I; + + m_FmtToGLFmtMap[TEX_FORMAT_RG16_TYPELESS] = GL_RG16F; + m_FmtToGLFmtMap[TEX_FORMAT_RG16_FLOAT] = GL_RG16F; + m_FmtToGLFmtMap[TEX_FORMAT_RG16_UNORM] = GL_RG16; + m_FmtToGLFmtMap[TEX_FORMAT_RG16_UINT] = GL_RG16UI; + m_FmtToGLFmtMap[TEX_FORMAT_RG16_SNORM] = GL_RG16_SNORM; + m_FmtToGLFmtMap[TEX_FORMAT_RG16_SINT] = GL_RG16I; + + m_FmtToGLFmtMap[TEX_FORMAT_R32_TYPELESS] = GL_R32F; + m_FmtToGLFmtMap[TEX_FORMAT_D32_FLOAT] = GL_DEPTH_COMPONENT32F; + m_FmtToGLFmtMap[TEX_FORMAT_R32_FLOAT] = GL_R32F; + m_FmtToGLFmtMap[TEX_FORMAT_R32_UINT] = GL_R32UI; + m_FmtToGLFmtMap[TEX_FORMAT_R32_SINT] = GL_R32I; + + m_FmtToGLFmtMap[TEX_FORMAT_R24G8_TYPELESS] = GL_DEPTH24_STENCIL8; + m_FmtToGLFmtMap[TEX_FORMAT_D24_UNORM_S8_UINT] = GL_DEPTH24_STENCIL8; + m_FmtToGLFmtMap[TEX_FORMAT_R24_UNORM_X8_TYPELESS] = GL_DEPTH24_STENCIL8; + m_FmtToGLFmtMap[TEX_FORMAT_X24_TYPELESS_G8_UINT] = 0;//GL_DEPTH24_STENCIL8; + + m_FmtToGLFmtMap[TEX_FORMAT_RG8_TYPELESS] = GL_RG8; + m_FmtToGLFmtMap[TEX_FORMAT_RG8_UNORM] = GL_RG8; + m_FmtToGLFmtMap[TEX_FORMAT_RG8_UINT] = GL_RG8UI; + m_FmtToGLFmtMap[TEX_FORMAT_RG8_SNORM] = GL_RG8_SNORM; + m_FmtToGLFmtMap[TEX_FORMAT_RG8_SINT] = GL_RG8I; + + m_FmtToGLFmtMap[TEX_FORMAT_R16_TYPELESS] = GL_R16F; + m_FmtToGLFmtMap[TEX_FORMAT_R16_FLOAT] = GL_R16F; + m_FmtToGLFmtMap[TEX_FORMAT_D16_UNORM] = GL_DEPTH_COMPONENT16; + m_FmtToGLFmtMap[TEX_FORMAT_R16_UNORM] = GL_R16; + m_FmtToGLFmtMap[TEX_FORMAT_R16_UINT] = GL_R16UI; + m_FmtToGLFmtMap[TEX_FORMAT_R16_SNORM] = GL_R16_SNORM; + m_FmtToGLFmtMap[TEX_FORMAT_R16_SINT] = GL_R16I; + + m_FmtToGLFmtMap[TEX_FORMAT_R8_TYPELESS] = GL_R8; + m_FmtToGLFmtMap[TEX_FORMAT_R8_UNORM] = GL_R8; + m_FmtToGLFmtMap[TEX_FORMAT_R8_UINT] = GL_R8UI; + m_FmtToGLFmtMap[TEX_FORMAT_R8_SNORM] = GL_R8_SNORM; + m_FmtToGLFmtMap[TEX_FORMAT_R8_SINT] = GL_R8I; + m_FmtToGLFmtMap[TEX_FORMAT_A8_UNORM] = 0; + + m_FmtToGLFmtMap[TEX_FORMAT_R1_UNORM] = 0; + + m_FmtToGLFmtMap[TEX_FORMAT_RGB9E5_SHAREDEXP] = GL_RGB9_E5; + m_FmtToGLFmtMap[TEX_FORMAT_RG8_B8G8_UNORM] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_G8R8_G8B8_UNORM] = 0; // http://www.g-truc.net/post-0335.html // http://renderingpipeline.com/2012/07/texture-compression/ - m_FmtToGLFmtMap[ TEX_FORMAT_BC1_TYPELESS ] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC1_UNORM ] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC1_UNORM_SRGB ] = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC2_TYPELESS ] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC2_UNORM ] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC2_UNORM_SRGB ] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC3_TYPELESS ] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC3_UNORM ] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC3_UNORM_SRGB ] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC4_TYPELESS ] = GL_COMPRESSED_RED_RGTC1; - m_FmtToGLFmtMap[ TEX_FORMAT_BC4_UNORM ] = GL_COMPRESSED_RED_RGTC1; - m_FmtToGLFmtMap[ TEX_FORMAT_BC4_SNORM ] = GL_COMPRESSED_SIGNED_RED_RGTC1; - m_FmtToGLFmtMap[ TEX_FORMAT_BC5_TYPELESS ] = GL_COMPRESSED_RG_RGTC2; - m_FmtToGLFmtMap[ TEX_FORMAT_BC5_UNORM ] = GL_COMPRESSED_RG_RGTC2; - m_FmtToGLFmtMap[ TEX_FORMAT_BC5_SNORM ] = GL_COMPRESSED_SIGNED_RG_RGTC2; - m_FmtToGLFmtMap[ TEX_FORMAT_B5G6R5_UNORM ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_B5G5R5A1_UNORM ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BGRA8_UNORM ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BGRX8_UNORM ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BGRA8_TYPELESS ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BGRX8_TYPELESS ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = 0; - m_FmtToGLFmtMap[ TEX_FORMAT_BC6H_TYPELESS ] = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC6H_UF16 ] = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC6H_SF16 ] = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; - m_FmtToGLFmtMap[ TEX_FORMAT_BC7_TYPELESS ] = GL_COMPRESSED_RGBA_BPTC_UNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_BC7_UNORM ] = GL_COMPRESSED_RGBA_BPTC_UNORM; - m_FmtToGLFmtMap[ TEX_FORMAT_BC7_UNORM_SRGB ] = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; + m_FmtToGLFmtMap[TEX_FORMAT_BC1_TYPELESS] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC1_UNORM] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC1_UNORM_SRGB] = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC2_TYPELESS] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC2_UNORM] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC2_UNORM_SRGB] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC3_TYPELESS] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC3_UNORM] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC3_UNORM_SRGB] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + m_FmtToGLFmtMap[TEX_FORMAT_BC4_TYPELESS] = GL_COMPRESSED_RED_RGTC1; + m_FmtToGLFmtMap[TEX_FORMAT_BC4_UNORM] = GL_COMPRESSED_RED_RGTC1; + m_FmtToGLFmtMap[TEX_FORMAT_BC4_SNORM] = GL_COMPRESSED_SIGNED_RED_RGTC1; + m_FmtToGLFmtMap[TEX_FORMAT_BC5_TYPELESS] = GL_COMPRESSED_RG_RGTC2; + m_FmtToGLFmtMap[TEX_FORMAT_BC5_UNORM] = GL_COMPRESSED_RG_RGTC2; + m_FmtToGLFmtMap[TEX_FORMAT_BC5_SNORM] = GL_COMPRESSED_SIGNED_RG_RGTC2; + m_FmtToGLFmtMap[TEX_FORMAT_B5G6R5_UNORM] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_B5G5R5A1_UNORM] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BGRA8_UNORM] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BGRX8_UNORM] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BGRA8_TYPELESS] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BGRA8_UNORM_SRGB] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BGRX8_TYPELESS] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BGRX8_UNORM_SRGB] = 0; + m_FmtToGLFmtMap[TEX_FORMAT_BC6H_TYPELESS] = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + m_FmtToGLFmtMap[TEX_FORMAT_BC6H_UF16] = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + m_FmtToGLFmtMap[TEX_FORMAT_BC6H_SF16] = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; + m_FmtToGLFmtMap[TEX_FORMAT_BC7_TYPELESS] = GL_COMPRESSED_RGBA_BPTC_UNORM; + m_FmtToGLFmtMap[TEX_FORMAT_BC7_UNORM] = GL_COMPRESSED_RGBA_BPTC_UNORM; + m_FmtToGLFmtMap[TEX_FORMAT_BC7_UNORM_SRGB] = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; + // clang-format on } - GLenum operator[](TEXTURE_FORMAT TexFormat)const + GLenum operator[](TEXTURE_FORMAT TexFormat) const { VERIFY_EXPR(TexFormat < _countof(m_FmtToGLFmtMap)); return m_FmtToGLFmtMap[TexFormat]; @@ -167,16 +169,16 @@ private: GLenum TexFormatToGLInternalTexFormat(TEXTURE_FORMAT TexFormat, Uint32 BindFlags) { static const FormatToGLInternalTexFormatMap FormatMap; - if( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) + if (TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS) { auto GLFormat = FormatMap[TexFormat]; - if( BindFlags != 0 ) - GLFormat = CorrectGLTexFormat( GLFormat, BindFlags ); + if (BindFlags != 0) + GLFormat = CorrectGLTexFormat(GLFormat, BindFlags); return GLFormat; } else { - UNEXPECTED( "Texture format (", int{TexFormat}, ") out of allowed range [0, ", int{TEX_FORMAT_NUM_FORMATS}-1, "]" ); + UNEXPECTED("Texture format (", int{TexFormat}, ") out of allowed range [0, ", int{TEX_FORMAT_NUM_FORMATS} - 1, "]"); return 0; } } @@ -186,20 +188,22 @@ class InternalTexFormatToTexFormatMap public: InternalTexFormatToTexFormatMap() { - for (TEXTURE_FORMAT TexFmt = TEX_FORMAT_UNKNOWN; TexFmt < TEX_FORMAT_NUM_FORMATS; TexFmt = static_cast<TEXTURE_FORMAT>(static_cast<int>(TexFmt) + 1) ) + for (TEXTURE_FORMAT TexFmt = TEX_FORMAT_UNKNOWN; TexFmt < TEX_FORMAT_NUM_FORMATS; TexFmt = static_cast<TEXTURE_FORMAT>(static_cast<int>(TexFmt) + 1)) { auto ComponentType = GetTextureFormatAttribs(TexFmt).ComponentType; - if ( ComponentType == COMPONENT_TYPE_UNDEFINED || - ComponentType == COMPONENT_TYPE_DEPTH_STENCIL || - TexFmt == TEX_FORMAT_RGB10A2_TYPELESS || - TexFmt == TEX_FORMAT_BC1_TYPELESS || - TexFmt == TEX_FORMAT_BC2_TYPELESS || - TexFmt == TEX_FORMAT_BC3_TYPELESS || - TexFmt == TEX_FORMAT_BC4_TYPELESS || - TexFmt == TEX_FORMAT_BC5_TYPELESS || - TexFmt == TEX_FORMAT_BC6H_TYPELESS || - TexFmt == TEX_FORMAT_BC7_TYPELESS) + // clang-format off + if (ComponentType == COMPONENT_TYPE_UNDEFINED || + ComponentType == COMPONENT_TYPE_DEPTH_STENCIL || + TexFmt == TEX_FORMAT_RGB10A2_TYPELESS || + TexFmt == TEX_FORMAT_BC1_TYPELESS || + TexFmt == TEX_FORMAT_BC2_TYPELESS || + TexFmt == TEX_FORMAT_BC3_TYPELESS || + TexFmt == TEX_FORMAT_BC4_TYPELESS || + TexFmt == TEX_FORMAT_BC5_TYPELESS || + TexFmt == TEX_FORMAT_BC6H_TYPELESS || + TexFmt == TEX_FORMAT_BC7_TYPELESS) continue; // Skip typeless and depth-stencil formats + // clang-format on auto GlTexFormat = TexFormatToGLInternalTexFormat(TexFmt); if (GlTexFormat != 0) { @@ -207,11 +211,11 @@ public: m_FormatMap[GlTexFormat] = TexFmt; } m_FormatMap[TexFormatToGLInternalTexFormat(TEX_FORMAT_D32_FLOAT_S8X24_UINT)] = TEX_FORMAT_D32_FLOAT_S8X24_UINT; - m_FormatMap[TexFormatToGLInternalTexFormat(TEX_FORMAT_D24_UNORM_S8_UINT)] = TEX_FORMAT_D24_UNORM_S8_UINT; + m_FormatMap[TexFormatToGLInternalTexFormat(TEX_FORMAT_D24_UNORM_S8_UINT)] = TEX_FORMAT_D24_UNORM_S8_UINT; } } - TEXTURE_FORMAT operator[](GLenum GlFormat)const + TEXTURE_FORMAT operator[](GLenum GlFormat) const { auto formatIt = m_FormatMap.find(GlFormat); if (formatIt != m_FormatMap.end()) @@ -236,13 +240,13 @@ TEXTURE_FORMAT GLInternalTexFormatToTexFormat(GLenum GlFormat) return FormatMap[GlFormat]; } -GLenum CorrectGLTexFormat( GLenum GLTexFormat, Uint32 BindFlags ) +GLenum CorrectGLTexFormat(GLenum GLTexFormat, Uint32 BindFlags) { - if( BindFlags & BIND_DEPTH_STENCIL ) + if (BindFlags & BIND_DEPTH_STENCIL) { - if( GLTexFormat == GL_R32F ) + if (GLTexFormat == GL_R32F) GLTexFormat = GL_DEPTH_COMPONENT32F; - if( GLTexFormat == GL_R16 ) + if (GLTexFormat == GL_R16) GLTexFormat = GL_DEPTH_COMPONENT16; } return GLTexFormat; @@ -252,416 +256,417 @@ NativePixelAttribs GetNativePixelTransferAttribs(TEXTURE_FORMAT TexFormat) { // http://www.opengl.org/wiki/Pixel_Transfer - static Bool bAttribsMapIntialized = false; + static Bool bAttribsMapIntialized = false; static NativePixelAttribs FmtToGLPixelFmt[TEX_FORMAT_NUM_FORMATS]; - if( !bAttribsMapIntialized) + if (!bAttribsMapIntialized) { + // clang-format off // http://www.opengl.org/wiki/Image_Format - FmtToGLPixelFmt[ TEX_FORMAT_UNKNOWN ] = NativePixelAttribs(); - - FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_FLOAT ] = NativePixelAttribs(GL_RGBA, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_INT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA32_SINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_INT); - - FmtToGLPixelFmt[ TEX_FORMAT_RGB32_TYPELESS ] = NativePixelAttribs(GL_RGB, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RGB32_FLOAT ] = NativePixelAttribs(GL_RGB, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RGB32_UINT ] = NativePixelAttribs(GL_RGB_INTEGER, GL_UNSIGNED_INT); - FmtToGLPixelFmt[ TEX_FORMAT_RGB32_SINT ] = NativePixelAttribs(GL_RGB_INTEGER, GL_INT); - - FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_HALF_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_FLOAT ] = NativePixelAttribs(GL_RGBA, GL_HALF_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_UNORM ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_SNORM ] = NativePixelAttribs(GL_RGBA, GL_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA16_SINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_SHORT); - - FmtToGLPixelFmt[ TEX_FORMAT_RG32_TYPELESS ] = NativePixelAttribs(GL_RG, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RG32_FLOAT ] = NativePixelAttribs(GL_RG, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RG32_UINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_INT); - FmtToGLPixelFmt[ TEX_FORMAT_RG32_SINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_INT); - - FmtToGLPixelFmt[ TEX_FORMAT_R32G8X24_TYPELESS ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - FmtToGLPixelFmt[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - FmtToGLPixelFmt[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]=NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - FmtToGLPixelFmt[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[TEX_FORMAT_UNKNOWN] = NativePixelAttribs(); + + FmtToGLPixelFmt[TEX_FORMAT_RGBA32_TYPELESS] = NativePixelAttribs(GL_RGBA, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA32_FLOAT] = NativePixelAttribs(GL_RGBA, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA32_UINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA32_SINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_INT); + + FmtToGLPixelFmt[TEX_FORMAT_RGB32_TYPELESS] = NativePixelAttribs(GL_RGB, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RGB32_FLOAT] = NativePixelAttribs(GL_RGB, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RGB32_UINT] = NativePixelAttribs(GL_RGB_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[TEX_FORMAT_RGB32_SINT] = NativePixelAttribs(GL_RGB_INTEGER, GL_INT); + + FmtToGLPixelFmt[TEX_FORMAT_RGBA16_TYPELESS] = NativePixelAttribs(GL_RGBA, GL_HALF_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA16_FLOAT] = NativePixelAttribs(GL_RGBA, GL_HALF_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA16_UNORM] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA16_UINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA16_SNORM] = NativePixelAttribs(GL_RGBA, GL_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_RGBA16_SINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_SHORT); + + FmtToGLPixelFmt[TEX_FORMAT_RG32_TYPELESS] = NativePixelAttribs(GL_RG, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RG32_FLOAT] = NativePixelAttribs(GL_RG, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RG32_UINT] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[TEX_FORMAT_RG32_SINT] = NativePixelAttribs(GL_RG_INTEGER, GL_INT); + + FmtToGLPixelFmt[TEX_FORMAT_R32G8X24_TYPELESS] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[TEX_FORMAT_D32_FLOAT_S8X24_UINT] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS]=NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + FmtToGLPixelFmt[TEX_FORMAT_X32_TYPELESS_G8X24_UINT]= NativePixelAttribs(GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); // Components are normally packed with the first component in the most significant // bits of the bitfield, and successive component occupying progressively less // significant locations.Types whose token names end with _REV reverse the component // packing order from least to most significant locations. - FmtToGLPixelFmt[ TEX_FORMAT_RGB10A2_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV); - FmtToGLPixelFmt[ TEX_FORMAT_RGB10A2_UNORM ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV); - FmtToGLPixelFmt[ TEX_FORMAT_RGB10A2_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV); - FmtToGLPixelFmt[ TEX_FORMAT_R11G11B10_FLOAT ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV); - - FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_TYPELESS ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_UNORM ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_UINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_SNORM ] = NativePixelAttribs(GL_RGBA, GL_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RGBA8_SINT ] = NativePixelAttribs(GL_RGBA_INTEGER, GL_BYTE); - - FmtToGLPixelFmt[ TEX_FORMAT_RG16_TYPELESS ] = NativePixelAttribs(GL_RG, GL_HALF_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RG16_FLOAT ] = NativePixelAttribs(GL_RG, GL_HALF_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_RG16_UNORM ] = NativePixelAttribs(GL_RG, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_RG16_UINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_RG16_SNORM ] = NativePixelAttribs(GL_RG, GL_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_RG16_SINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_SHORT); - - FmtToGLPixelFmt[ TEX_FORMAT_R32_TYPELESS ] = NativePixelAttribs(GL_RED, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_D32_FLOAT ] = NativePixelAttribs(GL_DEPTH_COMPONENT, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_R32_FLOAT ] = NativePixelAttribs(GL_RED, GL_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_R32_UINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_INT); - FmtToGLPixelFmt[ TEX_FORMAT_R32_SINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_INT); - - FmtToGLPixelFmt[ TEX_FORMAT_R24G8_TYPELESS ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); - FmtToGLPixelFmt[ TEX_FORMAT_D24_UNORM_S8_UINT ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); - FmtToGLPixelFmt[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); - FmtToGLPixelFmt[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); - - FmtToGLPixelFmt[ TEX_FORMAT_RG8_TYPELESS ] = NativePixelAttribs(GL_RG, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RG8_UNORM ] = NativePixelAttribs(GL_RG, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RG8_UINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RG8_SNORM ] = NativePixelAttribs(GL_RG, GL_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_RG8_SINT ] = NativePixelAttribs(GL_RG_INTEGER, GL_BYTE); - - FmtToGLPixelFmt[ TEX_FORMAT_R16_TYPELESS ] = NativePixelAttribs(GL_RED, GL_HALF_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_R16_FLOAT ] = NativePixelAttribs(GL_RED, GL_HALF_FLOAT); - FmtToGLPixelFmt[ TEX_FORMAT_D16_UNORM ] = NativePixelAttribs(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_R16_UNORM ] = NativePixelAttribs(GL_RED, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_R16_UINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_R16_SNORM ] = NativePixelAttribs(GL_RED, GL_SHORT); - FmtToGLPixelFmt[ TEX_FORMAT_R16_SINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_SHORT); - - FmtToGLPixelFmt[ TEX_FORMAT_R8_TYPELESS ] = NativePixelAttribs(GL_RED, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_R8_UNORM ] = NativePixelAttribs(GL_RED, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_R8_UINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_R8_SNORM ] = NativePixelAttribs(GL_RED, GL_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_R8_SINT ] = NativePixelAttribs(GL_RED_INTEGER, GL_BYTE); - FmtToGLPixelFmt[ TEX_FORMAT_A8_UNORM ] = NativePixelAttribs(); - - FmtToGLPixelFmt[ TEX_FORMAT_R1_UNORM ] = NativePixelAttribs(); - - FmtToGLPixelFmt[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV); - FmtToGLPixelFmt[ TEX_FORMAT_RG8_B8G8_UNORM ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_G8R8_G8B8_UNORM ] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_RGB10A2_TYPELESS] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV); + FmtToGLPixelFmt[TEX_FORMAT_RGB10A2_UNORM] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV); + FmtToGLPixelFmt[TEX_FORMAT_RGB10A2_UINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV); + FmtToGLPixelFmt[TEX_FORMAT_R11G11B10_FLOAT] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV); + + FmtToGLPixelFmt[TEX_FORMAT_RGBA8_TYPELESS] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RGBA8_UNORM] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RGBA8_UNORM_SRGB] = NativePixelAttribs(GL_RGBA, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RGBA8_UINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RGBA8_SNORM] = NativePixelAttribs(GL_RGBA, GL_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RGBA8_SINT] = NativePixelAttribs(GL_RGBA_INTEGER, GL_BYTE); + + FmtToGLPixelFmt[TEX_FORMAT_RG16_TYPELESS] = NativePixelAttribs(GL_RG, GL_HALF_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RG16_FLOAT] = NativePixelAttribs(GL_RG, GL_HALF_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_RG16_UNORM] = NativePixelAttribs(GL_RG, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_RG16_UINT] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_RG16_SNORM] = NativePixelAttribs(GL_RG, GL_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_RG16_SINT] = NativePixelAttribs(GL_RG_INTEGER, GL_SHORT); + + FmtToGLPixelFmt[TEX_FORMAT_R32_TYPELESS] = NativePixelAttribs(GL_RED, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_D32_FLOAT] = NativePixelAttribs(GL_DEPTH_COMPONENT, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_R32_FLOAT] = NativePixelAttribs(GL_RED, GL_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_R32_UINT] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_INT); + FmtToGLPixelFmt[TEX_FORMAT_R32_SINT] = NativePixelAttribs(GL_RED_INTEGER, GL_INT); + + FmtToGLPixelFmt[TEX_FORMAT_R24G8_TYPELESS] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + FmtToGLPixelFmt[TEX_FORMAT_D24_UNORM_S8_UINT] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + FmtToGLPixelFmt[TEX_FORMAT_R24_UNORM_X8_TYPELESS] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + FmtToGLPixelFmt[TEX_FORMAT_X24_TYPELESS_G8_UINT] = NativePixelAttribs(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + + FmtToGLPixelFmt[TEX_FORMAT_RG8_TYPELESS] = NativePixelAttribs(GL_RG, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RG8_UNORM] = NativePixelAttribs(GL_RG, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RG8_UINT] = NativePixelAttribs(GL_RG_INTEGER, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RG8_SNORM] = NativePixelAttribs(GL_RG, GL_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_RG8_SINT] = NativePixelAttribs(GL_RG_INTEGER, GL_BYTE); + + FmtToGLPixelFmt[TEX_FORMAT_R16_TYPELESS] = NativePixelAttribs(GL_RED, GL_HALF_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_R16_FLOAT] = NativePixelAttribs(GL_RED, GL_HALF_FLOAT); + FmtToGLPixelFmt[TEX_FORMAT_D16_UNORM] = NativePixelAttribs(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_R16_UNORM] = NativePixelAttribs(GL_RED, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_R16_UINT] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_R16_SNORM] = NativePixelAttribs(GL_RED, GL_SHORT); + FmtToGLPixelFmt[TEX_FORMAT_R16_SINT] = NativePixelAttribs(GL_RED_INTEGER, GL_SHORT); + + FmtToGLPixelFmt[TEX_FORMAT_R8_TYPELESS] = NativePixelAttribs(GL_RED, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_R8_UNORM] = NativePixelAttribs(GL_RED, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_R8_UINT] = NativePixelAttribs(GL_RED_INTEGER, GL_UNSIGNED_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_R8_SNORM] = NativePixelAttribs(GL_RED, GL_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_R8_SINT] = NativePixelAttribs(GL_RED_INTEGER, GL_BYTE); + FmtToGLPixelFmt[TEX_FORMAT_A8_UNORM] = NativePixelAttribs(); + + FmtToGLPixelFmt[TEX_FORMAT_R1_UNORM] = NativePixelAttribs(); + + FmtToGLPixelFmt[TEX_FORMAT_RGB9E5_SHAREDEXP] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV); + FmtToGLPixelFmt[TEX_FORMAT_RG8_B8G8_UNORM] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_G8R8_G8B8_UNORM] = NativePixelAttribs(); // http://www.g-truc.net/post-0335.html // http://renderingpipeline.com/2012/07/texture-compression/ - FmtToGLPixelFmt[ TEX_FORMAT_BC1_TYPELESS ] = NativePixelAttribs(GL_RGB, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC1_UNORM ] = NativePixelAttribs(GL_RGB, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC1_UNORM_SRGB ] = NativePixelAttribs(GL_RGB, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC2_TYPELESS ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC2_UNORM ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC2_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC3_TYPELESS ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC3_UNORM ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC3_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC4_TYPELESS ] = NativePixelAttribs(GL_RED, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC4_UNORM ] = NativePixelAttribs(GL_RED, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC4_SNORM ] = NativePixelAttribs(GL_RED, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC5_TYPELESS ] = NativePixelAttribs(GL_RG, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC5_UNORM ] = NativePixelAttribs(GL_RG, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC5_SNORM ] = NativePixelAttribs(GL_RG, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_B5G6R5_UNORM ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV); - FmtToGLPixelFmt[ TEX_FORMAT_B5G5R5A1_UNORM ] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_SHORT_1_5_5_5_REV); - FmtToGLPixelFmt[ TEX_FORMAT_BGRA8_UNORM ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_BGRX8_UNORM ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_BGRA8_TYPELESS ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_BGRX8_TYPELESS ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = NativePixelAttribs(); - FmtToGLPixelFmt[ TEX_FORMAT_BC6H_TYPELESS ] = NativePixelAttribs(GL_RGB, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC6H_UF16 ] = NativePixelAttribs(GL_RGB, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC6H_SF16 ] = NativePixelAttribs(GL_RGB, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC7_TYPELESS ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC7_UNORM ] = NativePixelAttribs(GL_RGBA, 0, True); - FmtToGLPixelFmt[ TEX_FORMAT_BC7_UNORM_SRGB ] = NativePixelAttribs(GL_RGBA, 0, True); - + FmtToGLPixelFmt[TEX_FORMAT_BC1_TYPELESS] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC1_UNORM] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC1_UNORM_SRGB] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC2_TYPELESS] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC2_UNORM] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC2_UNORM_SRGB] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC3_TYPELESS] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC3_UNORM] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC3_UNORM_SRGB] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC4_TYPELESS] = NativePixelAttribs(GL_RED, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC4_UNORM] = NativePixelAttribs(GL_RED, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC4_SNORM] = NativePixelAttribs(GL_RED, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC5_TYPELESS] = NativePixelAttribs(GL_RG, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC5_UNORM] = NativePixelAttribs(GL_RG, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC5_SNORM] = NativePixelAttribs(GL_RG, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_B5G6R5_UNORM] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV); + FmtToGLPixelFmt[TEX_FORMAT_B5G5R5A1_UNORM] = NativePixelAttribs(GL_RGB, GL_UNSIGNED_SHORT_1_5_5_5_REV); + FmtToGLPixelFmt[TEX_FORMAT_BGRA8_UNORM] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_BGRX8_UNORM] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_BGRA8_TYPELESS] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_BGRA8_UNORM_SRGB] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_BGRX8_TYPELESS] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_BGRX8_UNORM_SRGB] = NativePixelAttribs(); + FmtToGLPixelFmt[TEX_FORMAT_BC6H_TYPELESS] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC6H_UF16] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC6H_SF16] = NativePixelAttribs(GL_RGB, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC7_TYPELESS] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC7_UNORM] = NativePixelAttribs(GL_RGBA, 0, True); + FmtToGLPixelFmt[TEX_FORMAT_BC7_UNORM_SRGB] = NativePixelAttribs(GL_RGBA, 0, True); + // clang-format on bAttribsMapIntialized = true; } - if( TexFormat > TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) + if (TexFormat > TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS) { return FmtToGLPixelFmt[TexFormat]; } else { - UNEXPECTED( "Texture format (", int{TexFormat}, ") is out of allowed range [1, ", int{TEX_FORMAT_NUM_FORMATS}-1, "]" ); + UNEXPECTED("Texture format (", int{TexFormat}, ") is out of allowed range [1, ", int{TEX_FORMAT_NUM_FORMATS} - 1, "]"); return FmtToGLPixelFmt[0]; } } -GLenum AccessFlags2GLAccess( Uint32 UAVAccessFlags ) +GLenum AccessFlags2GLAccess(Uint32 UAVAccessFlags) { static GLenum AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_READ_WRITE + 1] = {}; - static bool bIsInit = false; - if( !bIsInit ) + static bool bIsInit = false; + if (!bIsInit) { AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_READ] = GL_READ_ONLY; AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_WRITE] = GL_WRITE_ONLY; AccessFlags2GLAccessMap[UAV_ACCESS_FLAG_READ_WRITE] = GL_READ_WRITE; - bIsInit = true; + bIsInit = true; } - + auto GLAccess = AccessFlags2GLAccessMap[UAVAccessFlags & UAV_ACCESS_FLAG_READ_WRITE]; return GLAccess; } -GLenum TypeToGLTexFormat( VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized ) +GLenum TypeToGLTexFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized) { - switch( ValType ) + switch (ValType) { case VT_FLOAT16: { - VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); - switch( NumComponents ) + VERIFY(!bIsNormalized, "Floating point formats cannot be normalized"); + switch (NumComponents) { case 1: return GL_R16F; case 2: return GL_RG16F; case 4: return GL_RGBA16F; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } case VT_FLOAT32: { - VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); - switch( NumComponents ) + VERIFY(!bIsNormalized, "Floating point formats cannot be normalized"); + switch (NumComponents) { case 1: return GL_R32F; case 2: return GL_RG32F; case 3: return GL_RGB32F; case 4: return GL_RGBA32F; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } case VT_INT32: { - VERIFY( !bIsNormalized , "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); - switch( NumComponents ) + VERIFY(!bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead"); + switch (NumComponents) { case 1: return GL_R32I; case 2: return GL_RG32I; case 3: return GL_RGB32I; case 4: return GL_RGBA32I; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } case VT_UINT32: { - VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); - switch( NumComponents ) + VERIFY(!bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead"); + switch (NumComponents) { case 1: return GL_R32UI; case 2: return GL_RG32UI; case 3: return GL_RGB32UI; case 4: return GL_RGBA32UI; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } case VT_INT16: { - if( bIsNormalized ) + if (bIsNormalized) { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R16_SNORM; case 2: return GL_RG16_SNORM; case 4: return GL_RGBA16_SNORM; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } else { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R16I; case 2: return GL_RG16I; case 4: return GL_RGBA16I; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } } case VT_UINT16: { - if( bIsNormalized ) + if (bIsNormalized) { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R16; case 2: return GL_RG16; case 4: return GL_RGBA16; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } else { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R16UI; case 2: return GL_RG16UI; case 4: return GL_RGBA16UI; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } } case VT_INT8: { - if( bIsNormalized ) + if (bIsNormalized) { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R8_SNORM; case 2: return GL_RG8_SNORM; case 4: return GL_RGBA8_SNORM; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } else { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R8I; case 2: return GL_RG8I; case 4: return GL_RGBA8I; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } } case VT_UINT8: { - if( bIsNormalized ) + if (bIsNormalized) { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R8; case 2: return GL_RG8; case 4: return GL_RGBA8; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } else { - switch( NumComponents ) + switch (NumComponents) { case 1: return GL_R8UI; case 2: return GL_RG8UI; case 4: return GL_RGBA8UI; - default: UNEXPECTED( "Unusupported number of components" ); return 0; + default: UNEXPECTED("Unusupported number of components"); return 0; } } } - default: UNEXPECTED( "Unusupported format" ); return 0; + default: UNEXPECTED("Unusupported format"); return 0; } } -GLenum StencilOp2GlStencilOp( STENCIL_OP StencilOp ) +GLenum StencilOp2GlStencilOp(STENCIL_OP StencilOp) { - static bool bIsInit = false; + static bool bIsInit = false; static GLenum GLStencilOps[STENCIL_OP_NUM_OPS] = {}; - if( !bIsInit ) + if (!bIsInit) { - GLStencilOps[STENCIL_OP_KEEP] = GL_KEEP; - GLStencilOps[STENCIL_OP_ZERO] = GL_ZERO; - GLStencilOps[STENCIL_OP_REPLACE] = GL_REPLACE; - GLStencilOps[STENCIL_OP_INCR_SAT] = GL_INCR; - GLStencilOps[STENCIL_OP_DECR_SAT] = GL_DECR; - GLStencilOps[STENCIL_OP_INVERT] = GL_INVERT; - GLStencilOps[STENCIL_OP_INCR_WRAP]= GL_INCR_WRAP; - GLStencilOps[STENCIL_OP_DECR_WRAP]= GL_DECR_WRAP; - bIsInit = true; + GLStencilOps[STENCIL_OP_KEEP] = GL_KEEP; + GLStencilOps[STENCIL_OP_ZERO] = GL_ZERO; + GLStencilOps[STENCIL_OP_REPLACE] = GL_REPLACE; + GLStencilOps[STENCIL_OP_INCR_SAT] = GL_INCR; + GLStencilOps[STENCIL_OP_DECR_SAT] = GL_DECR; + GLStencilOps[STENCIL_OP_INVERT] = GL_INVERT; + GLStencilOps[STENCIL_OP_INCR_WRAP] = GL_INCR_WRAP; + GLStencilOps[STENCIL_OP_DECR_WRAP] = GL_DECR_WRAP; + bIsInit = true; } - if( StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS ) + if (StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS) { auto GlStencilOp = GLStencilOps[StencilOp]; - VERIFY( GlStencilOp != 0 || GlStencilOp == 0 && StencilOp == STENCIL_OP_ZERO, "Unexpected stencil op" ); + VERIFY(GlStencilOp != 0 || GlStencilOp == 0 && StencilOp == STENCIL_OP_ZERO, "Unexpected stencil op"); return GlStencilOp; } else { - UNEXPECTED( "Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS-1, "]" ); + UNEXPECTED("Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS - 1, "]"); return 0; } } -GLenum BlendFactor2GLBlend( BLEND_FACTOR bf ) +GLenum BlendFactor2GLBlend(BLEND_FACTOR bf) { - static bool bIsInit = false; + static bool bIsInit = false; static GLenum GLBlend[BLEND_FACTOR_NUM_FACTORS] = {}; - if( !bIsInit ) + if (!bIsInit) { - GLBlend[ BLEND_FACTOR_ZERO ] = GL_ZERO; - GLBlend[ BLEND_FACTOR_ONE ] = GL_ONE; - GLBlend[ BLEND_FACTOR_SRC_COLOR ] = GL_SRC_COLOR; - GLBlend[ BLEND_FACTOR_INV_SRC_COLOR ] = GL_ONE_MINUS_SRC_COLOR; - GLBlend[ BLEND_FACTOR_SRC_ALPHA ] = GL_SRC_ALPHA; - GLBlend[ BLEND_FACTOR_INV_SRC_ALPHA ] = GL_ONE_MINUS_SRC_ALPHA; - GLBlend[ BLEND_FACTOR_DEST_ALPHA ] = GL_DST_ALPHA; - GLBlend[ BLEND_FACTOR_INV_DEST_ALPHA ] = GL_ONE_MINUS_DST_ALPHA; - GLBlend[ BLEND_FACTOR_DEST_COLOR ] = GL_DST_COLOR; - GLBlend[ BLEND_FACTOR_INV_DEST_COLOR ] = GL_ONE_MINUS_DST_COLOR; - GLBlend[ BLEND_FACTOR_SRC_ALPHA_SAT ] = GL_SRC_ALPHA_SATURATE; - GLBlend[ BLEND_FACTOR_BLEND_FACTOR ] = GL_CONSTANT_COLOR; - GLBlend[ BLEND_FACTOR_INV_BLEND_FACTOR ] = GL_ONE_MINUS_CONSTANT_COLOR; - GLBlend[ BLEND_FACTOR_SRC1_COLOR ] = GL_SRC1_COLOR; - GLBlend[ BLEND_FACTOR_INV_SRC1_COLOR ] = GL_ONE_MINUS_SRC1_COLOR; - GLBlend[ BLEND_FACTOR_SRC1_ALPHA ] = GL_SRC1_ALPHA; - GLBlend[ BLEND_FACTOR_INV_SRC1_ALPHA ] = GL_ONE_MINUS_SRC1_ALPHA; + GLBlend[BLEND_FACTOR_ZERO] = GL_ZERO; + GLBlend[BLEND_FACTOR_ONE] = GL_ONE; + GLBlend[BLEND_FACTOR_SRC_COLOR] = GL_SRC_COLOR; + GLBlend[BLEND_FACTOR_INV_SRC_COLOR] = GL_ONE_MINUS_SRC_COLOR; + GLBlend[BLEND_FACTOR_SRC_ALPHA] = GL_SRC_ALPHA; + GLBlend[BLEND_FACTOR_INV_SRC_ALPHA] = GL_ONE_MINUS_SRC_ALPHA; + GLBlend[BLEND_FACTOR_DEST_ALPHA] = GL_DST_ALPHA; + GLBlend[BLEND_FACTOR_INV_DEST_ALPHA] = GL_ONE_MINUS_DST_ALPHA; + GLBlend[BLEND_FACTOR_DEST_COLOR] = GL_DST_COLOR; + GLBlend[BLEND_FACTOR_INV_DEST_COLOR] = GL_ONE_MINUS_DST_COLOR; + GLBlend[BLEND_FACTOR_SRC_ALPHA_SAT] = GL_SRC_ALPHA_SATURATE; + GLBlend[BLEND_FACTOR_BLEND_FACTOR] = GL_CONSTANT_COLOR; + GLBlend[BLEND_FACTOR_INV_BLEND_FACTOR] = GL_ONE_MINUS_CONSTANT_COLOR; + GLBlend[BLEND_FACTOR_SRC1_COLOR] = GL_SRC1_COLOR; + GLBlend[BLEND_FACTOR_INV_SRC1_COLOR] = GL_ONE_MINUS_SRC1_COLOR; + GLBlend[BLEND_FACTOR_SRC1_ALPHA] = GL_SRC1_ALPHA; + GLBlend[BLEND_FACTOR_INV_SRC1_ALPHA] = GL_ONE_MINUS_SRC1_ALPHA; bIsInit = true; } - if( bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS ) + if (bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS) { auto glbf = GLBlend[bf]; - VERIFY( glbf != 0 || glbf == 0 && bf == BLEND_FACTOR_ZERO, "Incorrect blend factor" ); + VERIFY(glbf != 0 || glbf == 0 && bf == BLEND_FACTOR_ZERO, "Incorrect blend factor"); return glbf; } else { - UNEXPECTED( "Incorrect blend factor (", bf, ")" ); + UNEXPECTED("Incorrect blend factor (", bf, ")"); return 0; } } -GLenum BlendOperation2GLBlendOp( BLEND_OPERATION BlendOp ) +GLenum BlendOperation2GLBlendOp(BLEND_OPERATION BlendOp) { - static bool bIsInit = false; + static bool bIsInit = false; static GLenum GLBlendOp[BLEND_OPERATION_NUM_OPERATIONS] = {}; - if( !bIsInit ) + if (!bIsInit) { - GLBlendOp[ BLEND_OPERATION_ADD ] = GL_FUNC_ADD; - GLBlendOp[ BLEND_OPERATION_SUBTRACT ] = GL_FUNC_SUBTRACT; - GLBlendOp[ BLEND_OPERATION_REV_SUBTRACT ] = GL_FUNC_REVERSE_SUBTRACT; - GLBlendOp[ BLEND_OPERATION_MIN ] = GL_MIN; - GLBlendOp[ BLEND_OPERATION_MAX ] = GL_MAX; + GLBlendOp[BLEND_OPERATION_ADD] = GL_FUNC_ADD; + GLBlendOp[BLEND_OPERATION_SUBTRACT] = GL_FUNC_SUBTRACT; + GLBlendOp[BLEND_OPERATION_REV_SUBTRACT] = GL_FUNC_REVERSE_SUBTRACT; + GLBlendOp[BLEND_OPERATION_MIN] = GL_MIN; + GLBlendOp[BLEND_OPERATION_MAX] = GL_MAX; bIsInit = true; } - if( BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS ) + if (BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS) { auto glbop = GLBlendOp[BlendOp]; - VERIFY( glbop != 0, "Incorrect blend operation" ); + VERIFY(glbop != 0, "Incorrect blend operation"); return glbop; } else { - UNEXPECTED( "Incorrect blend operation (", BlendOp, ")" ); + UNEXPECTED("Incorrect blend operation (", BlendOp, ")"); return 0; } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 07e46e76..76153b29 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -35,7 +35,8 @@ namespace Diligent PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, RenderDeviceGLImpl* pDeviceGL, const PipelineStateDesc& PipelineDesc, - bool bIsDeviceInternal) : + bool bIsDeviceInternal) : + // clang-format off TPipelineStateBase { pRefCounters, @@ -45,6 +46,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, }, m_ResourceLayout {*this}, m_StaticResourceLayout{*this} +// clang-format on { if (!m_Desc.IsComputePipeline && m_pPS == nullptr) { @@ -61,7 +63,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, } auto& DeviceCaps = pDeviceGL->GetDeviceCaps(); - VERIFY( DeviceCaps.DevType != DeviceType::Undefined, "Device caps are not initialized" ); + VERIFY(DeviceCaps.DevType != DeviceType::Undefined, "Device caps are not initialized"); auto pImmediateCtx = m_pDevice->GetImmediateContext(); VERIFY_EXPR(pImmediateCtx); @@ -81,15 +83,15 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, m_GLPrograms.reserve(m_NumShaders); for (Uint32 i = 0; i < m_NumShaders; ++i) { - auto* pShaderGL = GetShader<ShaderGLImpl>(i); + auto* pShaderGL = GetShader<ShaderGLImpl>(i); const auto& ShaderDesc = pShaderGL->GetDesc(); m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&m_ppShaders[i], 1, true)); // Load uniforms and assign bindings m_ProgramResources[i].LoadUniforms(ShaderDesc.ShaderType, m_GLPrograms[i], GLState, - m_TotalUniformBufferBindings, - m_TotalSamplerBindings, - m_TotalImageBindings, - m_TotalStorageBufferBindings); + m_TotalUniformBufferBindings, + m_TotalSamplerBindings, + m_TotalImageBindings, + m_TotalStorageBufferBindings); HashCombine(m_ShaderResourceLayoutHash, m_ProgramResources[i].GetHash()); } @@ -105,10 +107,10 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, ShaderStages |= ShaderDesc.ShaderType; } m_ProgramResources[0].LoadUniforms(ShaderStages, m_GLPrograms[0], GLState, - m_TotalUniformBufferBindings, - m_TotalSamplerBindings, - m_TotalImageBindings, - m_TotalStorageBufferBindings); + m_TotalUniformBufferBindings, + m_TotalSamplerBindings, + m_TotalImageBindings, + m_TotalStorageBufferBindings); m_ShaderResourceLayoutHash = m_ProgramResources[0].GetHash(); } @@ -116,9 +118,9 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, // Initialize master resource layout that keeps all variable types and does not reference a resource cache m_ResourceLayout.Initialize(m_ProgramResources.data(), static_cast<Uint32>(m_GLPrograms.size()), m_Desc.ResourceLayout, nullptr, 0, nullptr); } - + m_StaticSamplers.resize(m_Desc.ResourceLayout.NumStaticSamplers); - for (Uint32 s=0; s < m_Desc.ResourceLayout.NumStaticSamplers; ++s) + for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumStaticSamplers; ++s) { pDeviceGL->CreateSampler(m_Desc.ResourceLayout.StaticSamplers[s].Desc, &m_StaticSamplers[s]); } @@ -138,20 +140,20 @@ PipelineStateGLImpl::~PipelineStateGLImpl() GetDevice()->OnDestroyPSO(this); } -IMPLEMENT_QUERY_INTERFACE( PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase ) +IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase) void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) { auto* pRenderDeviceGL = GetDevice(); - auto& SRBAllocator = pRenderDeviceGL->GetSRBAllocator(); - auto pResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this, m_ProgramResources.data(), static_cast<Uint32>(m_ProgramResources.size())); + auto& SRBAllocator = pRenderDeviceGL->GetSRBAllocator(); + auto pResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this, m_ProgramResources.data(), static_cast<Uint32>(m_ProgramResources.size())); if (InitStaticResources) pResBinding->InitializeStaticResources(this); pResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(ppShaderResourceBinding)); } -bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState* pPSO)const +bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState* pPSO) const { VERIFY_EXPR(pPSO != nullptr); @@ -165,7 +167,7 @@ bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState* pPSO)const if (m_ProgramResources.size() != pPSOGL->m_ProgramResources.size()) return false; - for (size_t i=0; i < m_ProgramResources.size(); ++i) + for (size_t i = 0; i < m_ProgramResources.size(); ++i) { if (!m_ProgramResources[i].IsCompatibleWith(pPSOGL->m_ProgramResources[i])) return false; @@ -186,7 +188,7 @@ void PipelineStateGLImpl::CommitProgram(GLContextState& State) State.SetProgram(GLObjectWrappers::GLProgramObj::Null()); auto& Pipeline = GetGLProgramPipeline(State.GetCurrentGLContext()); VERIFY(Pipeline != 0, "Program pipeline must not be null"); - State.SetPipeline( Pipeline ); + State.SetPipeline(Pipeline); } else { @@ -206,12 +208,12 @@ GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLCon // Create new progam pipeline m_GLProgPipelines.emplace_back(Context, true); - auto& ctx_pipeline = m_GLProgPipelines.back(); - GLuint Pipeline = ctx_pipeline.second; + auto& ctx_pipeline = m_GLProgPipelines.back(); + GLuint Pipeline = ctx_pipeline.second; for (Uint32 i = 0; i < m_NumShaders; ++i) { auto* pCurrShader = GetShader<ShaderGLImpl>(i); - auto GLShaderBit = ShaderTypeToGLShaderBit(pCurrShader->GetDesc().ShaderType); + auto GLShaderBit = ShaderTypeToGLShaderBit(pCurrShader->GetDesc().ShaderType); // If the program has an active code for each stage mentioned in set flags, // then that code will be used by the pipeline. If program is 0, then the given // stages are cleared from the pipeline. @@ -221,15 +223,15 @@ GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLCon return ctx_pipeline.second; } -void PipelineStateGLImpl::InitializeSRBResourceCache(GLProgramResourceCache& ResourceCache)const +void PipelineStateGLImpl::InitializeSRBResourceCache(GLProgramResourceCache& ResourceCache) const { ResourceCache.Initialize(m_TotalUniformBufferBindings, m_TotalSamplerBindings, m_TotalImageBindings, m_TotalStorageBufferBindings, GetRawAllocator()); InitStaticSamplersInResourceCache(m_ResourceLayout, ResourceCache); } -void PipelineStateGLImpl::InitStaticSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache)const +void PipelineStateGLImpl::InitStaticSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache) const { - for (Uint32 s=0; s < ResourceLayout.GetNumResources<GLPipelineResourceLayout::SamplerBindInfo>(); ++s) + for (Uint32 s = 0; s < ResourceLayout.GetNumResources<GLPipelineResourceLayout::SamplerBindInfo>(); ++s) { const auto& Sam = ResourceLayout.GetConstResource<GLPipelineResourceLayout::SamplerBindInfo>(s); if (Sam.m_StaticSamplerIdx >= 0) @@ -245,7 +247,7 @@ void PipelineStateGLImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMappi { m_StaticResourceLayout.BindResources(static_cast<SHADER_TYPE>(ShaderFlags), pResourceMapping, Flags, m_StaticResourceCache); } - + Uint32 PipelineStateGLImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const { return m_StaticResourceLayout.GetNumVariables(ShaderType); @@ -261,4 +263,4 @@ IShaderResourceVariable* PipelineStateGLImpl::GetStaticVariableByIndex(SHADER_TY return m_StaticResourceLayout.GetShaderVariable(ShaderType, Index); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp index 3ee32be7..e18d4201 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp @@ -27,29 +27,31 @@ namespace Diligent { - RenderDeviceGLESImpl::RenderDeviceGLESImpl(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - const EngineGLCreateInfo& InitAttribs, - const SwapChainDesc* pSCDesc) : - RenderDeviceGLImpl(pRefCounters, RawMemAllocator, pEngineFactory, InitAttribs, pSCDesc) - { - } - - IMPLEMENT_QUERY_INTERFACE( RenderDeviceGLESImpl, IID_RenderDeviceGLES, RenderDeviceGLImpl ) - - bool RenderDeviceGLESImpl::Invalidate() - { - return m_GLContext.Invalidate(); - } - - void RenderDeviceGLESImpl::Suspend() - { - m_GLContext.Suspend(); - } - - EGLint RenderDeviceGLESImpl::Resume( ANativeWindow* window ) - { - return m_GLContext.Resume(window); - } + +RenderDeviceGLESImpl::RenderDeviceGLESImpl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc* pSCDesc) : + RenderDeviceGLImpl(pRefCounters, RawMemAllocator, pEngineFactory, InitAttribs, pSCDesc) +{ } + +IMPLEMENT_QUERY_INTERFACE(RenderDeviceGLESImpl, IID_RenderDeviceGLES, RenderDeviceGLImpl) + +bool RenderDeviceGLESImpl::Invalidate() +{ + return m_GLContext.Invalidate(); +} + +void RenderDeviceGLESImpl::Suspend() +{ + m_GLContext.Suspend(); +} + +EGLint RenderDeviceGLESImpl::Resume(ANativeWindow* window) +{ + return m_GLContext.Resume(window); +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index c9b5825a..0caa24fa 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -47,11 +47,12 @@ namespace Diligent { -RenderDeviceGLImpl :: RenderDeviceGLImpl(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - const EngineGLCreateInfo& InitAttribs, - const SwapChainDesc* pSCDesc): +RenderDeviceGLImpl ::RenderDeviceGLImpl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc* pSCDesc) : + // clang-format off TRenderDeviceBase { pRefCounters, @@ -73,334 +74,324 @@ RenderDeviceGLImpl :: RenderDeviceGLImpl(IReferenceCounters* pRefCounters }, // Device caps must be filled in before the constructor of Pipeline Cache is called! m_GLContext{InitAttribs, m_DeviceCaps, pSCDesc} +// clang-format on { GLint NumExtensions = 0; - glGetIntegerv( GL_NUM_EXTENSIONS,& NumExtensions ); - CHECK_GL_ERROR( "Failed to get the number of extensions" ); + glGetIntegerv(GL_NUM_EXTENSIONS, &NumExtensions); + CHECK_GL_ERROR("Failed to get the number of extensions"); m_ExtensionStrings.reserve(NumExtensions); - for( int Ext = 0; Ext < NumExtensions; ++Ext ) + for (int Ext = 0; Ext < NumExtensions; ++Ext) { - auto CurrExtension = glGetStringi( GL_EXTENSIONS, Ext ); - CHECK_GL_ERROR( "Failed to get extension string #", Ext ); - m_ExtensionStrings.emplace( reinterpret_cast<const Char*>(CurrExtension) ); + auto CurrExtension = glGetStringi(GL_EXTENSIONS, Ext); + CHECK_GL_ERROR("Failed to get extension string #", Ext); + m_ExtensionStrings.emplace(reinterpret_cast<const Char*>(CurrExtension)); } FlagSupportedTexFormats(); QueryDeviceCaps(); - std::basic_string<GLubyte> glstrVendor = glGetString( GL_VENDOR ); - std::string Vendor = StrToLower(std::string(glstrVendor.begin(), glstrVendor.end())); + std::basic_string<GLubyte> glstrVendor = glGetString(GL_VENDOR); + std::string Vendor = StrToLower(std::string(glstrVendor.begin(), glstrVendor.end())); LOG_INFO_MESSAGE("GPU Vendor: ", Vendor); - if( Vendor.find( "intel" ) != std::string::npos ) + if (Vendor.find("intel") != std::string::npos) m_GPUInfo.Vendor = GPU_VENDOR::INTEL; - else if( Vendor.find( "nvidia" ) != std::string::npos ) + else if (Vendor.find("nvidia") != std::string::npos) m_GPUInfo.Vendor = GPU_VENDOR::NVIDIA; - else if( Vendor.find( "ati" ) != std::string::npos || - Vendor.find( "amd" ) != std::string::npos ) + else if (Vendor.find("ati") != std::string::npos || + Vendor.find("amd") != std::string::npos) m_GPUInfo.Vendor = GPU_VENDOR::ATI; - else if( Vendor.find( "qualcomm" ) ) + else if (Vendor.find("qualcomm")) m_GPUInfo.Vendor = GPU_VENDOR::QUALCOMM; } -RenderDeviceGLImpl :: ~RenderDeviceGLImpl() +RenderDeviceGLImpl ::~RenderDeviceGLImpl() { } -IMPLEMENT_QUERY_INTERFACE( RenderDeviceGLImpl, IID_RenderDeviceGL, TRenderDeviceBase ) +IMPLEMENT_QUERY_INTERFACE(RenderDeviceGLImpl, IID_RenderDeviceGL, TRenderDeviceBase) -void RenderDeviceGLImpl :: InitTexRegionRender() +void RenderDeviceGLImpl ::InitTexRegionRender() { m_pTexRegionRender.reset(new TexRegionRender(this)); } -void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer **ppBuffer, bool bIsDeviceInternal) +void RenderDeviceGLImpl ::CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer, bool bIsDeviceInternal) { - CreateDeviceObject( "buffer", BuffDesc, ppBuffer, - [&]() + CreateDeviceObject( + "buffer", BuffDesc, ppBuffer, + [&]() // { auto spDeviceContext = GetImmediateContext(); VERIFY(spDeviceContext, "Immediate device context has been destroyed"); auto* pDeviceContextGL = spDeviceContext.RawPtr<DeviceContextGLImpl>(); - BufferGLImpl *pBufferOGL( NEW_RC_OBJ(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl) - (m_BuffViewObjAllocator, this, pDeviceContextGL->GetContextState(), BuffDesc, pBuffData, bIsDeviceInternal ) ); - pBufferOGL->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); + BufferGLImpl* pBufferOGL(NEW_RC_OBJ(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl)(m_BuffViewObjAllocator, this, pDeviceContextGL->GetContextState(), BuffDesc, pBuffData, bIsDeviceInternal)); + pBufferOGL->QueryInterface(IID_Buffer, reinterpret_cast<IObject**>(ppBuffer)); pBufferOGL->CreateDefaultViews(); - OnCreateDeviceObject( pBufferOGL ); - } + OnCreateDeviceObject(pBufferOGL); + } // ); } -void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData* BuffData, IBuffer **ppBuffer) +void RenderDeviceGLImpl ::CreateBuffer(const BufferDesc& BuffDesc, const BufferData* BuffData, IBuffer** ppBuffer) { - CreateBuffer(BuffDesc, BuffData, ppBuffer, false); + CreateBuffer(BuffDesc, BuffData, ppBuffer, false); } -void RenderDeviceGLImpl :: CreateBufferFromGLHandle(Uint32 GLHandle, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer **ppBuffer) +void RenderDeviceGLImpl ::CreateBufferFromGLHandle(Uint32 GLHandle, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) { VERIFY(GLHandle, "GL buffer handle must not be null"); - CreateDeviceObject( "buffer", BuffDesc, ppBuffer, - [&]() + CreateDeviceObject( + "buffer", BuffDesc, ppBuffer, + [&]() // { auto spDeviceContext = GetImmediateContext(); VERIFY(spDeviceContext, "Immediate device context has been destroyed"); auto* pDeviceContextGL = spDeviceContext.RawPtr<DeviceContextGLImpl>(); - BufferGLImpl *pBufferOGL( NEW_RC_OBJ(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl) - (m_BuffViewObjAllocator, this, pDeviceContextGL->GetContextState(), BuffDesc, GLHandle, false ) ); - pBufferOGL->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); + BufferGLImpl* pBufferOGL(NEW_RC_OBJ(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl)(m_BuffViewObjAllocator, this, pDeviceContextGL->GetContextState(), BuffDesc, GLHandle, false)); + pBufferOGL->QueryInterface(IID_Buffer, reinterpret_cast<IObject**>(ppBuffer)); pBufferOGL->CreateDefaultViews(); - OnCreateDeviceObject( pBufferOGL ); - } + OnCreateDeviceObject(pBufferOGL); + } // ); } -void RenderDeviceGLImpl :: CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader, bool bIsDeviceInternal) +void RenderDeviceGLImpl ::CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader, bool bIsDeviceInternal) { - CreateDeviceObject( "shader", ShaderCreateInfo.Desc, ppShader, - [&]() + CreateDeviceObject( + "shader", ShaderCreateInfo.Desc, ppShader, + [&]() // { - ShaderGLImpl *pShaderOGL(NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderGLImpl instance", ShaderGLImpl) - (this, ShaderCreateInfo, bIsDeviceInternal)); - pShaderOGL->QueryInterface(IID_Shader, reinterpret_cast<IObject**>(ppShader) ); + ShaderGLImpl* pShaderOGL(NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderGLImpl instance", ShaderGLImpl)(this, ShaderCreateInfo, bIsDeviceInternal)); + pShaderOGL->QueryInterface(IID_Shader, reinterpret_cast<IObject**>(ppShader)); - OnCreateDeviceObject( pShaderOGL ); - } + OnCreateDeviceObject(pShaderOGL); + } // ); } -void RenderDeviceGLImpl :: CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader **ppShader) +void RenderDeviceGLImpl ::CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader) { - CreateShader(ShaderCreateInfo, ppShader, false); + CreateShader(ShaderCreateInfo, ppShader, false); } -void RenderDeviceGLImpl :: CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture **ppTexture, bool bIsDeviceInternal) +void RenderDeviceGLImpl ::CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture, bool bIsDeviceInternal) { - CreateDeviceObject( "texture", TexDesc, ppTexture, - [&]() + CreateDeviceObject( + "texture", TexDesc, ppTexture, + [&]() // { auto spDeviceContext = GetImmediateContext(); VERIFY(spDeviceContext, "Immediate device context has been destroyed"); auto& GLState = spDeviceContext.RawPtr<DeviceContextGLImpl>()->GetContextState(); - const auto& FmtInfo = GetTextureFormatInfo( TexDesc.Format ); - if( !FmtInfo.Supported ) + const auto& FmtInfo = GetTextureFormatInfo(TexDesc.Format); + if (!FmtInfo.Supported) { - LOG_ERROR_AND_THROW( FmtInfo.Name, " is not supported texture format" ); + LOG_ERROR_AND_THROW(FmtInfo.Name, " is not supported texture format"); } - TextureBaseGL *pTextureOGL = nullptr; - switch(TexDesc.Type) + TextureBaseGL* pTextureOGL = nullptr; + switch (TexDesc.Type) { case RESOURCE_DIM_TEX_1D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1D_OGL instance", Texture1D_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1D_OGL instance", Texture1D_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; - + case RESOURCE_DIM_TEX_1D_ARRAY: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1DArray_OGL instance", Texture1DArray_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1DArray_OGL instance", Texture1DArray_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; case RESOURCE_DIM_TEX_2D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2D_OGL instance", Texture2D_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2D_OGL instance", Texture2D_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; - + case RESOURCE_DIM_TEX_2D_ARRAY: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2DArray_OGL instance", Texture2DArray_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2DArray_OGL instance", Texture2DArray_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; case RESOURCE_DIM_TEX_3D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_OGL instance", Texture3D_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_OGL instance", Texture3D_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; case RESOURCE_DIM_TEX_CUBE: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCube_OGL instance", TextureCube_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCube_OGL instance", TextureCube_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; case RESOURCE_DIM_TEX_CUBE_ARRAY: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCubeArray_OGL instance", TextureCubeArray_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCubeArray_OGL instance", TextureCubeArray_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, pData, bIsDeviceInternal); break; - default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); + default: LOG_ERROR_AND_THROW("Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)"); } - - pTextureOGL->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + + pTextureOGL->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture)); pTextureOGL->CreateDefaultViews(); - OnCreateDeviceObject( pTextureOGL ); - } + OnCreateDeviceObject(pTextureOGL); + } // ); } -void RenderDeviceGLImpl::CreateTexture(const TextureDesc& TexDesc, const TextureData* Data, ITexture **ppTexture) +void RenderDeviceGLImpl::CreateTexture(const TextureDesc& TexDesc, const TextureData* Data, ITexture** ppTexture) { - CreateTexture(TexDesc, Data, ppTexture, false); + CreateTexture(TexDesc, Data, ppTexture, false); } -void RenderDeviceGLImpl::CreateTextureFromGLHandle(Uint32 GLHandle, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture **ppTexture) +void RenderDeviceGLImpl::CreateTextureFromGLHandle(Uint32 GLHandle, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture) { VERIFY(GLHandle, "GL texture handle must not be null"); - CreateDeviceObject( "texture", TexDesc, ppTexture, - [&]() + CreateDeviceObject( + "texture", TexDesc, ppTexture, + [&]() // { auto spDeviceContext = GetImmediateContext(); VERIFY(spDeviceContext, "Immediate device context has been destroyed"); auto& GLState = spDeviceContext.RawPtr<DeviceContextGLImpl>()->GetContextState(); - TextureBaseGL *pTextureOGL = nullptr; - switch(TexDesc.Type) + TextureBaseGL* pTextureOGL = nullptr; + switch (TexDesc.Type) { case RESOURCE_DIM_TEX_1D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1D_OGL instance", Texture1D_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1D_OGL instance", Texture1D_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; - + case RESOURCE_DIM_TEX_1D_ARRAY: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1DArray_OGL instance", Texture1DArray_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture1DArray_OGL instance", Texture1DArray_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; case RESOURCE_DIM_TEX_2D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2D_OGL instance", Texture2D_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2D_OGL instance", Texture2D_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; - + case RESOURCE_DIM_TEX_2D_ARRAY: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2DArray_OGL instance", Texture2DArray_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture2DArray_OGL instance", Texture2DArray_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; case RESOURCE_DIM_TEX_3D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_OGL instance", Texture3D_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_OGL instance", Texture3D_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; case RESOURCE_DIM_TEX_CUBE: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCube_OGL instance", TextureCube_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCube_OGL instance", TextureCube_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; case RESOURCE_DIM_TEX_CUBE_ARRAY: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCubeArray_OGL instance", TextureCubeArray_OGL) - (m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "TextureCubeArray_OGL instance", TextureCubeArray_OGL)(m_TexViewObjAllocator, this, GLState, TexDesc, GLHandle); break; - default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); + default: LOG_ERROR_AND_THROW("Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)"); } - - pTextureOGL->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + + pTextureOGL->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture)); pTextureOGL->CreateDefaultViews(); - OnCreateDeviceObject( pTextureOGL ); - } + OnCreateDeviceObject(pTextureOGL); + } // ); } -void RenderDeviceGLImpl :: CreateDummyTexture(const TextureDesc& TexDesc, RESOURCE_STATE InitialState, TextureBaseGL** ppTexture) +void RenderDeviceGLImpl ::CreateDummyTexture(const TextureDesc& TexDesc, RESOURCE_STATE InitialState, TextureBaseGL** ppTexture) { - CreateDeviceObject( "texture", TexDesc, ppTexture, - [&]() + CreateDeviceObject( + "texture", TexDesc, ppTexture, + [&]() // { TextureBaseGL* pTextureOGL = nullptr; - switch(TexDesc.Type) + switch (TexDesc.Type) { case RESOURCE_DIM_TEX_2D: - pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Dummy Texture2D_OGL instance", Texture2D_OGL) - (m_TexViewObjAllocator, this, TexDesc); + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Dummy Texture2D_OGL instance", Texture2D_OGL)(m_TexViewObjAllocator, this, TexDesc); break; - default: LOG_ERROR_AND_THROW( "Unsupported texture type." ); + default: LOG_ERROR_AND_THROW("Unsupported texture type."); } - - pTextureOGL->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + + pTextureOGL->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture)); pTextureOGL->CreateDefaultViews(); - OnCreateDeviceObject( pTextureOGL ); - } + OnCreateDeviceObject(pTextureOGL); + } // ); } -void RenderDeviceGLImpl :: CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler, bool bIsDeviceInternal) +void RenderDeviceGLImpl ::CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler, bool bIsDeviceInternal) { - CreateDeviceObject( "sampler", SamplerDesc, ppSampler, - [&]() + CreateDeviceObject( + "sampler", SamplerDesc, ppSampler, + [&]() // { - m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); - if( *ppSampler == nullptr ) + m_SamplersRegistry.Find(SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler)); + if (*ppSampler == nullptr) { - SamplerGLImpl *pSamplerOGL( NEW_RC_OBJ(m_SamplerObjAllocator, "SamplerGLImpl instance", SamplerGLImpl) - (this, SamplerDesc, bIsDeviceInternal ) ); - pSamplerOGL->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); - OnCreateDeviceObject( pSamplerOGL ); - m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); + SamplerGLImpl* pSamplerOGL(NEW_RC_OBJ(m_SamplerObjAllocator, "SamplerGLImpl instance", SamplerGLImpl)(this, SamplerDesc, bIsDeviceInternal)); + pSamplerOGL->QueryInterface(IID_Sampler, reinterpret_cast<IObject**>(ppSampler)); + OnCreateDeviceObject(pSamplerOGL); + m_SamplersRegistry.Add(SamplerDesc, *ppSampler); } - } + } // ); } -void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler) +void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler) { - CreateSampler(SamplerDesc, ppSampler, false); + CreateSampler(SamplerDesc, ppSampler, false); } -void RenderDeviceGLImpl::CreatePipelineState( const PipelineStateDesc& PipelineDesc, IPipelineState **ppPipelineState) +void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState) { CreatePipelineState(PipelineDesc, ppPipelineState, false); } -void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState **ppPipelineState, bool bIsDeviceInternal) +void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState, bool bIsDeviceInternal) { - CreateDeviceObject( "Pipeline state", PipelineDesc, ppPipelineState, - [&]() + CreateDeviceObject( + "Pipeline state", PipelineDesc, ppPipelineState, + [&]() // { - PipelineStateGLImpl *pPipelineStateOGL( NEW_RC_OBJ(m_PSOAllocator, "PipelineStateGLImpl instance", PipelineStateGLImpl) - (this, PipelineDesc, bIsDeviceInternal ) ); - pPipelineStateOGL->QueryInterface( IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState) ); - OnCreateDeviceObject( pPipelineStateOGL ); - } + PipelineStateGLImpl* pPipelineStateOGL(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateGLImpl instance", PipelineStateGLImpl)(this, PipelineDesc, bIsDeviceInternal)); + pPipelineStateOGL->QueryInterface(IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState)); + OnCreateDeviceObject(pPipelineStateOGL); + } // ); } void RenderDeviceGLImpl::CreateFence(const FenceDesc& Desc, IFence** ppFence) { - CreateDeviceObject( "Fence", Desc, ppFence, - [&]() + CreateDeviceObject( + "Fence", Desc, ppFence, + [&]() // { - FenceGLImpl* pFenceOGL( NEW_RC_OBJ(m_FenceAllocator, "FenceGLImpl instance", FenceGLImpl) - (this, Desc) ); - pFenceOGL->QueryInterface( IID_Fence, reinterpret_cast<IObject**>(ppFence) ); - OnCreateDeviceObject( pFenceOGL ); - } + FenceGLImpl* pFenceOGL(NEW_RC_OBJ(m_FenceAllocator, "FenceGLImpl instance", FenceGLImpl)(this, Desc)); + pFenceOGL->QueryInterface(IID_Fence, reinterpret_cast<IObject**>(ppFence)); + OnCreateDeviceObject(pFenceOGL); + } // ); } -bool RenderDeviceGLImpl::CheckExtension( const Char *ExtensionString ) +bool RenderDeviceGLImpl::CheckExtension(const Char* ExtensionString) { - return m_ExtensionStrings.find( ExtensionString ) != m_ExtensionStrings.end(); + return m_ExtensionStrings.find(ExtensionString) != m_ExtensionStrings.end(); } void RenderDeviceGLImpl::FlagSupportedTexFormats() { - const auto& DeviceCaps = GetDeviceCaps(); - bool bGL33OrAbove = DeviceCaps.DevType == DeviceType::OpenGL&& - (DeviceCaps.MajorVersion >= 4 || (DeviceCaps.MajorVersion == 3&& DeviceCaps.MinorVersion >= 3) ); - - bool bRGTC = CheckExtension( "GL_ARB_texture_compression_rgtc" ); - bool bBPTC = CheckExtension( "GL_ARB_texture_compression_bptc" ); - bool bS3TC = CheckExtension( "GL_EXT_texture_compression_s3tc" ); - bool bTexNorm16 = CheckExtension( "GL_EXT_texture_norm16" ); // Only for ES3.1+ - -#define FLAG_FORMAT(Fmt, IsSupported)\ - m_TextureFormatsInfo[Fmt].Supported=IsSupported + const auto& DeviceCaps = GetDeviceCaps(); + bool bGL33OrAbove = DeviceCaps.DevType == DeviceType::OpenGL && + (DeviceCaps.MajorVersion >= 4 || (DeviceCaps.MajorVersion == 3 && DeviceCaps.MinorVersion >= 3)); + + bool bRGTC = CheckExtension("GL_ARB_texture_compression_rgtc"); + bool bBPTC = CheckExtension("GL_ARB_texture_compression_bptc"); + bool bS3TC = CheckExtension("GL_EXT_texture_compression_s3tc"); + bool bTexNorm16 = CheckExtension("GL_EXT_texture_norm16"); // Only for ES3.1+ + +#define FLAG_FORMAT(Fmt, IsSupported) \ + m_TextureFormatsInfo[Fmt].Supported = IsSupported // The formats marked by true below are required in GL 3.3+ and GLES 3.0+ // Note that GLES2.0 does not specify any required formats + // clang-format off FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true ); FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true ); FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true ); @@ -504,47 +495,48 @@ void RenderDeviceGLImpl::FlagSupportedTexFormats() FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, bBPTC ); FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, bBPTC ); FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, bBPTC ); + // clang-format on #ifdef _DEBUG - bool bGL43OrAbove = DeviceCaps.DevType == DeviceType::OpenGL && - (DeviceCaps.MajorVersion >= 5 || (DeviceCaps.MajorVersion == 4 && DeviceCaps.MinorVersion >= 3) ); + bool bGL43OrAbove = DeviceCaps.DevType == DeviceType::OpenGL && + (DeviceCaps.MajorVersion >= 5 || (DeviceCaps.MajorVersion == 4 && DeviceCaps.MinorVersion >= 3)); - constexpr int TestTextureDim = 8; - constexpr int MaxTexelSize = 16; + constexpr int TestTextureDim = 8; + constexpr int MaxTexelSize = 16; std::vector<Uint8> ZeroData(TestTextureDim * TestTextureDim * MaxTexelSize); - + // Go through all formats and try to create small 2D texture to check if the format is supported - for( auto FmtInfo = m_TextureFormatsInfo.begin(); FmtInfo != m_TextureFormatsInfo.end(); ++FmtInfo ) + for (auto FmtInfo = m_TextureFormatsInfo.begin(); FmtInfo != m_TextureFormatsInfo.end(); ++FmtInfo) { - if( FmtInfo->Format == TEX_FORMAT_UNKNOWN ) + if (FmtInfo->Format == TEX_FORMAT_UNKNOWN) continue; auto GLFmt = TexFormatToGLInternalTexFormat(FmtInfo->Format); - if( GLFmt == 0 ) + if (GLFmt == 0) { - VERIFY( !FmtInfo->Supported, "Format should be marked as unsupported" ); + VERIFY(!FmtInfo->Supported, "Format should be marked as unsupported"); continue; } -#if GL_ARB_internalformat_query2 +# if GL_ARB_internalformat_query2 // Only works on GL4.3+ - if( bGL43OrAbove ) + if (bGL43OrAbove) { GLint params = 0; - glGetInternalformativ( GL_TEXTURE_2D, GLFmt, GL_INTERNALFORMAT_SUPPORTED, 1, ¶ms ); - CHECK_GL_ERROR( "glGetInternalformativ() failed" ); - VERIFY( FmtInfo->Supported == (params == GL_TRUE), "This internal format should be supported" ); + glGetInternalformativ(GL_TEXTURE_2D, GLFmt, GL_INTERNALFORMAT_SUPPORTED, 1, ¶ms); + CHECK_GL_ERROR("glGetInternalformativ() failed"); + VERIFY(FmtInfo->Supported == (params == GL_TRUE), "This internal format should be supported"); } -#endif +# endif // Check that the format is indeed supported if (FmtInfo->Supported) { - GLObjectWrappers::GLTextureObj TestGLTex( true ); + GLObjectWrappers::GLTextureObj TestGLTex(true); // Immediate context has not been created yet, so use raw GL functions - glBindTexture( GL_TEXTURE_2D, TestGLTex ); - CHECK_GL_ERROR( "Failed to bind texture" ); - glTexStorage2D( GL_TEXTURE_2D, 1, GLFmt, TestTextureDim, TestTextureDim ); + glBindTexture(GL_TEXTURE_2D, TestGLTex); + CHECK_GL_ERROR("Failed to bind texture"); + glTexStorage2D(GL_TEXTURE_2D, 1, GLFmt, TestTextureDim, TestTextureDim); if (glGetError() == GL_NO_ERROR) { // It turned out it is not enough to only allocate texture storage @@ -555,178 +547,196 @@ void RenderDeviceGLImpl::FlagSupportedTexFormats() if (TransferAttribs.IsCompressed) { const auto& FmtAttribs = GetTextureFormatAttribs(FmtInfo->Format); - static_assert( (TestTextureDim & (TestTextureDim-1)) == 0, "Test texture dim must be power of two!"); - auto BlockBytesInRow = (TestTextureDim/int{FmtAttribs.BlockWidth}) * int{FmtAttribs.ComponentSize}; - glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, // mip level - 0, 0, TestTextureDim, TestTextureDim, - GLFmt, - (TestTextureDim/int{FmtAttribs.BlockHeight}) * BlockBytesInRow, - ZeroData.data() ); + static_assert((TestTextureDim & (TestTextureDim - 1)) == 0, "Test texture dim must be power of two!"); + auto BlockBytesInRow = (TestTextureDim / int{FmtAttribs.BlockWidth}) * int{FmtAttribs.ComponentSize}; + glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, // mip level + 0, 0, TestTextureDim, TestTextureDim, + GLFmt, + (TestTextureDim / int{FmtAttribs.BlockHeight}) * BlockBytesInRow, + ZeroData.data()); } else { - glTexSubImage2D( GL_TEXTURE_2D, 0, // mip level - 0, 0, TestTextureDim, TestTextureDim, - TransferAttribs.PixelFormat, TransferAttribs.DataType, - ZeroData.data() ); + glTexSubImage2D(GL_TEXTURE_2D, 0, // mip level + 0, 0, TestTextureDim, TestTextureDim, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + ZeroData.data()); } if (glGetError() != GL_NO_ERROR) { LOG_WARNING_MESSAGE("Failed to upload data to a test ", TestTextureDim, "x", TestTextureDim, " ", FmtInfo->Name, " texture. " - "This likely indicates that the format is not supported despite being reported so by the device."); + "This likely indicates that the format is not supported despite being reported so by the device."); FmtInfo->Supported = false; } } else { - LOG_WARNING_MESSAGE( "Failed to allocate storage for a test ", TestTextureDim, "x", TestTextureDim, " ", FmtInfo->Name, " texture. " - "This likely indicates that the format is not supported despite being reported so by the device."); + LOG_WARNING_MESSAGE("Failed to allocate storage for a test ", TestTextureDim, "x", TestTextureDim, " ", FmtInfo->Name, " texture. " + "This likely indicates that the format is not supported despite being reported so by the device."); FmtInfo->Supported = false; } - glBindTexture( GL_TEXTURE_2D, 0 ); + glBindTexture(GL_TEXTURE_2D, 0); } } #endif } -template<typename CreateFuncType> +template <typename CreateFuncType> bool CreateTestGLTexture(GLContextState& GlCtxState, GLenum BindTarget, const GLObjectWrappers::GLTextureObj& GLTexObj, CreateFuncType CreateFunc) { GlCtxState.BindTexture(-1, BindTarget, GLTexObj); CreateFunc(); bool bSuccess = glGetError() == GL_NO_ERROR; - GlCtxState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GlCtxState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false)); return bSuccess; } -void RenderDeviceGLImpl::TestTextureFormat( TEXTURE_FORMAT TexFormat ) +void RenderDeviceGLImpl::TestTextureFormat(TEXTURE_FORMAT TexFormat) { auto& TexFormatInfo = m_TextureFormatsInfo[TexFormat]; - VERIFY( TexFormatInfo.Supported, "Texture format is not supported" ); + VERIFY(TexFormatInfo.Supported, "Texture format is not supported"); auto GLFmt = TexFormatToGLInternalTexFormat(TexFormat); - VERIFY( GLFmt != 0, "Incorrect internal GL format" ); + VERIFY(GLFmt != 0, "Incorrect internal GL format"); auto spDeviceContext = GetImmediateContext(); VERIFY(spDeviceContext, "Immediate device context has been destroyed"); - auto *pContextGL = spDeviceContext.RawPtr<DeviceContextGLImpl>(); + auto* pContextGL = spDeviceContext.RawPtr<DeviceContextGLImpl>(); auto& ContextState = pContextGL->GetContextState(); - const int TestTextureDim = 32; + const int TestTextureDim = 32; const int TestTextureDepth = 8; // Create test texture 1D TexFormatInfo.Tex1DFmt = false; - if( m_DeviceCaps.TexCaps.bTexture1DSupported && - TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED ) + if (m_DeviceCaps.TexCaps.bTexture1DSupported && + TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED) { - GLObjectWrappers::GLTextureObj TestGLTex( true ); - TexFormatInfo.Tex1DFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_1D, TestGLTex, [&]() - { - glTexStorage1D(GL_TEXTURE_1D, 1, GLFmt, TestTextureDim); - } ); + GLObjectWrappers::GLTextureObj TestGLTex(true); + TexFormatInfo.Tex1DFmt = CreateTestGLTexture( + ContextState, GL_TEXTURE_1D, TestGLTex, + [&]() // + { + glTexStorage1D(GL_TEXTURE_1D, 1, GLFmt, TestTextureDim); + } // + ); } // Create test texture 2D - TexFormatInfo.Tex2DFmt = false; - TexFormatInfo.TexCubeFmt = false; + TexFormatInfo.Tex2DFmt = false; + TexFormatInfo.TexCubeFmt = false; TexFormatInfo.ColorRenderable = false; TexFormatInfo.DepthRenderable = false; { - GLObjectWrappers::GLTextureObj TestGLTex( true ); - TexFormatInfo.Tex2DFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_2D, TestGLTex, [&]() - { - glTexStorage2D(GL_TEXTURE_2D, 1, GLFmt, TestTextureDim, TestTextureDim); - } ); + GLObjectWrappers::GLTextureObj TestGLTex(true); + TexFormatInfo.Tex2DFmt = CreateTestGLTexture( + ContextState, GL_TEXTURE_2D, TestGLTex, + [&]() // + { + glTexStorage2D(GL_TEXTURE_2D, 1, GLFmt, TestTextureDim, TestTextureDim); + } // + ); - if( TexFormatInfo.Tex2DFmt ) + if (TexFormatInfo.Tex2DFmt) { { - GLObjectWrappers::GLTextureObj TestGLCubeTex( true ); - TexFormatInfo.TexCubeFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_CUBE_MAP, TestGLCubeTex, [&]() - { - glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GLFmt, TestTextureDim, TestTextureDim); - } ); + GLObjectWrappers::GLTextureObj TestGLCubeTex(true); + TexFormatInfo.TexCubeFmt = CreateTestGLTexture( + ContextState, GL_TEXTURE_CUBE_MAP, TestGLCubeTex, + [&]() // + { + glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GLFmt, TestTextureDim, TestTextureDim); + } // + ); } - bool bTestDepthAttachment = + bool bTestDepthAttachment = TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL; bool bTestColorAttachment = !bTestDepthAttachment && TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED; GLObjectWrappers::GLFrameBufferObj NewFBO(false); - + GLint CurrentFramebuffer = -1; - if( bTestColorAttachment || bTestDepthAttachment ) + if (bTestColorAttachment || bTestDepthAttachment) { - glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &CurrentFramebuffer ); - CHECK_GL_ERROR( "Failed to get current framebuffer"); + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &CurrentFramebuffer); + CHECK_GL_ERROR("Failed to get current framebuffer"); NewFBO.Create(); - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, NewFBO ); - CHECK_GL_ERROR( "Failed to bind the framebuffer"); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, NewFBO); + CHECK_GL_ERROR("Failed to bind the framebuffer"); } - if( bTestDepthAttachment ) + if (bTestDepthAttachment) { GLenum Attachment = TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT; - glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, Attachment, GL_TEXTURE_2D, TestGLTex, 0 ); - if( glGetError() == GL_NO_ERROR ) + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, Attachment, GL_TEXTURE_2D, TestGLTex, 0); + if (glGetError() == GL_NO_ERROR) { // Create dummy texture2D since some older version do not allow depth only // attachments - GLObjectWrappers::GLTextureObj ColorTex( true ); - bool Success = CreateTestGLTexture( ContextState, GL_TEXTURE_2D, ColorTex, [&]() - { - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, TestTextureDim, TestTextureDim); - } ); - VERIFY( Success, "Failed to create dummy render target texture" ); (void)Success; - glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorTex, 0 ); - CHECK_GL_ERROR( "Failed to set bind dummy render target to framebuffer" ); - - static const GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers( _countof( DrawBuffers ), DrawBuffers ); - CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); - - GLenum Status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); + GLObjectWrappers::GLTextureObj ColorTex(true); + + bool Success = CreateTestGLTexture( + ContextState, GL_TEXTURE_2D, ColorTex, + [&]() // + { + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, TestTextureDim, TestTextureDim); + } // + ); + VERIFY(Success, "Failed to create dummy render target texture"); + (void)Success; + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorTex, 0); + CHECK_GL_ERROR("Failed to set bind dummy render target to framebuffer"); + + static const GLenum DrawBuffers[] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(_countof(DrawBuffers), DrawBuffers); + CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()"); + + GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); TexFormatInfo.DepthRenderable = (glGetError() == GL_NO_ERROR) && (Status == GL_FRAMEBUFFER_COMPLETE); } } - else if( bTestColorAttachment ) + else if (bTestColorAttachment) { - glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TestGLTex, 0 ); - if( glGetError() == GL_NO_ERROR ) + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TestGLTex, 0); + if (glGetError() == GL_NO_ERROR) { - static const GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers( _countof( DrawBuffers ), DrawBuffers ); - CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); + static const GLenum DrawBuffers[] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(_countof(DrawBuffers), DrawBuffers); + CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()"); - GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); TexFormatInfo.ColorRenderable = (glGetError() == GL_NO_ERROR) && (Status == GL_FRAMEBUFFER_COMPLETE); } } - if( bTestColorAttachment || bTestDepthAttachment ) + if (bTestColorAttachment || bTestDepthAttachment) { - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, CurrentFramebuffer ); - CHECK_GL_ERROR( "Failed to bind the framebuffer"); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, CurrentFramebuffer); + CHECK_GL_ERROR("Failed to bind the framebuffer"); } } } TexFormatInfo.SampleCounts = 0x01; - if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED && - m_DeviceCaps.TexCaps.bTexture2DMSSupported ) + if (TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED && + m_DeviceCaps.TexCaps.bTexture2DMSSupported) { #if GL_ARB_texture_storage_multisample for (GLsizei SampleCount = 2; SampleCount <= 8; SampleCount *= 2) { - GLObjectWrappers::GLTextureObj TestGLTex( true ); - auto SampleCountSupported = CreateTestGLTexture( ContextState, GL_TEXTURE_2D_MULTISAMPLE, TestGLTex, [&]() - { - glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SampleCount, GLFmt, TestTextureDim, TestTextureDim, GL_TRUE); - } ); + GLObjectWrappers::GLTextureObj TestGLTex(true); + + auto SampleCountSupported = CreateTestGLTexture( + ContextState, GL_TEXTURE_2D_MULTISAMPLE, TestGLTex, + [&]() // + { + glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SampleCount, GLFmt, TestTextureDim, TestTextureDim, GL_TRUE); + } // + ); if (SampleCountSupported) TexFormatInfo.SampleCounts |= SampleCount; } @@ -736,34 +746,37 @@ void RenderDeviceGLImpl::TestTextureFormat( TEXTURE_FORMAT TexFormat ) // Create test texture 3D TexFormatInfo.Tex3DFmt = false; // 3D textures do not support depth formats - if( !(TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || - TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) ) + if (!(TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL)) { - GLObjectWrappers::GLTextureObj TestGLTex( true ); - TexFormatInfo.Tex3DFmt = CreateTestGLTexture( ContextState, GL_TEXTURE_3D, TestGLTex, [&]() - { - glTexStorage3D(GL_TEXTURE_3D, 1, GLFmt, TestTextureDim, TestTextureDim, TestTextureDepth); - } ); + GLObjectWrappers::GLTextureObj TestGLTex(true); + TexFormatInfo.Tex3DFmt = CreateTestGLTexture( + ContextState, GL_TEXTURE_3D, TestGLTex, + [&]() // + { + glTexStorage3D(GL_TEXTURE_3D, 1, GLFmt, TestTextureDim, TestTextureDim, TestTextureDepth); + } // + ); } } -void RenderDeviceGLImpl :: QueryDeviceCaps() +void RenderDeviceGLImpl ::QueryDeviceCaps() { - if(glPolygonMode == nullptr) + if (glPolygonMode == nullptr) m_DeviceCaps.bWireframeFillSupported = false; - - if(m_DeviceCaps.bWireframeFillSupported) + + if (m_DeviceCaps.bWireframeFillSupported) { // Test glPolygonMode() function to check if it fails - // (It does fail on NVidia Shield tablet, but works fine + // (It does fail on NVidia Shield tablet, but works fine // on Intel hw) - VERIFY( glGetError() == GL_NO_ERROR, "Unhandled gl error encountered" ); + VERIFY(glGetError() == GL_NO_ERROR, "Unhandled gl error encountered"); m_DeviceCaps.bWireframeFillSupported = True; - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - if( glGetError() != GL_NO_ERROR ) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (glGetError() != GL_NO_ERROR) m_DeviceCaps.bWireframeFillSupported = False; - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - if( glGetError() != GL_NO_ERROR ) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (glGetError() != GL_NO_ERROR) m_DeviceCaps.bWireframeFillSupported = False; } } @@ -775,7 +788,7 @@ FBOCache& RenderDeviceGLImpl::GetFBOCache(GLContext::NativeGLContextType Context return m_FBOCache[Context]; } -void RenderDeviceGLImpl::OnReleaseTexture(ITexture *pTexture) +void RenderDeviceGLImpl::OnReleaseTexture(ITexture* pTexture) { ThreadingTools::LockHelper FBOCacheLock(m_FBOCacheLockFlag); for (auto& FBOCacheIt : m_FBOCache) @@ -788,14 +801,14 @@ VAOCache& RenderDeviceGLImpl::GetVAOCache(GLContext::NativeGLContextType Context return m_VAOCache[Context]; } -void RenderDeviceGLImpl::OnDestroyPSO(IPipelineState *pPSO) +void RenderDeviceGLImpl::OnDestroyPSO(IPipelineState* pPSO) { ThreadingTools::LockHelper VAOCacheLock(m_VAOCacheLockFlag); for (auto& VAOCacheIt : m_VAOCache) VAOCacheIt.second.OnDestroyPSO(pPSO); } -void RenderDeviceGLImpl::OnDestroyBuffer(IBuffer *pBuffer) +void RenderDeviceGLImpl::OnDestroyBuffer(IBuffer* pBuffer) { ThreadingTools::LockHelper VAOCacheLock(m_VAOCacheLockFlag); for (auto& VAOCacheIt : m_VAOCache) @@ -807,4 +820,4 @@ void RenderDeviceGLImpl::IdleGPU() glFinish(); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp index 1b18fe6e..9ddbac3a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp @@ -29,7 +29,8 @@ namespace Diligent { -SamplerGLImpl::SamplerGLImpl(IReferenceCounters *pRefCounters, class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal) : +SamplerGLImpl::SamplerGLImpl(IReferenceCounters* pRefCounters, class RenderDeviceGLImpl* pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal) : + // clang-format off TSamplerBase { pRefCounters, @@ -38,78 +39,80 @@ SamplerGLImpl::SamplerGLImpl(IReferenceCounters *pRefCounters, class RenderDevic bIsDeviceInternal }, m_GlSampler{true} +// clang-format on { const auto& SamCaps = pDeviceGL->GetDeviceCaps().SamCaps; - Bool bMinAnisotropic = False, bMagAnisotropic = False, bMipAnisotropic = False; - Bool bMinComparison = False, bMagComparison = False, bMipComparison = False; - GLenum GLMinFilter, GLMagFilter, GLMipFilter; + Bool bMinAnisotropic = False, bMagAnisotropic = False, bMipAnisotropic = False; + Bool bMinComparison = False, bMagComparison = False, bMipComparison = False; + GLenum GLMinFilter, GLMagFilter, GLMipFilter; FilterTypeToGLFilterType(SamplerDesc.MinFilter, GLMinFilter, bMinAnisotropic, bMinComparison); FilterTypeToGLFilterType(SamplerDesc.MagFilter, GLMagFilter, bMagAnisotropic, bMagComparison); FilterTypeToGLFilterType(SamplerDesc.MipFilter, GLMipFilter, bMipAnisotropic, bMipComparison); - VERIFY( bMinAnisotropic == bMagAnisotropic && bMagAnisotropic == bMipAnisotropic, "Incosistent anisotropy filter setting" ); - VERIFY( bMinComparison == bMagComparison && bMagComparison == bMipComparison, "Incosistent comparison filter setting" ); - + VERIFY(bMinAnisotropic == bMagAnisotropic && bMagAnisotropic == bMipAnisotropic, "Incosistent anisotropy filter setting"); + VERIFY(bMinComparison == bMagComparison && bMagComparison == bMipComparison, "Incosistent comparison filter setting"); + glSamplerParameteri(m_GlSampler, GL_TEXTURE_MAG_FILTER, GLMagFilter); GLenum GlMinMipFilter = 0; - if( GLMinFilter == GL_NEAREST && GLMipFilter == GL_NEAREST ) + if (GLMinFilter == GL_NEAREST && GLMipFilter == GL_NEAREST) GlMinMipFilter = GL_NEAREST_MIPMAP_NEAREST; - else if( GLMinFilter == GL_LINEAR && GLMipFilter == GL_NEAREST ) + else if (GLMinFilter == GL_LINEAR && GLMipFilter == GL_NEAREST) GlMinMipFilter = GL_LINEAR_MIPMAP_NEAREST; - else if( GLMinFilter == GL_NEAREST && GLMipFilter == GL_LINEAR ) + else if (GLMinFilter == GL_NEAREST && GLMipFilter == GL_LINEAR) GlMinMipFilter = GL_NEAREST_MIPMAP_LINEAR; - else if( GLMinFilter == GL_LINEAR && GLMipFilter == GL_LINEAR ) + else if (GLMinFilter == GL_LINEAR && GLMipFilter == GL_LINEAR) GlMinMipFilter = GL_LINEAR_MIPMAP_LINEAR; else - LOG_ERROR_AND_THROW( "Unsupported min/mip filter combination" ); + LOG_ERROR_AND_THROW("Unsupported min/mip filter combination"); glSamplerParameteri(m_GlSampler, GL_TEXTURE_MIN_FILTER, GlMinMipFilter); - GLenum WrapModes[3] = { 0 }; + GLenum WrapModes[3] = {0}; + TEXTURE_ADDRESS_MODE AddressModes[] = + { + SamplerDesc.AddressU, + SamplerDesc.AddressV, + SamplerDesc.AddressW // + }; + for (int i = 0; i < _countof(AddressModes); ++i) { - SamplerDesc.AddressU, - SamplerDesc.AddressV, - SamplerDesc.AddressW - }; - for( int i = 0; i < _countof( AddressModes ); ++i ) - { - auto &WrapMode = WrapModes[i]; - WrapMode = TexAddressModeToGLAddressMode( AddressModes[i] ); - if( !SamCaps.bBorderSamplingModeSupported && WrapMode == GL_CLAMP_TO_BORDER ) + auto& WrapMode = WrapModes[i]; + WrapMode = TexAddressModeToGLAddressMode(AddressModes[i]); + if (!SamCaps.bBorderSamplingModeSupported && WrapMode == GL_CLAMP_TO_BORDER) { - LOG_ERROR_MESSAGE( "GL_CLAMP_TO_BORDER filtering mode is not supported. Defaulting to GL_CLAMP_TO_EDGE.\n" ); + LOG_ERROR_MESSAGE("GL_CLAMP_TO_BORDER filtering mode is not supported. Defaulting to GL_CLAMP_TO_EDGE.\n"); WrapMode = GL_CLAMP_TO_EDGE; } } glSamplerParameteri(m_GlSampler, GL_TEXTURE_WRAP_S, WrapModes[0]); glSamplerParameteri(m_GlSampler, GL_TEXTURE_WRAP_T, WrapModes[1]); glSamplerParameteri(m_GlSampler, GL_TEXTURE_WRAP_R, WrapModes[2]); - - if( SamCaps.bLODBiasSupported ) // Can be unsupported + + if (SamCaps.bLODBiasSupported) // Can be unsupported glSamplerParameterf(m_GlSampler, GL_TEXTURE_LOD_BIAS, SamplerDesc.MipLODBias); else { - if( SamplerDesc.MipLODBias ) - LOG_WARNING_MESSAGE( "Texture LOD bias sampler attribute is not supported\n" ); + if (SamplerDesc.MipLODBias) + LOG_WARNING_MESSAGE("Texture LOD bias sampler attribute is not supported\n"); } - - if( SamCaps.bAnisotropicFilteringSupported ) // Can be unsupported + + if (SamCaps.bAnisotropicFilteringSupported) // Can be unsupported glSamplerParameterf(m_GlSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, bMipAnisotropic ? static_cast<float>(SamplerDesc.MaxAnisotropy) : 1.f); else { - if( bMipAnisotropic && SamplerDesc.MaxAnisotropy != 1 ) - LOG_WARNING_MESSAGE( "Max anisotropy sampler attribute is not supported\n" ); + if (bMipAnisotropic && SamplerDesc.MaxAnisotropy != 1) + LOG_WARNING_MESSAGE("Max anisotropy sampler attribute is not supported\n"); } glSamplerParameteri(m_GlSampler, GL_TEXTURE_COMPARE_MODE, bMinComparison ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE); - - if( SamCaps.bBorderSamplingModeSupported ) // Can be unsupported + + if (SamCaps.bBorderSamplingModeSupported) // Can be unsupported glSamplerParameterfv(m_GlSampler, GL_TEXTURE_BORDER_COLOR, SamplerDesc.BorderColor); else { - if( SamplerDesc.BorderColor[0] != 0 || SamplerDesc.BorderColor[1] != 0 || SamplerDesc.BorderColor[2] != 0 || SamplerDesc.BorderColor[3] != 0 ) - LOG_WARNING_MESSAGE( "Border color sampler attribute is not supported\n" ); + if (SamplerDesc.BorderColor[0] != 0 || SamplerDesc.BorderColor[1] != 0 || SamplerDesc.BorderColor[2] != 0 || SamplerDesc.BorderColor[3] != 0) + LOG_WARNING_MESSAGE("Border color sampler attribute is not supported\n"); } GLenum GLCompareFunc = CompareFuncToGLCompareFunc(SamplerDesc.ComparisonFunc); glSamplerParameteri(m_GlSampler, GL_TEXTURE_COMPARE_FUNC, GLCompareFunc); @@ -122,9 +125,8 @@ SamplerGLImpl::SamplerGLImpl(IReferenceCounters *pRefCounters, class RenderDevic SamplerGLImpl::~SamplerGLImpl() { - } -IMPLEMENT_QUERY_INTERFACE( SamplerGLImpl, IID_SamplerGL, TSamplerBase ) +IMPLEMENT_QUERY_INTERFACE(SamplerGLImpl, IID_SamplerGL, TSamplerBase) -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index d952f330..95d4963f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -34,10 +34,11 @@ using namespace Diligent; namespace Diligent { -ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDeviceGL, - const ShaderCreateInfo& CreationAttribs, - bool bIsDeviceInternal) : +ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDeviceGL, + const ShaderCreateInfo& CreationAttribs, + bool bIsDeviceInternal) : + // clang-format off TShaderBase { pRefCounters, @@ -46,43 +47,44 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, bIsDeviceInternal }, m_GLShaderObj{true, GLObjectWrappers::GLShaderObjCreateReleaseHelper{GetGLShaderType(m_Desc.ShaderType)}} +// clang-format on { auto GLSLSource = BuildGLSLSourceString(CreationAttribs, pDeviceGL->GetDeviceCaps(), TargetGLSLCompiler::driver); // Note: there is a simpler way to create the program: //m_uiShaderSeparateProg = glCreateShaderProgramv(GL_VERTEX_SHADER, _countof(ShaderStrings), ShaderStrings); - // NOTE: glCreateShaderProgramv() is considered equivalent to both a shader compilation and a program linking - // operation. Since it performs both at the same time, compiler or linker errors can be encountered. However, - // since this function only returns a program object, compiler-type errors will be reported as linker errors + // NOTE: glCreateShaderProgramv() is considered equivalent to both a shader compilation and a program linking + // operation. Since it performs both at the same time, compiler or linker errors can be encountered. However, + // since this function only returns a program object, compiler-type errors will be reported as linker errors // through the following API: // GLint isLinked = 0; // glGetProgramiv(program, GL_LINK_STATUS, &isLinked); // The log can then be queried in the same way - // Each element in the length array may contain the length of the corresponding string + // Each element in the length array may contain the length of the corresponding string // (the null character is not counted as part of the string length). // Not specifying lengths causes shader compilation errors on Android - const char* ShaderStrings[] = { GLSLSource.c_str() }; - GLint Lenghts[] = { static_cast<GLint>(GLSLSource.length()) }; + const char* ShaderStrings[] = {GLSLSource.c_str()}; + GLint Lenghts[] = {static_cast<GLint>(GLSLSource.length())}; // Provide source strings (the strings will be saved in internal OpenGL memory) - glShaderSource(m_GLShaderObj, _countof(ShaderStrings), ShaderStrings, Lenghts ); + glShaderSource(m_GLShaderObj, _countof(ShaderStrings), ShaderStrings, Lenghts); // When the shader is compiled, it will be compiled as if all of the given strings were concatenated end-to-end. glCompileShader(m_GLShaderObj); GLint compiled = GL_FALSE; // Get compilation status glGetShaderiv(m_GLShaderObj, GL_COMPILE_STATUS, &compiled); - if(!compiled) + if (!compiled) { std::string FullSource; - for(const auto* str : ShaderStrings) + for (const auto* str : ShaderStrings) FullSource.append(str); std::stringstream ErrorMsgSS; - ErrorMsgSS << "Failed to compile shader file '"<< (CreationAttribs.Desc.Name != nullptr ? CreationAttribs.Desc.Name : "") << '\'' << std::endl; + ErrorMsgSS << "Failed to compile shader file '" << (CreationAttribs.Desc.Name != nullptr ? CreationAttribs.Desc.Name : "") << '\'' << std::endl; int infoLogLen = 0; - // The function glGetShaderiv() tells how many bytes to allocate; the length includes the NULL terminator. + // The function glGetShaderiv() tells how many bytes to allocate; the length includes the NULL terminator. glGetShaderiv(m_GLShaderObj, GL_INFO_LOG_LENGTH, &infoLogLen); std::vector<GLchar> infoLog(infoLogLen); @@ -90,18 +92,19 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, { int charsWritten = 0; // Get the log. infoLogLen is the size of infoLog. This tells OpenGL how many bytes at maximum it will write - // charsWritten is a return value, specifying how many bytes it actually wrote. One may pass NULL if he + // charsWritten is a return value, specifying how many bytes it actually wrote. One may pass NULL if he // doesn't care glGetShaderInfoLog(m_GLShaderObj, infoLogLen, &charsWritten, infoLog.data()); - VERIFY(charsWritten == infoLogLen-1, "Unexpected info log length"); - ErrorMsgSS << "InfoLog:" << std::endl << infoLog.data() << std::endl; + VERIFY(charsWritten == infoLogLen - 1, "Unexpected info log length"); + ErrorMsgSS << "InfoLog:" << std::endl + << infoLog.data() << std::endl; } if (CreationAttribs.ppCompilerOutput != nullptr) { // infoLogLen accounts for null terminator auto* pOutputDataBlob = MakeNewRCObj<DataBlobImpl>()(infoLogLen + FullSource.length() + 1); - char* DataPtr = reinterpret_cast<char*>(pOutputDataBlob->GetDataPtr()); + char* DataPtr = reinterpret_cast<char*>(pOutputDataBlob->GetDataPtr()); if (infoLogLen > 0) memcpy(DataPtr, infoLog.data(), infoLogLen); memcpy(DataPtr + infoLogLen, FullSource.data(), FullSource.length() + 1); @@ -110,7 +113,9 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, else { // Dump full source code to debug output - LOG_INFO_MESSAGE("Failed shader full source: \n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", FullSource, "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); + LOG_INFO_MESSAGE("Failed shader full source: \n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", + FullSource, + "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } LOG_ERROR_AND_THROW(ErrorMsgSS.str().c_str()); @@ -118,13 +123,13 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, if (pDeviceGL->GetDeviceCaps().bSeparableProgramSupported) { - IShader* ThisShader[] = {this}; - GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true); - Uint32 UniformBufferBinding = 0; - Uint32 SamplerBinding = 0; - Uint32 ImageBinding = 0; - Uint32 StorageBufferBinding = 0; - auto pImmediateCtx = m_pDevice->GetImmediateContext(); + IShader* ThisShader[] = {this}; + GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true); + Uint32 UniformBufferBinding = 0; + Uint32 SamplerBinding = 0; + Uint32 ImageBinding = 0; + Uint32 StorageBufferBinding = 0; + auto pImmediateCtx = m_pDevice->GetImmediateContext(); VERIFY_EXPR(pImmediateCtx); auto& GLState = pImmediateCtx.RawPtr<DeviceContextGLImpl>()->GetContextState(); m_Resources.LoadUniforms(m_Desc.ShaderType, Program, GLState, UniformBufferBinding, SamplerBinding, ImageBinding, StorageBufferBinding); @@ -135,7 +140,7 @@ ShaderGLImpl::~ShaderGLImpl() { } -IMPLEMENT_QUERY_INTERFACE( ShaderGLImpl, IID_ShaderGL, TShaderBase ) +IMPLEMENT_QUERY_INTERFACE(ShaderGLImpl, IID_ShaderGL, TShaderBase) GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Uint32 NumShaders, bool IsSeparableProgram) @@ -182,7 +187,7 @@ GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Ui // Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog. glGetProgramInfoLog(GLProg, LengthWithNull, &Length, shaderProgramInfoLog.data()); - VERIFY(Length == LengthWithNull-1, "Incorrect program info log len"); + VERIFY(Length == LengthWithNull - 1, "Incorrect program info log len"); LOG_ERROR_MESSAGE("Failed to link shader program:\n", shaderProgramInfoLog.data(), '\n'); UNEXPECTED("glLinkProgram failed"); } @@ -197,7 +202,7 @@ GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Ui return GLProg; } -Uint32 ShaderGLImpl::GetResourceCount()const +Uint32 ShaderGLImpl::GetResourceCount() const { if (m_pDevice->GetDeviceCaps().bSeparableProgramSupported) { @@ -210,7 +215,7 @@ Uint32 ShaderGLImpl::GetResourceCount()const } } -ShaderResourceDesc ShaderGLImpl::GetResource(Uint32 Index)const +ShaderResourceDesc ShaderGLImpl::GetResource(Uint32 Index) const { ShaderResourceDesc ResourceDesc; if (m_pDevice->GetDeviceCaps().bSeparableProgramSupported) @@ -225,4 +230,4 @@ ShaderResourceDesc ShaderGLImpl::GetResource(Uint32 Index)const return ResourceDesc; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp index da861c71..cb474291 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp @@ -30,21 +30,24 @@ namespace Diligent { -ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, - PipelineStateGLImpl* pPSO, - GLProgramResources* ProgramResources, - Uint32 NumPrograms) : +ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, + PipelineStateGLImpl* pPSO, + GLProgramResources* ProgramResources, + Uint32 NumPrograms) : + // clang-format off TBase { pRefCounters, pPSO }, m_ResourceLayout{*this} +// clang-format on { pPSO->InitializeSRBResourceCache(m_ResourceCache); // Copy only mutable and dynamic variables from master resource layout const SHADER_RESOURCE_VARIABLE_TYPE SRBVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + const auto& ResourceLayout = pPSO->GetDesc().ResourceLayout; m_ResourceLayout.Initialize(ProgramResources, NumPrograms, ResourceLayout, SRBVarTypes, _countof(SRBVarTypes), &m_ResourceCache); } @@ -104,15 +107,15 @@ void ShaderResourceBindingGLImpl::InitializeStaticResources(const IPipelineState DEV_CHECK_ERR(pPipelineState->IsCompatibleWith(GetPipelineState()), "The pipeline state is not compatible with this SRB"); } - const auto* pPSOGL = ValidatedCast<const PipelineStateGLImpl>(pPipelineState); + const auto* pPSOGL = ValidatedCast<const PipelineStateGLImpl>(pPipelineState); const auto& StaticResLayout = pPSOGL->GetStaticResourceLayout(); #ifdef DEVELOPMENT if (!StaticResLayout.dvpVerifyBindings(pPSOGL->GetStaticResourceCache())) { - LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSOGL->GetDesc().Name, "' will not be successfully initialized " - "because not all static resource bindings in shader '", pPSOGL->GetDesc().Name, "' are valid. " - "Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " + LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSOGL->GetDesc().Name, + "' will not be successfully initialized because not all static resource bindings in shader '", pPSOGL->GetDesc().Name, + "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } #endif @@ -121,4 +124,4 @@ void ShaderResourceBindingGLImpl::InitializeStaticResources(const IPipelineState m_bIsStaticResourcesBound = true; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp index e227ac3d..c47b8812 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -28,11 +28,12 @@ namespace Diligent { -SwapChainGLImpl::SwapChainGLImpl(IReferenceCounters* pRefCounters, - const EngineGLCreateInfo& InitAttribs, - const SwapChainDesc& SCDesc, - RenderDeviceGLImpl* pRenderDeviceGL, - DeviceContextGLImpl* pImmediateContextGL) : +SwapChainGLImpl::SwapChainGLImpl(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SCDesc, + RenderDeviceGLImpl* pRenderDeviceGL, + DeviceContextGLImpl* pImmediateContextGL) : + // clang-format off TSwapChainBase { pRefCounters, @@ -40,35 +41,36 @@ SwapChainGLImpl::SwapChainGLImpl(IReferenceCounters* pRefCounters, pImmediateContextGL, SCDesc } +// clang-format on { #if PLATFORM_WIN32 HWND hWnd = reinterpret_cast<HWND>(InitAttribs.pNativeWndHandle); RECT rc; GetClientRect(hWnd, &rc); - m_SwapChainDesc.Width = rc.right - rc.left; + m_SwapChainDesc.Width = rc.right - rc.left; m_SwapChainDesc.Height = rc.bottom - rc.top; #elif PLATFORM_LINUX - auto wnd = static_cast<Window>(reinterpret_cast<size_t>(InitAttribs.pNativeWndHandle)); + auto wnd = static_cast<Window>(reinterpret_cast<size_t>(InitAttribs.pNativeWndHandle)); auto display = reinterpret_cast<Display*>(InitAttribs.pDisplay); XWindowAttributes XWndAttribs; XGetWindowAttributes(display, wnd, &XWndAttribs); - m_SwapChainDesc.Width = XWndAttribs.width; + m_SwapChainDesc.Width = XWndAttribs.width; m_SwapChainDesc.Height = XWndAttribs.height; #elif PLATFORM_ANDROID - auto &GLContext = pRenderDeviceGL->m_GLContext; - m_SwapChainDesc.Width = GLContext.GetScreenWidth(); + auto& GLContext = pRenderDeviceGL->m_GLContext; + m_SwapChainDesc.Width = GLContext.GetScreenWidth(); m_SwapChainDesc.Height = GLContext.GetScreenHeight(); #elif PLATFORM_MACOS //Set dummy width and height until resize is called by the app - m_SwapChainDesc.Width = 1024; + m_SwapChainDesc.Width = 1024; m_SwapChainDesc.Height = 768; #else -# error Unsupported platform +# error Unsupported platform #endif - CreateDummyBuffers(pRenderDeviceGL); + CreateDummyBuffers(pRenderDeviceGL); } void SwapChainGLImpl::CreateDummyBuffers(RenderDeviceGLImpl* pRenderDeviceGL) @@ -85,9 +87,9 @@ void SwapChainGLImpl::CreateDummyBuffers(RenderDeviceGLImpl* pRenderDeviceGL) m_pRenderTargetView = ValidatedCast<TextureViewGLImpl>(pDummyColorBuffer->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET)); TextureDesc DepthBuffDesc = ColorBuffDesc; - DepthBuffDesc.Name = "Main depth buffer stub"; - DepthBuffDesc.Format = m_SwapChainDesc.DepthBufferFormat; - DepthBuffDesc.BindFlags = BIND_DEPTH_STENCIL; + DepthBuffDesc.Name = "Main depth buffer stub"; + DepthBuffDesc.Format = m_SwapChainDesc.DepthBufferFormat; + DepthBuffDesc.BindFlags = BIND_DEPTH_STENCIL; RefCntAutoPtr<TextureBaseGL> pDummyDepthBuffer; pRenderDeviceGL->CreateDummyTexture(DepthBuffDesc, RESOURCE_STATE_DEPTH_WRITE, &pDummyDepthBuffer); m_pDepthStencilView = ValidatedCast<TextureViewGLImpl>(pDummyDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL)); @@ -97,54 +99,54 @@ SwapChainGLImpl::~SwapChainGLImpl() { } -IMPLEMENT_QUERY_INTERFACE( SwapChainGLImpl, IID_SwapChainGL, TSwapChainBase ) +IMPLEMENT_QUERY_INTERFACE(SwapChainGLImpl, IID_SwapChainGL, TSwapChainBase) void SwapChainGLImpl::Present(Uint32 SyncInterval) { #if PLATFORM_WIN32 || PLATFORM_LINUX || PLATFORM_ANDROID - auto *pDeviceGL = m_pRenderDevice.RawPtr<RenderDeviceGLImpl>(); - auto &GLContext = pDeviceGL->m_GLContext; + auto* pDeviceGL = m_pRenderDevice.RawPtr<RenderDeviceGLImpl>(); + auto& GLContext = pDeviceGL->m_GLContext; GLContext.SwapBuffers(); #elif PLATFORM_MACOS LOG_ERROR("Swap buffers operation must be performed by the app on MacOS"); #else -# error Unsupported platform +# error Unsupported platform #endif } -void SwapChainGLImpl::Resize( Uint32 NewWidth, Uint32 NewHeight ) +void SwapChainGLImpl::Resize(Uint32 NewWidth, Uint32 NewHeight) { #if PLATFORM_ANDROID - auto *pDeviceGL = m_pRenderDevice.RawPtr<RenderDeviceGLImpl>(); - auto &GLContext = pDeviceGL->m_GLContext; + auto* pDeviceGL = m_pRenderDevice.RawPtr<RenderDeviceGLImpl>(); + auto& GLContext = pDeviceGL->m_GLContext; GLContext.UpdateScreenSize(); - NewWidth = GLContext.GetScreenWidth(); + NewWidth = GLContext.GetScreenWidth(); NewHeight = GLContext.GetScreenHeight(); #endif - if( TSwapChainBase::Resize( NewWidth, NewHeight ) ) + if (TSwapChainBase::Resize(NewWidth, NewHeight)) { CreateDummyBuffers(m_pRenderDevice.RawPtr<RenderDeviceGLImpl>()); auto pDeviceContext = m_wpDeviceContext.Lock(); - VERIFY( pDeviceContext, "Immediate context has been released" ); - if( pDeviceContext ) + VERIFY(pDeviceContext, "Immediate context has been released"); + if (pDeviceContext) { - auto *pImmediateCtxGL = pDeviceContext.RawPtr<DeviceContextGLImpl>(); - bool bIsDefaultFBBound = pImmediateCtxGL->IsDefaultFBBound(); + auto* pImmediateCtxGL = pDeviceContext.RawPtr<DeviceContextGLImpl>(); + bool bIsDefaultFBBound = pImmediateCtxGL->IsDefaultFBBound(); // To update the viewport is the only thing we need to do in OpenGL - if( bIsDefaultFBBound ) + if (bIsDefaultFBBound) { // Update framebuffer size and viewport pImmediateCtxGL->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - pImmediateCtxGL->SetViewports( 1, nullptr, 0, 0 ); + pImmediateCtxGL->SetViewports(1, nullptr, 0, 0); } } } } -void SwapChainGLImpl::SetFullscreenMode(const DisplayModeAttribs &DisplayMode) +void SwapChainGLImpl::SetFullscreenMode(const DisplayModeAttribs& DisplayMode) { UNSUPPORTED("OpenGL does not support switching to the fullscreen mode"); } @@ -154,4 +156,4 @@ void SwapChainGLImpl::SetWindowedMode() UNSUPPORTED("OpenGL does not support switching to the windowed mode"); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp index 429cfe83..a32e9f6f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp @@ -30,199 +30,210 @@ namespace Diligent { - static const Char* VertexShaderSource = - { - //To use any built-in input or output in the gl_PerVertex and - //gl_PerFragment blocks in separable program objects, shader code must - //redeclare those blocks prior to use. - // - // Declaring this block causes compilation error on NVidia GLES - "#ifndef GL_ES \n" - "out gl_PerVertex \n" - "{ \n" - " vec4 gl_Position; \n" - "}; \n" - "#endif \n" - - "void main() \n" - "{ \n" - " vec4 Bounds = vec4(-1.0, -1.0, 1.0, 1.0); \n" - " vec2 PosXY[4]; \n" - " PosXY[0] = Bounds.xy; \n" - " PosXY[1] = Bounds.xw; \n" - " PosXY[2] = Bounds.zy; \n" - " PosXY[3] = Bounds.zw; \n" - " gl_Position = vec4(PosXY[gl_VertexID], 0.0, 1.0);\n" - "} \n" - }; - - TexRegionRender::TexRegionRender(class RenderDeviceGLImpl* pDeviceGL) + +// clang-format off +static const Char* VertexShaderSource = +{ + //To use any built-in input or output in the gl_PerVertex and + //gl_PerFragment blocks in separable program objects, shader code must + //redeclare those blocks prior to use. + // + // Declaring this block causes compilation error on NVidia GLES + "#ifndef GL_ES \n" + "out gl_PerVertex \n" + "{ \n" + " vec4 gl_Position; \n" + "}; \n" + "#endif \n" + + "void main() \n" + "{ \n" + " vec4 Bounds = vec4(-1.0, -1.0, 1.0, 1.0); \n" + " vec2 PosXY[4]; \n" + " PosXY[0] = Bounds.xy; \n" + " PosXY[1] = Bounds.xw; \n" + " PosXY[2] = Bounds.zy; \n" + " PosXY[3] = Bounds.zw; \n" + " gl_Position = vec4(PosXY[gl_VertexID], 0.0, 1.0);\n" + "} \n" +}; +// clang-format on + +TexRegionRender::TexRegionRender(class RenderDeviceGLImpl* pDeviceGL) +{ + ShaderCreateInfo ShaderAttrs; + ShaderAttrs.Desc.Name = "TexRegionRender : Vertex shader"; + ShaderAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX; + ShaderAttrs.Source = VertexShaderSource; + constexpr bool IsInternalDeviceObject = true; + pDeviceGL->CreateShader(ShaderAttrs, &m_pVertexShader, IsInternalDeviceObject); + + + static const char* SamplerType[RESOURCE_DIM_NUM_DIMENSIONS] = {}; + + SamplerType[RESOURCE_DIM_TEX_1D] = "sampler1D"; + SamplerType[RESOURCE_DIM_TEX_1D_ARRAY] = "sampler1DArray"; + SamplerType[RESOURCE_DIM_TEX_2D] = "sampler2D"; + SamplerType[RESOURCE_DIM_TEX_2D_ARRAY] = "sampler2DArray", + SamplerType[RESOURCE_DIM_TEX_3D] = "sampler3D"; + // There is no texelFetch() for texture cube [array] + //SamplerType[RESOURCE_DIM_TEX_CUBE] = "samplerCube"; + //SamplerType[RESOURCE_DIM_TEX_CUBE_ARRAY] = "smaplerCubeArray"; + + + static const char* SrcLocations[RESOURCE_DIM_NUM_DIMENSIONS] = {}; + + SrcLocations[RESOURCE_DIM_TEX_1D] = "int(gl_FragCoord.x) + Constants.x"; + SrcLocations[RESOURCE_DIM_TEX_1D_ARRAY] = "ivec2(int(gl_FragCoord.x) + Constants.x, Constants.z)"; + SrcLocations[RESOURCE_DIM_TEX_2D] = "ivec2(gl_FragCoord.xy) + Constants.xy"; + SrcLocations[RESOURCE_DIM_TEX_2D_ARRAY] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)", + SrcLocations[RESOURCE_DIM_TEX_3D] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)"; + // There is no texelFetch() for texture cube [array] + //CoordDim[RESOURCE_DIM_TEX_CUBE] = "ivec2(gl_FragCoord.xy)"; + //CoordDim[RESOURCE_DIM_TEX_CUBE_ARRAY] = "ivec2(gl_FragCoord.xy)"; + + BufferDesc CBDesc; + CBDesc.Name = "TexRegionRender: FS constants CB"; + CBDesc.uiSizeInBytes = sizeof(Int32) * 4; + CBDesc.Usage = USAGE_DYNAMIC; + CBDesc.BindFlags = BIND_UNIFORM_BUFFER; + CBDesc.CPUAccessFlags = CPU_ACCESS_WRITE; + pDeviceGL->CreateBuffer(CBDesc, nullptr, &m_pConstantBuffer, IsInternalDeviceObject); + + PipelineStateDesc PSODesc; + auto& GraphicsPipeline = PSODesc.GraphicsPipeline; + GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; + GraphicsPipeline.RasterizerDesc.FillMode = FILL_MODE_SOLID; + + GraphicsPipeline.DepthStencilDesc.DepthEnable = False; + GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = False; + GraphicsPipeline.pVS = m_pVertexShader; + GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + + static const char* CmpTypePrefix[3] = {"", "i", "u"}; + for (Int32 Dim = RESOURCE_DIM_TEX_2D; Dim <= RESOURCE_DIM_TEX_3D; ++Dim) { - ShaderCreateInfo ShaderAttrs; - ShaderAttrs.Desc.Name = "TexRegionRender : Vertex shader"; - ShaderAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX; - ShaderAttrs.Source = VertexShaderSource; - constexpr bool IsInternalDeviceObject = true; - pDeviceGL->CreateShader(ShaderAttrs, &m_pVertexShader, IsInternalDeviceObject); - - static const char* SamplerType[RESOURCE_DIM_NUM_DIMENSIONS] = {}; - SamplerType[RESOURCE_DIM_TEX_1D] = "sampler1D"; - SamplerType[RESOURCE_DIM_TEX_1D_ARRAY] = "sampler1DArray"; - SamplerType[RESOURCE_DIM_TEX_2D] = "sampler2D"; - SamplerType[RESOURCE_DIM_TEX_2D_ARRAY] = "sampler2DArray", - SamplerType[RESOURCE_DIM_TEX_3D] = "sampler3D"; - // There is no texelFetch() for texture cube [array] - //SamplerType[RESOURCE_DIM_TEX_CUBE] = "samplerCube"; - //SamplerType[RESOURCE_DIM_TEX_CUBE_ARRAY] = "smaplerCubeArray"; - - static const char* SrcLocations[RESOURCE_DIM_NUM_DIMENSIONS] = {}; - SrcLocations[RESOURCE_DIM_TEX_1D] = "int(gl_FragCoord.x) + Constants.x"; - SrcLocations[RESOURCE_DIM_TEX_1D_ARRAY] = "ivec2(int(gl_FragCoord.x) + Constants.x, Constants.z)"; - SrcLocations[RESOURCE_DIM_TEX_2D] = "ivec2(gl_FragCoord.xy) + Constants.xy"; - SrcLocations[RESOURCE_DIM_TEX_2D_ARRAY] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)", - SrcLocations[RESOURCE_DIM_TEX_3D] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)"; - // There is no texelFetch() for texture cube [array] - //CoordDim[RESOURCE_DIM_TEX_CUBE] = "ivec2(gl_FragCoord.xy)"; - //CoordDim[RESOURCE_DIM_TEX_CUBE_ARRAY] = "ivec2(gl_FragCoord.xy)"; - - BufferDesc CBDesc; - CBDesc.Name = "TexRegionRender: FS constants CB"; - CBDesc.uiSizeInBytes = sizeof(Int32)*4; - CBDesc.Usage = USAGE_DYNAMIC; - CBDesc.BindFlags = BIND_UNIFORM_BUFFER; - CBDesc.CPUAccessFlags = CPU_ACCESS_WRITE; - pDeviceGL->CreateBuffer(CBDesc, nullptr, &m_pConstantBuffer, IsInternalDeviceObject); - - PipelineStateDesc PSODesc; - auto& GraphicsPipeline = PSODesc.GraphicsPipeline; - GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; - GraphicsPipeline.RasterizerDesc.FillMode = FILL_MODE_SOLID; - - GraphicsPipeline.DepthStencilDesc.DepthEnable = False; - GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = False; - GraphicsPipeline.pVS = m_pVertexShader; - GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - - static const char* CmpTypePrefix[3] = { "", "i", "u" }; - for (Int32 Dim = RESOURCE_DIM_TEX_2D; Dim <= RESOURCE_DIM_TEX_3D; ++Dim) + const auto* SamplerDim = SamplerType[Dim]; + const auto* SrcLocation = SrcLocations[Dim]; + for (Int32 Fmt = 0; Fmt < 3; ++Fmt) { - const auto* SamplerDim = SamplerType[Dim]; - const auto* SrcLocation = SrcLocations[Dim]; - for( Int32 Fmt = 0; Fmt < 3; ++Fmt ) - { - const auto *Prefix = CmpTypePrefix[Fmt]; - String Name = "TexRegionRender : Pixel shader "; - Name.append(Prefix); - Name.append(SamplerDim); - ShaderAttrs.Desc.Name = Name.c_str(); - ShaderAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL; - - std::stringstream SourceSS; - SourceSS << "uniform " << Prefix << SamplerDim << " gSourceTex;\n" - "layout(location = 0) out " << Prefix << "vec4 Out;\n" - "uniform cbConstants\n" - "{\n" - " ivec4 Constants;\n" - "};\n" - "void main()\n" - "{\n" - " Out = texelFetch( gSourceTex, " << SrcLocation << ", Constants.w );\n" - "}\n"; - - auto Source = SourceSS.str(); - ShaderAttrs.Source = Source.c_str(); - auto &FragmetShader = m_pFragmentShaders[Dim*3 + Fmt]; - pDeviceGL->CreateShader(ShaderAttrs, &FragmetShader, IsInternalDeviceObject); - GraphicsPipeline.pPS = FragmetShader; - - PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; - ShaderResourceVariableDesc Vars[] = + const auto* Prefix = CmpTypePrefix[Fmt]; + String Name = "TexRegionRender : Pixel shader "; + Name.append(Prefix); + Name.append(SamplerDim); + ShaderAttrs.Desc.Name = Name.c_str(); + ShaderAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL; + + std::stringstream SourceSS; + SourceSS << "uniform " << Prefix << SamplerDim << " gSourceTex;\n" + << "layout(location = 0) out " << Prefix + << "vec4 Out;\n" + "uniform cbConstants\n" + "{\n" + " ivec4 Constants;\n" + "};\n" + "void main()\n" + "{\n" + " Out = texelFetch( gSourceTex, " + << SrcLocation + << ", Constants.w );\n" + "}\n"; + + auto Source = SourceSS.str(); + ShaderAttrs.Source = Source.c_str(); + auto& FragmetShader = m_pFragmentShaders[Dim * 3 + Fmt]; + pDeviceGL->CreateShader(ShaderAttrs, &FragmetShader, IsInternalDeviceObject); + GraphicsPipeline.pPS = FragmetShader; + + PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; + ShaderResourceVariableDesc Vars[] = { - {SHADER_TYPE_PIXEL, "cbConstants", SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE} + {SHADER_TYPE_PIXEL, "cbConstants", SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE} // }; - PSODesc.ResourceLayout.NumVariables = _countof(Vars); - PSODesc.ResourceLayout.Variables = Vars; + PSODesc.ResourceLayout.NumVariables = _countof(Vars); + PSODesc.ResourceLayout.Variables = Vars; - pDeviceGL->CreatePipelineState(PSODesc, &m_pPSO[Dim*3 + Fmt], IsInternalDeviceObject); - } + pDeviceGL->CreatePipelineState(PSODesc, &m_pPSO[Dim * 3 + Fmt], IsInternalDeviceObject); } - m_pPSO[RESOURCE_DIM_TEX_2D*3]->CreateShaderResourceBinding(&m_pSRB); - m_pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "cbConstants")->Set(m_pConstantBuffer); - m_pSrcTexVar = m_pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "gSourceTex"); } + m_pPSO[RESOURCE_DIM_TEX_2D * 3]->CreateShaderResourceBinding(&m_pSRB); + m_pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "cbConstants")->Set(m_pConstantBuffer); + m_pSrcTexVar = m_pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "gSourceTex"); +} - void TexRegionRender::SetStates( DeviceContextGLImpl *pCtxGL ) - { - pCtxGL->GetRenderTargets( m_NumRenderTargets, m_pOrigRTVs, &m_pOrigDSV ); +void TexRegionRender::SetStates(DeviceContextGLImpl* pCtxGL) +{ + pCtxGL->GetRenderTargets(m_NumRenderTargets, m_pOrigRTVs, &m_pOrigDSV); - Uint32 NumViewports = 0; - pCtxGL->GetViewports( NumViewports, nullptr ); - m_OrigViewports.resize(NumViewports); - pCtxGL->GetViewports( NumViewports, m_OrigViewports.data() ); + Uint32 NumViewports = 0; + pCtxGL->GetViewports(NumViewports, nullptr); + m_OrigViewports.resize(NumViewports); + pCtxGL->GetViewports(NumViewports, m_OrigViewports.data()); - pCtxGL->GetPipelineState(&m_pOrigPSO, m_OrigBlendFactors, m_OrigStencilRef); - } + pCtxGL->GetPipelineState(&m_pOrigPSO, m_OrigBlendFactors, m_OrigStencilRef); +} - void TexRegionRender::RestoreStates( DeviceContextGLImpl *pCtxGL ) +void TexRegionRender::RestoreStates(DeviceContextGLImpl* pCtxGL) +{ + pCtxGL->SetRenderTargets(m_NumRenderTargets, m_pOrigRTVs, m_pOrigDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + for (Uint32 rt = 0; rt < _countof(m_pOrigRTVs); ++rt) { - pCtxGL->SetRenderTargets( m_NumRenderTargets, m_pOrigRTVs, m_pOrigDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); - for (Uint32 rt = 0; rt < _countof( m_pOrigRTVs ); ++rt) - { - if( m_pOrigRTVs[rt] ) - m_pOrigRTVs[rt]->Release(); - m_pOrigRTVs[rt] = nullptr; - } - m_pOrigDSV.Release(); + if (m_pOrigRTVs[rt]) + m_pOrigRTVs[rt]->Release(); + m_pOrigRTVs[rt] = nullptr; + } + m_pOrigDSV.Release(); - pCtxGL->SetViewports((Uint32)m_OrigViewports.size(), m_OrigViewports.data(), 0, 0); + pCtxGL->SetViewports((Uint32)m_OrigViewports.size(), m_OrigViewports.data(), 0, 0); - if (m_pOrigPSO) - pCtxGL->SetPipelineState( m_pOrigPSO ); - m_pOrigPSO.Release(); - pCtxGL->SetStencilRef(m_OrigStencilRef); - pCtxGL->SetBlendFactors(m_OrigBlendFactors); - } + if (m_pOrigPSO) + pCtxGL->SetPipelineState(m_pOrigPSO); + m_pOrigPSO.Release(); + pCtxGL->SetStencilRef(m_OrigStencilRef); + pCtxGL->SetBlendFactors(m_OrigBlendFactors); +} - void TexRegionRender::Render( DeviceContextGLImpl* pCtxGL, - ITextureView* pSrcSRV, - RESOURCE_DIMENSION TexType, - TEXTURE_FORMAT TexFormat, - Int32 DstToSrcXOffset, - Int32 DstToSrcYOffset, - Int32 SrcZ, - Int32 SrcMipLevel) +void TexRegionRender::Render(DeviceContextGLImpl* pCtxGL, + ITextureView* pSrcSRV, + RESOURCE_DIMENSION TexType, + TEXTURE_FORMAT TexFormat, + Int32 DstToSrcXOffset, + Int32 DstToSrcYOffset, + Int32 SrcZ, + Int32 SrcMipLevel) +{ { - { - MapHelper<int> pConstant(pCtxGL, m_pConstantBuffer, MAP_WRITE, MAP_FLAG_DISCARD); - pConstant[0] = DstToSrcXOffset; - pConstant[1] = DstToSrcYOffset; - pConstant[2] = SrcZ; - pConstant[3] = SrcMipLevel; - } + MapHelper<int> pConstant(pCtxGL, m_pConstantBuffer, MAP_WRITE, MAP_FLAG_DISCARD); + pConstant[0] = DstToSrcXOffset; + pConstant[1] = DstToSrcYOffset; + pConstant[2] = SrcZ; + pConstant[3] = SrcMipLevel; + } - const auto& TexFmtAttribs = GetTextureFormatAttribs(TexFormat); - Uint32 FSInd = TexType * 3; - if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT) - FSInd += 1; - else if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT) - FSInd += 2; + const auto& TexFmtAttribs = GetTextureFormatAttribs(TexFormat); + Uint32 FSInd = TexType * 3; + if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT) + FSInd += 1; + else if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT) + FSInd += 2; - if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_SNORM) - { - LOG_WARNING_MESSAGE("CopyData() is performed by rendering to texture.\n" - "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero."); - } + if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_SNORM) + { + LOG_WARNING_MESSAGE("CopyData() is performed by rendering to texture.\n" + "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero."); + } - DEV_CHECK_ERR(m_pPSO[FSInd], "TexRegionRender does not support this combination of texture dimension/format"); + DEV_CHECK_ERR(m_pPSO[FSInd], "TexRegionRender does not support this combination of texture dimension/format"); - pCtxGL->SetPipelineState(m_pPSO[FSInd]); - m_pSrcTexVar->Set( pSrcSRV ); - pCtxGL->CommitShaderResources(m_pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pCtxGL->SetPipelineState(m_pPSO[FSInd]); + m_pSrcTexVar->Set(pSrcSRV); + pCtxGL->CommitShaderResources(m_pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - DrawAttribs DrawAttrs; - DrawAttrs.NumVertices = 4; - pCtxGL->Draw(DrawAttrs); + DrawAttribs DrawAttrs; + DrawAttrs.NumVertices = 4; + pCtxGL->Draw(DrawAttrs); - m_pSrcTexVar->Set(nullptr); - } + m_pSrcTexVar->Set(nullptr); } + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp index 265e54a5..1dc43a13 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp @@ -32,13 +32,14 @@ namespace Diligent { -Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -49,6 +50,7 @@ Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, pInitData, bIsDeviceInternal } +// clang-format on { GLState.BindTexture(-1, m_BindTarget, m_GlTexture); @@ -68,17 +70,17 @@ Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, { if (m_Desc.MipLevels * m_Desc.ArraySize == pInitData->NumSubresources) { - for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice ) + for (Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width>>Mip, 1U), - 0, 1 }; + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), + 0, 1}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture1DArray_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - Texture1DArray_OGL::UpdateData(GLState, Mip, Slice, DstBox, pInitData->pSubResources[Slice*m_Desc.MipLevels + Mip]); + // To call the required function, we need to explicitly specify the class: + Texture1DArray_OGL::UpdateData(GLState, Mip, Slice, DstBox, pInitData->pSubResources[Slice * m_Desc.MipLevels + Mip]); } } } @@ -88,17 +90,29 @@ Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, GL_TEXTURE_1D_ARRAY, bIsDeviceInternal) +Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + GL_TEXTURE_1D_ARRAY, + bIsDeviceInternal + } +// clang-format on { } @@ -106,22 +120,22 @@ Texture1DArray_OGL::~Texture1DArray_OGL() { } -void Texture1DArray_OGL::UpdateData( GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData ) +void Texture1DArray_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); - ContextState.BindTexture( -1, m_BindTarget, m_GlTexture ); + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // Bind buffer if it is provided; copy from CPU memory otherwise GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -129,54 +143,54 @@ void Texture1DArray_OGL::UpdateData( GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); - - glTexSubImage2D(m_BindTarget, MipLevel, - DstBox.MinX, - Slice, - DstBox.MaxX - DstBox.MinX, - 1, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + + glTexSubImage2D(m_BindTarget, MipLevel, + DstBox.MinX, + Slice, + DstBox.MaxX - DstBox.MinX, + 1, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexSubImage2D.xhtml SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); - + CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void Texture1DArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void Texture1DArray_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { - if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + if (ViewDesc.NumArraySlices == m_Desc.ArraySize) { - glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 1D array to draw framebuffer" ); - glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 1D array to read framebuffer" ); + glFramebufferTexture(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 1D array to draw framebuffer"); + glFramebufferTexture(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 1D array to read framebuffer"); } - else if( ViewDesc.NumArraySlices == 1 ) + else if (ViewDesc.NumArraySlices == 1) { - // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, // cube map array texture, or multisample array texture. - glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); - CHECK_GL_ERROR( "Failed to attach texture 1D array to draw framebuffer" ); - glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); - CHECK_GL_ERROR( "Failed to attach texture 1D array to read framebuffer" ); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice); + CHECK_GL_ERROR("Failed to attach texture 1D array to draw framebuffer"); + glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice); + CHECK_GL_ERROR("Failed to attach texture 1D array to read framebuffer"); } else { - UNEXPECTED( "Only one slice or the entire texture array can be attached to a framebuffer" ); - } + UNEXPECTED("Only one slice or the entire texture array can be attached to a framebuffer"); + } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp index b93a5dc0..95fb1123 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp @@ -32,13 +32,14 @@ namespace Diligent { -Texture1D_OGL::Texture1D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +Texture1D_OGL::Texture1D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -49,6 +50,7 @@ Texture1D_OGL::Texture1D_OGL(IReferenceCounters* pRefCounters, pInitData, bIsDeviceInternal } +// clang-format on { GLState.BindTexture(-1, m_BindTarget, m_GlTexture); @@ -68,34 +70,46 @@ Texture1D_OGL::Texture1D_OGL(IReferenceCounters* pRefCounters, { if (m_Desc.MipLevels == pInitData->NumSubresources) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width>>Mip, 1U), + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), 0, 1}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture1D_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - Texture1D_OGL::UpdateData( GLState, Mip, 0, DstBox, pInitData->pSubResources[Mip] ); + // To call the required function, we need to explicitly specify the class: + Texture1D_OGL::UpdateData(GLState, Mip, 0, DstBox, pInitData->pSubResources[Mip]); } } else { - UNEXPECTED( "Incorrect number of subresources" ); + UNEXPECTED("Incorrect number of subresources"); } } - GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -Texture1D_OGL::Texture1D_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, GL_TEXTURE_1D, bIsDeviceInternal) +Texture1D_OGL::Texture1D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + GL_TEXTURE_1D, + bIsDeviceInternal + } +// clang-format on { } @@ -103,22 +117,22 @@ Texture1D_OGL::~Texture1D_OGL() { } -void Texture1D_OGL::UpdateData( GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData ) +void Texture1D_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); - ContextState.BindTexture( -1, m_BindTarget, m_GlTexture ); + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // Bind buffer if it is provided; copy from CPU memory otherwise GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -126,36 +140,36 @@ void Texture1D_OGL::UpdateData( GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glTexSubImage1D(m_BindTarget, MipLevel, - DstBox.MinX, + DstBox.MinX, DstBox.MaxX - DstBox.MinX, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTexSubImage1D.xml SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void Texture1D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void Texture1D_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { // For glFramebufferTexture1D(), if texture name is not zero, then texture target must be GL_TEXTURE_1D - glFramebufferTexture1D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 1D to draw framebuffer" ); - glFramebufferTexture1D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 1D to read framebuffer" ); + glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 1D to draw framebuffer"); + glFramebufferTexture1D(GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 1D to read framebuffer"); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp index 17ba7fe0..c333becc 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp @@ -33,13 +33,14 @@ namespace Diligent { -Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -50,21 +51,22 @@ Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, pInitData, bIsDeviceInternal } +// clang-format on { GLState.BindTexture(-1, m_BindTarget, m_GlTexture); - if( m_Desc.SampleCount > 1 ) + if (m_Desc.SampleCount > 1) { // format width height depth glTexStorage3DMultisample(m_BindTarget, m_Desc.SampleCount, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize, GL_TRUE); - // The last parameter specifies whether the image will use identical sample locations and the same number of - // samples for all texels in the image, and the sample locations will not depend on the internal format or size + // The last parameter specifies whether the image will use identical sample locations and the same number of + // samples for all texels in the image, and the sample locations will not depend on the internal format or size // of the image. CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D multisample texture array"); // * An INVALID_ENUM error is generated if sizedinternalformat is not colorrenderable, // depth - renderable, or stencil - renderable - // * An INVALID_OPERATION error is generated if samples is greater than the maximum number of samples - // supported for this target and internalformat. The maximum number of samples supported can be + // * An INVALID_OPERATION error is generated if samples is greater than the maximum number of samples + // supported for this target and internalformat. The maximum number of samples supported can be // determined by calling glGetInternalformativ with a pname of GL_SAMPLES SetDefaultGLParameters(); @@ -86,19 +88,19 @@ Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, if (pInitData != nullptr && pInitData->pSubResources != nullptr) { - if( m_Desc.MipLevels * m_Desc.ArraySize == pInitData->NumSubresources ) + if (m_Desc.MipLevels * m_Desc.ArraySize == pInitData->NumSubresources) { - for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) + for (Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U)}; + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), + 0, std::max(m_Desc.Height >> Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture2DArray_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - Texture2DArray_OGL::UpdateData(GLState, Mip, Slice, DstBox, pInitData->pSubResources[Slice*m_Desc.MipLevels + Mip]); + // To call the required function, we need to explicitly specify the class: + Texture2DArray_OGL::UpdateData(GLState, Mip, Slice, DstBox, pInitData->pSubResources[Slice * m_Desc.MipLevels + Mip]); } } } @@ -109,18 +111,29 @@ Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -Texture2DArray_OGL::Texture2DArray_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, - TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY, bIsDeviceInternal) +Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + static_cast<GLenum>(TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY), + bIsDeviceInternal + } +// clang-format on { } @@ -128,11 +141,11 @@ Texture2DArray_OGL::~Texture2DArray_OGL() { } -void Texture2DArray_OGL::UpdateData(GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData) +void Texture2DArray_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); @@ -142,8 +155,8 @@ void Texture2DArray_OGL::UpdateData(GLContextState& ContextState, GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -151,70 +164,70 @@ void Texture2DArray_OGL::UpdateData(GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - if( TransferAttribs.IsCompressed ) + if (TransferAttribs.IsCompressed) { - auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); - VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), - "Compressed texture update region must be 4 pixel-aligned" ); + VERIFY((DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), + "Compressed texture update region must be 4 pixel-aligned"); #ifdef _DEBUG { - const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); - auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; - VERIFY( SubresData.Stride == BlockBytesInRow, - "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3) / 4) * Uint32{FmtAttribs.ComponentSize}; + VERIFY(SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")"); } #endif //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; - UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); - UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); - glCompressedTexSubImage3D(m_BindTarget, MipLevel, - DstBox.MinX, - DstBox.MinY, - Slice, - UpdateRegionWidth, - UpdateRegionHeight, - 1, - // The format must be the same compressed-texture format previously - // specified by glTexStorage2D() (thank you OpenGL for another useless - // parameter that is nothing but the source of confusion), otherwise - // INVALID_OPERATION error is generated. - m_GLTexFormat, - // An INVALID_VALUE error is generated if imageSize is not consistent with - // the format, dimensions, and contents of the compressed image( too little or - // too much data ), - ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, - // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated - // as a byte offset into the buffer object's data store. - // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage3D.xhtml - SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); + glCompressedTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + Slice, + UpdateRegionWidth, + UpdateRegionHeight, + 1, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3) / 4) * SubresData.Stride, + // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated + // as a byte offset into the buffer object's data store. + // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage3D.xhtml + SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); } else { const auto TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); - const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; - VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; + VERIFY((SubresData.Stride % PixelSize) == 0, "Data stride is not multiple of pixel size"); glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glTexSubImage3D(m_BindTarget, MipLevel, - DstBox.MinX, + glTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, DstBox.MinY, Slice, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, 1, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexSubImage3D.xhtml @@ -222,34 +235,34 @@ void Texture2DArray_OGL::UpdateData(GLContextState& ContextState, } CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void Texture2DArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void Texture2DArray_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { - if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + if (ViewDesc.NumArraySlices == m_Desc.ArraySize) { - glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 2D array to draw framebuffer" ); - glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 2D array to read framebuffer" ); + glFramebufferTexture(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 2D array to draw framebuffer"); + glFramebufferTexture(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 2D array to read framebuffer"); } - else if( ViewDesc.NumArraySlices == 1 ) + else if (ViewDesc.NumArraySlices == 1) { - // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, // cube map array texture, or multisample array texture. - glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); - CHECK_GL_ERROR( "Failed to attach texture 2D array to draw framebuffer" ); - glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); - CHECK_GL_ERROR( "Failed to attach texture 2D array to read framebuffer" ); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice); + CHECK_GL_ERROR("Failed to attach texture 2D array to draw framebuffer"); + glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice); + CHECK_GL_ERROR("Failed to attach texture 2D array to read framebuffer"); } else { - UNEXPECTED( "Only one slice or the entire texture array can be attached to a framebuffer" ); + UNEXPECTED("Only one slice or the entire texture array can be attached to a framebuffer"); } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp index 823a29bb..598a6280 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -33,13 +33,14 @@ namespace Diligent { -Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +Texture2D_OGL::Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -50,27 +51,28 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, pInitData, bIsDeviceInternal } +// clang-format on { GLState.BindTexture(-1, m_BindTarget, m_GlTexture); - if( m_Desc.SampleCount > 1 ) + if (m_Desc.SampleCount > 1) { #if GL_ARB_texture_storage_multisample // format width height depth glTexStorage2DMultisample(m_BindTarget, m_Desc.SampleCount, m_GLTexFormat, m_Desc.Width, m_Desc.Height, GL_TRUE); - // The last parameter specifies whether the image will use identical sample locations and the same number of - // samples for all texels in the image, and the sample locations will not depend on the internal format or size + // The last parameter specifies whether the image will use identical sample locations and the same number of + // samples for all texels in the image, and the sample locations will not depend on the internal format or size // of the image. CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D multisample texture"); // * An INVALID_ENUM error is generated if sizedinternalformat is not colorrenderable, // depth - renderable, or stencil - renderable - // * An INVALID_OPERATION error is generated if samples is greater than the maximum number of samples - // supported for this target and internalformat. The maximum number of samples supported can be + // * An INVALID_OPERATION error is generated if samples is greater than the maximum number of samples + // supported for this target and internalformat. The maximum number of samples supported can be // determined by calling glGetInternalformativ with a pname of GL_SAMPLES SetDefaultGLParameters(); - VERIFY(pInitData == nullptr || pInitData->pSubResources == nullptr, "Multisampled textures cannot be modified directly" ); + VERIFY(pInitData == nullptr || pInitData->pSubResources == nullptr, "Multisampled textures cannot be modified directly"); #else LOG_ERROR_AND_THROW("Multisampled textures are not supported"); #endif @@ -94,15 +96,15 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, { if (m_Desc.MipLevels == pInitData->NumSubresources) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U)}; + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), + 0, std::max(m_Desc.Height >> Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture2D_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - Texture2D_OGL::UpdateData( GLState, Mip, 0, DstBox, pInitData->pSubResources[Mip] ); + // To call the required function, we need to explicitly specify the class: + Texture2D_OGL::UpdateData(GLState, Mip, 0, DstBox, pInitData->pSubResources[Mip]); } } else @@ -112,16 +114,17 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : +Texture2D_OGL::Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off TextureBaseGL { pRefCounters, @@ -133,14 +136,16 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, static_cast<GLenum>(TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D), bIsDeviceInternal } +// clang-format on { } -Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - const TextureDesc& TexDesc, - bool bIsDeviceInternal) : +Texture2D_OGL::Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal) : + // clang-format off TextureBaseGL { pRefCounters, @@ -149,6 +154,7 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, TexDesc, bIsDeviceInternal } +// clang-format on { } @@ -157,11 +163,11 @@ Texture2D_OGL::~Texture2D_OGL() { } -void Texture2D_OGL::UpdateData( GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData ) +void Texture2D_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); @@ -171,8 +177,8 @@ void Texture2D_OGL::UpdateData( GLContextState& ContextState, GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -180,24 +186,24 @@ void Texture2D_OGL::UpdateData( GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - if( TransferAttribs.IsCompressed ) + if (TransferAttribs.IsCompressed) { - auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); - VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), - "Compressed texture update region must be 4 pixel-aligned" ); + VERIFY((DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), + "Compressed texture update region must be 4 pixel-aligned"); #ifdef _DEBUG { - const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); - auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; - VERIFY( SubresData.Stride == BlockBytesInRow, - "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3) / 4) * Uint32{FmtAttribs.ComponentSize}; + VERIFY(SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")"); } #endif @@ -205,42 +211,42 @@ void Texture2D_OGL::UpdateData( GLContextState& ContextState, //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; - UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); - UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); - glCompressedTexSubImage2D(m_BindTarget, MipLevel, - DstBox.MinX, - DstBox.MinY, - UpdateRegionWidth, - UpdateRegionHeight, - // The format must be the same compressed-texture format previously - // specified by glTexStorage2D() (thank you OpenGL for another useless - // parameter that is nothing but the source of confusion), otherwise - // INVALID_OPERATION error is generated. - m_GLTexFormat, - // An INVALID_VALUE error is generated if imageSize is not consistent with - // the format, dimensions, and contents of the compressed image( too little or - // too much data ), - ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, - // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated - // as a byte offset into the buffer object's data store. - // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage2D.xhtml - SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); + glCompressedTexSubImage2D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + UpdateRegionWidth, + UpdateRegionHeight, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3) / 4) * SubresData.Stride, + // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated + // as a byte offset into the buffer object's data store. + // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage2D.xhtml + SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); } else { const auto& TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); - const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; - VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; + VERIFY((SubresData.Stride % PixelSize) == 0, "Data stride is not multiple of pixel size"); glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glTexSubImage2D(m_BindTarget, MipLevel, - DstBox.MinX, - DstBox.MinY, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + glTexSubImage2D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexSubImage2D.xhtml @@ -248,20 +254,20 @@ void Texture2D_OGL::UpdateData( GLContextState& ContextState, } CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void Texture2D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void Texture2D_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { - // For glFramebufferTexture2D(), if texture name is not zero, then texture target must be GL_TEXTURE_2D, + // For glFramebufferTexture2D(), if texture name is not zero, then texture target must be GL_TEXTURE_2D, // GL_TEXTURE_RECTANGLE or one of the 6 cubemap face targets GL_TEXTURE_CUBE_MAP_POSITIVE_X, ... - glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 2D to draw framebuffer" ); - glFramebufferTexture2D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 2D to read framebuffer" ); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 2D to draw framebuffer"); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 2D to read framebuffer"); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp index 1eb7deb0..319ab0f0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp @@ -33,13 +33,14 @@ namespace Diligent { -Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= TextureData()*/, - bool bIsDeviceInternal /*= false*/) : +Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -50,6 +51,7 @@ Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, pInitData, bIsDeviceInternal } +// clang-format on { GLState.BindTexture(-1, m_BindTarget, m_GlTexture); @@ -71,16 +73,16 @@ Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, { if (m_Desc.MipLevels == pInitData->NumSubresources) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U), - 0, std::max(m_Desc.Depth >>Mip, 1U)}; + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), + 0, std::max(m_Desc.Height >> Mip, 1U), + 0, std::max(m_Desc.Depth >> Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of Texture3D_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - Texture3D_OGL::UpdateData( GLState, Mip, 0, DstBox, pInitData->pSubResources[Mip] ); + // To call the required function, we need to explicitly specify the class: + Texture3D_OGL::UpdateData(GLState, Mip, 0, DstBox, pInitData->pSubResources[Mip]); } } else @@ -89,17 +91,29 @@ Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -Texture3D_OGL::Texture3D_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, GL_TEXTURE_3D, bIsDeviceInternal) +Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + GL_TEXTURE_3D, + bIsDeviceInternal + } +// clang-format on { } @@ -108,11 +122,11 @@ Texture3D_OGL::~Texture3D_OGL() } -void Texture3D_OGL::UpdateData( GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData ) +void Texture3D_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); @@ -122,8 +136,8 @@ void Texture3D_OGL::UpdateData( GLContextState& ContextState, GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -131,69 +145,69 @@ void Texture3D_OGL::UpdateData( GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); const auto TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); - const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; - VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; + VERIFY((SubresData.Stride % PixelSize) == 0, "Data stride is not multiple of pixel size"); glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); - VERIFY( (SubresData.DepthStride % SubresData.Stride)==0, "Depth stride is not multiple of stride" ); + VERIFY((SubresData.DepthStride % SubresData.Stride) == 0, "Depth stride is not multiple of stride"); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, SubresData.DepthStride / SubresData.Stride); - glTexSubImage3D(m_BindTarget, MipLevel, - DstBox.MinX, + glTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, DstBox.MinY, DstBox.MinZ, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, DstBox.MaxZ - DstBox.MinZ, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexSubImage3D.xhtml SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); - + CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void Texture3D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void Texture3D_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { auto NumDepthSlicesInMip = m_Desc.Depth >> ViewDesc.MostDetailedMip; - if( ViewDesc.NumDepthSlices == NumDepthSlicesInMip ) + if (ViewDesc.NumDepthSlices == NumDepthSlicesInMip) { - glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 3D to draw framebuffer" ); - glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture 3D to read framebuffer" ); + glFramebufferTexture(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 3D to draw framebuffer"); + glFramebufferTexture(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture 3D to read framebuffer"); } - else if( ViewDesc.NumDepthSlices == 1 ) + else if (ViewDesc.NumDepthSlices == 1) { // For glFramebufferTexture3D(), if texture name is not zero, then texture target must be GL_TEXTURE_3D //glFramebufferTexture3D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); //glFramebufferTexture3D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_BindTarget, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); - // On Android (at least on Intel HW), glFramebufferTexture3D() runs without errors, but the + // On Android (at least on Intel HW), glFramebufferTexture3D() runs without errors, but the // FBO turns out to be incomplete. glFramebufferTextureLayer() seems to work fine. - glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); - CHECK_GL_ERROR( "Failed to attach texture 3D to draw framebuffer" ); - glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice ); - CHECK_GL_ERROR( "Failed to attach texture 3D to read framebuffer" ); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice); + CHECK_GL_ERROR("Failed to attach texture 3D to draw framebuffer"); + glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstDepthSlice); + CHECK_GL_ERROR("Failed to attach texture 3D to read framebuffer"); } else { - UNEXPECTED( "Only one slice or the entire 3D texture can be attached to a framebuffer" ); + UNEXPECTED("Only one slice or the entire 3D texture can be attached to a framebuffer"); } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp index 1803153e..0aefa95f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -35,13 +35,14 @@ namespace Diligent { -TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - const TextureDesc& TexDesc, - GLenum BindTarget, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + GLenum BindTarget, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TTextureBase { pRefCounters, @@ -54,9 +55,10 @@ TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, m_BindTarget {BindTarget }, m_GLTexFormat {TexFormatToGLInternalTexFormat(m_Desc.Format, m_Desc.BindFlags)} //m_uiMapTarget(0) +// clang-format on { - VERIFY( m_GLTexFormat != 0, "Unsupported texture format" ); - if( TexDesc.Usage == USAGE_STATIC && pInitData == nullptr ) + VERIFY(m_GLTexFormat != 0, "Unsupported texture format"); + if (TexDesc.Usage == USAGE_STATIC && pInitData == nullptr) LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time"); } @@ -71,16 +73,16 @@ static GLenum GetTextureInternalFormat(GLContextState& GLState, GLenum BindTarge GLint GlFormat = 0; #if GL_TEXTURE_INTERNAL_FORMAT glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &GlFormat); - CHECK_GL_ERROR( "Failed to get texture format through glGetTexLevelParameteriv()" ); + CHECK_GL_ERROR("Failed to get texture format through glGetTexLevelParameteriv()"); VERIFY(GlFormat != 0, "Unable to get texture format"); VERIFY(TexFmtFromDesc == TEX_FORMAT_UNKNOWN || static_cast<GLenum>(GlFormat) == TexFormatToGLInternalTexFormat(TexFmtFromDesc), "Texture format does not match the format specified by the texture description"); #else - if(TexFmtFromDesc != TEX_FORMAT_UNKNOWN) + if (TexFmtFromDesc != TEX_FORMAT_UNKNOWN) GlFormat = TexFormatToGLInternalTexFormat(TexFmtFromDesc); else UNSUPPORTED("Texture format cannot be queried and must be provided by the texture description"); #endif - GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null()); return GlFormat; } @@ -106,7 +108,7 @@ static TextureDesc GetTextureDescFromGLHandle(GLContextState& GLState, TextureDe #else VERIFY(TexDesc.Width != 0, "Texture width query is not supported; it must be specified by the texture description."); #endif - + if (TexDesc.Type >= RESOURCE_DIM_TEX_2D) { #if GL_TEXTURE_HEIGHT @@ -114,7 +116,7 @@ static TextureDesc GetTextureDescFromGLHandle(GLContextState& GLState, TextureDe glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_HEIGHT, &TexHeight); VERIFY_EXPR(TexHeight > 0); - VERIFY(TexDesc.Height == 0 || TexDesc.Height == static_cast<Uint32>(TexHeight), "Specified texture height (", TexDesc.Height,") does not match the actual height (", TexHeight, ")"); + VERIFY(TexDesc.Height == 0 || TexDesc.Height == static_cast<Uint32>(TexHeight), "Specified texture height (", TexDesc.Height, ") does not match the actual height (", TexHeight, ")"); TexDesc.Height = static_cast<Uint32>(TexHeight); #else VERIFY(TexDesc.Height != 0, "Texture height query is not supported; it must be specified by the texture description."); @@ -135,18 +137,18 @@ static TextureDesc GetTextureDescFromGLHandle(GLContextState& GLState, TextureDe VERIFY(TexDesc.Depth != 0, "Texture depth query is not supported; it must be specified by the texture description."); #endif } - + if (TexDesc.Type == RESOURCE_DIM_TEX_1D || TexDesc.Type == RESOURCE_DIM_TEX_2D) TexDesc.ArraySize = 1; // TexDesc.Depth also - + #if GL_TEXTURE_INTERNAL_FORMAT GLint GlFormat = 0; glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &GlFormat); - CHECK_GL_ERROR( "Failed to get texture level 0 parameters through glGetTexLevelParameteriv()" ); + CHECK_GL_ERROR("Failed to get texture level 0 parameters through glGetTexLevelParameteriv()"); VERIFY(GlFormat != 0, "Unable to get texture format"); if (TexDesc.Format != TEX_FORMAT_UNKNOWN) - VERIFY(static_cast<GLenum>(GlFormat) == TexFormatToGLInternalTexFormat(TexDesc.Format), "Specified texture format (", GetTextureFormatAttribs(TexDesc.Format).Name,") does not match GL texture internal format (", GlFormat, ")"); + VERIFY(static_cast<GLenum>(GlFormat) == TexFormatToGLInternalTexFormat(TexDesc.Format), "Specified texture format (", GetTextureFormatAttribs(TexDesc.Format).Name, ") does not match GL texture internal format (", GlFormat, ")"); else TexDesc.Format = GLInternalTexFormatToTexFormat(GlFormat); #else @@ -156,7 +158,7 @@ static TextureDesc GetTextureDescFromGLHandle(GLContextState& GLState, TextureDe // GL_TEXTURE_IMMUTABLE_LEVELS is only supported in GL4.3+ and GLES3.1+ GLint MipLevels = 0; glGetTexParameteriv(BindTarget, GL_TEXTURE_IMMUTABLE_LEVELS, &MipLevels); - if(glGetError() == GL_NO_ERROR) + if (glGetError() == GL_NO_ERROR) { VERIFY(TexDesc.MipLevels == 0 || TexDesc.MipLevels == static_cast<Uint32>(MipLevels), "Specified number of mip levels (", TexDesc.MipLevels, ") does not match the actual number of mip levels (", MipLevels, ")"); TexDesc.MipLevels = static_cast<Uint32>(MipLevels); @@ -165,19 +167,20 @@ static TextureDesc GetTextureDescFromGLHandle(GLContextState& GLState, TextureDe { VERIFY(TexDesc.MipLevels != 0, "Unable to query the number of mip levels, so it must be specified by the texture description."); } - - GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + + GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null()); return TexDesc; } -TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - GLenum BindTarget, - bool bIsDeviceInternal/* = false*/) : +TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + GLenum BindTarget, + bool bIsDeviceInternal /* = false*/) : + // clang-format off TTextureBase { pRefCounters, @@ -190,14 +193,16 @@ TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, m_GlTexture {true, GLObjectWrappers::GLTextureCreateReleaseHelper(GLTextureHandle)}, m_BindTarget {BindTarget}, m_GLTexFormat {GetTextureInternalFormat(GLState, BindTarget, m_GlTexture, TexDesc.Format)} +// clang-format on { } -TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - const TextureDesc& TexDesc, - bool bIsDeviceInternal) : +TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal) : + // clang-format off TTextureBase { pRefCounters, @@ -209,6 +214,7 @@ TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, m_GlTexture {false}, m_BindTarget {0 }, m_GLTexFormat{0 } +// clang-format on { } @@ -219,17 +225,17 @@ TextureBaseGL::~TextureBaseGL() // flag is set, because CopyData() can bind // texture as render target even when no flag // is set - static_cast<RenderDeviceGLImpl*>( GetDevice() )->OnReleaseTexture(this); + static_cast<RenderDeviceGLImpl*>(GetDevice())->OnReleaseTexture(this); } -IMPLEMENT_QUERY_INTERFACE( TextureBaseGL, IID_TextureGL, TTextureBase ) +IMPLEMENT_QUERY_INTERFACE(TextureBaseGL, IID_TextureGL, TTextureBase) -void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDesc, class ITextureView **ppView, bool bIsDefaultView ) +void TextureBaseGL::CreateViewInternal(const struct TextureViewDesc& OrigViewDesc, class ITextureView** ppView, bool bIsDefaultView) { - VERIFY( ppView != nullptr, "Null pointer provided" ); - if( !ppView )return; - VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + VERIFY(ppView != nullptr, "Null pointer provided"); + if (!ppView) return; + VERIFY(*ppView == nullptr, "Overwriting reference to existing object may cause memory leaks"); *ppView = nullptr; @@ -238,52 +244,53 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe auto ViewDesc = OrigViewDesc; CorrectTextureViewDesc(ViewDesc); - auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); - auto &TexViewAllocator = pDeviceGLImpl->GetTexViewObjAllocator(); - VERIFY( &TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" ); + auto* pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); + auto& TexViewAllocator = pDeviceGLImpl->GetTexViewObjAllocator(); + VERIFY(&TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization"); // http://www.opengl.org/wiki/Texture_Storage#Texture_views - GLenum GLViewFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format, m_Desc.BindFlags ); - VERIFY( GLViewFormat != 0, "Unsupported texture format" ); - - TextureViewGLImpl *pViewOGL = nullptr; - if( ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE ) + GLenum GLViewFormat = TexFormatToGLInternalTexFormat(ViewDesc.Format, m_Desc.BindFlags); + VERIFY(GLViewFormat != 0, "Unsupported texture format"); + + TextureViewGLImpl* pViewOGL = nullptr; + if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE) { + // clang-format off bool bIsFullTextureView = - ViewDesc.TextureDim == m_Desc.Type && - ViewDesc.Format == GetDefaultTextureViewFormat( m_Desc.Format, ViewDesc.ViewType, m_Desc.BindFlags ) && - ViewDesc.MostDetailedMip == 0 && + ViewDesc.TextureDim == m_Desc.Type && + ViewDesc.Format == GetDefaultTextureViewFormat(m_Desc.Format, ViewDesc.ViewType, m_Desc.BindFlags) && + ViewDesc.MostDetailedMip == 0 && ViewDesc.NumMipLevels == m_Desc.MipLevels && - ViewDesc.FirstArraySlice == 0 && + ViewDesc.FirstArraySlice == 0 && ViewDesc.NumArraySlices == m_Desc.ArraySize; + // clang-format on pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)( - pDeviceGLImpl, ViewDesc, this, - !bIsFullTextureView, // Create OpenGL texture view object if view - // does not address the whole texture - bIsDefaultView - ); - if( !bIsFullTextureView ) + pDeviceGLImpl, ViewDesc, this, + !bIsFullTextureView, // Create OpenGL texture view object if view + // does not address the whole texture + bIsDefaultView); + if (!bIsFullTextureView) { GLenum GLViewTarget = 0; - GLuint NumLayers = ViewDesc.NumArraySlices; - switch(ViewDesc.TextureDim) + GLuint NumLayers = ViewDesc.NumArraySlices; + switch (ViewDesc.TextureDim) { case RESOURCE_DIM_TEX_1D: - GLViewTarget = GL_TEXTURE_1D; + GLViewTarget = GL_TEXTURE_1D; ViewDesc.NumArraySlices = NumLayers = 1; break; - + case RESOURCE_DIM_TEX_1D_ARRAY: GLViewTarget = GL_TEXTURE_1D_ARRAY; break; case RESOURCE_DIM_TEX_2D: - GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; + GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; ViewDesc.NumArraySlices = NumLayers = 1; break; - + case RESOURCE_DIM_TEX_2D_ARRAY: GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY; break; @@ -293,13 +300,13 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe GLViewTarget = GL_TEXTURE_3D; // If target is GL_TEXTURE_3D, NumLayers must equal 1. Uint32 MipDepth = std::max(m_Desc.Depth >> ViewDesc.MostDetailedMip, 1U); - if(ViewDesc.FirstDepthSlice != 0 || ViewDesc.NumDepthSlices != MipDepth) + if (ViewDesc.FirstDepthSlice != 0 || ViewDesc.NumDepthSlices != MipDepth) { LOG_ERROR("3D texture view '", (ViewDesc.Name ? ViewDesc.Name : ""), "' (most detailed mip: ", ViewDesc.MostDetailedMip, "; mip levels: ", ViewDesc.NumMipLevels, "; first slice: ", ViewDesc.FirstDepthSlice, "; num depth slices: ", ViewDesc.NumDepthSlices, ") of texture '", m_Desc.Name, "' does not references" - " all depth slices. 3D texture views in OpenGL must address all depth slices."); - ViewDesc.NumDepthSlices = MipDepth; + " all depth slices. 3D texture views in OpenGL must address all depth slices."); + ViewDesc.NumDepthSlices = MipDepth; ViewDesc.FirstDepthSlice = 0; } NumLayers = 1; @@ -317,114 +324,113 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe default: UNEXPECTED("Unsupported texture view type"); } - glTextureView( pViewOGL->GetHandle(), GLViewTarget, m_GlTexture, GLViewFormat, ViewDesc.MostDetailedMip, ViewDesc.NumMipLevels, ViewDesc.FirstArraySlice, NumLayers ); - CHECK_GL_ERROR_AND_THROW( "Failed to create texture view" ); + glTextureView(pViewOGL->GetHandle(), GLViewTarget, m_GlTexture, GLViewFormat, ViewDesc.MostDetailedMip, ViewDesc.NumMipLevels, ViewDesc.FirstArraySlice, NumLayers); + CHECK_GL_ERROR_AND_THROW("Failed to create texture view"); pViewOGL->SetBindTarget(GLViewTarget); } } - else if( ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS ) + else if (ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS) { - VERIFY( ViewDesc.NumArraySlices == 1 || - m_Desc.Type == RESOURCE_DIM_TEX_3D && ViewDesc.NumDepthSlices == std::max(m_Desc.Depth >> ViewDesc.MostDetailedMip, 1U) || - ViewDesc.NumArraySlices == m_Desc.ArraySize, - "Only single array/depth slice or the whole texture can be bound as UAV in OpenGL."); - VERIFY( ViewDesc.AccessFlags != 0, "At least one access flag must be specified" ); + // clang-format off + VERIFY(ViewDesc.NumArraySlices == 1 || + m_Desc.Type == RESOURCE_DIM_TEX_3D && ViewDesc.NumDepthSlices == std::max(m_Desc.Depth >> ViewDesc.MostDetailedMip, 1U) || + ViewDesc.NumArraySlices == m_Desc.ArraySize, + "Only single array/depth slice or the whole texture can be bound as UAV in OpenGL."); + // clang-format on + VERIFY(ViewDesc.AccessFlags != 0, "At least one access flag must be specified"); pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)( - pDeviceGLImpl, ViewDesc, this, - false, // Do NOT create texture view OpenGL object - bIsDefaultView - ); + pDeviceGLImpl, ViewDesc, this, + false, // Do NOT create texture view OpenGL object + bIsDefaultView); } - else if( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET ) + else if (ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET) { - VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as RTV" ); + VERIFY(ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as RTV"); pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)( - pDeviceGLImpl, ViewDesc, this, - false, // Do NOT create texture view OpenGL object - bIsDefaultView - ); + pDeviceGLImpl, ViewDesc, this, + false, // Do NOT create texture view OpenGL object + bIsDefaultView); } - else if( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL ) + else if (ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL) { - VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as DSV" ); + VERIFY(ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as DSV"); pViewOGL = NEW_RC_OBJ(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, bIsDefaultView ? this : nullptr)( - pDeviceGLImpl, ViewDesc, this, - false, // Do NOT create texture view OpenGL object - bIsDefaultView - ); + pDeviceGLImpl, ViewDesc, this, + false, // Do NOT create texture view OpenGL object + bIsDefaultView); } - if( bIsDefaultView ) + if (bIsDefaultView) *ppView = pViewOGL; else { - if( pViewOGL ) + if (pViewOGL) { - pViewOGL->QueryInterface( IID_TextureView, reinterpret_cast<IObject**>(ppView) ); + pViewOGL->QueryInterface(IID_TextureView, reinterpret_cast<IObject**>(ppView)); } } } - catch( const std::runtime_error& ) + catch (const std::runtime_error&) { - const auto *ViewTypeName = GetTexViewTypeLiteralName(OrigViewDesc.ViewType); - LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for texture \"", m_Desc.Name ? m_Desc.Name : "", "\"" ); + const auto* ViewTypeName = GetTexViewTypeLiteralName(OrigViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for texture \"", m_Desc.Name ? m_Desc.Name : "", "\""); } } -void TextureBaseGL::UpdateData( GLContextState& CtxState, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +void TextureBaseGL::UpdateData(GLContextState& CtxState, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData) { // GL_TEXTURE_UPDATE_BARRIER_BIT: - // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, - // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect - // data written by shaders prior to the barrier. Additionally, texture writes from these - // commands issued after the barrier will not execute until all shader writes initiated prior + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior // to the barrier complete - TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, CtxState ); + TextureMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT, CtxState); } //void TextureBaseGL :: UpdateData(Uint32 Offset, Uint32 Size, const PVoid pData) //{ // CTexture::UpdateData(Offset, Size, pData); -// +// // glBindTexture(GL_ARRAY_Texture, m_GlTexture); // glTextureSubData(GL_ARRAY_Texture, Offset, Size, pData); // glBindTexture(GL_ARRAY_Texture, 0); //} // -void TextureBaseGL :: CopyData(DeviceContextGLImpl* pDeviceCtxGL, - TextureBaseGL* pSrcTextureGL, - Uint32 SrcMipLevel, - Uint32 SrcSlice, - const Box* pSrcBox, - Uint32 DstMipLevel, - Uint32 DstSlice, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ) +void TextureBaseGL ::CopyData(DeviceContextGLImpl* pDeviceCtxGL, + TextureBaseGL* pSrcTextureGL, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box* pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ) { const auto& SrcTexDesc = pSrcTextureGL->GetDesc(); Box SrcBox; - if( pSrcBox == nullptr ) + if (pSrcBox == nullptr) { - SrcBox.MaxX = std::max( SrcTexDesc.Width >> SrcMipLevel, 1u ); - if( SrcTexDesc.Type == RESOURCE_DIM_TEX_1D || - SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) + SrcBox.MaxX = std::max(SrcTexDesc.Width >> SrcMipLevel, 1u); + if (SrcTexDesc.Type == RESOURCE_DIM_TEX_1D || + SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY) SrcBox.MaxY = 1; else - SrcBox.MaxY = std::max( SrcTexDesc.Height >> SrcMipLevel, 1u ); + SrcBox.MaxY = std::max(SrcTexDesc.Height >> SrcMipLevel, 1u); - if( SrcTexDesc.Type == RESOURCE_DIM_TEX_3D ) - SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> SrcMipLevel, 1u ); + if (SrcTexDesc.Type == RESOURCE_DIM_TEX_3D) + SrcBox.MaxZ = std::max(SrcTexDesc.Depth >> SrcMipLevel, 1u); else SrcBox.MaxZ = 1; pSrcBox = &SrcBox; } #if GL_ARB_copy_image - if( glCopyImageSubData ) + if (glCopyImageSubData) { GLint SrcSliceY = (SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY) ? SrcSlice : 0; GLint SrcSliceZ = (SrcTexDesc.Type == RESOURCE_DIM_TEX_2D_ARRAY) ? SrcSlice : 0; @@ -445,16 +451,16 @@ void TextureBaseGL :: CopyData(DeviceContextGLImpl* pDeviceCtxGL, DstZ + DstSliceZ, // Slice must be zero for 3D texture pSrcBox->MaxX - pSrcBox->MinX, pSrcBox->MaxY - pSrcBox->MinY, - pSrcBox->MaxZ - pSrcBox->MinZ ); - CHECK_GL_ERROR( "glCopyImageSubData() failed" ); + pSrcBox->MaxZ - pSrcBox->MinZ); + CHECK_GL_ERROR("glCopyImageSubData() failed"); } else #endif { - const auto &FmtAttribs = GetDevice()->GetTextureFormatInfoExt( m_Desc.Format ); - if( !FmtAttribs.ColorRenderable ) + const auto& FmtAttribs = GetDevice()->GetTextureFormatInfoExt(m_Desc.Format); + if (!FmtAttribs.ColorRenderable) { - LOG_ERROR_MESSAGE( "Unable to perform copy operation because ", FmtAttribs.Name, " is not color renderable format" ); + LOG_ERROR_MESSAGE("Unable to perform copy operation because ", FmtAttribs.Name, " is not color renderable format"); return; } @@ -462,7 +468,7 @@ void TextureBaseGL :: CopyData(DeviceContextGLImpl* pDeviceCtxGL, #ifdef _DEBUG { auto& TexViewObjAllocator = pRenderDeviceGL->GetTexViewObjAllocator(); - VERIFY( &TexViewObjAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" ); + VERIFY(&TexViewObjAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization"); } #endif auto& TexRegionRender = *pRenderDeviceGL->m_pTexRegionRender; @@ -471,49 +477,49 @@ void TextureBaseGL :: CopyData(DeviceContextGLImpl* pDeviceCtxGL, // Create temporary SRV for the entire source texture TextureViewDesc SRVDesc; SRVDesc.TextureDim = SrcTexDesc.Type; - SRVDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE; - CorrectTextureViewDesc( SRVDesc ); + SRVDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE; + CorrectTextureViewDesc(SRVDesc); // Note: texture view allocates memory for the copy of the name // If the name is empty, memory should not be allocated // We have to provide allocator even though it will never be used - TextureViewGLImpl SRV( GetReferenceCounters(), GetDevice(), SRVDesc, pSrcTextureGL, - false, // Do NOT create texture view OpenGL object - true // The view, like default view, should not - // keep strong reference to the texture - ); + TextureViewGLImpl SRV(GetReferenceCounters(), GetDevice(), SRVDesc, pSrcTextureGL, + false, // Do NOT create texture view OpenGL object + true // The view, like default view, should not + // keep strong reference to the texture + ); - for( Uint32 DepthSlice = 0; DepthSlice < pSrcBox->MaxZ - pSrcBox->MinZ; ++DepthSlice ) + for (Uint32 DepthSlice = 0; DepthSlice < pSrcBox->MaxZ - pSrcBox->MinZ; ++DepthSlice) { // Create temporary RTV for the target subresource TextureViewDesc RTVDesc; - RTVDesc.TextureDim = m_Desc.Type; - RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + RTVDesc.TextureDim = m_Desc.Type; + RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; RTVDesc.FirstArraySlice = DepthSlice + DstSlice; RTVDesc.MostDetailedMip = DstMipLevel; - RTVDesc.NumArraySlices = 1; - CorrectTextureViewDesc( RTVDesc ); + RTVDesc.NumArraySlices = 1; + CorrectTextureViewDesc(RTVDesc); // Note: texture view allocates memory for the copy of the name // If the name is empty, memory should not be allocated // We have to provide allocator even though it will never be used - TextureViewGLImpl RTV( GetReferenceCounters(), GetDevice(), RTVDesc, this, - false, // Do NOT create texture view OpenGL object - true // The view, like default view, should not - // keep strong reference to the texture - ); + TextureViewGLImpl RTV(GetReferenceCounters(), GetDevice(), RTVDesc, this, + false, // Do NOT create texture view OpenGL object + true // The view, like default view, should not + // keep strong reference to the texture + ); - ITextureView *pRTVs[] = { &RTV }; - pDeviceCtxGL->SetRenderTargets( _countof( pRTVs ), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); + ITextureView* pRTVs[] = {&RTV}; + pDeviceCtxGL->SetRenderTargets(_countof(pRTVs), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); // No need to set up the viewport as SetRenderTargets() does that - TexRegionRender.Render( pDeviceCtxGL, - &SRV, - SrcTexDesc.Type, - SrcTexDesc.Format, - static_cast<Int32>(pSrcBox->MinX) - static_cast<Int32>(DstX), - static_cast<Int32>(pSrcBox->MinY) - static_cast<Int32>(DstY), - SrcSlice + pSrcBox->MinZ + DepthSlice, - SrcMipLevel ); + TexRegionRender.Render(pDeviceCtxGL, + &SRV, + SrcTexDesc.Type, + SrcTexDesc.Format, + static_cast<Int32>(pSrcBox->MinX) - static_cast<Int32>(DstX), + static_cast<Int32>(pSrcBox->MinY) - static_cast<Int32>(DstY), + SrcSlice + pSrcBox->MinZ + DepthSlice, + SrcMipLevel); } TexRegionRender.RestoreStates(pDeviceCtxGL); @@ -521,23 +527,25 @@ void TextureBaseGL :: CopyData(DeviceContextGLImpl* pDeviceCtxGL, } -void TextureBaseGL::TextureMemoryBarrier( Uint32 RequiredBarriers, GLContextState &GLContextState ) +void TextureBaseGL::TextureMemoryBarrier(Uint32 RequiredBarriers, GLContextState& GLContextState) { #if GL_ARB_shader_image_load_store - #ifdef _DEBUG +# ifdef _DEBUG { + // clang-format off constexpr Uint32 TextureBarriers = GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT; - VERIFY( (RequiredBarriers & TextureBarriers) != 0, "At least one texture memory barrier flag should be set" ); - VERIFY( (RequiredBarriers & ~TextureBarriers) == 0, "Inappropriate texture memory barrier flag" ); + // clang-format on + VERIFY((RequiredBarriers & TextureBarriers) != 0, "At least one texture memory barrier flag should be set"); + VERIFY((RequiredBarriers & ~TextureBarriers) == 0, "Inappropriate texture memory barrier flag"); } - #endif - - GLContextState.EnsureMemoryBarrier( RequiredBarriers, this ); +# endif + + GLContextState.EnsureMemoryBarrier(RequiredBarriers, this); #endif } @@ -546,8 +554,9 @@ void TextureBaseGL::SetDefaultGLParameters() #ifdef _DEBUG GLint BoundTex; GLint TextureBinding = 0; - switch( m_BindTarget ) + switch (m_BindTarget) { + // clang-format off case GL_TEXTURE_1D: TextureBinding = GL_TEXTURE_BINDING_1D; break; case GL_TEXTURE_1D_ARRAY: TextureBinding = GL_TEXTURE_BINDING_1D_ARRAY; break; case GL_TEXTURE_2D: TextureBinding = GL_TEXTURE_BINDING_2D; break; @@ -558,29 +567,30 @@ void TextureBaseGL::SetDefaultGLParameters() case GL_TEXTURE_CUBE_MAP: TextureBinding = GL_TEXTURE_BINDING_CUBE_MAP; break; case GL_TEXTURE_CUBE_MAP_ARRAY: TextureBinding = GL_TEXTURE_BINDING_CUBE_MAP_ARRAY; break; default: UNEXPECTED("Unknown bind target"); + // clang-format on } - glGetIntegerv( TextureBinding, &BoundTex ); - CHECK_GL_ERROR( "Failed to set GL_TEXTURE_MIN_FILTER texture parameter" ); - VERIFY( static_cast<GLuint>(BoundTex) == m_GlTexture, "Current texture is not bound to GL context" ); + glGetIntegerv(TextureBinding, &BoundTex); + CHECK_GL_ERROR("Failed to set GL_TEXTURE_MIN_FILTER texture parameter"); + VERIFY(static_cast<GLuint>(BoundTex) == m_GlTexture, "Current texture is not bound to GL context"); #endif - if( m_BindTarget != GL_TEXTURE_2D_MULTISAMPLE && - m_BindTarget != GL_TEXTURE_2D_MULTISAMPLE_ARRAY ) + if (m_BindTarget != GL_TEXTURE_2D_MULTISAMPLE && + m_BindTarget != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { // Note that texture bound to image unit must be complete. - // That means that if an integer texture is being bound, its + // That means that if an integer texture is being bound, its // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, // otherwise it will be incomplete // The default value of GL_TEXTURE_MIN_FILTER is GL_NEAREST_MIPMAP_LINEAR // Reset it to GL_NEAREST to avoid incompletness issues with integer textures - glTexParameteri( m_BindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - CHECK_GL_ERROR( "Failed to set GL_TEXTURE_MIN_FILTER texture parameter" ); + glTexParameteri(m_BindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + CHECK_GL_ERROR("Failed to set GL_TEXTURE_MIN_FILTER texture parameter"); // The default value of GL_TEXTURE_MAG_FILTER is GL_LINEAR - glTexParameteri( m_BindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - CHECK_GL_ERROR( "Failed to set GL_TEXTURE_MAG_FILTER texture parameter" ); + glTexParameteri(m_BindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + CHECK_GL_ERROR("Failed to set GL_TEXTURE_MAG_FILTER texture parameter"); } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp index db2b9bb1..99c08e2c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp @@ -33,13 +33,14 @@ namespace Diligent { -TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -50,15 +51,16 @@ TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCount pInitData, bIsDeviceInternal } +// clang-format on { VERIFY(m_Desc.SampleCount == 1, "Multisampled texture cube arrays are not supported"); - + GLState.BindTexture(-1, m_BindTarget, m_GlTexture); - // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. - // For example, when you allocate storage for the texture, you would use glTexStorage3D? or glTexImage3D? or similar. + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // For example, when you allocate storage for the texture, you would use glTexStorage3D? or glTexImage3D? or similar. // The depth? parameter will be the number of layer-faces, not layers. So it must be divisible by 6. - VERIFY( (m_Desc.ArraySize % 6) == 0, "Array size must be multiple of 6"); + VERIFY((m_Desc.ArraySize % 6) == 0, "Array size must be multiple of 6"); // levels format width height depth glTexStorage3D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize); CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the Cubemap texture array"); @@ -74,20 +76,20 @@ TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCount if (pInitData != nullptr && pInitData->pSubResources != nullptr) { - VERIFY( (m_Desc.ArraySize % 6) == 0, "Array size must be multiple of 6"); + VERIFY((m_Desc.ArraySize % 6) == 0, "Array size must be multiple of 6"); if (m_Desc.MipLevels * m_Desc.ArraySize == pInitData->NumSubresources) { - for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) + for (Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U)}; + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), + 0, std::max(m_Desc.Height >> Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of TextureCubeArray_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - TextureCubeArray_OGL::UpdateData(GLState, Mip, Slice, DstBox, pInitData->pSubResources[Slice*m_Desc.MipLevels + Mip]); + // To call the required function, we need to explicitly specify the class: + TextureCubeArray_OGL::UpdateData(GLState, Mip, Slice, DstBox, pInitData->pSubResources[Slice * m_Desc.MipLevels + Mip]); } } } @@ -97,17 +99,29 @@ TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCount } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -TextureCubeArray_OGL::TextureCubeArray_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, GL_TEXTURE_CUBE_MAP_ARRAY, bIsDeviceInternal) +TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + GL_TEXTURE_CUBE_MAP_ARRAY, + bIsDeviceInternal + } +// clang-format on { } @@ -115,11 +129,11 @@ TextureCubeArray_OGL::~TextureCubeArray_OGL() { } -void TextureCubeArray_OGL::UpdateData( GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData ) +void TextureCubeArray_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); @@ -129,8 +143,8 @@ void TextureCubeArray_OGL::UpdateData( GLContextState& ContextState, GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -138,81 +152,83 @@ void TextureCubeArray_OGL::UpdateData( GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - if( TransferAttribs.IsCompressed ) + if (TransferAttribs.IsCompressed) { - auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); - VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), - "Compressed texture update region must be 4 pixel-aligned" ); + // clang-format off + VERIFY((DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), + "Compressed texture update region must be 4 pixel-aligned"); + // clang-format on #ifdef _DEBUG { - const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); - auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; - VERIFY( SubresData.Stride == BlockBytesInRow, - "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3) / 4) * Uint32{FmtAttribs.ComponentSize}; + VERIFY(SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")"); } #endif - // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; - UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); - UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); - glCompressedTexSubImage3D(m_BindTarget, MipLevel, - DstBox.MinX, - DstBox.MinY, - Slice, - UpdateRegionWidth, - UpdateRegionHeight, - 1, - // The format must be the same compressed-texture format previously - // specified by glTexStorage2D() (thank you OpenGL for another useless - // parameter that is nothing but the source of confusion), otherwise - // INVALID_OPERATION error is generated. - m_GLTexFormat, - // An INVALID_VALUE error is generated if imageSize is not consistent with - // the format, dimensions, and contents of the compressed image( too little or - // too much data ), - ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, - // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated - // as a byte offset into the buffer object's data store. - // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage3D.xhtml - SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); + glCompressedTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + Slice, + UpdateRegionWidth, + UpdateRegionHeight, + 1, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3) / 4) * SubresData.Stride, + // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated + // as a byte offset into the buffer object's data store. + // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage3D.xhtml + SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); } else { const auto TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); - const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; - VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; + VERIFY((SubresData.Stride % PixelSize) == 0, "Data stride is not multiple of pixel size"); glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. - // When uploading texel data to the cubemap array, the parameters that represent the Z component - // are layer-faces. So if you want to upload to just the positive Z face of the second layer in the array, - // you would use call glTexSubImage3D?, with the zoffset?? parameter set to 10 (layer 1 * 6 faces per layer + face index 4), + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // When uploading texel data to the cubemap array, the parameters that represent the Z component + // are layer-faces. So if you want to upload to just the positive Z face of the second layer in the array, + // you would use call glTexSubImage3D?, with the zoffset?? parameter set to 10 (layer 1 * 6 faces per layer + face index 4), // and the depth? set to 1 (because you're only uploading one layer-face). // Target must be GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_CUBE_MAP_ARRAY. // (NO individual cubemap faces GL_TEXTURE_CUBE_MAP_POSITIVE_X .. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z!!!) - glTexSubImage3D(m_BindTarget, MipLevel, - DstBox.MinX, + glTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, DstBox.MinY, Slice, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, 1, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexSubImage3D.xhtml @@ -220,39 +236,39 @@ void TextureCubeArray_OGL::UpdateData( GLContextState& ContextState, } CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void TextureCubeArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void TextureCubeArray_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { // Same as for 2D array textures - // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. - // So the parameters that represent the Z component are layer-faces. - if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // So the parameters that represent the Z component are layer-faces. + if (ViewDesc.NumArraySlices == m_Desc.ArraySize) { // glFramebufferTexture() attaches the given mipmap levelas a layered image with the number of layers that the given texture has. - glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture cubemap array to draw framebuffer" ); - glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture cubemap array to read framebuffer" ); + glFramebufferTexture(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture cubemap array to draw framebuffer"); + glFramebufferTexture(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture cubemap array to read framebuffer"); } - else if( ViewDesc.NumArraySlices == 1 ) + else if (ViewDesc.NumArraySlices == 1) { - // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, // cube map array texture, or multisample array texture. - glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); - CHECK_GL_ERROR( "Failed to attach texture cubemap array to draw framebuffer" ); - glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); - CHECK_GL_ERROR( "Failed to attach texture cubemap array to read framebuffer" ); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice); + CHECK_GL_ERROR("Failed to attach texture cubemap array to draw framebuffer"); + glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice); + CHECK_GL_ERROR("Failed to attach texture cubemap array to read framebuffer"); } else { - UNEXPECTED( "Only one slice or the entire cubemap array can be attached to a framebuffer" ); + UNEXPECTED("Only one slice or the entire cubemap array can be attached to a framebuffer"); } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp index 8223a91f..0dfa6edc 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp @@ -33,13 +33,14 @@ namespace Diligent { -TextureCube_OGL::TextureCube_OGL(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - const TextureData* pInitData /*= nullptr*/, - bool bIsDeviceInternal /*= false*/) : +TextureCube_OGL::TextureCube_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + const TextureData* pInitData /*= nullptr*/, + bool bIsDeviceInternal /*= false*/) : + // clang-format off TextureBaseGL { pRefCounters, @@ -50,12 +51,13 @@ TextureCube_OGL::TextureCube_OGL(IReferenceCounters* pRefCounters, pInitData, bIsDeviceInternal } +// clang-format on { VERIFY(m_Desc.SampleCount == 1, "Multisampled cubemap textures are not supported"); - + GLState.BindTexture(-1, m_BindTarget, m_GlTexture); - VERIFY( m_Desc.ArraySize == 6, "Cubemap texture is expected to have 6 slices"); + VERIFY(m_Desc.ArraySize == 6, "Cubemap texture is expected to have 6 slices"); // levels format width height glTexStorage2D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height); CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the Cubemap texture"); @@ -72,40 +74,53 @@ TextureCube_OGL::TextureCube_OGL(IReferenceCounters* pRefCounters, if (pInitData != nullptr && pInitData->pSubResources != nullptr) { - const auto ExpectedSubresources = m_Desc.MipLevels*6; - if( m_Desc.MipLevels*6 == pInitData->NumSubresources ) + const auto ExpectedSubresources = m_Desc.MipLevels * 6; + if (m_Desc.MipLevels * 6 == pInitData->NumSubresources) { - for(Uint32 Face = 0; Face < 6; ++Face) + for (Uint32 Face = 0; Face < 6; ++Face) { - for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + for (Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) { - Box DstBox{0, std::max(m_Desc.Width >>Mip, 1U), - 0, std::max(m_Desc.Height>>Mip, 1U)}; + Box DstBox{0, std::max(m_Desc.Width >> Mip, 1U), + 0, std::max(m_Desc.Height >> Mip, 1U)}; // UpdateData() is a virtual function. If we try to call it through vtbl from here, // we will get into TextureBaseGL::UpdateData(), because instance of TextureCube_OGL // is not fully constructed yet. - // To call the required function, we need to explicitly specify the class: - TextureCube_OGL::UpdateData( GLState, Mip, Face, DstBox, pInitData->pSubResources[Face*m_Desc.MipLevels + Mip] ); + // To call the required function, we need to explicitly specify the class: + TextureCube_OGL::UpdateData(GLState, Mip, Face, DstBox, pInitData->pSubResources[Face * m_Desc.MipLevels + Mip]); } } } else { - UNEXPECTED("Incorrect number of subresources. ", pInitData->NumSubresources, " while ", ExpectedSubresources," is expected" ); (void)ExpectedSubresources; + UNEXPECTED("Incorrect number of subresources. ", pInitData->NumSubresources, " while ", ExpectedSubresources, " is expected"); + (void)ExpectedSubresources; } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -TextureCube_OGL::TextureCube_OGL( IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceGLImpl* pDeviceGL, - GLContextState& GLState, - const TextureDesc& TexDesc, - GLuint GLTextureHandle, - bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, GL_TEXTURE_CUBE_MAP, bIsDeviceInternal) +TextureCube_OGL::TextureCube_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + GLContextState& GLState, + const TextureDesc& TexDesc, + GLuint GLTextureHandle, + bool bIsDeviceInternal) : + // clang-format off + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + GL_TEXTURE_CUBE_MAP, + bIsDeviceInternal + } +// clang-format on { } @@ -115,7 +130,8 @@ TextureCube_OGL::~TextureCube_OGL() // Move static member initialization out of function to avoid // potential issues in multithreaded code -static const GLenum CubeMapFaces[6] = +// clang-format off +static constexpr GLenum CubeMapFaces[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -124,16 +140,17 @@ static const GLenum CubeMapFaces[6] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; +// clang-format on -void TextureCube_OGL::UpdateData( GLContextState& ContextState, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData ) +void TextureCube_OGL::UpdateData(GLContextState& ContextState, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData) { TextureBaseGL::UpdateData(ContextState, MipLevel, Slice, DstBox, SubresData); - // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glTexSubImage2D() + // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glTexSubImage2D() // then takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); @@ -143,8 +160,8 @@ void TextureCube_OGL::UpdateData( GLContextState& ContextState, GLuint UnpackBuffer = 0; if (SubresData.pSrcBuffer != nullptr) { - auto *pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); - UnpackBuffer = pBufferGL->GetGLHandle(); + auto* pBufferGL = ValidatedCast<BufferGLImpl>(SubresData.pSrcBuffer); + UnpackBuffer = pBufferGL->GetGLHandle(); } // Transfers to OpenGL memory are called unpack operations @@ -152,72 +169,74 @@ void TextureCube_OGL::UpdateData( GLContextState& ContextState, // operations will be performed from this buffer. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, UnpackBuffer); - const auto &TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); - + const auto& TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - if( TransferAttribs.IsCompressed ) + if (TransferAttribs.IsCompressed) { - auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); + auto MipWidth = std::max(m_Desc.Width >> MipLevel, 1U); auto MipHeight = std::max(m_Desc.Height >> MipLevel, 1U); - VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && - ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && - ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), - "Compressed texture update region must be 4 pixel-aligned" ); + // clang-format off + VERIFY((DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == MipWidth) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == MipHeight), + "Compressed texture update region must be 4 pixel-aligned" ); + // clang-format on #ifdef _DEBUG { - const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); - auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * Uint32{FmtAttribs.ComponentSize}; - VERIFY( SubresData.Stride == BlockBytesInRow, - "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3) / 4) * Uint32{FmtAttribs.ComponentSize}; + VERIFY(SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")"); } #endif - + //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); - - // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glCompressedTexSubImage2D() + + // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glCompressedTexSubImage2D() // takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z auto UpdateRegionWidth = DstBox.MaxX - DstBox.MinX; auto UpdateRegionHeight = DstBox.MaxY - DstBox.MinY; - UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); - UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); - glCompressedTexSubImage2D(CubeMapFaceBindTarget, MipLevel, - DstBox.MinX, - DstBox.MinY, - UpdateRegionWidth, - UpdateRegionHeight, - // The format must be the same compressed-texture format previously - // specified by glTexStorage2D() (thank you OpenGL for another useless - // parameter that is nothing but the source of confusion), otherwise - // INVALID_OPERATION error is generated. - m_GLTexFormat, - // An INVALID_VALUE error is generated if imageSize is not consistent with - // the format, dimensions, and contents of the compressed image( too little or - // too much data ), - ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, - // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated - // as a byte offset into the buffer object's data store. - // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage2D.xhtml - SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); + UpdateRegionWidth = std::min(UpdateRegionWidth, MipWidth - DstBox.MinX); + UpdateRegionHeight = std::min(UpdateRegionHeight, MipHeight - DstBox.MinY); + glCompressedTexSubImage2D(CubeMapFaceBindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + UpdateRegionWidth, + UpdateRegionHeight, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3) / 4) * SubresData.Stride, + // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated + // as a byte offset into the buffer object's data store. + // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage2D.xhtml + SubresData.pSrcBuffer != nullptr ? reinterpret_cast<void*>(static_cast<size_t>(SubresData.SrcOffset)) : SubresData.pData); } else { const auto& TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); - const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; - VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + const auto PixelSize = Uint32{TexFmtInfo.NumComponents} * Uint32{TexFmtInfo.ComponentSize}; + VERIFY((SubresData.Stride % PixelSize) == 0, "Data stride is not multiple of pixel size"); glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glTexSubImage2D() + // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glTexSubImage2D() // takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - glTexSubImage2D(CubeMapFaceBindTarget, MipLevel, - DstBox.MinX, - DstBox.MinY, - DstBox.MaxX - DstBox.MinX, - DstBox.MaxY - DstBox.MinY, - TransferAttribs.PixelFormat, TransferAttribs.DataType, + glTexSubImage2D(CubeMapFaceBindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + TransferAttribs.PixelFormat, TransferAttribs.DataType, // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target, 'data' is treated // as a byte offset into the buffer object's data store. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexSubImage2D.xhtml @@ -225,40 +244,40 @@ void TextureCube_OGL::UpdateData( GLContextState& ContextState, } CHECK_GL_ERROR("Failed to update subimage data"); - if(UnpackBuffer != 0) + if (UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); + ContextState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -void TextureCube_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +void TextureCube_OGL::AttachToFramebuffer(const TextureViewDesc& ViewDesc, GLenum AttachmentPoint) { - if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + if (ViewDesc.NumArraySlices == m_Desc.ArraySize) { - glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture cube to draw framebuffer" ); - glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture cube to read framebuffer" ); + glFramebufferTexture(GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture cube to draw framebuffer"); + glFramebufferTexture(GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture cube to read framebuffer"); } - else if( ViewDesc.NumArraySlices == 1 ) + else if (ViewDesc.NumArraySlices == 1) { - // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, // cube map array texture, or multisample array texture. auto CubeMapFaceBindTarget = CubeMapFaces[ViewDesc.FirstArraySlice]; - // For glFramebufferTexture2D, if texture is not zero, textarget must be one of GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE, - // GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - // GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + // For glFramebufferTexture2D, if texture is not zero, textarget must be one of GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE, + // GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + // GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // or GL_TEXTURE_2D_MULTISAMPLE. - glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, CubeMapFaceBindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture cube face to draw framebuffer" ); - glFramebufferTexture2D( GL_READ_FRAMEBUFFER, AttachmentPoint, CubeMapFaceBindTarget, m_GlTexture, ViewDesc.MostDetailedMip ); - CHECK_GL_ERROR( "Failed to attach texture cube face to read framebuffer" ); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, AttachmentPoint, CubeMapFaceBindTarget, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture cube face to draw framebuffer"); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, AttachmentPoint, CubeMapFaceBindTarget, m_GlTexture, ViewDesc.MostDetailedMip); + CHECK_GL_ERROR("Failed to attach texture cube face to read framebuffer"); } else { - UNEXPECTED( "Only one slice or the entire cubemap can be attached to a framebuffer" ); + UNEXPECTED("Only one slice or the entire cubemap can be attached to a framebuffer"); } } -} +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp index b3f8880a..6312eca8 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp @@ -30,52 +30,56 @@ namespace Diligent { - TextureViewGLImpl::TextureViewGLImpl(IReferenceCounters *pRefCounters, - RenderDeviceGLImpl *pDevice, - const TextureViewDesc& ViewDesc, - TextureBaseGL* pTexture, - bool bCreateGLViewTex, - bool bIsDefaultView) : - TTextureViewBase - { - pRefCounters, - pDevice, - ViewDesc, - pTexture, - bIsDefaultView - }, - m_ViewTexGLHandle {bCreateGLViewTex}, - m_ViewTexBindTarget {0 } - { - } - TextureViewGLImpl::~TextureViewGLImpl() +TextureViewGLImpl::TextureViewGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + const TextureViewDesc& ViewDesc, + TextureBaseGL* pTexture, + bool bCreateGLViewTex, + bool bIsDefaultView) : + // clang-format off + TTextureViewBase { - } + pRefCounters, + pDevice, + ViewDesc, + pTexture, + bIsDefaultView + }, + m_ViewTexGLHandle {bCreateGLViewTex}, + m_ViewTexBindTarget {0 } +// clang-format on +{ +} + +TextureViewGLImpl::~TextureViewGLImpl() +{ +} - IMPLEMENT_QUERY_INTERFACE( TextureViewGLImpl, IID_TextureViewGL, TTextureViewBase ) +IMPLEMENT_QUERY_INTERFACE(TextureViewGLImpl, IID_TextureViewGL, TTextureViewBase) - const GLObjectWrappers::GLTextureObj& TextureViewGLImpl::GetHandle() +const GLObjectWrappers::GLTextureObj& TextureViewGLImpl::GetHandle() +{ + if (m_ViewTexGLHandle) + return m_ViewTexGLHandle; + else { - if( m_ViewTexGLHandle ) - return m_ViewTexGLHandle; - else - { - auto *pTexture = GetTexture(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); - return static_cast<TextureBaseGL*>(pTexture)->GetGLHandle(); - } + auto* pTexture = GetTexture(); + CHECK_DYNAMIC_TYPE(TextureBaseGL, pTexture); + return static_cast<TextureBaseGL*>(pTexture)->GetGLHandle(); } +} - GLenum TextureViewGLImpl::GetBindTarget() +GLenum TextureViewGLImpl::GetBindTarget() +{ + if (m_ViewTexGLHandle) + return m_ViewTexBindTarget; + else { - if( m_ViewTexGLHandle ) - return m_ViewTexBindTarget; - else - { - auto *pTexture = GetTexture(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); - return static_cast<TextureBaseGL*>(pTexture)->GetBindTarget(); - } + auto* pTexture = GetTexture(); + CHECK_DYNAMIC_TYPE(TextureBaseGL, pTexture); + return static_cast<TextureBaseGL*>(pTexture)->GetBindTarget(); } } + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp index 3fce4c33..176d4e90 100644 --- a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp @@ -34,7 +34,7 @@ namespace Diligent { -VAOCache::VAOCache() : +VAOCache::VAOCache() : m_EmptyVAO{true} { m_Cache.max_load_factor(0.5f); @@ -45,26 +45,28 @@ VAOCache::VAOCache() : VAOCache::~VAOCache() { VERIFY(m_Cache.empty(), "VAO cache is not empty. Are there any unreleased objects?"); - VERIFY(m_PSOToKey.empty(), "PSOToKey hash is not empty" ); + VERIFY(m_PSOToKey.empty(), "PSOToKey hash is not empty"); VERIFY(m_BuffToKey.empty(), "BuffToKey hash is not empty"); } void VAOCache::OnDestroyBuffer(IBuffer* pBuffer) { ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + auto EqualRange = m_BuffToKey.equal_range(pBuffer); - for(auto It = EqualRange.first; It != EqualRange.second; ++It) + for (auto It = EqualRange.first; It != EqualRange.second; ++It) { m_Cache.erase(It->second); } m_BuffToKey.erase(EqualRange.first, EqualRange.second); } -void VAOCache::OnDestroyPSO(IPipelineState *pPSO) +void VAOCache::OnDestroyPSO(IPipelineState* pPSO) { ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); + auto EqualRange = m_PSOToKey.equal_range(pPSO); - for(auto It = EqualRange.first; It != EqualRange.second; ++It) + for (auto It = EqualRange.first; It != EqualRange.second; ++It) { m_Cache.erase(It->second); } @@ -83,16 +85,16 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* BufferGLImpl* VertexBuffers[MaxBufferSlots]; for (Uint32 s = 0; s < NumVertexStreams; ++s) VertexBuffers[s] = nullptr; - + // Get layout - auto* pPSOGL = ValidatedCast<PipelineStateGLImpl>(pPSO); - auto* pIndexBufferGL = ValidatedCast<BufferGLImpl>(pIndexBuffer); - const auto &InputLayout = pPSOGL->GetDesc().GraphicsPipeline.InputLayout; - const LayoutElement *LayoutElems = InputLayout.LayoutElements; - Uint32 NumElems = InputLayout.NumElements; + auto* pPSOGL = ValidatedCast<PipelineStateGLImpl>(pPSO); + auto* pIndexBufferGL = ValidatedCast<BufferGLImpl>(pIndexBuffer); + const auto& InputLayout = pPSOGL->GetDesc().GraphicsPipeline.InputLayout; + const LayoutElement* LayoutElems = InputLayout.LayoutElements; + Uint32 NumElems = InputLayout.NumElements; // Construct the key VAOCacheKey Key(pPSOGL->GetUniqueID(), pIndexBufferGL ? pIndexBufferGL->GetUniqueID() : 0); - + { auto LayoutIt = LayoutElems; for (size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt) @@ -123,10 +125,10 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* VERIFY(pCurrBuf != nullptr, "No buffer bound to slot ", BuffSlot); ValidatedCast<BufferGLImpl>(pCurrBuf)->BufferMemoryBarrier( - GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT,// Vertex data sourced from buffer objects after the barrier - // will reflect data written by shaders prior to the barrier. - // The set of buffer objects affected by this bit is derived - // from the GL_VERTEX_ARRAY_BUFFER_BINDING bindings + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT, // Vertex data sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier. + // The set of buffer objects affected by this bit is derived + // from the GL_VERTEX_ARRAY_BUFFER_BINDING bindings GLState); CurrStreamKey.BufferUId = pCurrBuf ? pCurrBuf->GetUniqueID() : 0; @@ -145,16 +147,16 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* if (pIndexBuffer) { pIndexBufferGL->BufferMemoryBarrier( - GL_ELEMENT_ARRAY_BARRIER_BIT,// Vertex array indices sourced from buffer objects after the barrier - // will reflect data written by shaders prior to the barrier. - // The buffer objects affected by this bit are derived from the - // ELEMENT_ARRAY_BUFFER binding. + GL_ELEMENT_ARRAY_BARRIER_BIT, // Vertex array indices sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier. + // The buffer objects affected by this bit are derived from the + // ELEMENT_ARRAY_BUFFER binding. GLState); } // Try to find VAO in the map auto It = m_Cache.find(Key); - if( It != m_Cache.end() ) + if (It != m_Cache.end()) { return It->second; } @@ -164,64 +166,64 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* GLObjectWrappers::GLVertexArrayObj NewVAO(true); // Initialize VAO - GLState.BindVAO( NewVAO ); + GLState.BindVAO(NewVAO); auto LayoutIt = LayoutElems; - for( size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt ) + for (size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt) { auto BuffSlot = LayoutIt->BufferSlot; - if( BuffSlot >= NumVertexStreams || BuffSlot >= MaxBufferSlots ) + if (BuffSlot >= NumVertexStreams || BuffSlot >= MaxBufferSlots) { - UNEXPECTED( "Incorrect input buffer slot" ); + UNEXPECTED("Incorrect input buffer slot"); continue; } // Get buffer through the strong reference. Note that we are not // using pointers stored in the key for safety - auto &CurrStream = VertexStreams[BuffSlot]; - auto Stride = pPSOGL->GetBufferStride(BuffSlot); - auto *pBuff = VertexBuffers[BuffSlot]; - VERIFY( pBuff != nullptr, "Vertex buffer is null" ); - const BufferGLImpl *pBufferOGL = static_cast<const BufferGLImpl*>( pBuff ); + auto& CurrStream = VertexStreams[BuffSlot]; + auto Stride = pPSOGL->GetBufferStride(BuffSlot); + auto* pBuff = VertexBuffers[BuffSlot]; + VERIFY(pBuff != nullptr, "Vertex buffer is null"); + const BufferGLImpl* pBufferOGL = static_cast<const BufferGLImpl*>(pBuff); constexpr bool ResetVAO = false; GLState.BindBuffer(GL_ARRAY_BUFFER, pBufferOGL->m_GlBuffer, ResetVAO); - GLvoid* DataStartOffset = reinterpret_cast<GLvoid*>( static_cast<size_t>( CurrStream.Offset + LayoutIt->RelativeOffset ) ); - auto GlType = TypeToGLType(LayoutIt->ValueType); - if( !LayoutIt->IsNormalized && - (LayoutIt->ValueType == VT_INT8 || + GLvoid* DataStartOffset = reinterpret_cast<GLvoid*>(static_cast<size_t>(CurrStream.Offset + LayoutIt->RelativeOffset)); + auto GlType = TypeToGLType(LayoutIt->ValueType); + if (!LayoutIt->IsNormalized && + (LayoutIt->ValueType == VT_INT8 || LayoutIt->ValueType == VT_INT16 || LayoutIt->ValueType == VT_INT32 || - LayoutIt->ValueType == VT_UINT8 || - LayoutIt->ValueType == VT_UINT16|| - LayoutIt->ValueType == VT_UINT32 ) ) - glVertexAttribIPointer(LayoutIt->InputIndex, LayoutIt->NumComponents, GlType, Stride, DataStartOffset ); + LayoutIt->ValueType == VT_UINT8 || + LayoutIt->ValueType == VT_UINT16 || + LayoutIt->ValueType == VT_UINT32)) + glVertexAttribIPointer(LayoutIt->InputIndex, LayoutIt->NumComponents, GlType, Stride, DataStartOffset); else - glVertexAttribPointer(LayoutIt->InputIndex, LayoutIt->NumComponents, GlType, LayoutIt->IsNormalized, Stride, DataStartOffset ); + glVertexAttribPointer(LayoutIt->InputIndex, LayoutIt->NumComponents, GlType, LayoutIt->IsNormalized, Stride, DataStartOffset); - if( LayoutIt->Frequency == LayoutElement::FREQUENCY_PER_INSTANCE ) + if (LayoutIt->Frequency == LayoutElement::FREQUENCY_PER_INSTANCE) { - // If divisor is zero, then the attribute acts like normal, being indexed by the array or index - // buffer. If divisor is non-zero, then the current instance is divided by this divisor, and + // If divisor is zero, then the attribute acts like normal, being indexed by the array or index + // buffer. If divisor is non-zero, then the current instance is divided by this divisor, and // the result of that is used to access the attribute array. glVertexAttribDivisor(LayoutIt->InputIndex, LayoutIt->InstanceDataStepRate); } - glEnableVertexAttribArray(LayoutIt->InputIndex); + glEnableVertexAttribArray(LayoutIt->InputIndex); } - if( pIndexBuffer ) + if (pIndexBuffer) { - const BufferGLImpl *pIndBufferOGL = static_cast<const BufferGLImpl*>( pIndexBuffer ); - constexpr bool ResetVAO = false; + const BufferGLImpl* pIndBufferOGL = static_cast<const BufferGLImpl*>(pIndexBuffer); + constexpr bool ResetVAO = false; GLState.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndBufferOGL->m_GlBuffer, ResetVAO); } - - auto NewElems = m_Cache.emplace( std::make_pair(Key, std::move(NewVAO)) ); + + auto NewElems = m_Cache.emplace(std::make_pair(Key, std::move(NewVAO))); // New element must be actually inserted - VERIFY( NewElems.second, "New element was not inserted into the cache" ); - m_PSOToKey.insert( std::make_pair(pPSO, Key) ); - for(Uint32 Slot = 0; Slot < Key.NumUsedSlots; ++Slot) + VERIFY(NewElems.second, "New element was not inserted into the cache"); + m_PSOToKey.insert(std::make_pair(pPSO, Key)); + for (Uint32 Slot = 0; Slot < Key.NumUsedSlots; ++Slot) { auto* pCurrBuff = VertexBuffers[Slot]; - if( pCurrBuff ) - m_BuffToKey.insert( std::make_pair(pCurrBuff, Key) ); + if (pCurrBuff) + m_BuffToKey.insert(std::make_pair(pCurrBuff, Key)); } return NewElems.first->second; @@ -233,4 +235,4 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetEmptyVAO() return m_EmptyVAO; } -} +} // namespace Diligent |
