From af77e4f49de804e9a37bbadb40bd3668d96a8d8c Mon Sep 17 00:00:00 2001 From: Egor Date: Mon, 19 Feb 2018 15:47:19 -0800 Subject: Fixed error when setting independent blend states on GLES devices that only support 4 render targets. --- .../GraphicsEngineOpenGL/include/GLContextState.h | 14 ++++++++----- .../src/DeviceContextGLImpl.cpp | 6 +++++- .../GraphicsEngineOpenGL/src/GLContextState.cpp | 24 ++++++++++++++++++++-- 3 files changed, 36 insertions(+), 8 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h index ab985d1d..919f73ce 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -77,6 +77,14 @@ public: void SetCurrentGLContext(GLContext::NativeGLContextType Context) { m_CurrentGLContext = Context; } GLContext::NativeGLContextType GetCurrentGLContext()const { return m_CurrentGLContext; } + struct ContextCaps + { + bool bFillModeSelectionSupported = True; + GLint m_iMaxCombinedTexUnits = 0; + GLint m_iMaxDrawBuffers = 0; + }; + 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 @@ -195,11 +203,7 @@ private: EnableStateHelper ScissorTestEnable; }m_RSState; - struct ContextCaps - { - bool bFillModeSelectionSupported = True; - GLint m_iMaxCombinedTexUnits = 0; - }m_Caps; + ContextCaps m_Caps; Uint32 m_ColorWriteMasks[MaxRenderTargets] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; EnableStateHelper m_bIndependentWriteMasks; diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 155758a5..f30b43b3 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -301,8 +301,12 @@ namespace Diligent Uint32 NumRenderTargets = m_NumBoundRenderTargets; VERIFY(NumRenderTargets < MaxRenderTargets, "Too many render targets (", NumRenderTargets, ") are being set"); - NumRenderTargets = std::min(NumRenderTargets, MaxRenderTargets); + + const auto& CtxCaps = m_ContextState.GetContextCaps(); + VERIFY(NumRenderTargets < CtxCaps.m_iMaxDrawBuffers, "This device only supports ", CtxCaps.m_iMaxDrawBuffers, " draw buffers, but ", NumRenderTargets, " are being set"); + NumRenderTargets = std::min(NumRenderTargets, static_cast(CtxCaps.m_iMaxDrawBuffers)); + ITextureView *pBoundRTVs[MaxRenderTargets] = {}; for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) pBoundRTVs[rt] = m_pBoundRenderTargets[rt]; diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index a12373aa..1b8e3a36 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -46,6 +46,11 @@ namespace Diligent 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); } m_BoundTextures.reserve( m_Caps.m_iMaxCombinedTexUnits ); @@ -577,8 +582,15 @@ namespace Diligent const auto& RT = BSDsc.RenderTargets[i]; if( RT.BlendEnable ) bEnableBlend = true; - - SetColorWriteMask(i, RT.RenderTargetWriteMask, 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"); + } } } else @@ -610,6 +622,14 @@ namespace Diligent for( int i = 0; i < BSDsc.MaxRenderTargets; ++i ) { 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 ); -- cgit v1.2.3