diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-08-25 01:07:40 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-08-25 01:30:09 +0000 |
| commit | 142c7880f92c3517a8897d2601336f6dba319c17 (patch) | |
| tree | 55fd757db90d80fe2a72b54970e95764f181bbfb /Graphics/GraphicsEngineOpenGL | |
| parent | Updated description of DrawMeshIndirect command (diff) | |
| parent | Fixed test crash in d3d11 mode on Intel GPU (diff) | |
| download | DiligentCore-142c7880f92c3517a8897d2601336f6dba319c17.tar.gz DiligentCore-142c7880f92c3517a8897d2601336f6dba319c17.zip | |
Merge branch 'master' into mesh_shader
# Conflicts:
# Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
# Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
# Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
3 files changed, 99 insertions, 7 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp index 332fc304..a93528ec 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp @@ -71,6 +71,8 @@ inline GLenum TypeToGLType(VALUE_TYPE Value) inline GLenum UsageToGLUsage(const BufferDesc& Desc) { + static_assert(USAGE_NUM_USAGES == 5, "Please update this function to handle the new usage type"); + // http://www.informit.com/articles/article.aspx?p=2033340&seqNum=2 // https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBufferData.xml switch (Desc.Usage) @@ -82,6 +84,7 @@ inline GLenum UsageToGLUsage(const BufferDesc& Desc) // clang-format off case USAGE_STATIC: return GL_STATIC_DRAW; case USAGE_DEFAULT: return GL_STATIC_DRAW; + case USAGE_UNIFIED: return GL_STATIC_DRAW; case USAGE_DYNAMIC: return GL_DYNAMIC_DRAW; case USAGE_STAGING: if(Desc.CPUAccessFlags & CPU_ACCESS_READ) diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp index 70df3725..e05d72ff 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -89,8 +89,15 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, m_GLUsageHint {UsageToGLUsage(BuffDesc)} // clang-format on { - if (BuffDesc.Usage == USAGE_STATIC && (pBuffData == nullptr || pBuffData->pData == nullptr)) - LOG_ERROR_AND_THROW("Static buffer must be initialized with data at creation time"); + ValidateBufferInitData(BuffDesc, pBuffData); + + if (m_Desc.Usage == USAGE_UNIFIED) + { + DecayUnifiedBuffer(); + } + + if (m_Desc.Usage == USAGE_STATIC) + VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for static buffers"); // TODO: find out if it affects performance if the buffer is originally bound to one target // and then bound to another (such as first to GL_ARRAY_BUFFER and then to GL_UNIFORM_BUFFER) diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index d7a95033..96c93e7a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -29,6 +29,7 @@ #include <iostream> #include <fstream> #include <string> +#include <array> #include "SwapChainGL.h" #include "DeviceContextGLImpl.hpp" @@ -143,6 +144,11 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) } m_ContextState.InvalidateVAO(); } + + // Note that the program may change if a shader is created after the call + // (GLProgramResources needs to bind a program to load uniforms), but before + // the draw command. + m_pPipelineState->CommitProgram(m_ContextState); } void DeviceContextGLImpl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) @@ -498,13 +504,20 @@ void DeviceContextGLImpl::EndSubpass() const auto& RPDesc = m_pActiveRenderPass->GetDesc(); VERIFY_EXPR(m_SubpassIndex < RPDesc.SubpassCount); const auto& SubpassDesc = RPDesc.pSubpasses[m_SubpassIndex]; - if (SubpassDesc.pResolveAttachments != nullptr) - { - const auto& SubpassFBOs = m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex); - glBindFramebuffer(GL_READ_FRAMEBUFFER, SubpassFBOs.RenderTarget); - DEV_CHECK_GL_ERROR("Failed to bind subpass render target FBO as read framebuffer"); + const auto& SubpassFBOs = m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex); +#ifdef DILIGENT_DEBUG + { + GLint glCurrReadFB = 0; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &glCurrReadFB); + CHECK_GL_ERROR("Failed to get current read framebuffer"); + GLuint glExpectedReadFB = SubpassFBOs.RenderTarget != 0 ? static_cast<GLuint>(SubpassFBOs.RenderTarget) : m_pSwapChain->GetDefaultFBO(); + VERIFY(static_cast<GLuint>(glCurrReadFB) == glExpectedReadFB, "Unexpected read framebuffer"); + } +#endif + if (SubpassDesc.pResolveAttachments != nullptr) + { GLuint ResolveDstFBO = SubpassFBOs.Resolve; if (ResolveDstFBO == 0) { @@ -521,6 +534,68 @@ void DeviceContextGLImpl::EndSubpass() ); DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled attachments"); } + + if (glInvalidateFramebuffer != nullptr) + { + // It is crucially important to invalidate the framebuffer while it is bound + // https://community.arm.com/developer/tools-software/graphics/b/blog/posts/mali-performance-2-how-to-correctly-handle-framebuffers + GLsizei InvalidateAttachmentsCount = 0; + + std::array<GLenum, MAX_RENDER_TARGETS + 1> InvalidateAttachments; + for (Uint32 rt = 0; rt < SubpassDesc.RenderTargetAttachmentCount; ++rt) + { + const auto RTAttachmentIdx = SubpassDesc.pRenderTargetAttachments[rt].AttachmentIndex; + if (RTAttachmentIdx != ATTACHMENT_UNUSED) + { + auto AttachmentLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(RTAttachmentIdx).second; + if (AttachmentLastUse == m_SubpassIndex && RPDesc.pAttachments[RTAttachmentIdx].StoreOp == ATTACHMENT_STORE_OP_DISCARD) + { + if (SubpassFBOs.RenderTarget == 0) + { + VERIFY(rt == 0, "Default framebuffer can only have single color attachment"); + InvalidateAttachments[InvalidateAttachmentsCount++] = GL_COLOR; + } + else + { + InvalidateAttachments[InvalidateAttachmentsCount++] = GL_COLOR_ATTACHMENT0 + rt; + } + } + } + } + + if (SubpassDesc.pDepthStencilAttachment != nullptr) + { + const auto DSAttachmentIdx = SubpassDesc.pDepthStencilAttachment->AttachmentIndex; + if (DSAttachmentIdx != ATTACHMENT_UNUSED) + { + auto AttachmentLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(DSAttachmentIdx).second; + if (AttachmentLastUse == m_SubpassIndex && RPDesc.pAttachments[DSAttachmentIdx].StoreOp == ATTACHMENT_STORE_OP_DISCARD) + { + const auto& FmtAttribs = GetTextureFormatAttribs(RPDesc.pAttachments[DSAttachmentIdx].Format); + VERIFY_EXPR(FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH || FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL); + if (SubpassFBOs.RenderTarget == 0) + { + InvalidateAttachments[InvalidateAttachmentsCount++] = GL_DEPTH; + if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) + InvalidateAttachments[InvalidateAttachmentsCount++] = GL_STENCIL; + } + else + { + InvalidateAttachments[InvalidateAttachmentsCount++] = FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT; + } + } + } + } + + if (InvalidateAttachmentsCount > 0) + { + glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, InvalidateAttachmentsCount, InvalidateAttachments.data()); + DEV_CHECK_GL_ERROR("glInvalidateFramebuffer() failed"); + } + } + + // TODO: invalidate input attachments using glInvalidateTexImage + m_ContextState.InvalidateFBO(); } @@ -544,6 +619,7 @@ void DeviceContextGLImpl::NextSubpass() EndSubpass(); TDeviceContextBase::NextSubpass(); BeginSubpass(); + m_AttachmentClearValues.clear(); } void DeviceContextGLImpl::EndRenderPass() @@ -810,6 +886,8 @@ void DeviceContextGLImpl::PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenu DvpVerifyRenderTargets(); #endif + // The program might have changed since the last SetPipelineState call if a shader was + // created after the call (GLProgramResources needs to bind a program to load uniforms). m_pPipelineState->CommitProgram(m_ContextState); auto CurrNativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext(); @@ -1040,6 +1118,8 @@ void DeviceContextGLImpl::DispatchCompute(const DispatchComputeAttribs& Attribs) return; #if GL_ARB_compute_shader + // The program might have changed since the last SetPipelineState call if a shader was + // created after the call (GLProgramResources needs to bind a program to load uniforms). m_pPipelineState->CommitProgram(m_ContextState); glDispatchCompute(Attribs.ThreadGroupCountX, Attribs.ThreadGroupCountY, Attribs.ThreadGroupCountZ); DEV_CHECK_GL_ERROR("glDispatchCompute() failed"); @@ -1056,6 +1136,8 @@ void DeviceContextGLImpl::DispatchComputeIndirect(const DispatchComputeIndirectA return; #if GL_ARB_compute_shader + // The program might have changed since the last SetPipelineState call if a shader was + // created after the call (GLProgramResources needs to bind a program to load uniforms). m_pPipelineState->CommitProgram(m_ContextState); auto* pBufferGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer); |
