summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-03-12 03:39:29 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-03-12 03:39:29 +0000
commitac8e241fbb5c20564d5a1942e8c4ba85313cb7ab (patch)
tree14d6c5eefc94b80ac49ecacfd6d96b75856c9a3c /Graphics/GraphicsEngineOpenGL
parentImplemented PSO compatibility in D3D12 (diff)
downloadDiligentCore-ac8e241fbb5c20564d5a1942e8c4ba85313cb7ab.tar.gz
DiligentCore-ac8e241fbb5c20564d5a1942e8c4ba85313cb7ab.zip
Implemented PSO compatibility in GL backend
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgram.h2
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h62
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp70
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp20
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp4
5 files changed, 153 insertions, 5 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h
index 7ccd0ea5..1d72f416 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h
+++ b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h
@@ -43,7 +43,7 @@ namespace Diligent
void BindConstantResources(IResourceMapping *pResourceMapping, Uint32 Flags);
- const GLProgramResources& GetAllResources(){return m_AllResources;}
+ const GLProgramResources& GetAllResources()const{return m_AllResources;}
GLProgramResources& GetConstantResources(){return m_ConstantResources;}
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h
index d26c8ba4..3e52d3e3 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h
+++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h
@@ -26,6 +26,7 @@
#include "HashUtils.h"
#include "ShaderBase.h"
#include "SamplerGLImpl.h"
+#include "HashUtils.h"
#ifdef _DEBUG
# define VERIFY_RESOURCE_BINDINGS
@@ -62,6 +63,17 @@ namespace Diligent
VERIFY_EXPR(_ArraySize >= 1);
}
+ bool IsCompatibleWith(const GLProgramVariableBase &Var)const
+ {
+ return VarType == Var.VarType &&
+ pResources.size() == Var.pResources.size();
+ }
+
+ size_t GetHash()const
+ {
+ return ComputeHash(VarType, pResources.size());
+ }
+
String Name;
std::vector< RefCntAutoPtr<IDeviceObject> > pResources;
SHADER_VARIABLE_TYPE VarType;
@@ -74,6 +86,17 @@ namespace Diligent
Index(_Index)
{}
+ bool IsCompatibleWith(const UniformBufferInfo& UBI)const
+ {
+ return Index == UBI.Index &&
+ GLProgramVariableBase::IsCompatibleWith(UBI);
+ }
+
+ size_t GetHash()const
+ {
+ return ComputeHash(Index, GLProgramVariableBase::GetHash());
+ }
+
GLuint Index;
};
std::vector<UniformBufferInfo>& GetUniformBlocks(){ return m_UniformBlocks; }
@@ -86,6 +109,19 @@ namespace Diligent
Type(_Type),
pStaticSampler(_pStaticSampler)
{}
+
+ bool IsCompatibleWith(const SamplerInfo& SI)const
+ {
+ return Location == SI.Location &&
+ Type == SI.Type &&
+ GLProgramVariableBase::IsCompatibleWith(SI);
+ }
+
+ size_t GetHash()const
+ {
+ return ComputeHash(Location, Type, GLProgramVariableBase::GetHash());
+ }
+
GLint Location;
GLenum Type;
RefCntAutoPtr<class SamplerGLImpl> pStaticSampler;
@@ -100,6 +136,18 @@ namespace Diligent
Type(_Type)
{}
+ bool IsCompatibleWith(const ImageInfo& II)const
+ {
+ return BindingPoint == II.BindingPoint &&
+ Type == II.Type &&
+ GLProgramVariableBase::IsCompatibleWith(II);
+ }
+
+ size_t GetHash()const
+ {
+ return ComputeHash(BindingPoint, Type, GLProgramVariableBase::GetHash());
+ }
+
GLint BindingPoint;
GLenum Type;
};
@@ -112,6 +160,17 @@ namespace Diligent
Binding(_Binding)
{}
+ bool IsCompatibleWith(const StorageBlockInfo& SBI)const
+ {
+ return Binding == SBI.Binding &&
+ GLProgramVariableBase::IsCompatibleWith(SBI);
+ }
+
+ size_t GetHash()const
+ {
+ return ComputeHash(Binding, GLProgramVariableBase::GetHash());
+ }
+
GLint Binding;
};
std::vector<StorageBlockInfo>& GetStorageBlocks(){ return m_StorageBlocks; }
@@ -149,6 +208,9 @@ namespace Diligent
const std::unordered_map<HashMapStringKey, CGLShaderVariable>& GetVariables(){return m_VariableHash;}
+ bool IsCompatibleWith(const GLProgramResources& Res)const;
+ size_t GetHash()const;
+
private:
const GLProgramResources& operator = (const GLProgramResources& Program);
diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp
index 682c1cb4..90230428 100644
--- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp
@@ -466,6 +466,76 @@ namespace Diligent
BindResourcesHelper( m_StorageBlocks, pResourceMapping, Flags );
}
+ bool GLProgramResources::IsCompatibleWith(const GLProgramResources& Res)const
+ {
+ if (m_UniformBlocks.size() != Res.m_UniformBlocks.size() ||
+ m_Samplers.size() != Res.m_Samplers.size() ||
+ m_Images.size() != Res.m_Images.size() ||
+ m_StorageBlocks.size() != Res.m_StorageBlocks.size())
+ return false;
+
+ for (size_t ub = 0; ub < m_UniformBlocks.size(); ++ub)
+ {
+ const auto &UB0 = m_UniformBlocks[ub];
+ const auto &UB1 = Res.m_UniformBlocks[ub];
+ if(!UB0.IsCompatibleWith(UB1))
+ return false;
+ }
+
+ for (size_t sam = 0; sam < m_Samplers.size(); ++sam)
+ {
+ const auto &Sam0 = m_Samplers[sam];
+ const auto &Sam1 = Res.m_Samplers[sam];
+ if (!Sam0.IsCompatibleWith(Sam1))
+ return false;
+ }
+
+ for (size_t img = 0; img < m_Images.size(); ++img)
+ {
+ const auto &Img0 = m_Images[img];
+ const auto &Img1 = Res.m_Images[img];
+ if (!Img0.IsCompatibleWith(Img1))
+ return false;
+ }
+
+ for (size_t sb = 0; sb < m_StorageBlocks.size(); ++sb)
+ {
+ const auto &SB0 = m_StorageBlocks[sb];
+ const auto &SB1 = Res.m_StorageBlocks[sb];
+ if (!SB0.IsCompatibleWith(SB1))
+ return false;
+ }
+
+ return true;
+ }
+
+ size_t GLProgramResources::GetHash()const
+ {
+ size_t hash = ComputeHash(m_UniformBlocks.size(), m_Samplers.size(), m_Images.size(), m_StorageBlocks.size());
+
+ for (auto ub = m_UniformBlocks.begin(); ub != m_UniformBlocks.end(); ++ub)
+ {
+ HashCombine(hash, ub->GetHash());
+ }
+
+ for (auto sam = m_Samplers.begin(); sam != m_Samplers.end(); ++sam)
+ {
+ HashCombine(hash, sam->GetHash());
+ }
+
+ for (auto img = m_Images.begin(); img != m_Images.end(); ++img)
+ {
+ HashCombine(hash, img->GetHash());
+ }
+
+ for (auto sb = m_StorageBlocks.begin(); sb != m_StorageBlocks.end(); ++sb)
+ {
+ HashCombine(hash, sb->GetHash());
+ }
+
+ return hash;
+ }
+
#ifdef VERIFY_RESOURCE_BINDINGS
template<typename TResArrayType>
void dbgVerifyResourceBindingsHelper(TResArrayType &ResArr, const Char *VarType)
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
index 90dbef39..8794e91c 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
@@ -49,6 +49,12 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported)
{
// Program pipelines are not shared between GL contexts, so we cannot create
// it now
+ m_ShaderResourceLayoutHash = 0;
+ for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader)
+ {
+ auto *pShaderGL = static_cast<ShaderGLImpl*>(m_ppShaders[Shader]);
+ HashCombine(m_ShaderResourceLayoutHash, pShaderGL->m_GlProgObj.GetAllResources().GetHash());
+ }
}
else
{
@@ -120,6 +126,8 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported)
auto pDeviceGL = static_cast<RenderDeviceGLImpl*>( GetDevice() );
m_GLProgram.InitResources(pDeviceGL, DefaultVarType, MergedVarTypesArray.data(), static_cast<Uint32>(MergedVarTypesArray.size()), MergedStSamArray.data(), static_cast<Uint32>(MergedStSamArray.size()), *this);
+
+ m_ShaderResourceLayoutHash = m_GLProgram.GetAllResources().GetHash();
}
}
@@ -157,8 +165,16 @@ void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding **p
bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState *pPSO)const
{
- UNSUPPORTED("Not yet implemented");
- return false;
+ VERIFY_EXPR(pPSO != nullptr);
+
+ if (pPSO == this)
+ return true;
+
+ const PipelineStateGLImpl *pPSOGL = ValidatedCast<const PipelineStateGLImpl>(pPSO);
+ if (m_ShaderResourceLayoutHash != pPSOGL->m_ShaderResourceLayoutHash)
+ return false;
+
+ return m_GLProgram.GetAllResources().IsCompatibleWith( pPSOGL->m_GLProgram.GetAllResources() );
}
GLObjectWrappers::GLPipelineObj &PipelineStateGLImpl::GetGLProgramPipeline(GLContext::NativeGLContextType Context)
diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp
index fe9760b3..91b19e72 100644
--- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp
@@ -99,9 +99,9 @@ GLProgramResources &ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE
{
#ifdef _DEBUG
auto pPSO = m_wpPSO.Lock();
- if (pPSO != pdbgPSO)
+ if (pdbgPSO->IsIncompatibleWith(pPSO))
{
- LOG_ERROR("Shader resource binding does not match the currently bound pipeline state.");
+ LOG_ERROR("Shader resource binding is incompatible with the currently bound pipeline state.");
}
#endif
auto ShaderInd = GetShaderTypeIndex(ShaderType);