diff --git a/examples/PhysicsDemo/main.cpp b/examples/PhysicsDemo/main.cpp index 0b402f7cd..fb22fe9d6 100644 --- a/examples/PhysicsDemo/main.cpp +++ b/examples/PhysicsDemo/main.cpp @@ -218,11 +218,11 @@ int main() registry.get(viewer).SetParent(registry, headingEntity); registry.get(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(); auto& entityGfx = registry.emplace(entity); diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 55057b343..62061b030 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -50,6 +50,17 @@ namespace Nz Orthographic, Perspective }; + + enum class PredefinedShaderBinding + { + InstanceDataUbo, + OverlayTexture, + ViewerDataUbo, + + Max = ViewerDataUbo + }; + + constexpr std::size_t PredefinedShaderBindingCount = static_cast(PredefinedShaderBinding::Max) + 1; } #endif // NAZARA_ENUMS_GRAPHICS_HPP diff --git a/include/Nazara/Graphics/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index dcce88373..d6016ba2e 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -42,7 +42,6 @@ namespace Nz inline MaterialPassRegistry& GetMaterialPassRegistry(); inline const MaterialPassRegistry& GetMaterialPassRegistry() const; inline PixelFormat GetPreferredDepthStencilFormat() const; - inline const std::shared_ptr& GetReferencePipelineLayout() const; inline const std::shared_ptr& GetRenderDevice() const; inline const RenderPassCache& GetRenderPassCache() const; inline TextureSamplerCache& GetSamplerCache(); @@ -58,14 +57,9 @@ namespace Nz std::shared_ptr 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 m_renderDevice; std::shared_ptr m_blitPipeline; std::shared_ptr m_blitPipelineLayout; - std::shared_ptr m_referencePipelineLayout; std::shared_ptr m_fullscreenVertexDeclaration; DefaultTextures m_defaultTextures; MaterialPassRegistry m_materialPassRegistry; diff --git a/include/Nazara/Graphics/Graphics.inl b/include/Nazara/Graphics/Graphics.inl index 855a8a91c..0f7d6af40 100644 --- a/include/Nazara/Graphics/Graphics.inl +++ b/include/Nazara/Graphics/Graphics.inl @@ -47,11 +47,6 @@ namespace Nz return m_preferredDepthStencilFormat; } - inline const std::shared_ptr& Graphics::GetReferencePipelineLayout() const - { - return m_referencePipelineLayout; - } - inline const std::shared_ptr& Graphics::GetRenderDevice() const { return m_renderDevice; diff --git a/include/Nazara/Graphics/MaterialPass.hpp b/include/Nazara/Graphics/MaterialPass.hpp index 16755e465..230b8ed29 100644 --- a/include/Nazara/Graphics/MaterialPass.hpp +++ b/include/Nazara/Graphics/MaterialPass.hpp @@ -70,7 +70,6 @@ namespace Nz inline PrimitiveMode GetPrimitiveMode() const; inline const std::shared_ptr& GetSettings() const; inline const std::shared_ptr& GetShader(ShaderStageType shaderStage) const; - inline ShaderBinding& GetShaderBinding(); inline const std::shared_ptr& GetTexture(std::size_t textureIndex) const; inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const; inline const std::shared_ptr& 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 m_pipeline; mutable MaterialPipelineInfo m_pipelineInfo; MaterialPassFlags m_flags; - ShaderBindingPtr m_shaderBinding; bool m_forceCommandBufferRegeneration; mutable bool m_pipelineUpdated; - bool m_shaderBindingUpdated; }; } diff --git a/include/Nazara/Graphics/MaterialPass.inl b/include/Nazara/Graphics/MaterialPass.inl index aecb90813..6b7539a89 100644 --- a/include/Nazara/Graphics/MaterialPass.inl +++ b/include/Nazara/Graphics/MaterialPass.inl @@ -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& 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 -#include "MaterialPass.hpp" diff --git a/include/Nazara/Graphics/MaterialSettings.hpp b/include/Nazara/Graphics/MaterialSettings.hpp index 0d7041fdc..969c5fce8 100644 --- a/include/Nazara/Graphics/MaterialSettings.hpp +++ b/include/Nazara/Graphics/MaterialSettings.hpp @@ -28,6 +28,7 @@ namespace Nz struct SharedUniformBlock; struct Texture; struct UniformBlock; + using PredefinedBinding = std::array; inline MaterialSettings(); inline MaterialSettings(Builder builder); @@ -64,6 +65,7 @@ namespace Nz std::vector textures; std::vector uniformBlocks; std::vector sharedUniformBlocks; + PredefinedBinding predefinedBindings; }; struct Option @@ -113,3 +115,5 @@ namespace Nz #include #endif // NAZARA_MATERIALPIPELINESETTINGS_HPP + + diff --git a/include/Nazara/Graphics/MaterialSettings.inl b/include/Nazara/Graphics/MaterialSettings.inl index 2c63337dd..1b4094e56 100644 --- a/include/Nazara/Graphics/MaterialSettings.inl +++ b/include/Nazara/Graphics/MaterialSettings.inl @@ -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 diff --git a/include/Nazara/Graphics/PredefinedShaderStructs.hpp b/include/Nazara/Graphics/PredefinedShaderStructs.hpp index b2a0a9b0a..fcf69a77c 100644 --- a/include/Nazara/Graphics/PredefinedShaderStructs.hpp +++ b/include/Nazara/Graphics/PredefinedShaderStructs.hpp @@ -31,7 +31,7 @@ namespace Nz std::array 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); }; } diff --git a/include/Nazara/Graphics/RenderSpriteChain.hpp b/include/Nazara/Graphics/RenderSpriteChain.hpp index d8f1ddf94..e0bb7bc76 100644 --- a/include/Nazara/Graphics/RenderSpriteChain.hpp +++ b/include/Nazara/Graphics/RenderSpriteChain.hpp @@ -8,6 +8,7 @@ #define NAZARA_RENDERSUBMESH_HPP #include +#include #include #include #include @@ -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, std::shared_ptr vertexDeclaration, std::shared_ptr 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, std::shared_ptr renderPipeline, const ViewerInstance& viewerInstance, const WorldInstance& worldInstance, std::shared_ptr vertexDeclaration, std::shared_ptr 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 m_materialPass; std::shared_ptr m_renderPipeline; std::shared_ptr m_vertexDeclaration; std::shared_ptr 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; }; diff --git a/include/Nazara/Graphics/RenderSpriteChain.inl b/include/Nazara/Graphics/RenderSpriteChain.inl index b124f6f2d..2aeee5034 100644 --- a/include/Nazara/Graphics/RenderSpriteChain.inl +++ b/include/Nazara/Graphics/RenderSpriteChain.inl @@ -8,28 +8,28 @@ namespace Nz { - inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr renderPipeline, std::shared_ptr vertexDeclaration, std::shared_ptr 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, std::shared_ptr renderPipeline, const ViewerInstance& viewerInstance, const WorldInstance& worldInstance, std::shared_ptr vertexDeclaration, std::shared_ptr 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); diff --git a/include/Nazara/Graphics/SpriteChainRenderer.hpp b/include/Nazara/Graphics/SpriteChainRenderer.hpp index e1d2efa50..04b30867a 100644 --- a/include/Nazara/Graphics/SpriteChainRenderer.hpp +++ b/include/Nazara/Graphics/SpriteChainRenderer.hpp @@ -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; }; diff --git a/include/Nazara/Graphics/ViewerInstance.hpp b/include/Nazara/Graphics/ViewerInstance.hpp index 91e42a23a..8b063f8ca 100644 --- a/include/Nazara/Graphics/ViewerInstance.hpp +++ b/include/Nazara/Graphics/ViewerInstance.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Nz @@ -36,7 +35,6 @@ namespace Nz inline const Matrix4f& GetViewProjMatrix() const; inline std::shared_ptr& GetInstanceBuffer(); inline const std::shared_ptr& 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; }; diff --git a/include/Nazara/Graphics/ViewerInstance.inl b/include/Nazara/Graphics/ViewerInstance.inl index bf269cd42..eccef26c2 100644 --- a/include/Nazara/Graphics/ViewerInstance.inl +++ b/include/Nazara/Graphics/ViewerInstance.inl @@ -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; diff --git a/include/Nazara/Graphics/WorldInstance.hpp b/include/Nazara/Graphics/WorldInstance.hpp index a402a6169..fee84b203 100644 --- a/include/Nazara/Graphics/WorldInstance.hpp +++ b/include/Nazara/Graphics/WorldInstance.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Nz @@ -34,8 +33,6 @@ namespace Nz inline std::shared_ptr& GetInstanceBuffer(); inline const std::shared_ptr& 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 m_instanceDataBuffer; Matrix4f m_invWorldMatrix; Matrix4f m_worldMatrix; - ShaderBindingPtr m_shaderBinding; bool m_dataInvalided; }; } diff --git a/include/Nazara/Graphics/WorldInstance.inl b/include/Nazara/Graphics/WorldInstance.inl index c5537bc5c..b831796ce 100644 --- a/include/Nazara/Graphics/WorldInstance.inl +++ b/include/Nazara/Graphics/WorldInstance.inl @@ -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; diff --git a/src/Nazara/Graphics/BasicMaterial.cpp b/src/Nazara/Graphics/BasicMaterial.cpp index ab31aa67d..492c55ef9 100644 --- a/src/Nazara/Graphics/BasicMaterial.cpp +++ b/src/Nazara/Graphics/BasicMaterial.cpp @@ -152,6 +152,16 @@ namespace Nz 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); for (std::shared_ptr uberShader : settings.shaders) diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index ceec16cd8..3e81eb978 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -67,13 +67,6 @@ namespace Nz MaterialPipeline::Initialize(); - RenderPipelineLayoutInfo referenceLayoutInfo; - FillDrawDataPipelineLayout(referenceLayoutInfo); - FillViewerPipelineLayout(referenceLayoutInfo); - FillWorldPipelineLayout(referenceLayoutInfo); - - m_referencePipelineLayout = m_renderDevice->InstantiateRenderPipelineLayout(std::move(referenceLayoutInfo)); - BuildDefaultTextures(); BuildFullscreenVertexBuffer(); BuildBlitPipeline(); diff --git a/src/Nazara/Graphics/MaterialPass.cpp b/src/Nazara/Graphics/MaterialPass.cpp index c005aab3a..9c63d88f0 100644 --- a/src/Nazara/Graphics/MaterialPass.cpp +++ b/src/Nazara/Graphics/MaterialPass.cpp @@ -29,8 +29,7 @@ namespace Nz MaterialPass::MaterialPass(std::shared_ptr settings) : m_settings(std::move(settings)), m_forceCommandBufferRegeneration(false), - m_pipelineUpdated(false), - m_shaderBindingUpdated(false) + m_pipelineUpdated(false) { m_pipelineInfo.settings = m_settings; @@ -44,14 +43,14 @@ namespace Nz const auto& textureSettings = m_settings->GetTextures(); 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()); - for (const auto& uniformBufferInfo : m_settings->GetUniformBlocks()) + m_uniformBuffers.reserve(uboSettings.size()); + for (const auto& uniformBufferInfo : uboSettings) { 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)) throw std::runtime_error("failed to initialize UBO memory"); @@ -60,20 +59,10 @@ namespace Nz uniformBuffer.data.resize(uniformBufferInfo.blockSize); std::memcpy(uniformBuffer.data.data(), uniformBufferInfo.defaultValues.data(), uniformBufferInfo.defaultValues.size()); } - - UpdateShaderBinding(); } bool MaterialPass::Update(RenderFrame& renderFrame, CommandBufferBuilder& builder) { - if (!m_shaderBindingUpdated) - { - renderFrame.PushForRelease(std::move(m_shaderBinding)); - m_shaderBinding.reset(); - - UpdateShaderBinding(); - } - UploadPool& uploadPool = renderFrame.GetUploadPool(); for (auto& ubo : m_uniformBuffers) @@ -118,60 +107,4 @@ namespace Nz m_pipeline = MaterialPipeline::Get(m_pipelineInfo); 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 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; - } } diff --git a/src/Nazara/Graphics/PredefinedShaderStructs.cpp b/src/Nazara/Graphics/PredefinedShaderStructs.cpp index 3fede9eb5..e770704a7 100644 --- a/src/Nazara/Graphics/PredefinedShaderStructs.cpp +++ b/src/Nazara/Graphics/PredefinedShaderStructs.cpp @@ -8,7 +8,7 @@ namespace Nz { - PredefinedLightData PredefinedLightData::GetOffset() + PredefinedLightData PredefinedLightData::GetOffsets() { PredefinedLightData lightData; @@ -34,7 +34,7 @@ namespace Nz MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock() { - PredefinedLightData lightData = GetOffset(); + PredefinedLightData lightData = GetOffsets(); std::vector lightDataVariables; for (std::size_t i = 0; i < lightData.lightArray.size(); ++i) @@ -67,6 +67,27 @@ namespace Nz return instanceData; } + MaterialSettings::SharedUniformBlock PredefinedInstanceData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages) + { + PredefinedInstanceData instanceData = GetOffsets(); + + std::vector variables = { + { + { "WorldMatrix", instanceData.worldMatrixOffset }, + { "InvWorldMatrix", instanceData.invWorldMatrixOffset } + } + }; + + MaterialSettings::SharedUniformBlock uniformBlock = { + bindingIndex, + "InstanceData", + std::move(variables), + shaderStages + }; + + return uniformBlock; + } + PredefinedViewerData PredefinedViewerData::GetOffsets() { FieldOffsets viewerStruct(StructLayout::Std140); @@ -86,4 +107,33 @@ namespace Nz return viewerData; } + + MaterialSettings::SharedUniformBlock PredefinedViewerData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages) + { + PredefinedViewerData viewerData = GetOffsets(); + + std::vector 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; + } + } diff --git a/src/Nazara/Graphics/SpriteChainRenderer.cpp b/src/Nazara/Graphics/SpriteChainRenderer.cpp index da53e9f30..0dacec985 100644 --- a/src/Nazara/Graphics/SpriteChainRenderer.cpp +++ b/src/Nazara/Graphics/SpriteChainRenderer.cpp @@ -65,10 +65,10 @@ namespace Nz const VertexDeclaration* currentVertexDeclaration = nullptr; AbstractBuffer* currentVertexBuffer = nullptr; const RenderPipeline* currentPipeline = nullptr; - const ShaderBinding* currentDrawDataBinding = nullptr; - const ShaderBinding* currentInstanceBinding = nullptr; - const ShaderBinding* currentMaterialBinding = nullptr; + const ShaderBinding* currentShaderBinding = nullptr; const Texture* currentTextureOverlay = nullptr; + const ViewerInstance* currentViewerInstance = nullptr; + const WorldInstance* currentWorldInstance = nullptr; auto FlushDrawCall = [&]() { @@ -79,7 +79,7 @@ namespace Nz { FlushDrawCall(); - currentDrawDataBinding = nullptr; + currentShaderBinding = nullptr; }; auto Flush = [&]() @@ -122,24 +122,24 @@ namespace Nz currentVertexDeclaration = vertexDeclaration; } - if (currentPipeline != spriteChain.GetRenderPipeline()) + if (currentPipeline != &spriteChain.GetRenderPipeline()) { FlushDrawCall(); - currentPipeline = spriteChain.GetRenderPipeline(); + currentPipeline = &spriteChain.GetRenderPipeline(); } - if (currentMaterialBinding != &spriteChain.GetMaterialBinding()) + if (currentViewerInstance != &spriteChain.GetViewerInstance()) { 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 // which is far from being efficient, using some bindless could help (or at least instancing?) FlushDrawCall(); - currentInstanceBinding = &spriteChain.GetInstanceBinding(); + currentWorldInstance = &spriteChain.GetWorldInstance(); } if (currentTextureOverlay != spriteChain.GetTextureOverlay()) @@ -177,9 +177,9 @@ namespace Nz 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({ { 0, @@ -189,7 +189,7 @@ namespace Nz } }); - currentDrawDataBinding = drawDataBinding.get(); + currentShaderBinding = drawDataBinding.get(); data.shaderBindings.emplace_back(std::move(drawDataBinding)); } @@ -199,9 +199,7 @@ namespace Nz data.drawCalls.push_back(SpriteChainRendererData::DrawCall{ currentVertexBuffer, currentPipeline, - currentDrawDataBinding, - currentInstanceBinding, - currentMaterialBinding, + currentShaderBinding, 6 * firstQuadIndex, 0, }); @@ -263,9 +261,9 @@ namespace Nz const AbstractBuffer* currentVertexBuffer = nullptr; const RenderPipeline* currentPipeline = nullptr; - const ShaderBinding* currentDrawDataBinding = nullptr; - const ShaderBinding* currentInstanceBinding = nullptr; - const ShaderBinding* currentMaterialBinding = nullptr; + const ShaderBinding* currentShaderBinding = nullptr; + const ViewerInstance* currentViewerInstance = nullptr; + const WorldInstance* currentWorldInstance = nullptr; const RenderSpriteChain* firstSpriteChain = static_cast(elements[0]); auto it = data.drawCallPerElement.find(firstSpriteChain); @@ -289,22 +287,10 @@ namespace Nz currentPipeline = drawCall.renderPipeline; } - if (currentDrawDataBinding != drawCall.drawDataBinding) + if (currentShaderBinding != drawCall.shaderBinding) { - commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *drawCall.drawDataBinding); - currentDrawDataBinding = drawCall.drawDataBinding; - } - - 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.BindShaderBinding(0, *drawCall.shaderBinding); + currentShaderBinding = drawCall.shaderBinding; } commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex); diff --git a/src/Nazara/Graphics/ViewerInstance.cpp b/src/Nazara/Graphics/ViewerInstance.cpp index b39dc8cf7..d4aecf554 100644 --- a/src/Nazara/Graphics/ViewerInstance.cpp +++ b/src/Nazara/Graphics/ViewerInstance.cpp @@ -14,49 +14,39 @@ namespace Nz { ViewerInstance::ViewerInstance() : - m_invProjectionMatrix(Nz::Matrix4f::Identity()), - m_invViewProjMatrix(Nz::Matrix4f::Identity()), - m_invViewMatrix(Nz::Matrix4f::Identity()), - m_projectionMatrix(Nz::Matrix4f::Identity()), - m_viewProjMatrix(Nz::Matrix4f::Identity()), - m_viewMatrix(Nz::Matrix4f::Identity()), - m_targetSize(Nz::Vector2f(0.f, 0.f)), + m_invProjectionMatrix(Matrix4f::Identity()), + m_invViewProjMatrix(Matrix4f::Identity()), + m_invViewMatrix(Matrix4f::Identity()), + m_projectionMatrix(Matrix4f::Identity()), + m_viewProjMatrix(Matrix4f::Identity()), + m_viewMatrix(Matrix4f::Identity()), + m_targetSize(Vector2f(0.f, 0.f)), m_dataInvalided(true) { - Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets(); + PredefinedViewerData viewerUboOffsets = PredefinedViewerData::GetOffsets(); 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"); - - 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) { if (m_dataInvalided) { - Nz::PredefinedViewerData viewerDataOffsets = Nz::PredefinedViewerData::GetOffsets(); + PredefinedViewerData viewerDataOffsets = PredefinedViewerData::GetOffsets(); auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize); - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation(); - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation(); + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix; - Nz::AccessByOffset(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix; + AccessByOffset(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix; builder.CopyBuffer(allocation, m_viewerDataBuffer.get()); diff --git a/src/Nazara/Graphics/WorldInstance.cpp b/src/Nazara/Graphics/WorldInstance.cpp index 0ef10a809..97564a04e 100644 --- a/src/Nazara/Graphics/WorldInstance.cpp +++ b/src/Nazara/Graphics/WorldInstance.cpp @@ -14,25 +14,15 @@ namespace Nz { WorldInstance::WorldInstance() : - m_invWorldMatrix(Nz::Matrix4f::Identity()), - m_worldMatrix(Nz::Matrix4f::Identity()), + m_invWorldMatrix(Matrix4f::Identity()), + m_worldMatrix(Matrix4f::Identity()), m_dataInvalided(true) { PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets(); 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"); - - 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)