Rework shader bindings (WIP)
This commit is contained in:
parent
cb716e5da5
commit
58485cfa79
|
|
@ -218,11 +218,11 @@ int main()
|
||||||
registry.get<Nz::NodeComponent>(viewer).SetParent(registry, headingEntity);
|
registry.get<Nz::NodeComponent>(viewer).SetParent(registry, headingEntity);
|
||||||
registry.get<Nz::NodeComponent>(viewer).SetPosition(Nz::Vector3f::Backward() * 2.5f + Nz::Vector3f::Up() * 1.f);
|
registry.get<Nz::NodeComponent>(viewer).SetPosition(Nz::Vector3f::Backward() * 2.5f + Nz::Vector3f::Up() * 1.f);
|
||||||
|
|
||||||
for (std::size_t x = 0; x < 1; ++x)
|
for (std::size_t x = 0; x < 2; ++x)
|
||||||
{
|
{
|
||||||
for (std::size_t y = 0; y < 1; ++y)
|
for (std::size_t y = 0; y < 2; ++y)
|
||||||
{
|
{
|
||||||
for (std::size_t z = 0; z < 1; ++z)
|
for (std::size_t z = 0; z < 2; ++z)
|
||||||
{
|
{
|
||||||
entt::entity entity = registry.create();
|
entt::entity entity = registry.create();
|
||||||
auto& entityGfx = registry.emplace<Nz::GraphicsComponent>(entity);
|
auto& entityGfx = registry.emplace<Nz::GraphicsComponent>(entity);
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,17 @@ namespace Nz
|
||||||
Orthographic,
|
Orthographic,
|
||||||
Perspective
|
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
|
#endif // NAZARA_ENUMS_GRAPHICS_HPP
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ namespace Nz
|
||||||
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
||||||
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
||||||
inline PixelFormat GetPreferredDepthStencilFormat() const;
|
inline PixelFormat GetPreferredDepthStencilFormat() const;
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& GetReferencePipelineLayout() const;
|
|
||||||
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
||||||
inline const RenderPassCache& GetRenderPassCache() const;
|
inline const RenderPassCache& GetRenderPassCache() const;
|
||||||
inline TextureSamplerCache& GetSamplerCache();
|
inline TextureSamplerCache& GetSamplerCache();
|
||||||
|
|
@ -58,14 +57,9 @@ namespace Nz
|
||||||
std::shared_ptr<Texture> whiteTexture2d;
|
std::shared_ptr<Texture> whiteTexture2d;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr UInt32 DrawDataBindingSet = 2;
|
static void FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
|
||||||
static constexpr UInt32 MaterialBindingSet = 3;
|
static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
|
||||||
static constexpr UInt32 ViewerBindingSet = 0;
|
static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
|
||||||
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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void BuildBlitPipeline();
|
void BuildBlitPipeline();
|
||||||
|
|
@ -80,7 +74,6 @@ namespace Nz
|
||||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||||
std::shared_ptr<RenderPipeline> m_blitPipeline;
|
std::shared_ptr<RenderPipeline> m_blitPipeline;
|
||||||
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
||||||
std::shared_ptr<RenderPipelineLayout> m_referencePipelineLayout;
|
|
||||||
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
|
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
|
||||||
DefaultTextures m_defaultTextures;
|
DefaultTextures m_defaultTextures;
|
||||||
MaterialPassRegistry m_materialPassRegistry;
|
MaterialPassRegistry m_materialPassRegistry;
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,6 @@ namespace Nz
|
||||||
return m_preferredDepthStencilFormat;
|
return m_preferredDepthStencilFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& Graphics::GetReferencePipelineLayout() const
|
|
||||||
{
|
|
||||||
return m_referencePipelineLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const std::shared_ptr<RenderDevice>& Graphics::GetRenderDevice() const
|
inline const std::shared_ptr<RenderDevice>& Graphics::GetRenderDevice() const
|
||||||
{
|
{
|
||||||
return m_renderDevice;
|
return m_renderDevice;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ namespace Nz
|
||||||
inline PrimitiveMode GetPrimitiveMode() const;
|
inline PrimitiveMode GetPrimitiveMode() const;
|
||||||
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
||||||
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) 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 std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
||||||
inline const TextureSamplerInfo& GetTextureSampler(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;
|
inline const std::shared_ptr<AbstractBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
|
||||||
|
|
@ -110,11 +109,9 @@ namespace Nz
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void InvalidatePipeline();
|
inline void InvalidatePipeline();
|
||||||
inline void InvalidateShaderBinding();
|
|
||||||
inline void InvalidateTextureSampler(std::size_t textureIndex);
|
inline void InvalidateTextureSampler(std::size_t textureIndex);
|
||||||
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
|
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
|
||||||
void UpdatePipeline() const;
|
void UpdatePipeline() const;
|
||||||
void UpdateShaderBinding();
|
|
||||||
|
|
||||||
struct MaterialTexture
|
struct MaterialTexture
|
||||||
{
|
{
|
||||||
|
|
@ -137,10 +134,8 @@ namespace Nz
|
||||||
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
||||||
mutable MaterialPipelineInfo m_pipelineInfo;
|
mutable MaterialPipelineInfo m_pipelineInfo;
|
||||||
MaterialPassFlags m_flags;
|
MaterialPassFlags m_flags;
|
||||||
ShaderBindingPtr m_shaderBinding;
|
|
||||||
bool m_forceCommandBufferRegeneration;
|
bool m_forceCommandBufferRegeneration;
|
||||||
mutable bool m_pipelineUpdated;
|
mutable bool m_pipelineUpdated;
|
||||||
bool m_shaderBindingUpdated;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -373,12 +373,6 @@ namespace Nz
|
||||||
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
|
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
|
inline const std::shared_ptr<Texture>& MaterialPass::GetTexture(std::size_t textureIndex) const
|
||||||
{
|
{
|
||||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||||
|
|
@ -614,7 +608,7 @@ namespace Nz
|
||||||
if (m_textures[textureIndex].texture != texture)
|
if (m_textures[textureIndex].texture != texture)
|
||||||
{
|
{
|
||||||
m_textures[textureIndex].texture = std::move(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].buffer = std::move(uniformBuffer);
|
||||||
m_uniformBuffers[bufferIndex].dataInvalidated = true;
|
m_uniformBuffers[bufferIndex].dataInvalidated = true;
|
||||||
InvalidateShaderBinding();
|
|
||||||
|
OnMaterialInvalidated(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -647,20 +642,12 @@ namespace Nz
|
||||||
OnMaterialInvalidated(this);
|
OnMaterialInvalidated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MaterialPass::InvalidateShaderBinding()
|
|
||||||
{
|
|
||||||
m_forceCommandBufferRegeneration = true;
|
|
||||||
m_shaderBindingUpdated = false;
|
|
||||||
|
|
||||||
OnMaterialInvalidated(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
|
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
|
||||||
{
|
{
|
||||||
assert(textureIndex < m_textures.size());
|
assert(textureIndex < m_textures.size());
|
||||||
m_textures[textureIndex].sampler.reset();
|
m_textures[textureIndex].sampler.reset();
|
||||||
|
|
||||||
InvalidateShaderBinding();
|
OnMaterialInvalidated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
|
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
|
||||||
|
|
@ -674,4 +661,3 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Graphics/DebugOff.hpp>
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
#include "MaterialPass.hpp"
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ namespace Nz
|
||||||
struct SharedUniformBlock;
|
struct SharedUniformBlock;
|
||||||
struct Texture;
|
struct Texture;
|
||||||
struct UniformBlock;
|
struct UniformBlock;
|
||||||
|
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
|
||||||
|
|
||||||
inline MaterialSettings();
|
inline MaterialSettings();
|
||||||
inline MaterialSettings(Builder builder);
|
inline MaterialSettings(Builder builder);
|
||||||
|
|
@ -64,6 +65,7 @@ namespace Nz
|
||||||
std::vector<Texture> textures;
|
std::vector<Texture> textures;
|
||||||
std::vector<UniformBlock> uniformBlocks;
|
std::vector<UniformBlock> uniformBlocks;
|
||||||
std::vector<SharedUniformBlock> sharedUniformBlocks;
|
std::vector<SharedUniformBlock> sharedUniformBlocks;
|
||||||
|
PredefinedBinding predefinedBindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Option
|
struct Option
|
||||||
|
|
@ -113,3 +115,5 @@ namespace Nz
|
||||||
#include <Nazara/Graphics/MaterialSettings.inl>
|
#include <Nazara/Graphics/MaterialSettings.inl>
|
||||||
|
|
||||||
#endif // NAZARA_MATERIALPIPELINESETTINGS_HPP
|
#endif // NAZARA_MATERIALPIPELINESETTINGS_HPP
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,11 @@ namespace Nz
|
||||||
m_data(std::move(data))
|
m_data(std::move(data))
|
||||||
{
|
{
|
||||||
RenderPipelineLayoutInfo info;
|
RenderPipelineLayoutInfo info;
|
||||||
Graphics::FillDrawDataPipelineLayout(info);
|
|
||||||
Graphics::FillViewerPipelineLayout(info);
|
|
||||||
Graphics::FillWorldPipelineLayout(info);
|
|
||||||
|
|
||||||
for (const Texture& textureInfo : m_data.textures)
|
for (const Texture& textureInfo : m_data.textures)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
Graphics::MaterialBindingSet,
|
0,
|
||||||
textureInfo.bindingIndex,
|
textureInfo.bindingIndex,
|
||||||
ShaderBindingType::Texture,
|
ShaderBindingType::Texture,
|
||||||
textureInfo.shaderStages
|
textureInfo.shaderStages
|
||||||
|
|
@ -35,7 +32,7 @@ namespace Nz
|
||||||
for (const UniformBlock& ubo : m_data.uniformBlocks)
|
for (const UniformBlock& ubo : m_data.uniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
Graphics::MaterialBindingSet,
|
0,
|
||||||
ubo.bindingIndex,
|
ubo.bindingIndex,
|
||||||
ShaderBindingType::UniformBuffer,
|
ShaderBindingType::UniformBuffer,
|
||||||
ubo.shaderStages
|
ubo.shaderStages
|
||||||
|
|
@ -45,7 +42,7 @@ namespace Nz
|
||||||
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
|
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
Graphics::MaterialBindingSet,
|
0,
|
||||||
ubo.bindingIndex,
|
ubo.bindingIndex,
|
||||||
ShaderBindingType::UniformBuffer,
|
ShaderBindingType::UniformBuffer,
|
||||||
ubo.shaderStages
|
ubo.shaderStages
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Nz
|
||||||
std::array<std::size_t, 3> lightArray;
|
std::array<std::size_t, 3> lightArray;
|
||||||
std::size_t lightArraySize;
|
std::size_t lightArraySize;
|
||||||
|
|
||||||
static PredefinedLightData GetOffset();
|
static PredefinedLightData GetOffsets();
|
||||||
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -42,6 +42,7 @@ namespace Nz
|
||||||
std::size_t worldMatrixOffset;
|
std::size_t worldMatrixOffset;
|
||||||
|
|
||||||
static PredefinedInstanceData GetOffsets();
|
static PredefinedInstanceData GetOffsets();
|
||||||
|
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NAZARA_GRAPHICS_API PredefinedViewerData
|
struct NAZARA_GRAPHICS_API PredefinedViewerData
|
||||||
|
|
@ -58,6 +59,7 @@ namespace Nz
|
||||||
std::size_t viewProjMatrixOffset;
|
std::size_t viewProjMatrixOffset;
|
||||||
|
|
||||||
static PredefinedViewerData GetOffsets();
|
static PredefinedViewerData GetOffsets();
|
||||||
|
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define NAZARA_RENDERSUBMESH_HPP
|
#define NAZARA_RENDERSUBMESH_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||||
#include <Nazara/Graphics/RenderElement.hpp>
|
#include <Nazara/Graphics/RenderElement.hpp>
|
||||||
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
||||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||||
|
|
@ -17,36 +18,37 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class AbstractBuffer;
|
class AbstractBuffer;
|
||||||
class RenderPipeline;
|
class MaterialPass;
|
||||||
class ShaderBinding;
|
|
||||||
class VertexDeclaration;
|
class VertexDeclaration;
|
||||||
|
class ViewerInstance;
|
||||||
|
|
||||||
class RenderSpriteChain : public RenderElement
|
class RenderSpriteChain : public RenderElement
|
||||||
{
|
{
|
||||||
public:
|
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;
|
~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 MaterialPass& GetMaterialPass() const;
|
||||||
inline const ShaderBinding& GetMaterialBinding() const;
|
inline const RenderPipeline& GetRenderPipeline() const;
|
||||||
inline const RenderPipeline* GetRenderPipeline() const;
|
|
||||||
inline std::size_t GetSpriteCount() const;
|
inline std::size_t GetSpriteCount() const;
|
||||||
inline const void* GetSpriteData() const;
|
inline const void* GetSpriteData() const;
|
||||||
inline const Texture* GetTextureOverlay() const;
|
inline const Texture* GetTextureOverlay() const;
|
||||||
inline const VertexDeclaration* GetVertexDeclaration() const;
|
inline const VertexDeclaration* GetVertexDeclaration() const;
|
||||||
|
inline const ViewerInstance& GetViewerInstance() const;
|
||||||
|
inline const WorldInstance& GetWorldInstance() const;
|
||||||
|
|
||||||
inline void Register(RenderQueueRegistry& registry) const override;
|
inline void Register(RenderQueueRegistry& registry) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<MaterialPass> m_materialPass;
|
||||||
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
||||||
std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
|
std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
|
||||||
std::shared_ptr<Texture> m_textureOverlay;
|
std::shared_ptr<Texture> m_textureOverlay;
|
||||||
std::size_t m_spriteCount;
|
std::size_t m_spriteCount;
|
||||||
const void* m_spriteData;
|
const void* m_spriteData;
|
||||||
MaterialPassFlags m_matFlags;
|
const ViewerInstance& m_viewerInstance;
|
||||||
const ShaderBinding& m_materialBinding;
|
|
||||||
const WorldInstance& m_worldInstance;
|
const WorldInstance& m_worldInstance;
|
||||||
int m_renderLayer;
|
int m_renderLayer;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,28 @@
|
||||||
|
|
||||||
namespace Nz
|
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),
|
RenderElement(BasicRenderElement::SpriteChain),
|
||||||
|
m_materialPass(std::move(materialPass)),
|
||||||
m_renderPipeline(std::move(renderPipeline)),
|
m_renderPipeline(std::move(renderPipeline)),
|
||||||
m_vertexDeclaration(std::move(vertexDeclaration)),
|
m_vertexDeclaration(std::move(vertexDeclaration)),
|
||||||
m_textureOverlay(std::move(textureOverlay)),
|
m_textureOverlay(std::move(textureOverlay)),
|
||||||
m_spriteCount(spriteCount),
|
m_spriteCount(spriteCount),
|
||||||
m_spriteData(spriteData),
|
m_spriteData(spriteData),
|
||||||
m_matFlags(matFlags),
|
m_viewerInstance(viewerInstance),
|
||||||
m_materialBinding(materialBinding),
|
|
||||||
m_worldInstance(worldInstance),
|
m_worldInstance(worldInstance),
|
||||||
m_renderLayer(renderLayer)
|
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 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||||
UInt64 elementType = GetElementType();
|
UInt64 elementType = GetElementType();
|
||||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||||
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
|
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
|
||||||
|
|
||||||
if (m_matFlags.Test(MaterialPassFlag::Transparent))
|
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::Transparent))
|
||||||
{
|
{
|
||||||
UInt64 matFlags = 1;
|
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;
|
return *m_renderPipeline;
|
||||||
}
|
|
||||||
|
|
||||||
inline const RenderPipeline* RenderSpriteChain::GetRenderPipeline() const
|
|
||||||
{
|
|
||||||
return m_renderPipeline.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t RenderSpriteChain::GetSpriteCount() const
|
inline std::size_t RenderSpriteChain::GetSpriteCount() const
|
||||||
|
|
@ -101,6 +96,16 @@ namespace Nz
|
||||||
return m_vertexDeclaration.get();
|
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
|
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
|
||||||
{
|
{
|
||||||
registry.RegisterLayer(m_renderLayer);
|
registry.RegisterLayer(m_renderLayer);
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const AbstractBuffer* vertexBuffer;
|
const AbstractBuffer* vertexBuffer;
|
||||||
const RenderPipeline* renderPipeline;
|
const RenderPipeline* renderPipeline;
|
||||||
const ShaderBinding* drawDataBinding;
|
const ShaderBinding* shaderBinding;
|
||||||
const ShaderBinding* instanceBinding;
|
|
||||||
const ShaderBinding* materialBinding;
|
|
||||||
std::size_t firstIndex;
|
std::size_t firstIndex;
|
||||||
std::size_t quadCount;
|
std::size_t quadCount;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Math/Matrix4.hpp>
|
#include <Nazara/Math/Matrix4.hpp>
|
||||||
#include <Nazara/Graphics/Config.hpp>
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -36,7 +35,6 @@ namespace Nz
|
||||||
inline const Matrix4f& GetViewProjMatrix() const;
|
inline const Matrix4f& GetViewProjMatrix() const;
|
||||||
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
||||||
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
||||||
inline ShaderBinding& GetShaderBinding();
|
|
||||||
|
|
||||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||||
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
|
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
|
||||||
|
|
@ -59,7 +57,6 @@ namespace Nz
|
||||||
Matrix4f m_projectionMatrix;
|
Matrix4f m_projectionMatrix;
|
||||||
Matrix4f m_viewProjMatrix;
|
Matrix4f m_viewProjMatrix;
|
||||||
Matrix4f m_viewMatrix;
|
Matrix4f m_viewMatrix;
|
||||||
ShaderBindingPtr m_shaderBinding;
|
|
||||||
Vector2f m_targetSize;
|
Vector2f m_targetSize;
|
||||||
bool m_dataInvalided;
|
bool m_dataInvalided;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,6 @@ namespace Nz
|
||||||
return m_viewerDataBuffer;
|
return m_viewerDataBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ShaderBinding& ViewerInstance::GetShaderBinding()
|
|
||||||
{
|
|
||||||
return *m_shaderBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
|
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
|
||||||
{
|
{
|
||||||
m_projectionMatrix = projectionMatrix;
|
m_projectionMatrix = projectionMatrix;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Math/Matrix4.hpp>
|
#include <Nazara/Math/Matrix4.hpp>
|
||||||
#include <Nazara/Graphics/Config.hpp>
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -34,8 +33,6 @@ namespace Nz
|
||||||
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
||||||
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
||||||
inline const Matrix4f& GetInvWorldMatrix() const;
|
inline const Matrix4f& GetInvWorldMatrix() const;
|
||||||
inline ShaderBinding& GetShaderBinding();
|
|
||||||
inline const ShaderBinding& GetShaderBinding() const;
|
|
||||||
inline const Matrix4f& GetWorldMatrix() const;
|
inline const Matrix4f& GetWorldMatrix() const;
|
||||||
|
|
||||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||||
|
|
@ -49,7 +46,6 @@ namespace Nz
|
||||||
std::shared_ptr<AbstractBuffer> m_instanceDataBuffer;
|
std::shared_ptr<AbstractBuffer> m_instanceDataBuffer;
|
||||||
Matrix4f m_invWorldMatrix;
|
Matrix4f m_invWorldMatrix;
|
||||||
Matrix4f m_worldMatrix;
|
Matrix4f m_worldMatrix;
|
||||||
ShaderBindingPtr m_shaderBinding;
|
|
||||||
bool m_dataInvalided;
|
bool m_dataInvalided;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,16 +23,6 @@ namespace Nz
|
||||||
return m_invWorldMatrix;
|
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
|
inline const Matrix4f& WorldInstance::GetWorldMatrix() const
|
||||||
{
|
{
|
||||||
return m_worldMatrix;
|
return m_worldMatrix;
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,16 @@ namespace Nz
|
||||||
std::move(defaultValues)
|
std::move(defaultValues)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Common data
|
||||||
|
settings.textures.push_back({
|
||||||
|
3,
|
||||||
|
"TextureOverlay",
|
||||||
|
ImageType::E2D
|
||||||
|
});
|
||||||
|
|
||||||
|
settings.sharedUniformBlocks.push_back(PredefinedInstanceData::GetUniformBlock(4, ShaderStageType::Vertex));
|
||||||
|
settings.sharedUniformBlocks.push_back(PredefinedViewerData::GetUniformBlock(5, ShaderStageType_All));
|
||||||
|
|
||||||
settings.shaders = std::move(uberShaders);
|
settings.shaders = std::move(uberShaders);
|
||||||
|
|
||||||
for (std::shared_ptr<UberShader> uberShader : settings.shaders)
|
for (std::shared_ptr<UberShader> uberShader : settings.shaders)
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,6 @@ namespace Nz
|
||||||
|
|
||||||
MaterialPipeline::Initialize();
|
MaterialPipeline::Initialize();
|
||||||
|
|
||||||
RenderPipelineLayoutInfo referenceLayoutInfo;
|
|
||||||
FillDrawDataPipelineLayout(referenceLayoutInfo);
|
|
||||||
FillViewerPipelineLayout(referenceLayoutInfo);
|
|
||||||
FillWorldPipelineLayout(referenceLayoutInfo);
|
|
||||||
|
|
||||||
m_referencePipelineLayout = m_renderDevice->InstantiateRenderPipelineLayout(std::move(referenceLayoutInfo));
|
|
||||||
|
|
||||||
BuildDefaultTextures();
|
BuildDefaultTextures();
|
||||||
BuildFullscreenVertexBuffer();
|
BuildFullscreenVertexBuffer();
|
||||||
BuildBlitPipeline();
|
BuildBlitPipeline();
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ namespace Nz
|
||||||
MaterialPass::MaterialPass(std::shared_ptr<const MaterialSettings> settings) :
|
MaterialPass::MaterialPass(std::shared_ptr<const MaterialSettings> settings) :
|
||||||
m_settings(std::move(settings)),
|
m_settings(std::move(settings)),
|
||||||
m_forceCommandBufferRegeneration(false),
|
m_forceCommandBufferRegeneration(false),
|
||||||
m_pipelineUpdated(false),
|
m_pipelineUpdated(false)
|
||||||
m_shaderBindingUpdated(false)
|
|
||||||
{
|
{
|
||||||
m_pipelineInfo.settings = m_settings;
|
m_pipelineInfo.settings = m_settings;
|
||||||
|
|
||||||
|
|
@ -44,14 +43,14 @@ namespace Nz
|
||||||
const auto& textureSettings = m_settings->GetTextures();
|
const auto& textureSettings = m_settings->GetTextures();
|
||||||
const auto& uboSettings = m_settings->GetUniformBlocks();
|
const auto& uboSettings = m_settings->GetUniformBlocks();
|
||||||
|
|
||||||
m_textures.resize(m_settings->GetTextures().size());
|
m_textures.resize(textureSettings.size());
|
||||||
|
|
||||||
m_uniformBuffers.reserve(m_settings->GetUniformBlocks().size());
|
m_uniformBuffers.reserve(uboSettings.size());
|
||||||
for (const auto& uniformBufferInfo : m_settings->GetUniformBlocks())
|
for (const auto& uniformBufferInfo : uboSettings)
|
||||||
{
|
{
|
||||||
auto& uniformBuffer = m_uniformBuffers.emplace_back();
|
auto& uniformBuffer = m_uniformBuffers.emplace_back();
|
||||||
|
|
||||||
uniformBuffer.buffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(Nz::BufferType::Uniform);
|
uniformBuffer.buffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||||
if (!uniformBuffer.buffer->Initialize(uniformBufferInfo.blockSize, BufferUsage::Dynamic))
|
if (!uniformBuffer.buffer->Initialize(uniformBufferInfo.blockSize, BufferUsage::Dynamic))
|
||||||
throw std::runtime_error("failed to initialize UBO memory");
|
throw std::runtime_error("failed to initialize UBO memory");
|
||||||
|
|
||||||
|
|
@ -60,20 +59,10 @@ namespace Nz
|
||||||
uniformBuffer.data.resize(uniformBufferInfo.blockSize);
|
uniformBuffer.data.resize(uniformBufferInfo.blockSize);
|
||||||
std::memcpy(uniformBuffer.data.data(), uniformBufferInfo.defaultValues.data(), uniformBufferInfo.defaultValues.size());
|
std::memcpy(uniformBuffer.data.data(), uniformBufferInfo.defaultValues.data(), uniformBufferInfo.defaultValues.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateShaderBinding();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MaterialPass::Update(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
bool MaterialPass::Update(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||||
{
|
{
|
||||||
if (!m_shaderBindingUpdated)
|
|
||||||
{
|
|
||||||
renderFrame.PushForRelease(std::move(m_shaderBinding));
|
|
||||||
m_shaderBinding.reset();
|
|
||||||
|
|
||||||
UpdateShaderBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
||||||
|
|
||||||
for (auto& ubo : m_uniformBuffers)
|
for (auto& ubo : m_uniformBuffers)
|
||||||
|
|
@ -118,60 +107,4 @@ namespace Nz
|
||||||
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
||||||
m_pipelineUpdated = true;
|
m_pipelineUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialPass::UpdateShaderBinding()
|
|
||||||
{
|
|
||||||
assert(!m_shaderBinding);
|
|
||||||
|
|
||||||
const auto& textureSettings = m_settings->GetTextures();
|
|
||||||
const auto& uboSettings = m_settings->GetUniformBlocks();
|
|
||||||
|
|
||||||
// TODO: Use StackVector
|
|
||||||
std::vector<ShaderBinding::Binding> bindings;
|
|
||||||
|
|
||||||
// Textures
|
|
||||||
for (std::size_t i = 0; i < m_textures.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& textureSetting = textureSettings[i];
|
|
||||||
const auto& textureSlot = m_textures[i];
|
|
||||||
|
|
||||||
if (!textureSlot.sampler)
|
|
||||||
{
|
|
||||||
TextureSamplerCache& samplerCache = Graphics::Instance()->GetSamplerCache();
|
|
||||||
textureSlot.sampler = samplerCache.Get(textureSlot.samplerInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Use "missing" texture
|
|
||||||
if (textureSlot.texture)
|
|
||||||
{
|
|
||||||
bindings.push_back({
|
|
||||||
textureSetting.bindingIndex,
|
|
||||||
ShaderBinding::TextureBinding {
|
|
||||||
textureSlot.texture.get(), textureSlot.sampler.get()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shared UBO (TODO)
|
|
||||||
|
|
||||||
// Owned UBO
|
|
||||||
for (std::size_t i = 0; i < m_uniformBuffers.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& uboSetting = uboSettings[i];
|
|
||||||
const auto& uboSlot = m_uniformBuffers[i];
|
|
||||||
|
|
||||||
bindings.push_back({
|
|
||||||
uboSetting.bindingIndex,
|
|
||||||
ShaderBinding::UniformBufferBinding {
|
|
||||||
uboSlot.buffer.get(), 0, uboSlot.buffer->GetSize()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
m_shaderBinding = m_settings->GetRenderPipelineLayout()->AllocateShaderBinding(Graphics::MaterialBindingSet);
|
|
||||||
m_shaderBinding->Update(bindings.data(), bindings.size());
|
|
||||||
|
|
||||||
m_shaderBindingUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
PredefinedLightData PredefinedLightData::GetOffset()
|
PredefinedLightData PredefinedLightData::GetOffsets()
|
||||||
{
|
{
|
||||||
PredefinedLightData lightData;
|
PredefinedLightData lightData;
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace Nz
|
||||||
|
|
||||||
MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock()
|
MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock()
|
||||||
{
|
{
|
||||||
PredefinedLightData lightData = GetOffset();
|
PredefinedLightData lightData = GetOffsets();
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformVariable> lightDataVariables;
|
std::vector<MaterialSettings::UniformVariable> lightDataVariables;
|
||||||
for (std::size_t i = 0; i < lightData.lightArray.size(); ++i)
|
for (std::size_t i = 0; i < lightData.lightArray.size(); ++i)
|
||||||
|
|
@ -67,6 +67,27 @@ namespace Nz
|
||||||
return instanceData;
|
return instanceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock PredefinedInstanceData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages)
|
||||||
|
{
|
||||||
|
PredefinedInstanceData instanceData = GetOffsets();
|
||||||
|
|
||||||
|
std::vector<MaterialSettings::UniformVariable> variables = {
|
||||||
|
{
|
||||||
|
{ "WorldMatrix", instanceData.worldMatrixOffset },
|
||||||
|
{ "InvWorldMatrix", instanceData.invWorldMatrixOffset }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock uniformBlock = {
|
||||||
|
bindingIndex,
|
||||||
|
"InstanceData",
|
||||||
|
std::move(variables),
|
||||||
|
shaderStages
|
||||||
|
};
|
||||||
|
|
||||||
|
return uniformBlock;
|
||||||
|
}
|
||||||
|
|
||||||
PredefinedViewerData PredefinedViewerData::GetOffsets()
|
PredefinedViewerData PredefinedViewerData::GetOffsets()
|
||||||
{
|
{
|
||||||
FieldOffsets viewerStruct(StructLayout::Std140);
|
FieldOffsets viewerStruct(StructLayout::Std140);
|
||||||
|
|
@ -86,4 +107,33 @@ namespace Nz
|
||||||
|
|
||||||
return viewerData;
|
return viewerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock PredefinedViewerData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages)
|
||||||
|
{
|
||||||
|
PredefinedViewerData viewerData = GetOffsets();
|
||||||
|
|
||||||
|
std::vector<MaterialSettings::UniformVariable> variables = {
|
||||||
|
{
|
||||||
|
{ "EyePosition", viewerData.eyePositionOffset },
|
||||||
|
{ "InvProjMatrix", viewerData.invProjMatrixOffset },
|
||||||
|
{ "InvTargetSize", viewerData.invTargetSizeOffset },
|
||||||
|
{ "InvViewMatrix", viewerData.invViewMatrixOffset },
|
||||||
|
{ "InvViewProjMatrix", viewerData.invViewProjMatrixOffset },
|
||||||
|
{ "ProjMatrix", viewerData.projMatrixOffset },
|
||||||
|
{ "TargetSize", viewerData.targetSizeOffset },
|
||||||
|
{ "ViewMatrix", viewerData.viewMatrixOffset },
|
||||||
|
{ "ViewProjMatrix", viewerData.viewProjMatrixOffset }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock uniformBlock = {
|
||||||
|
bindingIndex,
|
||||||
|
"ViewerData",
|
||||||
|
std::move(variables),
|
||||||
|
shaderStages
|
||||||
|
};
|
||||||
|
|
||||||
|
return uniformBlock;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,10 @@ namespace Nz
|
||||||
const VertexDeclaration* currentVertexDeclaration = nullptr;
|
const VertexDeclaration* currentVertexDeclaration = nullptr;
|
||||||
AbstractBuffer* currentVertexBuffer = nullptr;
|
AbstractBuffer* currentVertexBuffer = nullptr;
|
||||||
const RenderPipeline* currentPipeline = nullptr;
|
const RenderPipeline* currentPipeline = nullptr;
|
||||||
const ShaderBinding* currentDrawDataBinding = nullptr;
|
const ShaderBinding* currentShaderBinding = nullptr;
|
||||||
const ShaderBinding* currentInstanceBinding = nullptr;
|
|
||||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
|
||||||
const Texture* currentTextureOverlay = nullptr;
|
const Texture* currentTextureOverlay = nullptr;
|
||||||
|
const ViewerInstance* currentViewerInstance = nullptr;
|
||||||
|
const WorldInstance* currentWorldInstance = nullptr;
|
||||||
|
|
||||||
auto FlushDrawCall = [&]()
|
auto FlushDrawCall = [&]()
|
||||||
{
|
{
|
||||||
|
|
@ -79,7 +79,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
FlushDrawCall();
|
FlushDrawCall();
|
||||||
|
|
||||||
currentDrawDataBinding = nullptr;
|
currentShaderBinding = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto Flush = [&]()
|
auto Flush = [&]()
|
||||||
|
|
@ -122,24 +122,24 @@ namespace Nz
|
||||||
currentVertexDeclaration = vertexDeclaration;
|
currentVertexDeclaration = vertexDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPipeline != spriteChain.GetRenderPipeline())
|
if (currentPipeline != &spriteChain.GetRenderPipeline())
|
||||||
{
|
{
|
||||||
FlushDrawCall();
|
FlushDrawCall();
|
||||||
currentPipeline = spriteChain.GetRenderPipeline();
|
currentPipeline = &spriteChain.GetRenderPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentMaterialBinding != &spriteChain.GetMaterialBinding())
|
if (currentViewerInstance != &spriteChain.GetViewerInstance())
|
||||||
{
|
{
|
||||||
FlushDrawCall();
|
FlushDrawCall();
|
||||||
currentMaterialBinding = &spriteChain.GetMaterialBinding();
|
currentViewerInstance = &spriteChain.GetViewerInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentInstanceBinding != &spriteChain.GetInstanceBinding())
|
if (currentWorldInstance != &spriteChain.GetWorldInstance())
|
||||||
{
|
{
|
||||||
// TODO: Flushing draw calls on instance binding means we can have e.g. 1000 sprites rendered using a draw call for each one
|
// TODO: Flushing draw calls on instance binding means we can have e.g. 1000 sprites rendered using a draw call for each one
|
||||||
// which is far from being efficient, using some bindless could help (or at least instancing?)
|
// which is far from being efficient, using some bindless could help (or at least instancing?)
|
||||||
FlushDrawCall();
|
FlushDrawCall();
|
||||||
currentInstanceBinding = &spriteChain.GetInstanceBinding();
|
currentWorldInstance = &spriteChain.GetWorldInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTextureOverlay != spriteChain.GetTextureOverlay())
|
if (currentTextureOverlay != spriteChain.GetTextureOverlay())
|
||||||
|
|
@ -177,9 +177,9 @@ namespace Nz
|
||||||
data.vertexBuffers.emplace_back(std::move(vertexBuffer));
|
data.vertexBuffers.emplace_back(std::move(vertexBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentDrawDataBinding)
|
if (!currentShaderBinding)
|
||||||
{
|
{
|
||||||
ShaderBindingPtr drawDataBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::DrawDataBindingSet);
|
ShaderBindingPtr drawDataBinding = currentPipeline->GetPipelineInfo().pipelineLayout->AllocateShaderBinding(0);
|
||||||
drawDataBinding->Update({
|
drawDataBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
|
@ -189,7 +189,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
currentDrawDataBinding = drawDataBinding.get();
|
currentShaderBinding = drawDataBinding.get();
|
||||||
|
|
||||||
data.shaderBindings.emplace_back(std::move(drawDataBinding));
|
data.shaderBindings.emplace_back(std::move(drawDataBinding));
|
||||||
}
|
}
|
||||||
|
|
@ -199,9 +199,7 @@ namespace Nz
|
||||||
data.drawCalls.push_back(SpriteChainRendererData::DrawCall{
|
data.drawCalls.push_back(SpriteChainRendererData::DrawCall{
|
||||||
currentVertexBuffer,
|
currentVertexBuffer,
|
||||||
currentPipeline,
|
currentPipeline,
|
||||||
currentDrawDataBinding,
|
currentShaderBinding,
|
||||||
currentInstanceBinding,
|
|
||||||
currentMaterialBinding,
|
|
||||||
6 * firstQuadIndex,
|
6 * firstQuadIndex,
|
||||||
0,
|
0,
|
||||||
});
|
});
|
||||||
|
|
@ -263,9 +261,9 @@ namespace Nz
|
||||||
|
|
||||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||||
const RenderPipeline* currentPipeline = nullptr;
|
const RenderPipeline* currentPipeline = nullptr;
|
||||||
const ShaderBinding* currentDrawDataBinding = nullptr;
|
const ShaderBinding* currentShaderBinding = nullptr;
|
||||||
const ShaderBinding* currentInstanceBinding = nullptr;
|
const ViewerInstance* currentViewerInstance = nullptr;
|
||||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
const WorldInstance* currentWorldInstance = nullptr;
|
||||||
|
|
||||||
const RenderSpriteChain* firstSpriteChain = static_cast<const RenderSpriteChain*>(elements[0]);
|
const RenderSpriteChain* firstSpriteChain = static_cast<const RenderSpriteChain*>(elements[0]);
|
||||||
auto it = data.drawCallPerElement.find(firstSpriteChain);
|
auto it = data.drawCallPerElement.find(firstSpriteChain);
|
||||||
|
|
@ -289,22 +287,10 @@ namespace Nz
|
||||||
currentPipeline = drawCall.renderPipeline;
|
currentPipeline = drawCall.renderPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentDrawDataBinding != drawCall.drawDataBinding)
|
if (currentShaderBinding != drawCall.shaderBinding)
|
||||||
{
|
{
|
||||||
commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *drawCall.drawDataBinding);
|
commandBuffer.BindShaderBinding(0, *drawCall.shaderBinding);
|
||||||
currentDrawDataBinding = drawCall.drawDataBinding;
|
currentShaderBinding = drawCall.shaderBinding;
|
||||||
}
|
|
||||||
|
|
||||||
if (currentMaterialBinding != drawCall.materialBinding)
|
|
||||||
{
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, *drawCall.materialBinding);
|
|
||||||
currentMaterialBinding = drawCall.materialBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentInstanceBinding != drawCall.instanceBinding)
|
|
||||||
{
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::WorldBindingSet, *drawCall.instanceBinding);
|
|
||||||
currentInstanceBinding = drawCall.instanceBinding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex);
|
commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex);
|
||||||
|
|
|
||||||
|
|
@ -14,49 +14,39 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
ViewerInstance::ViewerInstance() :
|
ViewerInstance::ViewerInstance() :
|
||||||
m_invProjectionMatrix(Nz::Matrix4f::Identity()),
|
m_invProjectionMatrix(Matrix4f::Identity()),
|
||||||
m_invViewProjMatrix(Nz::Matrix4f::Identity()),
|
m_invViewProjMatrix(Matrix4f::Identity()),
|
||||||
m_invViewMatrix(Nz::Matrix4f::Identity()),
|
m_invViewMatrix(Matrix4f::Identity()),
|
||||||
m_projectionMatrix(Nz::Matrix4f::Identity()),
|
m_projectionMatrix(Matrix4f::Identity()),
|
||||||
m_viewProjMatrix(Nz::Matrix4f::Identity()),
|
m_viewProjMatrix(Matrix4f::Identity()),
|
||||||
m_viewMatrix(Nz::Matrix4f::Identity()),
|
m_viewMatrix(Matrix4f::Identity()),
|
||||||
m_targetSize(Nz::Vector2f(0.f, 0.f)),
|
m_targetSize(Vector2f(0.f, 0.f)),
|
||||||
m_dataInvalided(true)
|
m_dataInvalided(true)
|
||||||
{
|
{
|
||||||
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
|
PredefinedViewerData viewerUboOffsets = PredefinedViewerData::GetOffsets();
|
||||||
|
|
||||||
m_viewerDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
m_viewerDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||||
if (!m_viewerDataBuffer->Initialize(viewerUboOffsets.totalSize, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic))
|
if (!m_viewerDataBuffer->Initialize(viewerUboOffsets.totalSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic))
|
||||||
throw std::runtime_error("failed to initialize viewer data UBO");
|
throw std::runtime_error("failed to initialize viewer data UBO");
|
||||||
|
|
||||||
m_shaderBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::ViewerBindingSet);
|
|
||||||
m_shaderBinding->Update({
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
ShaderBinding::UniformBufferBinding {
|
|
||||||
m_viewerDataBuffer.get(), 0, m_viewerDataBuffer->GetSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewerInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
void ViewerInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
||||||
{
|
{
|
||||||
if (m_dataInvalided)
|
if (m_dataInvalided)
|
||||||
{
|
{
|
||||||
Nz::PredefinedViewerData viewerDataOffsets = Nz::PredefinedViewerData::GetOffsets();
|
PredefinedViewerData viewerDataOffsets = PredefinedViewerData::GetOffsets();
|
||||||
|
|
||||||
auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize);
|
auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize);
|
||||||
Nz::AccessByOffset<Nz::Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation();
|
AccessByOffset<Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation();
|
||||||
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
|
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
|
||||||
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
|
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
|
||||||
|
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix;
|
||||||
|
|
||||||
builder.CopyBuffer(allocation, m_viewerDataBuffer.get());
|
builder.CopyBuffer(allocation, m_viewerDataBuffer.get());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,25 +14,15 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
WorldInstance::WorldInstance() :
|
WorldInstance::WorldInstance() :
|
||||||
m_invWorldMatrix(Nz::Matrix4f::Identity()),
|
m_invWorldMatrix(Matrix4f::Identity()),
|
||||||
m_worldMatrix(Nz::Matrix4f::Identity()),
|
m_worldMatrix(Matrix4f::Identity()),
|
||||||
m_dataInvalided(true)
|
m_dataInvalided(true)
|
||||||
{
|
{
|
||||||
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
||||||
|
|
||||||
m_instanceDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
m_instanceDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||||
if (!m_instanceDataBuffer->Initialize(instanceUboOffsets.totalSize, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic))
|
if (!m_instanceDataBuffer->Initialize(instanceUboOffsets.totalSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic))
|
||||||
throw std::runtime_error("failed to initialize viewer data UBO");
|
throw std::runtime_error("failed to initialize viewer data UBO");
|
||||||
|
|
||||||
m_shaderBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::WorldBindingSet);
|
|
||||||
m_shaderBinding->Update({
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
ShaderBinding::UniformBufferBinding {
|
|
||||||
m_instanceDataBuffer.get(), 0, m_instanceDataBuffer->GetSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
void WorldInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue