From 2b396d236ab33dfe9c0defbe401d354ed3fb34f9 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 21:45:01 +0300 Subject: removed strong references to shaders in PSO --- .../src/PipelineStateGLImpl.cpp | 41 ++++++++++++++-------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 399983c9..c61ead8c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -52,7 +52,9 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_StaticResourceLayout{*this} // clang-format on { - if (m_Desc.IsAnyGraphicsPipeline() && m_pPS == nullptr) + RefCntAutoPtr pTempPS; + + if (m_Desc.IsAnyGraphicsPipeline() && m_Desc.GraphicsPipeline.pPS == nullptr) { // Some OpenGL implementations fail if fragment shader is not present, so // create a dummy one. @@ -61,9 +63,16 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun 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; + pDeviceGL->CreateShader(ShaderCI, &pTempPS); + } + + ShaderStages_t ShaderStages; + ExtractShaders(ShaderStages); + + if (pTempPS) + { + m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_PIXEL; + ShaderStages.push_back({SHADER_TYPE_PIXEL, pTempPS}); } auto& DeviceCaps = pDeviceGL->GetDeviceCaps(); @@ -83,13 +92,14 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun // 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) + m_ProgramResources.resize(ShaderStages.size()); + m_GLPrograms.reserve(ShaderStages.size()); + for (size_t i = 0; i < ShaderStages.size(); ++i) { - auto* pShaderGL = GetShader(i); + auto* pShader = ShaderStages[i].second; + auto* pShaderGL = ValidatedCast(pShader); const auto& ShaderDesc = pShaderGL->GetDesc(); - m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&m_ppShaders[i], 1, true)); + m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&pShader, 1, true)); // Load uniforms and assign bindings m_ProgramResources[i].LoadUniforms(ShaderDesc.ShaderType, m_GLPrograms[i], GLState, m_TotalUniformBufferBindings, @@ -102,10 +112,12 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun } else { - m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(m_ppShaders.data(), m_NumShaders, false)); + UNEXPECTED("TODO"); + // AZ TODO + /*m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(m_ppShaders.data(), ShaderStages.size(), false)); m_ProgramResources.resize(1); SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN; - for (Uint32 i = 0; i < m_NumShaders; ++i) + for (size_t i = 0; i < ShaderStages.size(); ++i) { const auto& ShaderDesc = m_ppShaders[i]->GetDesc(); ShaderStages |= ShaderDesc.ShaderType; @@ -116,7 +128,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_TotalImageBindings, m_TotalStorageBufferBindings); - m_ShaderResourceLayoutHash = m_ProgramResources[0].GetHash(); + m_ShaderResourceLayoutHash = m_ProgramResources[0].GetHash();*/ } // Initialize master resource layout that keeps all variable types and does not reference a resource cache @@ -214,10 +226,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 < GetNumShaderTypes(); ++i) { - auto* pCurrShader = GetShader(i); - auto GLShaderBit = ShaderTypeToGLShaderBit(pCurrShader->GetDesc().ShaderType); + auto GLShaderBit = ShaderTypeToGLShaderBit(GetShaderTypes()[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. -- cgit v1.2.3 From 998165f350cfd8ae6bd9cbf6fc812874c1c3c3da Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 22:14:06 +0300 Subject: Revert some changes in ShaderResourceLayoutVk, fixed PSO comparison --- .../GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index c61ead8c..48b24c04 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -112,23 +112,23 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun } else { - UNEXPECTED("TODO"); - // AZ TODO - /*m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(m_ppShaders.data(), ShaderStages.size(), false)); - m_ProgramResources.resize(1); - SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN; + std::vector Shaders; + SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; for (size_t i = 0; i < ShaderStages.size(); ++i) { - const auto& ShaderDesc = m_ppShaders[i]->GetDesc(); - ShaderStages |= ShaderDesc.ShaderType; + Shaders.push_back(ShaderStages[i].second); + ActiveStages |= ShaderStages[i].first; } - m_ProgramResources[0].LoadUniforms(ShaderStages, m_GLPrograms[0], GLState, + + m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast(ShaderStages.size()), false)); + m_ProgramResources.resize(1); + m_ProgramResources[0].LoadUniforms(ActiveStages, m_GLPrograms[0], GLState, m_TotalUniformBufferBindings, m_TotalSamplerBindings, m_TotalImageBindings, m_TotalStorageBufferBindings); - m_ShaderResourceLayoutHash = m_ProgramResources[0].GetHash();*/ + m_ShaderResourceLayoutHash = m_ProgramResources[0].GetHash(); } // Initialize master resource layout that keeps all variable types and does not reference a resource cache -- cgit v1.2.3 From bff90b395a3cbcc96a199cf8db95309b13e8e855 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 23:51:30 +0300 Subject: formating --- Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 48b24c04..e6e6a84f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -113,7 +113,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun else { std::vector Shaders; - SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; + SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; for (size_t i = 0; i < ShaderStages.size(); ++i) { Shaders.push_back(ShaderStages[i].second); -- cgit v1.2.3 From 91aac63f651da1079be93d2fe722cd10e4e15570 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 10 Oct 2020 19:28:54 -0700 Subject: A number of corrections for PSO refactoring --- .../GraphicsEngineOpenGL/include/ShaderGLImpl.hpp | 2 +- .../src/PipelineStateGLImpl.cpp | 46 ++++++++++++---------- Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp | 6 +-- 3 files changed, 30 insertions(+), 24 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') 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/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index e6e6a84f..8590e203 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -52,8 +52,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_StaticResourceLayout{*this} // clang-format on { - RefCntAutoPtr pTempPS; - + RefCntAutoPtr pTempPS; if (m_Desc.IsAnyGraphicsPipeline() && m_Desc.GraphicsPipeline.pPS == nullptr) { // Some OpenGL implementations fail if fragment shader is not present, so @@ -63,17 +62,23 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun ShaderCI.Source = "void main(){}"; ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; ShaderCI.Desc.Name = "Dummy fragment shader"; - pDeviceGL->CreateShader(ShaderCI, &pTempPS); - } + pDeviceGL->CreateShader(ShaderCI, reinterpret_cast(static_cast(&pTempPS))); - ShaderStages_t ShaderStages; - ExtractShaders(ShaderStages); + m_Desc.GraphicsPipeline.pPS = pTempPS; + } - if (pTempPS) + struct GLPipelineShaderStageInfo { - m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_PIXEL; - ShaderStages.push_back({SHADER_TYPE_PIXEL, pTempPS}); - } + const SHADER_TYPE Type; + ShaderGLImpl* const pShader; + GLPipelineShaderStageInfo(SHADER_TYPE _Type, + ShaderGLImpl* _pShader) : + Type{_Type}, + pShader{_pShader} + {} + }; + std::vector ShaderStages; + ExtractShaders(ShaderStages); auto& DeviceCaps = pDeviceGL->GetDeviceCaps(); VERIFY(DeviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized"); @@ -96,10 +101,9 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_GLPrograms.reserve(ShaderStages.size()); for (size_t i = 0; i < ShaderStages.size(); ++i) { - auto* pShader = ShaderStages[i].second; - auto* pShaderGL = ValidatedCast(pShader); + auto* pShaderGL = ShaderStages[i].pShader; const auto& ShaderDesc = pShaderGL->GetDesc(); - m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&pShader, 1, true)); + m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&pShaderGL, 1, true)); // Load uniforms and assign bindings m_ProgramResources[i].LoadUniforms(ShaderDesc.ShaderType, m_GLPrograms[i], GLState, m_TotalUniformBufferBindings, @@ -112,12 +116,14 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun } else { - std::vector Shaders; - SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; - for (size_t i = 0; i < ShaderStages.size(); ++i) + std::vector Shaders; + + SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; + for (const auto& Stage : ShaderStages) { - Shaders.push_back(ShaderStages[i].second); - ActiveStages |= ShaderStages[i].first; + Shaders.push_back(Stage.pShader); + VERIFY((ActiveStages & Stage.Type) == 0, "Shader stage ", GetShaderTypeLiteralName(Stage.Type), " is already active"); + ActiveStages |= Stage.Type; } m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast(ShaderStages.size()), false)); @@ -226,9 +232,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 < GetNumShaderTypes(); ++i) + for (Uint32 i = 0; i < GetNumShaderStages(); ++i) { - auto GLShaderBit = ShaderTypeToGLShaderBit(GetShaderTypes()[i]); + 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. 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(ppShaders[i]); + auto* pCurrShader = ppShaders[i]; glAttachShader(GLProg, pCurrShader->m_GLShaderObj); CHECK_GL_ERROR("glAttachShader() failed"); } -- cgit v1.2.3 From b3fec8bd40e80115086281bce74774617aa95e23 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 14 Oct 2020 01:04:05 -0700 Subject: Added buffer mode validation when binding buffer views --- .../src/GLPipelineResourceLayout.cpp | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp index 0955a54f..914a09bb 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp @@ -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)); -- cgit v1.2.3 From 259a9d5897937dcaaca1b4b294bb8d5250371e76 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 15 Oct 2020 20:55:38 +0300 Subject: Added GraphicsPipelineCreateInfo and ComputePipelineCreateInfo instead of single PipelineCreateInfo. Some optimizations for dynamic memory allocations in PipelineState. --- .../include/PipelineStateGLImpl.hpp | 35 ++++-- .../include/RenderDeviceGLImpl.hpp | 20 ++- .../src/DeviceContextGLImpl.cpp | 6 +- .../src/PipelineStateGLImpl.cpp | 140 +++++++++++++++------ .../src/RenderDeviceGLImpl.cpp | 25 +++- .../GraphicsEngineOpenGL/src/TexRegionRender.cpp | 17 ++- Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp | 2 +- 7 files changed, 177 insertions(+), 68 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp index dea1d6c8..55c53c25 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; - 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 @@ -92,10 +97,25 @@ private: void InitStaticSamplersInResourceCache(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} + {} + }; + void InitResourceLayouts(RenderDeviceGLImpl* pDeviceVk, + const std::vector& ShaderStages, + LinearAllocator& MemPool); + // 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 m_GLPrograms; + using GLProgramObj = GLObjectWrappers::GLProgramObj; + GLProgramObj* m_GLPrograms = nullptr; // [m_NumShaderStages] ThreadingTools::LockFlag m_ProgPipelineLockFlag; @@ -113,14 +133,15 @@ private: GLProgramResourceCache m_StaticResourceCache; // Program resources for all shader stages in the pipeline - std::vector 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> m_StaticSamplers; + using SamplerPtr = RefCntAutoPtr; + SamplerPtr* m_StaticSamplers = nullptr; // [m_Desc.ResourceLayout.NumStaticSamplers] }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp index afb46edb..d23142e0 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 CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, + IPipelineState** ppPipelineState) override final; + + /// Implementation of IRenderDevice::CreateComputePipelineState() in OpenGL backend. + virtual void 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; diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index f4ef1136..d8af2feb 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/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 8590e203..4ac36396 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -36,10 +36,10 @@ namespace Diligent { -PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDeviceGL, - const PipelineStateCreateInfo& CreateInfo, - bool bIsDeviceInternal) : +PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDeviceGL, + const GraphicsPipelineStateCreateInfo& CreateInfo, + bool bIsDeviceInternal) : // clang-format off TPipelineStateBase { @@ -52,8 +52,11 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_StaticResourceLayout{*this} // clang-format on { + std::vector ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); + RefCntAutoPtr pTempPS; - if (m_Desc.IsAnyGraphicsPipeline() && m_Desc.GraphicsPipeline.pPS == nullptr) + if (CreateInfo.pPS == nullptr) { // Some OpenGL implementations fail if fragment shader is not present, so // create a dummy one. @@ -64,22 +67,92 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun ShaderCI.Desc.Name = "Dummy fragment shader"; pDeviceGL->CreateShader(ShaderCI, reinterpret_cast(static_cast(&pTempPS))); - m_Desc.GraphicsPipeline.pPS = pTempPS; + ShaderStages.emplace_back(SHADER_TYPE_PIXEL, pTempPS); + m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL; } - struct GLPipelineShaderStageInfo + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(m_Desc.ResourceLayout.NumStaticSamplers); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + InitResourceLayouts(pDeviceGL, ShaderStages, MemPool); + InitGraphicsPipeline(CreateInfo, MemPool); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_GLPrograms); +} + +PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDeviceGL, + const ComputePipelineStateCreateInfo& CreateInfo, + bool bIsDeviceInternal) : + // clang-format off + TPipelineStateBase { - const SHADER_TYPE Type; - ShaderGLImpl* const pShader; - GLPipelineShaderStageInfo(SHADER_TYPE _Type, - ShaderGLImpl* _pShader) : - Type{_Type}, - pShader{_pShader} - {} - }; + pRefCounters, + pDeviceGL, + CreateInfo.PSODesc, + bIsDeviceInternal + }, + m_ResourceLayout {*this}, + m_StaticResourceLayout{*this} +// clang-format on +{ std::vector ShaderStages; - ExtractShaders(ShaderStages); + ExtractShaders(CreateInfo, ShaderStages); + + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(m_Desc.ResourceLayout.NumStaticSamplers); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + InitResourceLayouts(pDeviceGL, ShaderStages, MemPool); + InitComputePipeline(CreateInfo, MemPool); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_GLPrograms); +} +PipelineStateGLImpl::~PipelineStateGLImpl() +{ + auto& RawAllocator = GetRawAllocator(); + m_StaticResourceCache.Destroy(RawAllocator); + GetDevice()->OnDestroyPSO(this); + + for (Uint32 i = 0; i < GetNumShaderStages(); ++i) + { + m_GLPrograms[i].~GLProgramObj(); + m_ProgramResources[i].~GLProgramResources(); + } + for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumStaticSamplers; ++i) + { + m_StaticSamplers[i].~SamplerPtr(); + } + + void* pRawMem = m_GLPrograms; + RawAllocator.Free(pRawMem); +} + +IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase) + + +void PipelineStateGLImpl::InitResourceLayouts(RenderDeviceGLImpl* pDeviceGL, + const std::vector& ShaderStages, + LinearAllocator& MemPool) +{ auto& DeviceCaps = pDeviceGL->GetDeviceCaps(); VERIFY(DeviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized"); @@ -97,13 +170,13 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun // Program pipelines are not shared between GL contexts, so we cannot create // it now m_ShaderResourceLayoutHash = 0; - m_ProgramResources.resize(ShaderStages.size()); - m_GLPrograms.reserve(ShaderStages.size()); + m_GLPrograms = MemPool.Allocate(ShaderStages.size()); + m_ProgramResources = MemPool.ConstructArray(ShaderStages.size()); for (size_t i = 0; i < ShaderStages.size(); ++i) { auto* pShaderGL = ShaderStages[i].pShader; const auto& ShaderDesc = pShaderGL->GetDesc(); - m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&pShaderGL, 1, true)); + new (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, @@ -126,8 +199,9 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun ActiveStages |= Stage.Type; } - m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast(ShaderStages.size()), false)); - m_ProgramResources.resize(1); + m_GLPrograms = MemPool.Construct(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast(ShaderStages.size()), false)); + m_ProgramResources = MemPool.Construct(); + m_ProgramResources[0].LoadUniforms(ActiveStages, m_GLPrograms[0], GLState, m_TotalUniformBufferBindings, m_TotalSamplerBindings, @@ -138,10 +212,10 @@ 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(m_GLPrograms.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr); + m_ResourceLayout.Initialize(m_ProgramResources, static_cast(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr); } - m_StaticSamplers.resize(m_Desc.ResourceLayout.NumStaticSamplers); + m_StaticSamplers = MemPool.ConstructArray(m_Desc.ResourceLayout.NumStaticSamplers); for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumStaticSamplers; ++s) { pDeviceGL->CreateSampler(m_Desc.ResourceLayout.StaticSamplers[s].Desc, &m_StaticSamplers[s]); @@ -150,26 +224,16 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun { // 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(m_GLPrograms.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache); + m_StaticResourceLayout.Initialize(m_ProgramResources, static_cast(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache); InitStaticSamplersInResourceCache(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(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(ppShaderResourceBinding)); @@ -186,10 +250,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; @@ -214,7 +278,7 @@ void PipelineStateGLImpl::CommitProgram(GLContextState& State) } else { - VERIFY_EXPR(m_GLPrograms.size() == 1); + VERIFY_EXPR(m_GLPrograms != nullptr); State.SetProgram(m_GLPrograms[0]); } } diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 466f1387..59b4bdfd 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -696,13 +696,20 @@ void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler* CreateSampler(SamplerDesc, ppSampler, false); } - -void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) { - CreatePipelineState(PSOCreateInfo, ppPipelineState, false); + CreateDeviceObject( + "Pipeline state", PSOCreateInfo.PSODesc, ppPipelineState, + [&]() // + { + PipelineStateGLImpl* pPipelineStateOGL(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateGLImpl instance", PipelineStateGLImpl)(this, PSOCreateInfo, bIsDeviceInternal)); + pPipelineStateOGL->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); + OnCreateDeviceObject(pPipelineStateOGL); + } // + ); } -void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) +void RenderDeviceGLImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) { CreateDeviceObject( "Pipeline state", PSOCreateInfo.PSODesc, ppPipelineState, @@ -715,6 +722,16 @@ void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOC ); } +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/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp index bd47e4ac..1a9c99c0 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,17 @@ 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; + PSOCreateInfo.PSODesc.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; + PSOCreateInfo.PSODesc.ResourceLayout.NumVariables = _countof(Vars); + PSOCreateInfo.PSODesc.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/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(pPSO); auto* pIndexBufferGL = ValidatedCast(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 -- cgit v1.2.3 From e7b18160a758b30dd6b701b4aa6f43c9c2061ccf Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 17 Oct 2020 09:56:34 -0700 Subject: All backends: added resource dimension validation when setting shader variables --- Graphics/GraphicsEngineOpenGL/include/GLProgramResources.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') 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 -- cgit v1.2.3 From e8f439dc0f87f6820e3db53ecd8ee41cc878d90c Mon Sep 17 00:00:00 2001 From: azhirnov Date: Sat, 17 Oct 2020 20:02:58 +0300 Subject: Fixed compilation, some fixes after review --- Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp index d23142e0..5c8037c3 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp @@ -87,12 +87,12 @@ public: ISampler** ppSampler) override final; /// Implementation of IRenderDevice::CreateGraphicsPipelineState() in OpenGL backend. - virtual void CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, - IPipelineState** ppPipelineState) override final; + virtual void DILIGENT_CALL_TYPE CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, + IPipelineState** ppPipelineState) override final; /// Implementation of IRenderDevice::CreateComputePipelineState() in OpenGL backend. - virtual void CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, - IPipelineState** ppPipelineState) override final; + virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, + IPipelineState** ppPipelineState) override final; void CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, -- cgit v1.2.3 From 645ef7e425d6ff4ee64b782d27767e0a5732be50 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 18 Oct 2020 13:06:48 -0700 Subject: A number of fixes for PSO creation refactoring (API240075) --- .../include/PipelineStateGLImpl.hpp | 7 ++- .../include/RenderDeviceGLImpl.hpp | 3 ++ .../src/PipelineStateGLImpl.cpp | 62 ++++++++++------------ .../src/RenderDeviceGLImpl.cpp | 18 +++---- .../GraphicsEngineOpenGL/src/TexRegionRender.cpp | 8 +-- 5 files changed, 48 insertions(+), 50 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp index 55c53c25..83f8bdad 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp @@ -107,8 +107,11 @@ private: pShader{_pShader} {} }; - void InitResourceLayouts(RenderDeviceGLImpl* pDeviceVk, - const std::vector& ShaderStages, + + template + void Initialize(const PSOCreateInfoType& CreateInfo, const std::vector& ShaderStages); + + void InitResourceLayouts(const std::vector& ShaderStages, LinearAllocator& MemPool); // Linked GL programs for every shader stage. Every pipeline needs to have its own programs diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp index 5c8037c3..6b76feb9 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp @@ -175,6 +175,9 @@ protected: std::unique_ptr m_pTexRegionRender; private: + template + 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/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 4ac36396..7b7d4e21 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -36,6 +36,28 @@ namespace Diligent { + +template +void PipelineStateGLImpl::Initialize(const PSOCreateInfoType& CreateInfo, const std::vector& ShaderStages) +{ + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddSpace(GetNumShaderStages()); + MemPool.AddSpace(GetNumShaderStages()); + MemPool.AddSpace(m_Desc.ResourceLayout.NumStaticSamplers); + + ReserveSpaceForPipelineDesc(CreateInfo, MemPool); + + MemPool.Reserve(); + + InitResourceLayouts(ShaderStages, MemPool); + InitializePipelineDesc(CreateInfo, MemPool); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_GLPrograms); +} + PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, RenderDeviceGLImpl* pDeviceGL, const GraphicsPipelineStateCreateInfo& CreateInfo, @@ -71,22 +93,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL; } - // Memory must be released if an exception is thrown. - LinearAllocator MemPool{GetRawAllocator()}; - - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(m_Desc.ResourceLayout.NumStaticSamplers); - - ValidateAndReserveSpace(CreateInfo, MemPool); - - MemPool.Reserve(); - - InitResourceLayouts(pDeviceGL, ShaderStages, MemPool); - InitGraphicsPipeline(CreateInfo, MemPool); - - void* Ptr = MemPool.Release(); - VERIFY_EXPR(Ptr == m_GLPrograms); + Initialize(CreateInfo, ShaderStages); } PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, @@ -108,22 +115,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* p std::vector ShaderStages; ExtractShaders(CreateInfo, ShaderStages); - // Memory must be released if an exception is thrown. - LinearAllocator MemPool{GetRawAllocator()}; - - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(m_Desc.ResourceLayout.NumStaticSamplers); - - ValidateAndReserveSpace(CreateInfo, MemPool); - - MemPool.Reserve(); - - InitResourceLayouts(pDeviceGL, ShaderStages, MemPool); - InitComputePipeline(CreateInfo, MemPool); - - void* Ptr = MemPool.Release(); - VERIFY_EXPR(Ptr == m_GLPrograms); + Initialize(CreateInfo, ShaderStages); } PipelineStateGLImpl::~PipelineStateGLImpl() @@ -149,11 +141,11 @@ PipelineStateGLImpl::~PipelineStateGLImpl() IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase) -void PipelineStateGLImpl::InitResourceLayouts(RenderDeviceGLImpl* pDeviceGL, - const std::vector& ShaderStages, +void PipelineStateGLImpl::InitResourceLayouts(const std::vector& ShaderStages, LinearAllocator& MemPool) { - auto& DeviceCaps = pDeviceGL->GetDeviceCaps(); + 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(); diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 59b4bdfd..7911fa47 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -696,7 +696,8 @@ void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler* CreateSampler(SamplerDesc, ppSampler, false); } -void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) +template +void RenderDeviceGLImpl::CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) { CreateDeviceObject( "Pipeline state", PSOCreateInfo.PSODesc, ppPipelineState, @@ -709,17 +710,14 @@ void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineState ); } +void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) +{ + CreatePipelineState(PSOCreateInfo, ppPipelineState, bIsDeviceInternal); +} + void RenderDeviceGLImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState, bool bIsDeviceInternal) { - CreateDeviceObject( - "Pipeline state", PSOCreateInfo.PSODesc, ppPipelineState, - [&]() // - { - PipelineStateGLImpl* pPipelineStateOGL(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateGLImpl instance", PipelineStateGLImpl)(this, PSOCreateInfo, bIsDeviceInternal)); - pPipelineStateOGL->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); - OnCreateDeviceObject(pPipelineStateOGL); - } // - ); + CreatePipelineState(PSOCreateInfo, ppPipelineState, bIsDeviceInternal); } void RenderDeviceGLImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp index 1a9c99c0..5861005e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp @@ -151,13 +151,15 @@ TexRegionRender::TexRegionRender(class RenderDeviceGLImpl* pDeviceGL) pDeviceGL->CreateShader(ShaderAttrs, &FragmetShader, IsInternalDeviceObject); PSOCreateInfo.pPS = FragmetShader; - PSOCreateInfo.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} // }; - PSOCreateInfo.PSODesc.ResourceLayout.NumVariables = _countof(Vars); - PSOCreateInfo.PSODesc.ResourceLayout.Variables = Vars; + ResourceLayout.NumVariables = _countof(Vars); + ResourceLayout.Variables = Vars; pDeviceGL->CreateGraphicsPipelineState(PSOCreateInfo, &m_pPSO[Dim * 3 + Fmt], IsInternalDeviceObject); } -- cgit v1.2.3 From ff88c0507d8e8d4571b00adb421557bca1f4ed48 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 18 Oct 2020 17:25:39 -0700 Subject: Updated third-party modules; fixed compiler warnings --- Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp index 914a09bb..04a08af1 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp @@ -311,7 +311,7 @@ void GLPipelineResourceLayout::SamplerBindInfo::BindResource(IDeviceObject* pVie { 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)) + 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."); @@ -361,7 +361,7 @@ void GLPipelineResourceLayout::ImageBindInfo::BindResource(IDeviceObject* pView, { 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)) + 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."); -- cgit v1.2.3 From a520bf4f9748d20e432bcf7994be3148d0b75d54 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 19 Oct 2020 10:21:30 -0700 Subject: Renamed static sampler to immutable sampler (API240076) --- .../include/GLPipelineResourceLayout.hpp | 12 +++++------ .../include/GLProgramResourceCache.hpp | 4 ++-- .../include/PipelineStateGLImpl.hpp | 6 +++--- .../src/GLPipelineResourceLayout.cpp | 18 ++++++++-------- .../src/PipelineStateGLImpl.cpp | 24 +++++++++++----------- 5 files changed, 32 insertions(+), 32 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') 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..eab96f6a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp @@ -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(pStaticSampler); + GetSampler(Binding).pSampler = ValidatedCast(pImtblSampler); } void CopySampler(Uint32 Binding, const CachedResourceView& SrcSam) diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp index 83f8bdad..0c5692d0 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp @@ -95,7 +95,7 @@ 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 { @@ -143,8 +143,8 @@ private: Uint32 m_TotalImageBindings = 0; Uint32 m_TotalStorageBufferBindings = 0; - using SamplerPtr = RefCntAutoPtr; - SamplerPtr* m_StaticSamplers = nullptr; // [m_Desc.ResourceLayout.NumStaticSamplers] + using SamplerPtr = RefCntAutoPtr; + SamplerPtr* m_ImmutableSamplers = nullptr; // [m_Desc.ResourceLayout.NumImmutableSamplers] }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp b/Graphics/GraphicsEngineOpenGL/src/GLPipelineResourceLayout.cpp index 04a08af1..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(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) { @@ -794,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/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 7b7d4e21..8bc3802e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -45,7 +45,7 @@ void PipelineStateGLImpl::Initialize(const PSOCreateInfoType& CreateInfo, const MemPool.AddSpace(GetNumShaderStages()); MemPool.AddSpace(GetNumShaderStages()); - MemPool.AddSpace(m_Desc.ResourceLayout.NumStaticSamplers); + MemPool.AddSpace(m_Desc.ResourceLayout.NumImmutableSamplers); ReserveSpaceForPipelineDesc(CreateInfo, MemPool); @@ -129,9 +129,9 @@ PipelineStateGLImpl::~PipelineStateGLImpl() m_GLPrograms[i].~GLProgramObj(); m_ProgramResources[i].~GLProgramResources(); } - for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumStaticSamplers; ++i) + for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumImmutableSamplers; ++i) { - m_StaticSamplers[i].~SamplerPtr(); + m_ImmutableSamplers[i].~SamplerPtr(); } void* pRawMem = m_GLPrograms; @@ -207,17 +207,17 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr); } - m_StaticSamplers = MemPool.ConstructArray(m_Desc.ResourceLayout.NumStaticSamplers); - for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumStaticSamplers; ++s) + m_ImmutableSamplers = MemPool.ConstructArray(m_Desc.ResourceLayout.NumImmutableSamplers); + 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, static_cast(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache); - InitStaticSamplersInResourceCache(m_StaticResourceLayout, m_StaticResourceCache); + InitImmutableSamplersInResourceCache(m_StaticResourceLayout, m_StaticResourceCache); } } @@ -303,19 +303,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(); ++s) { const auto& Sam = ResourceLayout.GetConstResource(s); - if (Sam.m_StaticSamplerIdx >= 0) + if (Sam.m_ImtblSamplerIdx >= 0) { - ISampler* pSampler = m_StaticSamplers[Sam.m_StaticSamplerIdx].RawPtr(); + ISampler* pSampler = m_ImmutableSamplers[Sam.m_ImtblSamplerIdx].RawPtr(); 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); } } } -- cgit v1.2.3 From e5f36378de4a7258fcc9d6ca7a349df1136b7444 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 19 Oct 2020 12:08:40 -0700 Subject: Renamed USAGE_STATIC to USAGE_IMMUTABLE (API240077) --- Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.hpp | 2 +- Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp | 4 ++-- Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') 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/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/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) { -- cgit v1.2.3 From 13b0b54987db2684e46e337d2e5be5b81366083b Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 13:26:21 -0700 Subject: Improved exception safety of pipeline state object construction --- .../include/GLProgramResourceCache.hpp | 2 +- .../include/PipelineStateGLImpl.hpp | 2 + .../src/GLProgramResourceCache.cpp | 4 +- .../src/PipelineStateGLImpl.cpp | 130 ++++++++++++++------- 4 files changed, 92 insertions(+), 46 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp index eab96f6a..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(); diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp index 0c5692d0..93180774 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp @@ -114,6 +114,8 @@ private: void InitResourceLayouts(const std::vector& 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. 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 8bc3802e..8b429094 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -40,22 +40,37 @@ namespace Diligent template void PipelineStateGLImpl::Initialize(const PSOCreateInfoType& CreateInfo, const std::vector& ShaderStages) { - // Memory must be released if an exception is thrown. LinearAllocator MemPool{GetRawAllocator()}; + VERIFY_EXPR(m_NumShaderStages > 0 && m_NumShaderStages == ShaderStages.size()); + if (!GetDevice()->GetDeviceCaps().Features.SeparablePrograms) + m_NumShaderStages = 1; - MemPool.AddSpace(GetNumShaderStages()); - MemPool.AddSpace(GetNumShaderStages()); + const auto NumPrograms = GetNumShaderStages(); + + MemPool.AddSpace(NumPrograms); + MemPool.AddSpace(NumPrograms); MemPool.AddSpace(m_Desc.ResourceLayout.NumImmutableSamplers); ReserveSpaceForPipelineDesc(CreateInfo, MemPool); MemPool.Reserve(); - InitResourceLayouts(ShaderStages, MemPool); - InitializePipelineDesc(CreateInfo, MemPool); + m_GLPrograms = MemPool.ConstructArray(NumPrograms, false); - void* Ptr = MemPool.Release(); + // 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(NumPrograms); + + m_ImmutableSamplers = MemPool.ConstructArray(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, @@ -74,26 +89,33 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* m_StaticResourceLayout{*this} // clang-format on { - std::vector ShaderStages; - ExtractShaders(CreateInfo, ShaderStages); + try + { + std::vector ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); + + RefCntAutoPtr 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(static_cast(&pTempPS))); + + ShaderStages.emplace_back(SHADER_TYPE_PIXEL, pTempPS); + m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL; + } - RefCntAutoPtr pTempPS; - if (CreateInfo.pPS == nullptr) + 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, reinterpret_cast(static_cast(&pTempPS))); - - ShaderStages.emplace_back(SHADER_TYPE_PIXEL, pTempPS); - m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL; + Destruct(); } - - Initialize(CreateInfo, ShaderStages); } PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters, @@ -112,30 +134,54 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* p m_StaticResourceLayout{*this} // clang-format on { - std::vector ShaderStages; - ExtractShaders(CreateInfo, ShaderStages); + try + { + std::vector ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); - Initialize(CreateInfo, ShaderStages); + Initialize(CreateInfo, ShaderStages); + } + catch (...) + { + Destruct(); + } } PipelineStateGLImpl::~PipelineStateGLImpl() +{ + Destruct(); +} + +void PipelineStateGLImpl::Destruct() { auto& RawAllocator = GetRawAllocator(); m_StaticResourceCache.Destroy(RawAllocator); GetDevice()->OnDestroyPSO(this); - for (Uint32 i = 0; i < GetNumShaderStages(); ++i) + if (m_ImmutableSamplers != nullptr) { - m_GLPrograms[i].~GLProgramObj(); - m_ProgramResources[i].~GLProgramResources(); + for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumImmutableSamplers; ++i) + { + m_ImmutableSamplers[i].~SamplerPtr(); + } } - for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumImmutableSamplers; ++i) + + for (Uint32 i = 0; i < GetNumShaderStages(); ++i) { - m_ImmutableSamplers[i].~SamplerPtr(); + if (m_GLPrograms != nullptr) + { + m_GLPrograms[i].~GLProgramObj(); + } + if (m_ProgramResources != nullptr) + { + m_ProgramResources[i].~GLProgramResources(); + } } - void* pRawMem = m_GLPrograms; - RawAllocator.Free(pRawMem); + if (void* pRawMem = m_GLPrograms) + { + RawAllocator.Free(pRawMem); + } } IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase) @@ -145,8 +191,8 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vectorGetDeviceCaps(); - VERIFY(DeviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized"); + 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); @@ -157,18 +203,16 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector(ShaderStages.size()); - m_ProgramResources = MemPool.ConstructArray(ShaderStages.size()); for (size_t i = 0; i < ShaderStages.size(); ++i) { auto* pShaderGL = ShaderStages[i].pShader; const auto& ShaderDesc = pShaderGL->GetDesc(); - new (m_GLPrograms + i) GLProgramObj{ShaderGLImpl::LinkProgram(&pShaderGL, 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, @@ -191,8 +235,7 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast(ShaderStages.size()), false)); - m_ProgramResources = MemPool.Construct(); + m_GLPrograms[0] = ShaderGLImpl::LinkProgram(Shaders.data(), static_cast(Shaders.size()), false); m_ProgramResources[0].LoadUniforms(ActiveStages, m_GLPrograms[0], GLState, m_TotalUniformBufferBindings, @@ -204,10 +247,9 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector(ShaderStages.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_ImmutableSamplers = MemPool.ConstructArray(m_Desc.ResourceLayout.NumImmutableSamplers); for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumImmutableSamplers; ++s) { pDeviceGL->CreateSampler(m_Desc.ResourceLayout.ImmutableSamplers[s].Desc, &m_ImmutableSamplers[s]); @@ -216,7 +258,7 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache); + m_StaticResourceLayout.Initialize(m_ProgramResources, GetNumShaderStages(), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache); InitImmutableSamplersInResourceCache(m_StaticResourceLayout, m_StaticResourceCache); } } -- cgit v1.2.3 From b9d1a84943f61d1b48ffb1847cd0b3f7b8c60fb2 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 18:05:02 -0700 Subject: Added ShaderResourceQueries device feature and EngineGLCreateInfo::ForceNonSeparablePrograms parameter (API 240078) --- Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 7911fa47..919d5aef 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -336,7 +336,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 @@ -395,7 +396,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"); @@ -456,7 +458,7 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters, #undef SET_FEATURE_STATE #if defined(_MSC_VER) && defined(_WIN64) - static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); + static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); #endif } -- cgit v1.2.3 From 1a36d301e62781a806a0bced72adf711382ea776 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 18:18:43 -0700 Subject: GL backend: added info message about forcing non-separable programs --- Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 919d5aef..5aae4d90 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -329,6 +329,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); -- cgit v1.2.3