summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-02-21 17:12:03 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-02-21 17:12:03 +0000
commit01b7a5ff496b155f9b0fa610262cd888a30293cc (patch)
tree24bcd70401768606e460adf9f739c1868a1a6240 /Graphics/GraphicsEngineOpenGL
parentNot accessing program pipeline when separate shaders are not supported in GL ... (diff)
downloadDiligentCore-01b7a5ff496b155f9b0fa610262cd888a30293cc.tar.gz
DiligentCore-01b7a5ff496b155f9b0fa610262cd888a30293cc.zip
Fixed SRBs with non-separable shaders in GL back-end
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgram.h33
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h17
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h13
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h46
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp140
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp76
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp127
9 files changed, 264 insertions, 196 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h
index 759a072f..296ff4fd 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h
+++ b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h
@@ -30,34 +30,35 @@ namespace Diligent
class GLProgram : public GLObjectWrappers::GLProgramObj
{
public:
- GLProgram( bool CreateObject );
- GLProgram( GLProgram&& Program );
+ GLProgram(bool CreateObject);
+ GLProgram(GLProgram&& Program);
- void InitResources(RenderDeviceGLImpl* pDeviceGLImpl,
- SHADER_VARIABLE_TYPE DefaultVariableType,
- const ShaderVariableDesc *VariableDesc,
- Uint32 NumVars,
- const StaticSamplerDesc *StaticSamplers,
- Uint32 NumStaticSamplers,
- IObject &Owner);
+ GLProgram (const GLProgram&) = delete;
+ GLProgram& operator = (const GLProgram&) = delete;
+ GLProgram& operator = ( GLProgram&&) = delete;
- void BindConstantResources(IResourceMapping *pResourceMapping, Uint32 Flags);
+ void InitResources(RenderDeviceGLImpl* pDeviceGLImpl,
+ SHADER_VARIABLE_TYPE DefaultVariableType,
+ const ShaderVariableDesc* VariableDesc,
+ Uint32 NumVars,
+ const StaticSamplerDesc* StaticSamplers,
+ Uint32 NumStaticSamplers,
+ IObject& Owner);
- const GLProgramResources& GetAllResources()const{return m_AllResources;}
+ void BindConstantResources(IResourceMapping* pResourceMapping, Uint32 Flags);
+
+ const GLProgramResources& GetAllResources() const{return m_AllResources;}
GLProgramResources& GetConstantResources() {return m_ConstantResources;}
const GLProgramResources& GetConstantResources()const{return m_ConstantResources;}
#ifdef VERIFY_RESOURCE_BINDINGS
template<typename TResArrayType>
- void dbgVerifyBindingCompletenessHelper(TResArrayType &ResArr, GLProgramResources *pDynamicResources);
- void dbgVerifyBindingCompleteness(GLProgramResources *pDynamicResources, class PipelineStateGLImpl *pPSO);
+ void dbgVerifyBindingCompletenessHelper(TResArrayType& ResArr, GLProgramResources* pDynamicResources);
+ void dbgVerifyBindingCompleteness(GLProgramResources* pDynamicResources, class PipelineStateGLImpl* pPSO);
#endif
private:
- GLProgram( const GLProgram& Program );
- const GLProgram& operator = (const GLProgram& Program);
-
GLProgramResources m_AllResources;
GLProgramResources m_ConstantResources;
// When adding new member DO NOT FORGET TO UPDATE GLProgram( GLProgram&& Program )!!!
diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h
index ac7ff869..3e1bbbb1 100644
--- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h
+++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h
@@ -42,20 +42,23 @@ class PipelineStateGLImpl final : public PipelineStateBase<IPipelineStateGL, Ren
public:
using TPipelineStateBase = PipelineStateBase<IPipelineStateGL, RenderDeviceGLImpl>;
- PipelineStateGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const PipelineStateDesc& PipelineDesc, bool IsDeviceInternal = false);
+ PipelineStateGLImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceGLImpl* pDeviceGL,
+ const PipelineStateDesc& PipelineDesc,
+ bool IsDeviceInternal = false);
~PipelineStateGLImpl();
/// Queries the specific interface, see IObject::QueryInterface() for details
- virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override;
+ virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override;
- virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override final;
+ virtual void BindShaderResources( IResourceMapping* pResourceMapping, Uint32 Flags )override final;
- virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final;
+ virtual void CreateShaderResourceBinding( IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources )override final;
- virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final;
+ virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final;
- GLProgram &GetGLProgram(){return m_GLProgram;}
- GLObjectWrappers::GLPipelineObj &GetGLProgramPipeline(GLContext::NativeGLContextType Context);
+ GLProgram& GetGLProgram(){return m_GLProgram;}
+ GLObjectWrappers::GLPipelineObj& GetGLProgramPipeline(GLContext::NativeGLContextType Context);
private:
void LinkGLProgram(bool bIsProgramPipelineSupported);
diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h
index 6fc2fd27..ac76461b 100644
--- a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h
+++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h
@@ -36,18 +36,20 @@ namespace Diligent
{
class FixedBlockMemoryAllocator;
+class PipelineStateGLImpl;
+
/// Implementation of the Diligent::IShaderResourceBindingGL interface
class ShaderResourceBindingGLImpl final : public ShaderResourceBindingBase<IShaderResourceBindingGL>
{
public:
using TBase = ShaderResourceBindingBase<IShaderResourceBindingGL>;
- ShaderResourceBindingGLImpl(IReferenceCounters *pRefCounters, class PipelineStateGLImpl *pPSO);
+ ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, PipelineStateGLImpl* pPSO);
~ShaderResourceBindingGLImpl();
- virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final;
+ virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override final;
- virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags)override final;
+ virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)override final;
virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, const char *Name)override final;
@@ -57,11 +59,12 @@ public:
virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final;
- GLProgramResources &GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl *pdbgPSO);
+ GLProgramResources& GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl* pdbgPSO);
private:
+ bool IsUsingSeparatePrograms()const;
+
GLProgramResources m_DynamicProgResources[6];
- RefCntWeakPtr<PipelineStateGLImpl> m_wpPSO;
};
}
diff --git a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h
index 531e32e9..91c31b08 100644
--- a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h
+++ b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h
@@ -30,31 +30,33 @@ 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:
- Diligent::RefCntAutoPtr<IShader> m_pVertexShader;
- Diligent::RefCntAutoPtr<IShader> m_pFragmentShaders[RESOURCE_DIM_NUM_DIMENSIONS * 3];
- Diligent::RefCntAutoPtr<IBuffer> m_pConstantBuffer;
- Diligent::RefCntAutoPtr<IPipelineState> m_pPSO[RESOURCE_DIM_NUM_DIMENSIONS * 3];
+ 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;
+ IShaderVariable* m_pSrcTexVar = nullptr;
- Diligent::RefCntAutoPtr<IPipelineState> m_pOrigPSO;
- Uint32 m_OrigStencilRef = 0;
- float m_OrigBlendFactors[4] = {};
- Uint32 m_NumRenderTargets = 0;
- ITextureView *m_pOrigRTVs[MaxRenderTargets] = {};
- Diligent::RefCntAutoPtr<ITextureView> m_pOrigDSV;
- std::vector<Viewport> m_OrigViewports;
+ 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;
};
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index 42db91b6..b5889d94 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -63,7 +63,7 @@ namespace Diligent
IMPLEMENT_QUERY_INTERFACE( DeviceContextGLImpl, IID_DeviceContextGL, TDeviceContextBase )
- void DeviceContextGLImpl::SetPipelineState(IPipelineState *pPipelineState)
+ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState)
{
auto* pPipelineStateGLImpl = ValidatedCast<PipelineStateGLImpl>(pPipelineState);
TDeviceContextBase::SetPipelineState(pPipelineStateGLImpl, 0 /*Dummy*/);
@@ -425,9 +425,9 @@ namespace Diligent
#define LOG_MISSING_BINDING(VarType, Res, ArrInd)\
do{ \
if(Res->pResources.size()>1) \
- LOG_ERROR_MESSAGE( "No ", VarType, " is bound to \"", Res->Name, '[', ArrInd, "]\" variable in shader \"", pShaderGL->GetDesc().Name, "\"" );\
+ LOG_ERROR_MESSAGE( "No ", VarType, " is bound to '", Res->Name, '[', ArrInd, "]' variable in shader '", pShaderGL->GetDesc().Name, "'" );\
else \
- LOG_ERROR_MESSAGE( "No ", VarType, " is bound to \"", Res->Name, "\" variable in shader \"", pShaderGL->GetDesc().Name, "\"" );\
+ LOG_ERROR_MESSAGE( "No ", VarType, " is bound to '", Res->Name, "' variable in shader '", pShaderGL->GetDesc().Name, "'" );\
}while(false)
LOG_MISSING_BINDING("uniform buffer", it, ArrInd);
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
index caaec37a..5a22c65b 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
@@ -31,7 +31,10 @@
namespace Diligent
{
-PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters *pRefCounters, class RenderDeviceGLImpl *pDeviceGL, const PipelineStateDesc& PipelineDesc, bool bIsDeviceInternal) :
+PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceGLImpl* pDeviceGL,
+ const PipelineStateDesc& PipelineDesc,
+ bool bIsDeviceInternal) :
TPipelineStateBase(pRefCounters, pDeviceGL, PipelineDesc, bIsDeviceInternal),
m_GLProgram(false)
{
@@ -45,14 +48,14 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters *pRefCounters, class
void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported)
{
- if( bIsProgramPipelineSupported )
+ if (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 = GetShader<ShaderGLImpl>(Shader);
+ auto* pShaderGL = GetShader<ShaderGLImpl>(Shader);
HashCombine(m_ShaderResourceLayoutHash, pShaderGL->m_GlProgObj.GetAllResources().GetHash());
}
}
@@ -60,71 +63,114 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported)
{
// Create new progam
m_GLProgram.Create();
- for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader )
+ for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader)
{
- auto *pCurrShader = GetShader<ShaderGLImpl>(Shader);
- glAttachShader( m_GLProgram, pCurrShader->m_GLShaderObj );
- CHECK_GL_ERROR( "glAttachShader() failed" );
+ auto* pCurrShader = GetShader<ShaderGLImpl>(Shader);
+ glAttachShader(m_GLProgram, pCurrShader->m_GLShaderObj);
+ CHECK_GL_ERROR("glAttachShader() failed");
}
- glLinkProgram( m_GLProgram );
- CHECK_GL_ERROR( "glLinkProgram() failed" );
+ glLinkProgram(m_GLProgram);
+ CHECK_GL_ERROR("glLinkProgram() failed");
int IsLinked = GL_FALSE;
- glGetProgramiv( m_GLProgram, GL_LINK_STATUS, (int *)&IsLinked );
- CHECK_GL_ERROR( "glGetProgramiv() failed" );
- if( !IsLinked )
+ glGetProgramiv(m_GLProgram, GL_LINK_STATUS, &IsLinked);
+ CHECK_GL_ERROR("glGetProgramiv() failed");
+ if (!IsLinked)
{
int LengthWithNull = 0, Length = 0;
// Notice that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv.
// The length of the info log includes a null terminator.
- glGetProgramiv( m_GLProgram, GL_INFO_LOG_LENGTH, &LengthWithNull );
+ glGetProgramiv(m_GLProgram, GL_INFO_LOG_LENGTH, &LengthWithNull);
// The maxLength includes the NULL character
- std::vector<char> shaderProgramInfoLog( LengthWithNull );
+ std::vector<char> shaderProgramInfoLog(LengthWithNull);
// Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog.
- glGetProgramInfoLog( m_GLProgram, LengthWithNull, &Length, &shaderProgramInfoLog[0] );
- VERIFY( Length == LengthWithNull-1, "Incorrect program info log len" );
- LOG_ERROR_MESSAGE( "Failed to link shader program:\n", &shaderProgramInfoLog[0], '\n');
- UNEXPECTED( "glLinkProgram failed" );
+ glGetProgramInfoLog(m_GLProgram, LengthWithNull, &Length, shaderProgramInfoLog.data());
+ VERIFY(Length == LengthWithNull-1, "Incorrect program info log len");
+ LOG_ERROR_MESSAGE("Failed to link shader program:\n", shaderProgramInfoLog.data(), '\n');
+ UNEXPECTED("glLinkProgram failed");
}
// Detach shaders from the program object
- for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader )
+ for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader)
{
- auto *pCurrShader = GetShader<ShaderGLImpl>(Shader);
- glDetachShader( m_GLProgram, pCurrShader->m_GLShaderObj );
- CHECK_GL_ERROR( "glDetachShader() failed" );
+ auto* pCurrShader = GetShader<ShaderGLImpl>(Shader);
+ glDetachShader(m_GLProgram, pCurrShader->m_GLShaderObj);
+ CHECK_GL_ERROR("glDetachShader() failed");
}
std::vector<ShaderVariableDesc> MergedVarTypesArray;
std::vector<StaticSamplerDesc> MergedStSamArray;
SHADER_VARIABLE_TYPE DefaultVarType = SHADER_VARIABLE_TYPE_STATIC;
- for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader )
+ for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader)
{
- auto *pCurrShader = GetShader<ShaderGLImpl>(Shader);
+ auto* pCurrShader = GetShader<ShaderGLImpl>(Shader);
const auto& Desc = pCurrShader->GetDesc();
if (Shader == 0)
{
DefaultVarType = Desc.DefaultVariableType;
- for (Uint32 v = 0; v < Desc.NumVariables; ++v)
+ }
+ else
+ {
+ if (DefaultVarType != Desc.DefaultVariableType)
{
- MergedVarTypesArray.push_back(Desc.VariableDesc[v]);
+ LOG_ERROR_MESSAGE("When separate shader programs are not available, all shaders linked into a program "
+ "must use the same default variable type.");
}
- for (Uint32 s = 0; s < Desc.NumStaticSamplers; ++s)
+ }
+
+ for (Uint32 v = 0; v < Desc.NumVariables; ++v)
+ {
+ const auto& NewVar = Desc.VariableDesc[v];
+ bool VarExists = false;
+ for (const auto& Var : MergedVarTypesArray)
{
- MergedStSamArray.push_back(Desc.StaticSamplers[s]);
+ if (strcmp(Var.Name, NewVar.Name) == 0)
+ {
+ VarExists = true;
+ if (Var.Type != NewVar.Type)
+ {
+ LOG_ERROR_MESSAGE("The type of variable '", Var.Name, "' is not consistent between shader stages. "
+ "When separate shader programs are not available, all shaders must use the same "
+ "type for identically named shader variables.");
+ }
+ break;
+ }
+ }
+
+ if (!VarExists)
+ {
+ MergedVarTypesArray.push_back(NewVar);
}
}
- else
+
+ for (Uint32 s = 0; s < Desc.NumStaticSamplers; ++s)
{
- if (DefaultVarType != Desc.DefaultVariableType)
+ const auto& NewSampler = Desc.StaticSamplers[s];
+ bool SamplerExists = false;
+ for (const auto& Sampler : MergedStSamArray)
+ {
+ if (strcmp(Sampler.SamplerOrTextureName, NewSampler.SamplerOrTextureName) == 0)
+ {
+ SamplerExists = true;
+ if ( !(Sampler.Desc == NewSampler.Desc) )
+ {
+ LOG_ERROR_MESSAGE("Static sampler defined for texture '", NewSampler.SamplerOrTextureName, "' is not consistent between shader stages. "
+ "When separate shader programs are not available, all shaders must use the same "
+ "static samplers for identically named shader variables.");
+ }
+ break;
+ }
+ }
+
+ if (!SamplerExists)
{
- LOG_ERROR("Inconsistent default variable types for shaders in one program");
+ MergedStSamArray.push_back(NewSampler);
}
}
}
- auto pDeviceGL = static_cast<RenderDeviceGLImpl*>( GetDevice() );
+ auto pDeviceGL = 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();
@@ -134,49 +180,49 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported)
PipelineStateGLImpl::~PipelineStateGLImpl()
{
- static_cast<RenderDeviceGLImpl*>( GetDevice() )->OnDestroyPSO(this);
+ GetDevice()->OnDestroyPSO(this);
}
IMPLEMENT_QUERY_INTERFACE( PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase )
-void PipelineStateGLImpl::BindShaderResources(IResourceMapping *pResourceMapping, Uint32 Flags)
+void PipelineStateGLImpl::BindShaderResources(IResourceMapping* pResourceMapping, Uint32 Flags)
{
- if( GetDevice()->GetDeviceCaps().bSeparableProgramSupported )
+ if (GetDevice()->GetDeviceCaps().bSeparableProgramSupported)
{
TPipelineStateBase::BindShaderResources(pResourceMapping, Flags);
}
else
{
- if( m_GLProgram )
- m_GLProgram.BindConstantResources( pResourceMapping, Flags );
+ if (m_GLProgram)
+ m_GLProgram.BindConstantResources(pResourceMapping, Flags);
}
}
-void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources)
+void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources)
{
- auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>( GetDevice() );
- auto &SRBAllocator = pRenderDeviceGL->GetSRBAllocator();
- auto pResBinding = NEW_RC_OBJ( SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this);
+ auto* pRenderDeviceGL = GetDevice();
+ auto& SRBAllocator = pRenderDeviceGL->GetSRBAllocator();
+ auto pResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this);
if (InitStaticResources)
pResBinding->InitializeStaticResources(nullptr);
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);
if (pPSO == this)
return true;
- const PipelineStateGLImpl *pPSOGL = ValidatedCast<const PipelineStateGLImpl>(pPSO);
+ const PipelineStateGLImpl* pPSOGL = ValidatedCast<const PipelineStateGLImpl>(pPSO);
if (m_ShaderResourceLayoutHash != pPSOGL->m_ShaderResourceLayoutHash)
return false;
- return m_GLProgram.GetAllResources().IsCompatibleWith( pPSOGL->m_GLProgram.GetAllResources() );
+ return m_GLProgram.GetAllResources().IsCompatibleWith(pPSOGL->m_GLProgram.GetAllResources());
}
-GLObjectWrappers::GLPipelineObj &PipelineStateGLImpl::GetGLProgramPipeline(GLContext::NativeGLContextType Context)
+GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLContext::NativeGLContextType Context)
{
ThreadingTools::LockHelper Lock(m_ProgPipelineLockFlag);
auto it = m_GLProgPipelines.find(Context);
@@ -185,11 +231,11 @@ GLObjectWrappers::GLPipelineObj &PipelineStateGLImpl::GetGLProgramPipeline(GLCon
else
{
// Create new progam pipeline
- it = m_GLProgPipelines.emplace( Context, true ).first;
+ it = m_GLProgPipelines.emplace(Context, true).first;
GLuint Pipeline = it->second;
for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader)
{
- auto *pCurrShader = GetShader<ShaderGLImpl>(Shader);
+ auto* pCurrShader = GetShader<ShaderGLImpl>(Shader);
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
diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
index c4d2cbb0..d7f79554 100644
--- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
@@ -136,7 +136,7 @@ void RenderDeviceGLImpl :: CreateBufferFromGLHandle(Uint32 GLHandle, const Buffe
);
}
-void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader **ppShader, bool bIsDeviceInternal)
+void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader** ppShader, bool bIsDeviceInternal)
{
CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader,
[&]()
diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp
index 236b90a6..05a79001 100644
--- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp
@@ -30,17 +30,12 @@
namespace Diligent
{
-ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl( IReferenceCounters *pRefCounters, PipelineStateGLImpl *pPSO) :
- TBase( pRefCounters, pPSO ),
- m_wpPSO(pPSO)
+ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, PipelineStateGLImpl* pPSO) :
+ TBase (pRefCounters, pPSO)
{
- SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC};
- if ( static_cast<GLuint>( pPSO->GetGLProgram() ) )
- {
- m_DynamicProgResources[0].Clone(pPSO->GetGLProgram().GetAllResources(), VarTypes, _countof(VarTypes), *this);
- }
- else
+ if (IsUsingSeparatePrograms())
{
+ SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC};
#define INIT_SHADER(SN)\
if(auto p##SN = ValidatedCast<ShaderGLImpl>( pPSO->Get##SN() )) \
{ \
@@ -56,60 +51,77 @@ ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl( IReferenceCounters *pR
INIT_SHADER(CS)
#undef INIT_SHADER
}
+ else
+ {
+ // Clone all variable types
+ SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC, SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC};
+ m_DynamicProgResources[0].Clone(pPSO->GetGLProgram().GetAllResources(), VarTypes, _countof(VarTypes), *this);
+ }
}
ShaderResourceBindingGLImpl::~ShaderResourceBindingGLImpl()
{
-
}
-IMPLEMENT_QUERY_INTERFACE( ShaderResourceBindingGLImpl, IID_ShaderResourceBindingGL, TBase )
+IMPLEMENT_QUERY_INTERFACE(ShaderResourceBindingGLImpl, IID_ShaderResourceBindingGL, TBase)
-void ShaderResourceBindingGLImpl::BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags)
+bool ShaderResourceBindingGLImpl::IsUsingSeparatePrograms()const
{
- if(ShaderFlags & SHADER_TYPE_VERTEX)
- m_DynamicProgResources[VSInd].BindResources(pResMapping, Flags);
- if(ShaderFlags & SHADER_TYPE_PIXEL)
- m_DynamicProgResources[PSInd].BindResources(pResMapping, Flags);
- if(ShaderFlags & SHADER_TYPE_GEOMETRY)
- m_DynamicProgResources[GSInd].BindResources(pResMapping, Flags);
- if(ShaderFlags & SHADER_TYPE_HULL)
- m_DynamicProgResources[HSInd].BindResources(pResMapping, Flags);
- if(ShaderFlags & SHADER_TYPE_DOMAIN)
- m_DynamicProgResources[DSInd].BindResources(pResMapping, Flags);
- if(ShaderFlags & SHADER_TYPE_COMPUTE)
- m_DynamicProgResources[CSInd].BindResources(pResMapping, Flags);
+ return GetPipelineState<PipelineStateGLImpl>()->GetGLProgram() == 0;
+}
+
+void ShaderResourceBindingGLImpl::BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)
+{
+ if (IsUsingSeparatePrograms())
+ {
+ if(ShaderFlags & SHADER_TYPE_VERTEX)
+ m_DynamicProgResources[VSInd].BindResources(pResMapping, Flags);
+ if(ShaderFlags & SHADER_TYPE_PIXEL)
+ m_DynamicProgResources[PSInd].BindResources(pResMapping, Flags);
+ if(ShaderFlags & SHADER_TYPE_GEOMETRY)
+ m_DynamicProgResources[GSInd].BindResources(pResMapping, Flags);
+ if(ShaderFlags & SHADER_TYPE_HULL)
+ m_DynamicProgResources[HSInd].BindResources(pResMapping, Flags);
+ if(ShaderFlags & SHADER_TYPE_DOMAIN)
+ m_DynamicProgResources[DSInd].BindResources(pResMapping, Flags);
+ if(ShaderFlags & SHADER_TYPE_COMPUTE)
+ m_DynamicProgResources[CSInd].BindResources(pResMapping, Flags);
+ }
+ else
+ {
+ // Using non-separable program
+ m_DynamicProgResources[0].BindResources(pResMapping, Flags);
+ }
}
-IShaderVariable *ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, const char *Name)
+IShaderVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, const char* Name)
{
- auto ShaderInd = GetShaderTypeIndex(ShaderType);
+ auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0;
return m_DynamicProgResources[ShaderInd].GetShaderVariable(Name);
}
Uint32 ShaderResourceBindingGLImpl::GetVariableCount(SHADER_TYPE ShaderType) const
{
- auto ShaderInd = GetShaderTypeIndex(ShaderType);
+ auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0;
return m_DynamicProgResources[ShaderInd].GetVariableCount();
}
IShaderVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index)
{
- auto ShaderInd = GetShaderTypeIndex(ShaderType);
+ auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0;
return m_DynamicProgResources[ShaderInd].GetShaderVariable(Index);
}
static GLProgramResources NullProgramResources;
-GLProgramResources &ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl *pdbgPSO)
+GLProgramResources& ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl* pdbgPSO)
{
#ifdef _DEBUG
- auto pPSO = m_wpPSO.Lock();
- if (pdbgPSO->IsIncompatibleWith(pPSO))
+ if (pdbgPSO->IsIncompatibleWith(GetPipelineState()))
{
LOG_ERROR("Shader resource binding is incompatible with the currently bound pipeline state.");
}
#endif
- auto ShaderInd = GetShaderTypeIndex(ShaderType);
+ auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0;
return m_DynamicProgResources[ShaderInd];
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp
index f0793679..312889e7 100644
--- a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp
@@ -59,12 +59,12 @@ namespace Diligent
TexRegionRender::TexRegionRender( class RenderDeviceGLImpl *pDeviceGL )
{
ShaderCreationAttribs ShaderAttrs;
- ShaderAttrs.Desc.Name = "TexRegionRender : Vertex shader";
- ShaderAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX;
- ShaderAttrs.Source = VertexShaderSource;
- pDeviceGL->CreateShader( ShaderAttrs, &m_pVertexShader,
- true // We must indicate the shader is internal device object
- );
+ ShaderAttrs.Desc.Name = "TexRegionRender : Vertex shader";
+ ShaderAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX;
+ ShaderAttrs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_DYNAMIC;
+ 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";
@@ -87,64 +87,65 @@ namespace Diligent
//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.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,
- true // We must indicate the buffer is internal device object
- );
+ pDeviceGL->CreateBuffer(CBDesc, nullptr, &m_pConstantBuffer, IsInternalDeviceObject);
PipelineStateDesc PSODesc;
- auto &GraphicsPipeline = PSODesc.GraphicsPipeline;
+ 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.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 )
+ for (Int32 Dim = RESOURCE_DIM_TEX_2D; Dim <= RESOURCE_DIM_TEX_3D; ++Dim)
{
- const auto *SamplerDim = SamplerType[Dim];
- const auto *SrcLocation = SrcLocations[Dim];
+ 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();
+ Name.append(Prefix);
+ Name.append(SamplerDim);
+ ShaderAttrs.Desc.Name = Name.c_str();
ShaderAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL;
-
+ ShaderVariableDesc Vars[] =
+ {
+ {"cbConstants", SHADER_VARIABLE_TYPE_MUTABLE}
+ };
+ ShaderAttrs.Desc.NumVariables = _countof(Vars);
+ ShaderAttrs.Desc.VariableDesc = Vars;
+
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";
+ "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,
- true // We must indicate the shader is an internal device object
- );
+ pDeviceGL->CreateShader(ShaderAttrs, &FragmetShader, IsInternalDeviceObject);
GraphicsPipeline.pPS = FragmetShader;
- pDeviceGL->CreatePipelineState( PSODesc, &m_pPSO[Dim*3 + Fmt],
- true // We must indicate the PSO is an internal device object
- );
-
- FragmetShader->GetShaderVariable( "cbConstants" )->Set( m_pConstantBuffer );
+ pDeviceGL->CreatePipelineState(PSODesc, &m_pPSO[Dim*3 + Fmt], IsInternalDeviceObject);
}
+ m_pPSO[RESOURCE_DIM_TEX_2D*3]->CreateShaderResourceBinding(&m_pSRB);
+ m_pSRB->GetVariable(SHADER_TYPE_PIXEL, "cbConstants")->Set(m_pConstantBuffer);
+ m_pSrcTexVar = m_pSRB->GetVariable(SHADER_TYPE_PIXEL, "gSourceTex");
}
}
@@ -163,7 +164,7 @@ namespace Diligent
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 )
+ for (Uint32 rt = 0; rt < _countof( m_pOrigRTVs ); ++rt)
{
if( m_pOrigRTVs[rt] )
m_pOrigRTVs[rt]->Release();
@@ -171,55 +172,55 @@ namespace Diligent
}
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)
+ 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 );
+ 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);
+ const auto& TexFmtAttribs = GetTextureFormatAttribs(TexFormat);
Uint32 FSInd = TexType * 3;
- if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT )
+ if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT)
FSInd += 1;
- else if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT )
+ else if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT)
FSInd += 2;
- if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SNORM )
+ 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");
+
pCtxGL->SetPipelineState(m_pPSO[FSInd]);
- // Technically resetting static varaibles is not allowed, but in GL this is OK
- auto SrcTexVar = m_pFragmentShaders[FSInd]->GetShaderVariable( "gSourceTex" );
- SrcTexVar->Set( pSrcSRV );
- pCtxGL->CommitShaderResources(nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ m_pSrcTexVar->Set( pSrcSRV );
+ pCtxGL->CommitShaderResources(m_pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
DrawAttribs DrawAttrs;
DrawAttrs.NumVertices = 4;
- pCtxGL->Draw( DrawAttrs );
+ pCtxGL->Draw(DrawAttrs);
- SrcTexVar->Set( nullptr );
+ m_pSrcTexVar->Set(nullptr);
}
}