summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-10-21 22:15:55 +0000
committerazhirnov <zh1dron@gmail.com>2020-10-25 10:50:53 +0000
commit42217cc1ec7f81c028dcc5c1f845a2fc3b3da497 (patch)
tree2efcb7c0fdeae582ecb5c8d13c7bedd593ab9a3c /Graphics/GraphicsEngineOpenGL
parentFixed Mac/iOS build (diff)
parentUpdated Metal testing environment (diff)
downloadDiligentCore-42217cc1ec7f81c028dcc5c1f845a2fc3b3da497.tar.gz
DiligentCore-42217cc1ec7f81c028dcc5c1f845a2fc3b3da497.zip
Merge branch 'master' into ray_tracing
# Conflicts: # Graphics/GraphicsEngine/interface/PipelineState.h # Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp # Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp # Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.hpp12
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgramResources.hpp10
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp42
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp23
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp48
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp231
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp40
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp19
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp2
17 files changed, 338 insertions, 123 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.hpp b/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.hpp
index 80f622c9..24e88004 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/GLPipelineResourceLayout.hpp
@@ -118,15 +118,15 @@ public:
GLVariableBase(const GLProgramResources::GLResourceAttribs& ResourceAttribs,
GLPipelineResourceLayout& ParentLayout,
SHADER_RESOURCE_VARIABLE_TYPE VariableType,
- Int32 StaticSamplerIdx) :
+ Int32 ImtblSamplerIdx) :
// clang-format off
TBase {ParentLayout},
m_Attribs {ResourceAttribs },
m_VariableType {VariableType },
- m_StaticSamplerIdx{StaticSamplerIdx}
+ m_ImtblSamplerIdx {ImtblSamplerIdx}
// clang-format on
{
- VERIFY_EXPR(StaticSamplerIdx < 0 || ResourceAttribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV);
+ VERIFY_EXPR(ImtblSamplerIdx < 0 || ResourceAttribs.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV);
}
virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final
@@ -146,7 +146,7 @@ public:
const GLProgramResources::GLResourceAttribs& m_Attribs;
const SHADER_RESOURCE_VARIABLE_TYPE m_VariableType;
- const Int32 m_StaticSamplerIdx;
+ const Int32 m_ImtblSamplerIdx;
};
@@ -188,8 +188,8 @@ public:
SamplerBindInfo(const GLProgramResources::GLResourceAttribs& ResourceAttribs,
GLPipelineResourceLayout& ParentResLayout,
SHADER_RESOURCE_VARIABLE_TYPE VariableType,
- Int32 StaticSamplerIdx) :
- GLVariableBase{ResourceAttribs, ParentResLayout, VariableType, StaticSamplerIdx}
+ Int32 ImtblSamplerIdx) :
+ GLVariableBase{ResourceAttribs, ParentResLayout, VariableType, ImtblSamplerIdx}
{}
// Non-virtual function
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp
index 3fbc550e..07c8f39e 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp
@@ -45,7 +45,7 @@ namespace Diligent
class GLProgramResourceCache
{
public:
- GLProgramResourceCache()
+ GLProgramResourceCache() noexcept
{}
~GLProgramResourceCache();
@@ -128,9 +128,9 @@ public:
GetSampler(Binding).Set(std::move(pTexView), SetSampler);
}
- void SetStaticSampler(Uint32 Binding, ISampler* pStaticSampler)
+ void SetImmutableSampler(Uint32 Binding, ISampler* pImtblSampler)
{
- GetSampler(Binding).pSampler = ValidatedCast<SamplerGLImpl>(pStaticSampler);
+ GetSampler(Binding).pSampler = ValidatedCast<SamplerGLImpl>(pImtblSampler);
}
void CopySampler(Uint32 Binding, const CachedResourceView& SrcSam)
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.hpp b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.hpp
index a3b13b6d..091d0e31 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.hpp
@@ -147,6 +147,16 @@ public:
ResourceDesc.Type = ResourceType;
return ResourceDesc;
}
+
+ RESOURCE_DIMENSION GetResourceDimension() const
+ {
+ return RESOURCE_DIM_UNDEFINED;
+ }
+
+ bool IsMultisample() const
+ {
+ return false;
+ }
};
struct UniformBufferInfo final : GLResourceAttribs
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp
index a93528ec..4c57652f 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp
@@ -82,7 +82,7 @@ inline GLenum UsageToGLUsage(const BufferDesc& Desc)
// DYNAMIC: The data store contents will be modified repeatedly and used many times.
// clang-format off
- case USAGE_STATIC: return GL_STATIC_DRAW;
+ case USAGE_IMMUTABLE: 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;
diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp
index dea1d6c8..93180774 100644
--- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp
@@ -37,6 +37,7 @@
#include "GLProgramResources.hpp"
#include "GLPipelineResourceLayout.hpp"
#include "GLProgramResourceCache.hpp"
+#include "ShaderGLImpl.hpp"
namespace Diligent
{
@@ -49,10 +50,14 @@ class PipelineStateGLImpl final : public PipelineStateBase<IPipelineStateGL, Ren
public:
using TPipelineStateBase = PipelineStateBase<IPipelineStateGL, RenderDeviceGLImpl>;
- PipelineStateGLImpl(IReferenceCounters* pRefCounters,
- RenderDeviceGLImpl* pDeviceGL,
- const PipelineStateCreateInfo& CreateInfo,
- bool IsDeviceInternal = false);
+ PipelineStateGLImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceGLImpl* pDeviceGL,
+ const GraphicsPipelineStateCreateInfo& CreateInfo,
+ bool IsDeviceInternal = false);
+ PipelineStateGLImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceGLImpl* pDeviceGL,
+ const ComputePipelineStateCreateInfo& CreateInfo,
+ bool IsDeviceInternal = false);
~PipelineStateGLImpl();
/// Queries the specific interface, see IObject::QueryInterface() for details
@@ -90,12 +95,32 @@ public:
private:
GLObjectWrappers::GLPipelineObj& GetGLProgramPipeline(GLContext::NativeGLContextType Context);
- void InitStaticSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache) const;
+ void InitImmutableSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache) const;
+
+ struct GLPipelineShaderStageInfo
+ {
+ const SHADER_TYPE Type;
+ ShaderGLImpl* const pShader;
+ GLPipelineShaderStageInfo(SHADER_TYPE _Type,
+ ShaderGLImpl* _pShader) :
+ Type{_Type},
+ pShader{_pShader}
+ {}
+ };
+
+ template <typename PSOCreateInfoType>
+ void Initialize(const PSOCreateInfoType& CreateInfo, const std::vector<GLPipelineShaderStageInfo>& ShaderStages);
+
+ void InitResourceLayouts(const std::vector<GLPipelineShaderStageInfo>& ShaderStages,
+ LinearAllocator& MemPool);
+
+ void Destruct();
// Linked GL programs for every shader stage. Every pipeline needs to have its own programs
// because resource bindings assigned by GLProgramResources::LoadUniforms depend on other
// shader stages.
- std::vector<GLObjectWrappers::GLProgramObj> m_GLPrograms;
+ using GLProgramObj = GLObjectWrappers::GLProgramObj;
+ GLProgramObj* m_GLPrograms = nullptr; // [m_NumShaderStages]
ThreadingTools::LockFlag m_ProgPipelineLockFlag;
@@ -113,14 +138,15 @@ private:
GLProgramResourceCache m_StaticResourceCache;
// Program resources for all shader stages in the pipeline
- std::vector<GLProgramResources> m_ProgramResources;
+ GLProgramResources* m_ProgramResources = nullptr; // [m_NumShaderStages]
Uint32 m_TotalUniformBufferBindings = 0;
Uint32 m_TotalSamplerBindings = 0;
Uint32 m_TotalImageBindings = 0;
Uint32 m_TotalStorageBufferBindings = 0;
- std::vector<RefCntAutoPtr<ISampler>> m_StaticSamplers;
+ using SamplerPtr = RefCntAutoPtr<ISampler>;
+ SamplerPtr* m_ImmutableSamplers = nullptr; // [m_Desc.ResourceLayout.NumImmutableSamplers]
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp
index be2b4ddc..3c34b483 100644
--- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp
@@ -86,12 +86,20 @@ public:
virtual void DILIGENT_CALL_TYPE CreateSampler(const SamplerDesc& SamplerDesc,
ISampler** ppSampler) override final;
- /// Implementation of IRenderDevice::CreatePipelineState() in OpenGL backend.
- void CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo,
- IPipelineState** ppPipelineState,
- bool bIsDeviceInternal);
- virtual void DILIGENT_CALL_TYPE CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo,
- IPipelineState** ppPipelineState) override final;
+ /// Implementation of IRenderDevice::CreateGraphicsPipelineState() in OpenGL backend.
+ virtual void DILIGENT_CALL_TYPE CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo,
+ IPipelineState** ppPipelineState) override final;
+
+ /// Implementation of IRenderDevice::CreateComputePipelineState() in OpenGL backend.
+ virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo,
+ IPipelineState** ppPipelineState) override final;
+
+ void CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo,
+ IPipelineState** ppPipelineState,
+ bool bIsDeviceInternal);
+ void CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo,
+ IPipelineState** ppPipelineState,
+ bool bIsDeviceInternal);
/// Implementation of IRenderDevice::CreateFence() in OpenGL backend.
virtual void DILIGENT_CALL_TYPE CreateFence(const FenceDesc& Desc, IFence** ppFence) override final;
@@ -179,6 +187,9 @@ protected:
std::unique_ptr<TexRegionRender> m_pTexRegionRender;
private:
+ template <typename PSOCreateInfoType>
+ void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal);
+
virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final;
bool CheckExtension(const Char* ExtensionString);
void FlagSupportedTexFormats();
diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp
index bc0f32e6..d4c4b87e 100644
--- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp
@@ -92,7 +92,7 @@ public:
/// Implementation of IShader::GetResource() in OpenGL backend.
virtual void DILIGENT_CALL_TYPE GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final;
- static GLObjectWrappers::GLProgramObj LinkProgram(IShader** ppShaders, Uint32 NumShaders, bool IsSeparableProgram);
+ static GLObjectWrappers::GLProgramObj LinkProgram(ShaderGLImpl** ppShaders, Uint32 NumShaders, bool IsSeparableProgram);
private:
GLObjectWrappers::GLShaderObj m_GLShaderObj;
diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
index 4bba7d46..ac99cfa0 100644
--- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
@@ -96,8 +96,8 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters,
LOG_ERROR_AND_THROW("Unified resources are not supported in OpenGL/GLES");
}
- if (m_Desc.Usage == USAGE_STATIC)
- VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for static buffers");
+ if (m_Desc.Usage == USAGE_IMMUTABLE)
+ VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for immutable 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 deea5ade..7b09f9ce 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -85,12 +85,12 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState)
TDeviceContextBase::SetPipelineState(pPipelineStateGLImpl, 0 /*Dummy*/);
const auto& Desc = pPipelineStateGLImpl->GetDesc();
- if (Desc.IsComputePipeline())
+ if (Desc.PipelineType == PIPELINE_TYPE_COMPUTE)
{
}
else if (Desc.PipelineType == PIPELINE_TYPE_GRAPHICS)
{
- const auto& GraphicsPipeline = Desc.GraphicsPipeline;
+ const auto& GraphicsPipeline = pPipelineStateGLImpl->GetGraphicsPipelineDesc();
// Set rasterizer state
{
const auto& RasterizerDesc = GraphicsPipeline.RasterizerDesc;
@@ -896,7 +896,7 @@ void DeviceContextGLImpl::PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenu
m_pPipelineState->CommitProgram(m_ContextState);
auto CurrNativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext();
- const auto& PipelineDesc = m_pPipelineState->GetDesc().GraphicsPipeline;
+ const auto& PipelineDesc = m_pPipelineState->GetGraphicsPipelineDesc();
if (!m_ContextState.IsValidVAOBound())
{
auto& VAOCache = m_pDevice->GetVAOCache(CurrNativeGLContext);
diff --git a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp
index 0955a54f..d2f9cddc 100644
--- a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp
@@ -147,11 +147,11 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P
{
auto VarType = GetShaderVariableType(ShaderStages, Sam.Name, ResourceLayout);
VERIFY_EXPR(IsAllowedType(VarType, DbgAllowedTypeBits));
- Int32 StaticSamplerIdx = -1;
+ Int32 ImtblSamplerIdx = -1;
if (Sam.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV)
{
- StaticSamplerIdx = FindStaticSampler(ResourceLayout.StaticSamplers, ResourceLayout.NumStaticSamplers, ShaderStages,
- Sam.Name, nullptr);
+ ImtblSamplerIdx = FindImmutableSampler(ResourceLayout.ImmutableSamplers, ResourceLayout.NumImmutableSamplers, ShaderStages,
+ Sam.Name, nullptr);
}
auto* pSamVar = new (&GetResource<SamplerBindInfo>(VarCounters.NumSamplers++))
SamplerBindInfo //
@@ -159,7 +159,7 @@ void GLPipelineResourceLayout::Initialize(GLProgramResources* P
Sam,
*this,
VarType,
- StaticSamplerIdx //
+ ImtblSamplerIdx //
};
SamplerBindingSlots = std::max(SamplerBindingSlots, pSamVar->m_Attribs.Binding + pSamVar->m_Attribs.ArraySize);
},
@@ -290,13 +290,13 @@ void GLPipelineResourceLayout::SamplerBindInfo::BindResource(IDeviceObject* pVie
{
auto& CachedTexSampler = ResourceCache.GetConstSampler(m_Attribs.Binding + ArrayIndex);
VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewGL.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE}, CachedTexSampler.pView.RawPtr());
- if (m_StaticSamplerIdx >= 0)
+ if (m_ImtblSamplerIdx >= 0)
{
- VERIFY(CachedTexSampler.pSampler != nullptr, "Static samplers must be initialized by PipelineStateGLImpl::InitializeSRBResourceCache!");
+ VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineStateGLImpl::InitializeSRBResourceCache!");
}
}
#endif
- ResourceCache.SetTexSampler(m_Attribs.Binding + ArrayIndex, std::move(pViewGL), m_StaticSamplerIdx < 0);
+ ResourceCache.SetTexSampler(m_Attribs.Binding + ArrayIndex, std::move(pViewGL), m_ImtblSamplerIdx < 0);
}
else if (m_Attribs.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV)
{
@@ -307,6 +307,16 @@ void GLPipelineResourceLayout::SamplerBindInfo::BindResource(IDeviceObject* pVie
{
auto& CachedBuffSampler = ResourceCache.GetConstSampler(m_Attribs.Binding + ArrayIndex);
VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE}, CachedBuffSampler.pView.RawPtr());
+ if (pViewGL != nullptr)
+ {
+ const auto& ViewDesc = pViewGL->GetDesc();
+ const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
+ if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW))
+ {
+ LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
+ m_Attribs.Name, ": formatted buffer view is expected.");
+ }
+ }
}
#endif
ResourceCache.SetBufSampler(m_Attribs.Binding + ArrayIndex, std::move(pViewGL));
@@ -347,6 +357,16 @@ void GLPipelineResourceLayout::ImageBindInfo::BindResource(IDeviceObject* pView,
{
auto& CachedUAV = ResourceCache.GetConstImage(m_Attribs.Binding + ArrayIndex);
VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewGL.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS}, CachedUAV.pView.RawPtr());
+ if (pViewGL != nullptr)
+ {
+ const auto& ViewDesc = pViewGL->GetDesc();
+ const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
+ if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW))
+ {
+ LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
+ m_Attribs.Name, ": formatted buffer view is expected.");
+ }
+ }
}
#endif
ResourceCache.SetBufImage(m_Attribs.Binding + ArrayIndex, std::move(pViewGL));
@@ -375,6 +395,16 @@ void GLPipelineResourceLayout::StorageBufferBindInfo::BindResource(IDeviceObject
auto& CachedSSBO = ResourceCache.GetConstSSBO(m_Attribs.Binding + ArrayIndex);
// HLSL structured buffers are mapped to SSBOs in GLSL
VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE, BUFFER_VIEW_UNORDERED_ACCESS}, CachedSSBO.pBufferView.RawPtr());
+ if (pViewGL != nullptr)
+ {
+ const auto& ViewDesc = pViewGL->GetDesc();
+ const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
+ if (BuffDesc.Mode != BUFFER_MODE_STRUCTURED && BuffDesc.Mode != BUFFER_MODE_RAW)
+ {
+ LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
+ m_Attribs.Name, ": structured buffer view is expected.");
+ }
+ }
}
#endif
ResourceCache.SetSSBO(m_Attribs.Binding + ArrayIndex, std::move(pViewGL));
@@ -764,9 +794,9 @@ bool GLPipelineResourceLayout::dvpVerifyBindings(const GLProgramResourceCache& R
else
{
const auto& CachedSampler = ResourceCache.GetConstSampler(BindPoint);
- if (sam.m_StaticSamplerIdx >= 0 && CachedSampler.pSampler == nullptr)
+ if (sam.m_ImtblSamplerIdx >= 0 && CachedSampler.pSampler == nullptr)
{
- LOG_ERROR_MESSAGE("Static sampler is not initialized for texture '", sam.m_Attribs.Name, "'");
+ LOG_ERROR_MESSAGE("Immutable sampler is not initialized for texture '", sam.m_Attribs.Name, "'");
BindingsOK = false;
}
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp
index 95557557..84cdc46e 100644
--- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp
@@ -92,7 +92,9 @@ GLProgramResourceCache::~GLProgramResourceCache()
void GLProgramResourceCache::Destroy(IMemoryAllocator& MemAllocator)
{
- VERIFY(IsInitialized(), "Resource cache is not initialized");
+ if (!IsInitialized())
+ return;
+
VERIFY(m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources");
for (Uint32 cb = 0; cb < GetUBCount(); ++cb)
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
index 399983c9..8b429094 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
@@ -36,10 +36,47 @@
namespace Diligent
{
-PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters,
- RenderDeviceGLImpl* pDeviceGL,
- const PipelineStateCreateInfo& CreateInfo,
- bool bIsDeviceInternal) :
+
+template <typename PSOCreateInfoType>
+void PipelineStateGLImpl::Initialize(const PSOCreateInfoType& CreateInfo, const std::vector<GLPipelineShaderStageInfo>& ShaderStages)
+{
+ LinearAllocator MemPool{GetRawAllocator()};
+ VERIFY_EXPR(m_NumShaderStages > 0 && m_NumShaderStages == ShaderStages.size());
+ if (!GetDevice()->GetDeviceCaps().Features.SeparablePrograms)
+ m_NumShaderStages = 1;
+
+ const auto NumPrograms = GetNumShaderStages();
+
+ MemPool.AddSpace<GLProgramObj>(NumPrograms);
+ MemPool.AddSpace<GLProgramResources>(NumPrograms);
+ MemPool.AddSpace<SamplerPtr>(m_Desc.ResourceLayout.NumImmutableSamplers);
+
+ ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
+
+ MemPool.Reserve();
+
+ m_GLPrograms = MemPool.ConstructArray<GLProgramObj>(NumPrograms, false);
+
+ // The memory is now owned by PipelineStateVkImpl and will be freed by Destruct().
+ auto* Ptr = MemPool.ReleaseOwnership();
+ VERIFY_EXPR(Ptr == m_GLPrograms);
+ (void)Ptr;
+
+ m_ProgramResources = MemPool.ConstructArray<GLProgramResources>(NumPrograms);
+
+ m_ImmutableSamplers = MemPool.ConstructArray<SamplerPtr>(m_Desc.ResourceLayout.NumImmutableSamplers);
+
+ // It is important to construct all objects before initializing them because if an exception is thrown,
+ // destructors will be called for all objects
+
+ InitResourceLayouts(ShaderStages, MemPool);
+ InitializePipelineDesc(CreateInfo, MemPool);
+}
+
+PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceGLImpl* pDeviceGL,
+ const GraphicsPipelineStateCreateInfo& CreateInfo,
+ bool bIsDeviceInternal) :
// clang-format off
TPipelineStateBase
{
@@ -52,22 +89,110 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun
m_StaticResourceLayout{*this}
// clang-format on
{
- if (m_Desc.IsAnyGraphicsPipeline() && m_pPS == nullptr)
+ try
+ {
+ std::vector<GLPipelineShaderStageInfo> ShaderStages;
+ ExtractShaders<ShaderGLImpl>(CreateInfo, ShaderStages);
+
+ RefCntAutoPtr<ShaderGLImpl> pTempPS;
+ if (CreateInfo.pPS == nullptr)
+ {
+ // Some OpenGL implementations fail if fragment shader is not present, so
+ // create a dummy one.
+ ShaderCreateInfo ShaderCI;
+ ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL;
+ ShaderCI.Source = "void main(){}";
+ ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
+ ShaderCI.Desc.Name = "Dummy fragment shader";
+ pDeviceGL->CreateShader(ShaderCI, reinterpret_cast<IShader**>(static_cast<ShaderGLImpl**>(&pTempPS)));
+
+ ShaderStages.emplace_back(SHADER_TYPE_PIXEL, pTempPS);
+ m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL;
+ }
+
+ Initialize(CreateInfo, ShaderStages);
+ }
+ catch (...)
{
- // Some OpenGL implementations fail if fragment shader is not present, so
- // create a dummy one.
- ShaderCreateInfo ShaderCI;
- ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL;
- ShaderCI.Source = "void main(){}";
- ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
- ShaderCI.Desc.Name = "Dummy fragment shader";
- pDeviceGL->CreateShader(ShaderCI, &m_pPS);
- m_Desc.GraphicsPipeline.pPS = m_pPS;
- m_ppShaders[m_NumShaders++] = m_pPS;
+ Destruct();
}
+}
+
+PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceGLImpl* pDeviceGL,
+ const ComputePipelineStateCreateInfo& CreateInfo,
+ bool bIsDeviceInternal) :
+ // clang-format off
+ TPipelineStateBase
+ {
+ pRefCounters,
+ pDeviceGL,
+ CreateInfo.PSODesc,
+ bIsDeviceInternal
+ },
+ m_ResourceLayout {*this},
+ m_StaticResourceLayout{*this}
+// clang-format on
+{
+ try
+ {
+ std::vector<GLPipelineShaderStageInfo> ShaderStages;
+ ExtractShaders<ShaderGLImpl>(CreateInfo, ShaderStages);
- auto& DeviceCaps = pDeviceGL->GetDeviceCaps();
- VERIFY(DeviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized");
+ Initialize(CreateInfo, ShaderStages);
+ }
+ catch (...)
+ {
+ Destruct();
+ }
+}
+
+PipelineStateGLImpl::~PipelineStateGLImpl()
+{
+ Destruct();
+}
+
+void PipelineStateGLImpl::Destruct()
+{
+ auto& RawAllocator = GetRawAllocator();
+ m_StaticResourceCache.Destroy(RawAllocator);
+ GetDevice()->OnDestroyPSO(this);
+
+ if (m_ImmutableSamplers != nullptr)
+ {
+ for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumImmutableSamplers; ++i)
+ {
+ m_ImmutableSamplers[i].~SamplerPtr();
+ }
+ }
+
+ for (Uint32 i = 0; i < GetNumShaderStages(); ++i)
+ {
+ if (m_GLPrograms != nullptr)
+ {
+ m_GLPrograms[i].~GLProgramObj();
+ }
+ if (m_ProgramResources != nullptr)
+ {
+ m_ProgramResources[i].~GLProgramResources();
+ }
+ }
+
+ if (void* pRawMem = m_GLPrograms)
+ {
+ RawAllocator.Free(pRawMem);
+ }
+}
+
+IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase)
+
+
+void PipelineStateGLImpl::InitResourceLayouts(const std::vector<GLPipelineShaderStageInfo>& ShaderStages,
+ LinearAllocator& MemPool)
+{
+ auto* const pDeviceGL = GetDevice();
+ const auto& deviceCaps = pDeviceGL->GetDeviceCaps();
+ VERIFY(deviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized");
auto pImmediateCtx = m_pDevice->GetImmediateContext();
VERIFY_EXPR(pImmediateCtx);
@@ -78,18 +203,16 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun
m_TotalSamplerBindings = 0;
m_TotalImageBindings = 0;
m_TotalStorageBufferBindings = 0;
- if (DeviceCaps.Features.SeparablePrograms)
+ if (deviceCaps.Features.SeparablePrograms)
{
// Program pipelines are not shared between GL contexts, so we cannot create
// it now
m_ShaderResourceLayoutHash = 0;
- m_ProgramResources.resize(m_NumShaders);
- m_GLPrograms.reserve(m_NumShaders);
- for (Uint32 i = 0; i < m_NumShaders; ++i)
+ for (size_t i = 0; i < ShaderStages.size(); ++i)
{
- auto* pShaderGL = GetShader<ShaderGLImpl>(i);
+ auto* pShaderGL = ShaderStages[i].pShader;
const auto& ShaderDesc = pShaderGL->GetDesc();
- m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&m_ppShaders[i], 1, true));
+ m_GLPrograms[i] = GLProgramObj{ShaderGLImpl::LinkProgram(&pShaderGL, 1, true)};
// Load uniforms and assign bindings
m_ProgramResources[i].LoadUniforms(ShaderDesc.ShaderType, m_GLPrograms[i], GLState,
m_TotalUniformBufferBindings,
@@ -102,15 +225,19 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun
}
else
{
- m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(m_ppShaders.data(), m_NumShaders, false));
- m_ProgramResources.resize(1);
- SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN;
- for (Uint32 i = 0; i < m_NumShaders; ++i)
+ std::vector<ShaderGLImpl*> Shaders;
+
+ SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN;
+ for (const auto& Stage : ShaderStages)
{
- const auto& ShaderDesc = m_ppShaders[i]->GetDesc();
- ShaderStages |= ShaderDesc.ShaderType;
+ Shaders.push_back(Stage.pShader);
+ VERIFY((ActiveStages & Stage.Type) == 0, "Shader stage ", GetShaderTypeLiteralName(Stage.Type), " is already active");
+ ActiveStages |= Stage.Type;
}
- m_ProgramResources[0].LoadUniforms(ShaderStages, m_GLPrograms[0], GLState,
+
+ m_GLPrograms[0] = ShaderGLImpl::LinkProgram(Shaders.data(), static_cast<Uint32>(Shaders.size()), false);
+
+ m_ProgramResources[0].LoadUniforms(ActiveStages, m_GLPrograms[0], GLState,
m_TotalUniformBufferBindings,
m_TotalSamplerBindings,
m_TotalImageBindings,
@@ -120,38 +247,27 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun
}
// Initialize master resource layout that keeps all variable types and does not reference a resource cache
- m_ResourceLayout.Initialize(m_ProgramResources.data(), static_cast<Uint32>(m_GLPrograms.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr);
+ m_ResourceLayout.Initialize(m_ProgramResources, GetNumShaderStages(), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr);
}
- m_StaticSamplers.resize(m_Desc.ResourceLayout.NumStaticSamplers);
- for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumStaticSamplers; ++s)
+ for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumImmutableSamplers; ++s)
{
- pDeviceGL->CreateSampler(m_Desc.ResourceLayout.StaticSamplers[s].Desc, &m_StaticSamplers[s]);
+ pDeviceGL->CreateSampler(m_Desc.ResourceLayout.ImmutableSamplers[s].Desc, &m_ImmutableSamplers[s]);
}
{
// Clone only static variables into static resource layout, assign and initialize static resource cache
const SHADER_RESOURCE_VARIABLE_TYPE StaticVars[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
- m_StaticResourceLayout.Initialize(m_ProgramResources.data(), static_cast<Uint32>(m_GLPrograms.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache);
- InitStaticSamplersInResourceCache(m_StaticResourceLayout, m_StaticResourceCache);
+ m_StaticResourceLayout.Initialize(m_ProgramResources, GetNumShaderStages(), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache);
+ InitImmutableSamplersInResourceCache(m_StaticResourceLayout, m_StaticResourceCache);
}
}
-
-PipelineStateGLImpl::~PipelineStateGLImpl()
-{
- m_StaticResourceCache.Destroy(GetRawAllocator());
- GetDevice()->OnDestroyPSO(this);
-}
-
-IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase)
-
-
void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources)
{
auto* pRenderDeviceGL = GetDevice();
auto& SRBAllocator = pRenderDeviceGL->GetSRBAllocator();
- auto pResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this, m_ProgramResources.data(), static_cast<Uint32>(m_ProgramResources.size()));
+ auto pResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this, m_ProgramResources, GetNumShaderStages());
if (InitStaticResources)
pResBinding->InitializeStaticResources(this);
pResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(ppShaderResourceBinding));
@@ -168,10 +284,10 @@ bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState* pPSO) const
if (m_ShaderResourceLayoutHash != pPSOGL->m_ShaderResourceLayoutHash)
return false;
- if (m_ProgramResources.size() != pPSOGL->m_ProgramResources.size())
+ if (GetNumShaderStages() != pPSOGL->GetNumShaderStages())
return false;
- for (size_t i = 0; i < m_ProgramResources.size(); ++i)
+ for (size_t i = 0; i < GetNumShaderStages(); ++i)
{
if (!m_ProgramResources[i].IsCompatibleWith(pPSOGL->m_ProgramResources[i]))
return false;
@@ -196,7 +312,7 @@ void PipelineStateGLImpl::CommitProgram(GLContextState& State)
}
else
{
- VERIFY_EXPR(m_GLPrograms.size() == 1);
+ VERIFY_EXPR(m_GLPrograms != nullptr);
State.SetProgram(m_GLPrograms[0]);
}
}
@@ -214,10 +330,9 @@ GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLCon
m_GLProgPipelines.emplace_back(Context, true);
auto& ctx_pipeline = m_GLProgPipelines.back();
GLuint Pipeline = ctx_pipeline.second;
- for (Uint32 i = 0; i < m_NumShaders; ++i)
+ for (Uint32 i = 0; i < GetNumShaderStages(); ++i)
{
- auto* pCurrShader = GetShader<ShaderGLImpl>(i);
- auto GLShaderBit = ShaderTypeToGLShaderBit(pCurrShader->GetDesc().ShaderType);
+ auto GLShaderBit = ShaderTypeToGLShaderBit(GetShaderStageType(i));
// 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
// stages are cleared from the pipeline.
@@ -230,19 +345,19 @@ GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLCon
void PipelineStateGLImpl::InitializeSRBResourceCache(GLProgramResourceCache& ResourceCache) const
{
ResourceCache.Initialize(m_TotalUniformBufferBindings, m_TotalSamplerBindings, m_TotalImageBindings, m_TotalStorageBufferBindings, GetRawAllocator());
- InitStaticSamplersInResourceCache(m_ResourceLayout, ResourceCache);
+ InitImmutableSamplersInResourceCache(m_ResourceLayout, ResourceCache);
}
-void PipelineStateGLImpl::InitStaticSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache) const
+void PipelineStateGLImpl::InitImmutableSamplersInResourceCache(const GLPipelineResourceLayout& ResourceLayout, GLProgramResourceCache& Cache) const
{
for (Uint32 s = 0; s < ResourceLayout.GetNumResources<GLPipelineResourceLayout::SamplerBindInfo>(); ++s)
{
const auto& Sam = ResourceLayout.GetConstResource<GLPipelineResourceLayout::SamplerBindInfo>(s);
- if (Sam.m_StaticSamplerIdx >= 0)
+ if (Sam.m_ImtblSamplerIdx >= 0)
{
- ISampler* pSampler = m_StaticSamplers[Sam.m_StaticSamplerIdx].RawPtr<ISampler>();
+ ISampler* pSampler = m_ImmutableSamplers[Sam.m_ImtblSamplerIdx].RawPtr<ISampler>();
for (Uint32 binding = Sam.m_Attribs.Binding; binding < Sam.m_Attribs.Binding + Sam.m_Attribs.ArraySize; ++binding)
- Cache.SetStaticSampler(binding, pSampler);
+ Cache.SetImmutableSampler(binding, pSampler);
}
}
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
index b7bdf993..ca75a9ca 100644
--- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
@@ -330,6 +330,9 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
SET_FEATURE_STATE(WireframeFill, WireframeFillSupported, "Wireframe fill is");
}
+ if (InitAttribs.ForceNonSeparablePrograms)
+ LOG_INFO_MESSAGE("Forcing non-separable shader programs");
+
if (m_DeviceCaps.DevType == RENDER_DEVICE_TYPE_GL)
{
const bool IsGL46OrAbove = (MajorVersion >= 5) || (MajorVersion == 4 && MinorVersion >= 6);
@@ -337,7 +340,8 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
const bool IsGL42OrAbove = (MajorVersion >= 5) || (MajorVersion == 4 && MinorVersion >= 2);
const bool IsGL41OrAbove = (MajorVersion >= 5) || (MajorVersion == 4 && MinorVersion >= 1);
- Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
+ SET_FEATURE_STATE(SeparablePrograms, !InitAttribs.ForceNonSeparablePrograms, "Separable programs are");
+ SET_FEATURE_STATE(ShaderResourceQueries, Features.SeparablePrograms != DEVICE_FEATURE_STATE_DISABLED, "Shader resource queries are");
Features.IndirectRendering = DEVICE_FEATURE_STATE_ENABLED;
Features.WireframeFill = DEVICE_FEATURE_STATE_ENABLED;
// clang-format off
@@ -396,7 +400,8 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
bool IsGLES32OrAbove = (MajorVersion >= 4) || (MajorVersion == 3 && MinorVersion >= 2);
// clang-format off
- SET_FEATURE_STATE(SeparablePrograms, IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects"), "Separable programs are");
+ SET_FEATURE_STATE(SeparablePrograms, (IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects")) && !InitAttribs.ForceNonSeparablePrograms, "Separable programs are");
+ SET_FEATURE_STATE(ShaderResourceQueries, Features.SeparablePrograms != DEVICE_FEATURE_STATE_DISABLED, "Shader resource queries are");
SET_FEATURE_STATE(IndirectRendering, IsGLES31OrAbove || strstr(Extensions, "draw_indirect"), "Indirect rendering is");
SET_FEATURE_STATE(WireframeFill, false, "Wireframe fill is");
SET_FEATURE_STATE(MultithreadedResourceCreation, false, "Multithreaded resource creation is");
@@ -457,7 +462,7 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
#undef SET_FEATURE_STATE
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 32, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
}
@@ -697,13 +702,8 @@ void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler*
CreateSampler(SamplerDesc, ppSampler, false);
}
-
-void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
-{
- CreatePipelineState(PSOCreateInfo, ppPipelineState, false);
-}
-
-void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal)
+template <typename PSOCreateInfoType>
+void RenderDeviceGLImpl::CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal)
{
CreateDeviceObject(
"Pipeline state", PSOCreateInfo.PSODesc, ppPipelineState,
@@ -716,6 +716,26 @@ void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOC
);
}
+void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal)
+{
+ CreatePipelineState(PSOCreateInfo, ppPipelineState, bIsDeviceInternal);
+}
+
+void RenderDeviceGLImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal)
+{
+ CreatePipelineState(PSOCreateInfo, ppPipelineState, bIsDeviceInternal);
+}
+
+void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
+{
+ return CreateGraphicsPipelineState(PSOCreateInfo, ppPipelineState, false);
+}
+
+void RenderDeviceGLImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
+{
+ return CreateComputePipelineState(PSOCreateInfo, ppPipelineState, false);
+}
+
void RenderDeviceGLImpl::CreateFence(const FenceDesc& Desc, IFence** ppFence)
{
CreateDeviceObject(
diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
index c7a493cd..e27a8a4c 100644
--- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp
@@ -158,7 +158,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters,
if (deviceCaps.Features.SeparablePrograms)
{
- IShader* ThisShader[] = {this};
+ ShaderGLImpl* ThisShader[] = {this};
GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true);
Uint32 UniformBufferBinding = 0;
Uint32 SamplerBinding = 0;
@@ -178,7 +178,7 @@ ShaderGLImpl::~ShaderGLImpl()
IMPLEMENT_QUERY_INTERFACE(ShaderGLImpl, IID_ShaderGL, TShaderBase)
-GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Uint32 NumShaders, bool IsSeparableProgram)
+GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(ShaderGLImpl** ppShaders, Uint32 NumShaders, bool IsSeparableProgram)
{
VERIFY(!IsSeparableProgram || NumShaders == 1, "Number of shaders must be 1 when separable program is created");
@@ -190,7 +190,7 @@ GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Ui
for (Uint32 i = 0; i < NumShaders; ++i)
{
- auto* pCurrShader = ValidatedCast<ShaderGLImpl>(ppShaders[i]);
+ auto* pCurrShader = ppShaders[i];
glAttachShader(GLProg, pCurrShader->m_GLShaderObj);
CHECK_GL_ERROR("glAttachShader() failed");
}
diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp
index bd47e4ac..5861005e 100644
--- a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp
@@ -105,16 +105,15 @@ TexRegionRender::TexRegionRender(class RenderDeviceGLImpl* pDeviceGL)
CBDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
pDeviceGL->CreateBuffer(CBDesc, nullptr, &m_pConstantBuffer, IsInternalDeviceObject);
- PipelineStateCreateInfo PSOCreateInfo;
- PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc;
+ GraphicsPipelineStateCreateInfo PSOCreateInfo;
- auto& GraphicsPipeline = PSODesc.GraphicsPipeline;
+ auto& GraphicsPipeline = PSOCreateInfo.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;
+ PSOCreateInfo.pVS = m_pVertexShader;
GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
static const char* CmpTypePrefix[3] = {"", "i", "u"};
@@ -150,17 +149,19 @@ TexRegionRender::TexRegionRender(class RenderDeviceGLImpl* pDeviceGL)
ShaderAttrs.Source = Source.c_str();
auto& FragmetShader = m_pFragmentShaders[Dim * 3 + Fmt];
pDeviceGL->CreateShader(ShaderAttrs, &FragmetShader, IsInternalDeviceObject);
- GraphicsPipeline.pPS = FragmetShader;
+ PSOCreateInfo.pPS = FragmetShader;
- PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC;
+ auto& ResourceLayout = PSOCreateInfo.PSODesc.ResourceLayout;
+
+ ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC;
ShaderResourceVariableDesc Vars[] =
{
{SHADER_TYPE_PIXEL, "cbConstants", SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE} //
};
- PSODesc.ResourceLayout.NumVariables = _countof(Vars);
- PSODesc.ResourceLayout.Variables = Vars;
+ ResourceLayout.NumVariables = _countof(Vars);
+ ResourceLayout.Variables = Vars;
- pDeviceGL->CreatePipelineState(PSOCreateInfo, &m_pPSO[Dim * 3 + Fmt], IsInternalDeviceObject);
+ pDeviceGL->CreateGraphicsPipelineState(PSOCreateInfo, &m_pPSO[Dim * 3 + Fmt], IsInternalDeviceObject);
}
}
m_pPSO[RESOURCE_DIM_TEX_2D * 3]->CreateShaderResourceBinding(&m_pSRB);
diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
index 564d16cb..243ab1c9 100644
--- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp
@@ -63,8 +63,8 @@ TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters,
// clang-format on
{
VERIFY(m_GLTexFormat != 0, "Unsupported texture format");
- if (TexDesc.Usage == USAGE_STATIC && pInitData == nullptr)
- LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time");
+ if (TexDesc.Usage == USAGE_IMMUTABLE && pInitData == nullptr)
+ LOG_ERROR_AND_THROW("Immutable textures must be initialized with data at creation time");
if (TexDesc.Usage == USAGE_STAGING)
{
diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp
index 8838b968..acb22e2a 100644
--- a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp
@@ -93,7 +93,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState*
// Get layout
auto* pPSOGL = ValidatedCast<PipelineStateGLImpl>(pPSO);
auto* pIndexBufferGL = ValidatedCast<BufferGLImpl>(pIndexBuffer);
- const auto& InputLayout = pPSOGL->GetDesc().GraphicsPipeline.InputLayout;
+ const auto& InputLayout = pPSOGL->GetGraphicsPipelineDesc().InputLayout;
const LayoutElement* LayoutElems = InputLayout.LayoutElements;
Uint32 NumElems = InputLayout.NumElements;
// Construct the key