Rework shader bindings (WIP)

This commit is contained in:
Jérôme Leclercq
2021-10-16 12:10:14 +02:00
parent cb716e5da5
commit 58485cfa79
23 changed files with 171 additions and 253 deletions

View File

@@ -50,6 +50,17 @@ namespace Nz
Orthographic,
Perspective
};
enum class PredefinedShaderBinding
{
InstanceDataUbo,
OverlayTexture,
ViewerDataUbo,
Max = ViewerDataUbo
};
constexpr std::size_t PredefinedShaderBindingCount = static_cast<std::size_t>(PredefinedShaderBinding::Max) + 1;
}
#endif // NAZARA_ENUMS_GRAPHICS_HPP

View File

@@ -42,7 +42,6 @@ namespace Nz
inline MaterialPassRegistry& GetMaterialPassRegistry();
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
inline PixelFormat GetPreferredDepthStencilFormat() const;
inline const std::shared_ptr<RenderPipelineLayout>& GetReferencePipelineLayout() const;
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
inline const RenderPassCache& GetRenderPassCache() const;
inline TextureSamplerCache& GetSamplerCache();
@@ -58,14 +57,9 @@ namespace Nz
std::shared_ptr<Texture> whiteTexture2d;
};
static constexpr UInt32 DrawDataBindingSet = 2;
static constexpr UInt32 MaterialBindingSet = 3;
static constexpr UInt32 ViewerBindingSet = 0;
static constexpr UInt32 WorldBindingSet = 1;
static void FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = DrawDataBindingSet);
static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = ViewerBindingSet);
static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = WorldBindingSet);
static void FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
private:
void BuildBlitPipeline();
@@ -80,7 +74,6 @@ namespace Nz
std::shared_ptr<RenderDevice> m_renderDevice;
std::shared_ptr<RenderPipeline> m_blitPipeline;
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
std::shared_ptr<RenderPipelineLayout> m_referencePipelineLayout;
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
DefaultTextures m_defaultTextures;
MaterialPassRegistry m_materialPassRegistry;

View File

@@ -47,11 +47,6 @@ namespace Nz
return m_preferredDepthStencilFormat;
}
inline const std::shared_ptr<RenderPipelineLayout>& Graphics::GetReferencePipelineLayout() const
{
return m_referencePipelineLayout;
}
inline const std::shared_ptr<RenderDevice>& Graphics::GetRenderDevice() const
{
return m_renderDevice;

View File

@@ -70,7 +70,6 @@ namespace Nz
inline PrimitiveMode GetPrimitiveMode() const;
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
inline ShaderBinding& GetShaderBinding();
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
inline const std::shared_ptr<AbstractBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
@@ -110,11 +109,9 @@ namespace Nz
private:
inline void InvalidatePipeline();
inline void InvalidateShaderBinding();
inline void InvalidateTextureSampler(std::size_t textureIndex);
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
void UpdatePipeline() const;
void UpdateShaderBinding();
struct MaterialTexture
{
@@ -137,10 +134,8 @@ namespace Nz
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
mutable MaterialPipelineInfo m_pipelineInfo;
MaterialPassFlags m_flags;
ShaderBindingPtr m_shaderBinding;
bool m_forceCommandBufferRegeneration;
mutable bool m_pipelineUpdated;
bool m_shaderBindingUpdated;
};
}

View File

@@ -373,12 +373,6 @@ namespace Nz
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
}
inline ShaderBinding& MaterialPass::GetShaderBinding()
{
assert(m_shaderBinding);
return *m_shaderBinding;
}
inline const std::shared_ptr<Texture>& MaterialPass::GetTexture(std::size_t textureIndex) const
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
@@ -614,7 +608,7 @@ namespace Nz
if (m_textures[textureIndex].texture != texture)
{
m_textures[textureIndex].texture = std::move(texture);
InvalidateShaderBinding();
OnMaterialInvalidated(this);
}
}
@@ -635,7 +629,8 @@ namespace Nz
{
m_uniformBuffers[bufferIndex].buffer = std::move(uniformBuffer);
m_uniformBuffers[bufferIndex].dataInvalidated = true;
InvalidateShaderBinding();
OnMaterialInvalidated(this);
}
}
@@ -647,20 +642,12 @@ namespace Nz
OnMaterialInvalidated(this);
}
inline void MaterialPass::InvalidateShaderBinding()
{
m_forceCommandBufferRegeneration = true;
m_shaderBindingUpdated = false;
OnMaterialInvalidated(this);
}
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
{
assert(textureIndex < m_textures.size());
m_textures[textureIndex].sampler.reset();
InvalidateShaderBinding();
OnMaterialInvalidated(this);
}
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
@@ -674,4 +661,3 @@ namespace Nz
}
#include <Nazara/Graphics/DebugOff.hpp>
#include "MaterialPass.hpp"

View File

@@ -28,6 +28,7 @@ namespace Nz
struct SharedUniformBlock;
struct Texture;
struct UniformBlock;
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
inline MaterialSettings();
inline MaterialSettings(Builder builder);
@@ -64,6 +65,7 @@ namespace Nz
std::vector<Texture> textures;
std::vector<UniformBlock> uniformBlocks;
std::vector<SharedUniformBlock> sharedUniformBlocks;
PredefinedBinding predefinedBindings;
};
struct Option
@@ -113,3 +115,5 @@ namespace Nz
#include <Nazara/Graphics/MaterialSettings.inl>
#endif // NAZARA_MATERIALPIPELINESETTINGS_HPP

View File

@@ -18,14 +18,11 @@ namespace Nz
m_data(std::move(data))
{
RenderPipelineLayoutInfo info;
Graphics::FillDrawDataPipelineLayout(info);
Graphics::FillViewerPipelineLayout(info);
Graphics::FillWorldPipelineLayout(info);
for (const Texture& textureInfo : m_data.textures)
{
info.bindings.push_back({
Graphics::MaterialBindingSet,
0,
textureInfo.bindingIndex,
ShaderBindingType::Texture,
textureInfo.shaderStages
@@ -35,7 +32,7 @@ namespace Nz
for (const UniformBlock& ubo : m_data.uniformBlocks)
{
info.bindings.push_back({
Graphics::MaterialBindingSet,
0,
ubo.bindingIndex,
ShaderBindingType::UniformBuffer,
ubo.shaderStages
@@ -45,7 +42,7 @@ namespace Nz
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
{
info.bindings.push_back({
Graphics::MaterialBindingSet,
0,
ubo.bindingIndex,
ShaderBindingType::UniformBuffer,
ubo.shaderStages

View File

@@ -31,7 +31,7 @@ namespace Nz
std::array<std::size_t, 3> lightArray;
std::size_t lightArraySize;
static PredefinedLightData GetOffset();
static PredefinedLightData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock();
};
@@ -42,6 +42,7 @@ namespace Nz
std::size_t worldMatrixOffset;
static PredefinedInstanceData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
};
struct NAZARA_GRAPHICS_API PredefinedViewerData
@@ -58,6 +59,7 @@ namespace Nz
std::size_t viewProjMatrixOffset;
static PredefinedViewerData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
};
}

View File

@@ -8,6 +8,7 @@
#define NAZARA_RENDERSUBMESH_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Graphics/WorldInstance.hpp>
@@ -17,36 +18,37 @@
namespace Nz
{
class AbstractBuffer;
class RenderPipeline;
class ShaderBinding;
class MaterialPass;
class VertexDeclaration;
class ViewerInstance;
class RenderSpriteChain : public RenderElement
{
public:
inline RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const WorldInstance& worldInstance, const MaterialPassFlags& matFlags);
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const ViewerInstance& viewerInstance, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData);
~RenderSpriteChain() = default;
inline UInt64 ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const override;
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
inline const ShaderBinding& GetInstanceBinding() const;
inline const ShaderBinding& GetMaterialBinding() const;
inline const RenderPipeline* GetRenderPipeline() const;
inline const MaterialPass& GetMaterialPass() const;
inline const RenderPipeline& GetRenderPipeline() const;
inline std::size_t GetSpriteCount() const;
inline const void* GetSpriteData() const;
inline const Texture* GetTextureOverlay() const;
inline const VertexDeclaration* GetVertexDeclaration() const;
inline const ViewerInstance& GetViewerInstance() const;
inline const WorldInstance& GetWorldInstance() const;
inline void Register(RenderQueueRegistry& registry) const override;
private:
std::shared_ptr<MaterialPass> m_materialPass;
std::shared_ptr<RenderPipeline> m_renderPipeline;
std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
std::shared_ptr<Texture> m_textureOverlay;
std::size_t m_spriteCount;
const void* m_spriteData;
MaterialPassFlags m_matFlags;
const ShaderBinding& m_materialBinding;
const ViewerInstance& m_viewerInstance;
const WorldInstance& m_worldInstance;
int m_renderLayer;
};

View File

@@ -8,28 +8,28 @@
namespace Nz
{
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const WorldInstance& worldInstance, const MaterialPassFlags& matFlags) :
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const ViewerInstance& viewerInstance, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData) :
RenderElement(BasicRenderElement::SpriteChain),
m_materialPass(std::move(materialPass)),
m_renderPipeline(std::move(renderPipeline)),
m_vertexDeclaration(std::move(vertexDeclaration)),
m_textureOverlay(std::move(textureOverlay)),
m_spriteCount(spriteCount),
m_spriteData(spriteData),
m_matFlags(matFlags),
m_materialBinding(materialBinding),
m_viewerInstance(viewerInstance),
m_worldInstance(worldInstance),
m_renderLayer(renderLayer)
{
}
inline UInt64 RenderSpriteChain::ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const
inline UInt64 RenderSpriteChain::ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const
{
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
UInt64 elementType = GetElementType();
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
if (m_matFlags.Test(MaterialPassFlag::Transparent))
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::Transparent))
{
UInt64 matFlags = 1;
@@ -66,19 +66,14 @@ namespace Nz
}
}
inline const ShaderBinding& RenderSpriteChain::GetInstanceBinding() const
inline const MaterialPass& RenderSpriteChain::GetMaterialPass() const
{
return m_worldInstance.GetShaderBinding();
return *m_materialPass;
}
inline const ShaderBinding& RenderSpriteChain::GetMaterialBinding() const
inline const RenderPipeline& RenderSpriteChain::GetRenderPipeline() const
{
return m_materialBinding;
}
inline const RenderPipeline* RenderSpriteChain::GetRenderPipeline() const
{
return m_renderPipeline.get();
return *m_renderPipeline;
}
inline std::size_t RenderSpriteChain::GetSpriteCount() const
@@ -101,6 +96,16 @@ namespace Nz
return m_vertexDeclaration.get();
}
inline const ViewerInstance& RenderSpriteChain::GetViewerInstance() const
{
return m_viewerInstance;
}
inline const WorldInstance& RenderSpriteChain::GetWorldInstance() const
{
return m_worldInstance;
}
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
{
registry.RegisterLayer(m_renderLayer);

View File

@@ -61,9 +61,7 @@ namespace Nz
{
const AbstractBuffer* vertexBuffer;
const RenderPipeline* renderPipeline;
const ShaderBinding* drawDataBinding;
const ShaderBinding* instanceBinding;
const ShaderBinding* materialBinding;
const ShaderBinding* shaderBinding;
std::size_t firstIndex;
std::size_t quadCount;
};

View File

@@ -10,7 +10,6 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <memory>
namespace Nz
@@ -36,7 +35,6 @@ namespace Nz
inline const Matrix4f& GetViewProjMatrix() const;
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
inline ShaderBinding& GetShaderBinding();
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
@@ -59,7 +57,6 @@ namespace Nz
Matrix4f m_projectionMatrix;
Matrix4f m_viewProjMatrix;
Matrix4f m_viewMatrix;
ShaderBindingPtr m_shaderBinding;
Vector2f m_targetSize;
bool m_dataInvalided;
};

View File

@@ -48,11 +48,6 @@ namespace Nz
return m_viewerDataBuffer;
}
inline ShaderBinding& ViewerInstance::GetShaderBinding()
{
return *m_shaderBinding;
}
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
{
m_projectionMatrix = projectionMatrix;

View File

@@ -10,7 +10,6 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <memory>
namespace Nz
@@ -34,8 +33,6 @@ namespace Nz
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
inline const Matrix4f& GetInvWorldMatrix() const;
inline ShaderBinding& GetShaderBinding();
inline const ShaderBinding& GetShaderBinding() const;
inline const Matrix4f& GetWorldMatrix() const;
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
@@ -49,7 +46,6 @@ namespace Nz
std::shared_ptr<AbstractBuffer> m_instanceDataBuffer;
Matrix4f m_invWorldMatrix;
Matrix4f m_worldMatrix;
ShaderBindingPtr m_shaderBinding;
bool m_dataInvalided;
};
}

View File

@@ -23,16 +23,6 @@ namespace Nz
return m_invWorldMatrix;
}
inline ShaderBinding& WorldInstance::GetShaderBinding()
{
return *m_shaderBinding;
}
inline const ShaderBinding& WorldInstance::GetShaderBinding() const
{
return *m_shaderBinding;
}
inline const Matrix4f& WorldInstance::GetWorldMatrix() const
{
return m_worldMatrix;