Add initial support for shader binding sets (WIP)

This commit is contained in:
Jérôme Leclercq
2021-06-14 22:35:05 +02:00
parent 815a7b0c62
commit f22b501e25
53 changed files with 885 additions and 511 deletions

View File

@@ -39,7 +39,7 @@ namespace Nz
inline void BindIndexBuffer(GLuint indexBuffer, UInt64 offset = 0);
inline void BindPipeline(const OpenGLRenderPipeline* pipeline);
inline void BindShaderBinding(const OpenGLShaderBinding* binding);
inline void BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
inline void BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset = 0);
inline void CopyBuffer(GLuint source, GLuint target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0);
@@ -102,10 +102,10 @@ namespace Nz
GLuint indexBuffer = 0;
const OpenGLRenderPipeline* pipeline = nullptr;
const OpenGLShaderBinding* shaderBindings = nullptr;
UInt64 indexBufferOffset;
std::optional<Recti> scissorRegion;
std::optional<Recti> viewportRegion;
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
std::vector<VertexBuffer> vertexBuffers;
bool shouldFlipY = false;
};

View File

@@ -44,9 +44,12 @@ namespace Nz
m_currentStates.pipeline = pipeline;
}
inline void OpenGLCommandBuffer::BindShaderBinding(const OpenGLShaderBinding* binding)
inline void OpenGLCommandBuffer::BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
{
m_currentStates.shaderBindings = binding;
if (set >= m_currentStates.shaderBindings.size())
m_currentStates.shaderBindings.resize(set + 1);
m_currentStates.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
}
inline void OpenGLCommandBuffer::BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset)

View File

@@ -28,7 +28,8 @@ namespace Nz
void BindIndexBuffer(AbstractBuffer* indexBuffer, UInt64 offset = 0) override;
void BindPipeline(const RenderPipeline& pipeline) override;
void BindShaderBinding(const ShaderBinding& binding) override;
void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override;
void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
void BindVertexBuffer(UInt32 binding, Nz::AbstractBuffer* vertexBuffer, UInt64 offset = 0) override;
void CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0) override;

View File

@@ -40,7 +40,7 @@ namespace Nz
std::shared_ptr<RenderPass> InstantiateRenderPass(std::vector<RenderPass::Attachment> attachments, std::vector<RenderPass::SubpassDescription> subpassDescriptions, std::vector<RenderPass::SubpassDependency> subpassDependencies) override;
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderAst::StatementPtr& shaderAst, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;

View File

@@ -14,6 +14,7 @@
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
#include <Nazara/Shader/GlslWriter.hpp>
#include <memory>
#include <type_traits>
#include <vector>
@@ -30,13 +31,11 @@ namespace Nz
OpenGLRenderPipelineLayout(OpenGLRenderPipelineLayout&&) = delete;
~OpenGLRenderPipelineLayout();
ShaderBindingPtr AllocateShaderBinding() override;
ShaderBindingPtr AllocateShaderBinding(UInt32 setIndex) override;
inline const GlslWriter::BindingMapping& GetBindingMapping() const;
inline const RenderPipelineLayoutInfo& GetLayoutInfo() const;
inline std::size_t GetTextureDescriptorCount() const;
inline std::size_t GetUniformBufferDescriptorCount() const;
OpenGLRenderPipelineLayout& operator=(const OpenGLRenderPipelineLayout&) = delete;
OpenGLRenderPipelineLayout& operator=(OpenGLRenderPipelineLayout&&) = delete;
@@ -46,17 +45,15 @@ namespace Nz
struct UniformBufferDescriptor;
DescriptorPool& AllocatePool();
ShaderBindingPtr AllocateFromPool(std::size_t poolIndex);
TextureDescriptor& GetTextureDescriptor(std::size_t poolIndex, std::size_t bindingIndex, std::size_t textureIndex);
UniformBufferDescriptor& GetUniformBufferDescriptor(std::size_t poolIndex, std::size_t bindingIndex, std::size_t uniformBufferIndex);
ShaderBindingPtr AllocateFromPool(std::size_t poolIndex, UInt32 setIndex);
template<typename F> void ForEachDescriptor(std::size_t poolIndex, std::size_t bindingIndex, F&& functor);
TextureDescriptor& GetTextureDescriptor(std::size_t poolIndex, std::size_t bindingIndex, std::size_t descriptorIndex);
UniformBufferDescriptor& GetUniformBufferDescriptor(std::size_t poolIndex, std::size_t bindingIndex, std::size_t descriptorIndex);
void Release(ShaderBinding& binding);
inline void TryToShrink();
static constexpr UInt32 InvalidIndex = 0xFFFFFFFF;
struct TextureDescriptor
{
UInt32 bindingIndex = InvalidIndex;
GLuint texture;
GLuint sampler;
GL::TextureTarget textureTarget;
@@ -64,25 +61,25 @@ namespace Nz
struct UniformBufferDescriptor
{
UInt32 bindingIndex = InvalidIndex;
GLuint buffer;
GLintptr offset;
GLsizeiptr size;
};
using Descriptor = std::variant<std::monostate, TextureDescriptor, UniformBufferDescriptor>;
struct DescriptorPool
{
using BindingStorage = std::aligned_storage_t<sizeof(OpenGLShaderBinding), alignof(OpenGLShaderBinding)>;
Bitset<UInt64> freeBindings;
std::vector<TextureDescriptor> textureDescriptor;
std::vector<UniformBufferDescriptor> uniformBufferDescriptor;
std::vector<Descriptor> descriptors;
std::unique_ptr<BindingStorage[]> storage;
};
std::size_t m_textureDescriptorCount;
std::size_t m_uniformBufferDescriptorCount;
std::size_t m_maxDescriptorCount;
std::vector<DescriptorPool> m_descriptorPools;
GlslWriter::BindingMapping m_bindingMapping;
RenderPipelineLayoutInfo m_layoutInfo;
};
}

View File

@@ -7,19 +7,32 @@
namespace Nz
{
inline const GlslWriter::BindingMapping& OpenGLRenderPipelineLayout::GetBindingMapping() const
{
return m_bindingMapping;
}
inline const RenderPipelineLayoutInfo& OpenGLRenderPipelineLayout::GetLayoutInfo() const
{
return m_layoutInfo;
}
inline std::size_t OpenGLRenderPipelineLayout::GetTextureDescriptorCount() const
template<typename F>
void OpenGLRenderPipelineLayout::ForEachDescriptor(std::size_t poolIndex, std::size_t bindingIndex, F&& functor)
{
return m_textureDescriptorCount;
}
assert(poolIndex < m_descriptorPools.size());
auto& pool = m_descriptorPools[poolIndex];
assert(!pool.freeBindings.Test(bindingIndex));
inline std::size_t OpenGLRenderPipelineLayout::GetUniformBufferDescriptorCount() const
{
return m_uniformBufferDescriptorCount;
for (std::size_t descriptorIndex = 0; descriptorIndex < m_maxDescriptorCount; ++descriptorIndex)
{
std::visit([&](auto&& arg)
{
if constexpr (!std::is_same_v<std::decay_t<decltype(arg)>, std::monostate>)
functor(UInt32(descriptorIndex), arg);
},
pool.descriptors[bindingIndex * m_maxDescriptorCount + descriptorIndex]);
}
}
inline void OpenGLRenderPipelineLayout::TryToShrink()

View File

@@ -24,7 +24,7 @@ namespace Nz
OpenGLShaderBinding(OpenGLShaderBinding&&) = delete;
~OpenGLShaderBinding() = default;
void Apply(const GL::Context& context) const;
void Apply(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 setIndex, const GL::Context& context) const;
inline std::size_t GetBindingIndex() const;
inline std::size_t GetPoolIndex() const;

View File

@@ -11,8 +11,10 @@
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderModule.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Program.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Shader.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/GlslWriter.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <vector>
namespace Nz
@@ -20,30 +22,40 @@ namespace Nz
class NAZARA_OPENGLRENDERER_API OpenGLShaderModule : public ShaderModule
{
public:
struct Shader;
OpenGLShaderModule(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::StatementPtr& shaderAst, const ShaderWriter::States& states = {});
OpenGLShaderModule(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states = {});
OpenGLShaderModule(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states = {});
OpenGLShaderModule(const OpenGLShaderModule&) = delete;
OpenGLShaderModule(OpenGLShaderModule&&) noexcept = default;
~OpenGLShaderModule() = default;
inline const std::vector<Shader>& GetShaders() const;
ShaderStageTypeFlags Attach(GL::Program& program, const GlslWriter::BindingMapping& bindingMapping) const;
OpenGLShaderModule& operator=(const OpenGLShaderModule&) = delete;
OpenGLShaderModule& operator=(OpenGLShaderModule&&) noexcept = default;
struct Shader
{
ShaderStageType stage;
GL::Shader shader;
};
private:
void Create(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::StatementPtr& shaderAst, const ShaderWriter::States& states);
void Create(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states);
static void CheckCompilationStatus(GL::Shader& shader);
struct GlslShader
{
std::string sourceCode;
};
struct ShaderStatement
{
std::shared_ptr<ShaderAst::Statement> ast;
};
struct Shader
{
ShaderStageType stage;
std::variant<GlslShader, ShaderStatement> shader;
};
OpenGLDevice& m_device;
ShaderWriter::States m_states;
std::vector<Shader> m_shaders;
};
}

View File

@@ -7,10 +7,6 @@
namespace Nz
{
inline auto OpenGLShaderModule::GetShaders() const -> const std::vector<Shader>&
{
return m_shaders;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>