diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-10-21 22:15:55 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-10-25 10:50:53 +0000 |
| commit | 42217cc1ec7f81c028dcc5c1f845a2fc3b3da497 (patch) | |
| tree | 2efcb7c0fdeae582ecb5c8d13c7bedd593ab9a3c /Graphics/GraphicsEngineOpenGL | |
| parent | Fixed Mac/iOS build (diff) | |
| parent | Updated Metal testing environment (diff) | |
| download | DiligentCore-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')
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 |
