summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2021-03-06 05:25:09 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:16 +0000
commit335670925e06e08f2e31efc40b8cf2e5aba820c5 (patch)
tree05784503faa83d5584212bed15608d496a962522 /Graphics/GraphicsEngineOpenGL
parentSome updates to DXBCUtils and DXCompiler (diff)
downloadDiligentCore-335670925e06e08f2e31efc40b8cf2e5aba820c5.tar.gz
DiligentCore-335670925e06e08f2e31efc40b8cf2e5aba820c5.zip
OpenGL backend: updated resource binding procedure
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp17
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp5
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/ShaderResourceCacheGL.hpp8
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp18
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp15
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp213
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp181
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp16
10 files changed, 242 insertions, 237 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp
index 9fd8be2f..b4a27125 100644
--- a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp
@@ -72,7 +72,7 @@ public:
void MapRange(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, Uint32 Offset, Uint32 Length, PVoid& pMappedData);
void Unmap(GLContextState& CtxState);
- void BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, class GLContextState& GLContextState);
+ __forceinline void BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState);
const GLObjectWrappers::GLBufferObj& GetGLHandle() { return m_GlBuffer; }
@@ -96,4 +96,19 @@ private:
const GLenum m_GLUsageHint;
};
+void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState)
+{
+#if GL_ARB_shader_image_load_store
+# ifdef DILIGENT_DEBUG
+ {
+ constexpr auto BufferBarriers = MEMORY_BARRIER_ALL_BUFFER_BARRIERS;
+ 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
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
index 9926204f..79ea1926 100644
--- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
@@ -283,7 +283,6 @@ private:
__forceinline void PostDraw();
using TBindings = PipelineResourceSignatureGLImpl::TBindings;
- void BindProgramResources(MEMORY_BARRIER& NewMemoryBarriers, const ShaderResourceBindingGLImpl* pShaderResBindingGL, TBindings& Bindings);
void BindProgramResources();
#ifdef DILIGENT_DEVELOPMENT
@@ -307,8 +306,8 @@ private:
#ifdef DILIGENT_DEVELOPMENT
bool CommittedResourcesValidated = false;
- // Binding offsets that was used at last BindProgramResources() call.
- std::array<TBindings, MAX_RESOURCE_SIGNATURES> BoundResOffsets = {};
+ // Binding offsets that was used in the last BindProgramResources() call.
+ std::array<TBindings, MAX_RESOURCE_SIGNATURES> BaseBindings = {};
#endif
SRBState()
diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp
index a1a0de52..3c2ad8ee 100644
--- a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp
@@ -129,7 +129,7 @@ public:
SHADER_TYPE Stages,
const TBindings& Bindings) const;
- __forceinline void AddBindings(TBindings& Bindings) const
+ __forceinline void ShiftBindings(TBindings& Bindings) const
{
for (Uint32 i = 0; i < Bindings.size(); ++i)
{
diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceCacheGL.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceCacheGL.hpp
index 35e340cc..38b7e6ec 100644
--- a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceCacheGL.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceCacheGL.hpp
@@ -27,6 +27,9 @@
#pragma once
+#include <array>
+#include <vector>
+
#include "BufferGLImpl.hpp"
#include "TextureBaseGL.hpp"
#include "SamplerGLImpl.hpp"
@@ -253,6 +256,11 @@ public:
bool StaticResourcesInitialized() const { return m_bStaticResourcesInitialized; }
#endif
+ void BindResources(GLContextState& GLState,
+ const std::array<Uint32, 4>& BaseBindings,
+ std::vector<TextureBaseGL*>& WritableTextures,
+ std::vector<BufferGLImpl*>& WritableBuffers) const;
+
private:
CachedUB& GetUB(Uint32 CacheOffset)
{
diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp
index 2d4101ea..8a6faebb 100644
--- a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp
@@ -35,6 +35,7 @@
#include "TextureViewGLImpl.hpp"
#include "AsyncWritableResource.hpp"
#include "RenderDeviceGLImpl.hpp"
+#include "GLContextState.hpp"
namespace Diligent
{
@@ -82,7 +83,7 @@ public:
GLenum GetGLTexFormat() const { return m_GLTexFormat; }
- void TextureMemoryBarrier(MEMORY_BARRIER RequiredBarriers, class GLContextState& GLContextState);
+ __forceinline void TextureMemoryBarrier(MEMORY_BARRIER RequiredBarriers, class GLContextState& GLContextState);
virtual void AttachToFramebuffer(const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint) = 0;
@@ -133,4 +134,19 @@ protected:
//Uint32 m_uiMapTarget;
};
+void TextureBaseGL::TextureMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState)
+{
+#if GL_ARB_shader_image_load_store
+# ifdef DILIGENT_DEBUG
+ {
+ constexpr Uint32 TextureBarriers = MEMORY_BARRIER_ALL_TEXTURE_BARRIERS;
+ 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
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
index 2ef67a48..e7d45caf 100644
--- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
@@ -346,21 +346,6 @@ void BufferGLImpl::Unmap(GLContextState& CtxState)
(void)Result;
}
-void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState)
-{
-#if GL_ARB_shader_image_load_store
-# ifdef DILIGENT_DEBUG
- {
- constexpr auto BufferBarriers = MEMORY_BARRIER_ALL_BUFFER_BARRIERS;
- 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
-}
-
void BufferGLImpl::CreateViewInternal(const BufferViewDesc& OrigViewDesc, IBufferView** ppView, bool bIsDefaultView)
{
VERIFY(ppView != nullptr, "Buffer view pointer address is null");
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index 7c843321..36b6df70 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -126,9 +126,7 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState)
m_ContextState.EnableDepthTest(DepthStencilDesc.DepthEnable);
m_ContextState.EnableDepthWrites(DepthStencilDesc.DepthWriteEnable);
m_ContextState.SetDepthFunc(DepthStencilDesc.DepthFunc);
-
m_ContextState.EnableStencilTest(DepthStencilDesc.StencilEnable);
-
m_ContextState.SetStencilWriteMask(DepthStencilDesc.StencilWriteMask);
{
@@ -687,7 +685,7 @@ void DeviceContextGLImpl::DvpValidateCommittedShaderResources()
if (m_BindInfo.CommittedResourcesValidated)
return;
- m_pPipelineState->DvpVerifySRBResources(m_BindInfo.SRBs.data(), m_BindInfo.BoundResOffsets.data(), static_cast<Uint32>(m_BindInfo.SRBs.size()));
+ m_pPipelineState->DvpVerifySRBResources(m_BindInfo.SRBs.data(), m_BindInfo.BaseBindings.data(), static_cast<Uint32>(m_BindInfo.SRBs.size()));
m_BindInfo.CommittedResourcesValidated = true;
}
#endif
@@ -700,219 +698,38 @@ void DeviceContextGLImpl::BindProgramResources()
if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
return;
+ VERIFY_EXPR(m_BoundWritableTextures.empty());
+ VERIFY_EXPR(m_BoundWritableBuffers.empty());
+
m_CommitedResourcesTentativeBarriers = MEMORY_BARRIER_NONE;
TBindings Bindings = {};
auto ActiveSRBMask = Uint32{m_BindInfo.ActiveSRBMask};
while (ActiveSRBMask != 0)
{
- Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
- Uint32 SigBit = (1u << sign);
+ Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
- ActiveSRBMask &= ~SigBit;
+ Uint32 SignBit = (1u << sign);
+ ActiveSRBMask &= ~SignBit;
const auto* pSRB = m_BindInfo.SRBs[sign];
- VERIFY_EXPR(pSRB);
+ DEV_CHECK_ERR(pSRB != nullptr, "No SRB is bound for index ", sign);
- if (m_BindInfo.StaleSRBMask & SigBit)
+ if (m_BindInfo.StaleSRBMask & SignBit)
{
- BindProgramResources(m_CommitedResourcesTentativeBarriers, pSRB, Bindings);
+ auto& ResoureCache = pSRB->GetResourceCache();
+ ResoureCache.BindResources(GetContextState(), Bindings, m_BoundWritableTextures, m_BoundWritableBuffers);
#ifdef DILIGENT_DEVELOPMENT
- m_BindInfo.BoundResOffsets[sign] = Bindings;
+ m_BindInfo.BaseBindings[sign] = Bindings;
#endif
}
- pSRB->GetSignature()->AddBindings(Bindings);
+ pSRB->GetSignature()->ShiftBindings(Bindings);
}
m_BindInfo.StaleSRBMask &= ~m_BindInfo.ActiveSRBMask;
-}
-
-void DeviceContextGLImpl::BindProgramResources(MEMORY_BARRIER& NewMemoryBarriers, const ShaderResourceBindingGLImpl* pShaderResBindingGL, TBindings& Bindings)
-{
- const auto SRBIndex = pShaderResBindingGL->GetBindingIndex();
- const auto& ResourceCache = pShaderResBindingGL->GetResourceCache();
-
-
- VERIFY_EXPR(m_BoundWritableTextures.empty());
- VERIFY_EXPR(m_BoundWritableBuffers.empty());
-
- for (Uint32 ub = 0, binding = Bindings[BINDING_RANGE_UNIFORM_BUFFER]; ub < ResourceCache.GetUBCount(); ++ub, ++binding)
- {
- const auto& UB = ResourceCache.GetConstUB(ub);
- if (!UB.pBuffer)
- continue;
-
- auto* pBufferGL = UB.pBuffer.RawPtr<BufferGLImpl>();
- pBufferGL->BufferMemoryBarrier(
- MEMORY_BARRIER_UNIFORM_BUFFER, // Shader uniforms sourced from buffer objects after the barrier
- // will reflect data written by shaders prior to the barrier
- m_ContextState);
-
- m_ContextState.BindUniformBuffer(binding, pBufferGL->m_GlBuffer);
- //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferGL->m_GlBuffer, 0, pBufferGL->GetDesc().uiSizeInBytes);
- }
-
- for (Uint32 s = 0, binding = Bindings[BINDING_RANGE_TEXTURE]; s < ResourceCache.GetTextureCount(); ++s, ++binding)
- {
- const auto& Sam = ResourceCache.GetConstTexture(s);
- if (!Sam.pView)
- continue;
-
- // We must check 'pTexture' first as 'pBuffer' is in union with 'pSampler'
- if (Sam.pTexture != nullptr)
- {
- auto* pTexViewGL = Sam.pView.RawPtr<TextureViewGLImpl>();
- auto* pTextureGL = ValidatedCast<TextureBaseGL>(Sam.pTexture);
- VERIFY_EXPR(pTextureGL == pTexViewGL->GetTexture());
- m_ContextState.BindTexture(binding, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle());
-
- pTextureGL->TextureMemoryBarrier(
- MEMORY_BARRIER_TEXTURE_FETCH, // 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(binding, Sam.pSampler->GetHandle());
- }
- else
- {
- m_ContextState.BindSampler(binding, 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(binding, GL_TEXTURE_BUFFER, pBufViewGL->GetTexBufferHandle());
- m_ContextState.BindSampler(binding, GLObjectWrappers::GLSamplerObj(false)); // Use default texture sampling parameters
-
- pBufferGL->BufferMemoryBarrier(
- MEMORY_BARRIER_TEXEL_BUFFER, // 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, binding = Bindings[BINDING_RANGE_IMAGE]; img < ResourceCache.GetImageCount(); ++img, ++binding)
- {
- 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)
- {
- 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(
- MEMORY_BARRIER_STORAGE_IMAGE, // 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 DILIGENT_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);
- DEV_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(binding, 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)
- {
- 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(
- MEMORY_BARRIER_IMAGE_BUFFER, // 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_BoundWritableBuffers.push_back(pBufferGL);
-
- auto GlFormat = TypeToGLTexFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized);
- m_ContextState.BindImage(binding, pBuffViewGL, GL_READ_WRITE, GlFormat);
- }
- }
-#endif
-
-
-#if GL_ARB_shader_storage_buffer_object
- for (Uint32 ssbo = 0, binding = Bindings[BINDING_RANGE_STORAGE_BUFFER]; ssbo < ResourceCache.GetSSBOCount(); ++ssbo, ++binding)
- {
- 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(
- MEMORY_BARRIER_STORAGE_BUFFER, // Accesses to shader storage blocks after the barrier
- // will reflect writes prior to the barrier
- m_ContextState);
-
- m_ContextState.BindStorageBlock(binding, 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
@@ -920,7 +737,7 @@ void DeviceContextGLImpl::BindProgramResources(MEMORY_BARRIER& NewMemoryBarriers
{
constexpr MEMORY_BARRIER TextureMemBarriers = MEMORY_BARRIER_ALL_TEXTURE_BARRIERS;
- NewMemoryBarriers |= TextureMemBarriers;
+ m_CommitedResourcesTentativeBarriers |= TextureMemBarriers;
// Set new required barriers for the time when texture is used next time
pWritableTex->SetPendingMemoryBarriers(TextureMemBarriers);
@@ -931,7 +748,7 @@ void DeviceContextGLImpl::BindProgramResources(MEMORY_BARRIER& NewMemoryBarriers
{
constexpr MEMORY_BARRIER BufferMemoryBarriers = MEMORY_BARRIER_ALL_BUFFER_BARRIERS;
- NewMemoryBarriers |= BufferMemoryBarriers;
+ m_CommitedResourcesTentativeBarriers |= BufferMemoryBarriers;
// Set new required barriers for the time when buffer is used next time
pWritableBuff->SetPendingMemoryBarriers(BufferMemoryBarriers);
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
index 4841ebb4..b787fd38 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
@@ -215,7 +215,7 @@ void PipelineStateGLImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre
{
pSignature->ApplyBindings(m_GLPrograms[0], CtxState, ActiveStages, Bindings);
}
- pSignature->AddBindings(Bindings);
+ pSignature->ShiftBindings(Bindings);
}
const auto& Limits = GetDevice()->GetDeviceLimits();
@@ -590,7 +590,7 @@ void PipelineStateGLImpl::DvpVerifySRBResources(ShaderResourceBindingGLImpl* pSR
DEV_CHECK_ERR(Bindings == BoundResOffsets[sign],
"Bound resources has incorrect base binding indices, this may indicate a bug in resource signature compatibility comparison.");
- pSignature->AddBindings(Bindings);
+ pSignature->ShiftBindings(Bindings);
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp
index fe1a2078..94f2ebfc 100644
--- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp
@@ -28,6 +28,7 @@
#include "pch.h"
#include "ShaderResourceCacheGL.hpp"
#include "PipelineResourceSignatureGLImpl.hpp"
+#include "GLTypeConversions.hpp"
namespace Diligent
{
@@ -116,4 +117,184 @@ ShaderResourceCacheGL::~ShaderResourceCacheGL()
}
}
+void ShaderResourceCacheGL::BindResources(GLContextState& GLState,
+ const std::array<Uint32, 4>& BaseBindings,
+ std::vector<TextureBaseGL*>& WritableTextures,
+ std::vector<BufferGLImpl*>& WritableBuffers) const
+{
+ for (Uint32 ub = 0, binding = BaseBindings[BINDING_RANGE_UNIFORM_BUFFER]; ub < GetUBCount(); ++ub, ++binding)
+ {
+ const auto& UB = GetConstUB(ub);
+ if (!UB.pBuffer)
+ continue;
+
+ auto* pBufferGL = UB.pBuffer.RawPtr<BufferGLImpl>();
+ pBufferGL->BufferMemoryBarrier(
+ MEMORY_BARRIER_UNIFORM_BUFFER, // Shader uniforms sourced from buffer objects after the barrier
+ // will reflect data written by shaders prior to the barrier
+ GLState);
+
+ GLState.BindUniformBuffer(binding, pBufferGL->GetGLHandle());
+ //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferGL->m_GlBuffer, 0, pBufferGL->GetDesc().uiSizeInBytes);
+ }
+
+ for (Uint32 s = 0, binding = BaseBindings[BINDING_RANGE_TEXTURE]; s < GetTextureCount(); ++s, ++binding)
+ {
+ const auto& Tex = GetConstTexture(s);
+ if (!Tex.pView)
+ continue;
+
+ // We must check 'pTexture' first as 'pBuffer' is in union with 'pSampler'
+ if (Tex.pTexture != nullptr)
+ {
+ auto* pTexViewGL = Tex.pView.RawPtr<TextureViewGLImpl>();
+ auto* pTextureGL = ValidatedCast<TextureBaseGL>(Tex.pTexture);
+ VERIFY_EXPR(pTextureGL == pTexViewGL->GetTexture());
+ GLState.BindTexture(binding, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle());
+
+ pTextureGL->TextureMemoryBarrier(
+ MEMORY_BARRIER_TEXTURE_FETCH, // 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
+ GLState);
+
+ if (Tex.pSampler)
+ {
+ GLState.BindSampler(binding, Tex.pSampler->GetHandle());
+ }
+ else
+ {
+ GLState.BindSampler(binding, GLObjectWrappers::GLSamplerObj{false});
+ }
+ }
+ else if (Tex.pBuffer != nullptr)
+ {
+ auto* pBufViewGL = Tex.pView.RawPtr<BufferViewGLImpl>();
+ auto* pBufferGL = ValidatedCast<BufferGLImpl>(Tex.pBuffer);
+ VERIFY_EXPR(pBufferGL == pBufViewGL->GetBuffer());
+
+ GLState.BindTexture(binding, GL_TEXTURE_BUFFER, pBufViewGL->GetTexBufferHandle());
+ GLState.BindSampler(binding, GLObjectWrappers::GLSamplerObj{false}); // Use default texture sampling parameters
+
+ pBufferGL->BufferMemoryBarrier(
+ MEMORY_BARRIER_TEXEL_BUFFER, // 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
+ GLState);
+ }
+ }
+
+#if GL_ARB_shader_image_load_store
+ for (Uint32 img = 0, binding = BaseBindings[BINDING_RANGE_IMAGE]; img < GetImageCount(); ++img, ++binding)
+ {
+ const auto& Img = GetConstImage(img);
+ if (!Img.pView)
+ continue;
+
+ // 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(
+ MEMORY_BARRIER_STORAGE_IMAGE, // 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.
+ GLState);
+ // We cannot set pending memory barriers here, because
+ // if some texture is bound twice, the logic will fail
+ WritableTextures.push_back(pTextureGL);
+ }
+
+# ifdef DILIGENT_DEBUG
+ // Check that the texure being bound has immutable storage
+ {
+ GLState.BindTexture(-1, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle());
+ GLint IsImmutable = 0;
+ glGetTexParameteriv(pTexViewGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable);
+ DEV_CHECK_GL_ERROR("glGetTexParameteriv() failed");
+ VERIFY(IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()");
+ GLState.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
+ GLState.BindImage(binding, 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)
+ {
+ 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(
+ MEMORY_BARRIER_IMAGE_BUFFER, // 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.
+ GLState);
+
+ WritableBuffers.push_back(pBufferGL);
+
+ auto GlFormat = TypeToGLTexFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized);
+ GLState.BindImage(binding, pBuffViewGL, GL_READ_WRITE, GlFormat);
+ }
+ }
+#endif
+
+
+#if GL_ARB_shader_storage_buffer_object
+ for (Uint32 ssbo = 0, binding = BaseBindings[BINDING_RANGE_STORAGE_BUFFER]; ssbo < GetSSBOCount(); ++ssbo, ++binding)
+ {
+ const auto& SSBO = GetConstSSBO(ssbo);
+ if (!SSBO.pBufferView)
+ return;
+
+ auto* const 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(
+ MEMORY_BARRIER_STORAGE_BUFFER, // Accesses to shader storage blocks after the barrier
+ // will reflect writes prior to the barrier
+ GLState);
+
+ GLState.BindStorageBlock(binding, pBufferGL->GetGLHandle(), ViewDesc.ByteOffset, ViewDesc.ByteWidth);
+
+ if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS)
+ WritableBuffers.push_back(pBufferGL);
+ }
+#endif
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
index 67a69a61..d38a468d 100644
--- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
@@ -646,22 +646,6 @@ void TextureBaseGL::CopyData(DeviceContextGLImpl* pDeviceCtxGL,
}
}
-
-void TextureBaseGL::TextureMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState)
-{
-#if GL_ARB_shader_image_load_store
-# ifdef DILIGENT_DEBUG
- {
- constexpr Uint32 TextureBarriers = MEMORY_BARRIER_ALL_TEXTURE_BARRIERS;
- 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
-}
-
void TextureBaseGL::SetDefaultGLParameters()
{
#ifdef DILIGENT_DEBUG