Graphics: Fix WorldInstance removal while being in use
This commit is contained in:
parent
03236b70c1
commit
5b1123b971
|
|
@ -28,8 +28,7 @@ namespace Nz
|
||||||
inline void DetachRenderable(const std::shared_ptr<InstancedRenderable>& renderable);
|
inline void DetachRenderable(const std::shared_ptr<InstancedRenderable>& renderable);
|
||||||
|
|
||||||
inline const std::vector<std::shared_ptr<InstancedRenderable>>& GetRenderables() const;
|
inline const std::vector<std::shared_ptr<InstancedRenderable>>& GetRenderables() const;
|
||||||
inline WorldInstance& GetWorldInstance();
|
inline const WorldInstancePtr& GetWorldInstance() const;
|
||||||
inline const WorldInstance& GetWorldInstance() const;
|
|
||||||
|
|
||||||
GraphicsComponent& operator=(const GraphicsComponent&) = default;
|
GraphicsComponent& operator=(const GraphicsComponent&) = default;
|
||||||
GraphicsComponent& operator=(GraphicsComponent&&) = default;
|
GraphicsComponent& operator=(GraphicsComponent&&) = default;
|
||||||
|
|
@ -39,7 +38,7 @@ namespace Nz
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<InstancedRenderable>> m_renderables;
|
std::vector<std::shared_ptr<InstancedRenderable>> m_renderables;
|
||||||
std::unique_ptr<WorldInstance> m_worldInstance;
|
WorldInstancePtr m_worldInstance;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
inline GraphicsComponent::GraphicsComponent()
|
inline GraphicsComponent::GraphicsComponent()
|
||||||
{
|
{
|
||||||
m_worldInstance = std::make_unique<WorldInstance>(); //< FIXME
|
m_worldInstance = std::make_shared<WorldInstance>(); //< FIXME: Use pools
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GraphicsComponent::AttachRenderable(std::shared_ptr<InstancedRenderable> renderable)
|
inline void GraphicsComponent::AttachRenderable(std::shared_ptr<InstancedRenderable> renderable)
|
||||||
|
|
@ -35,13 +35,8 @@ namespace Nz
|
||||||
return m_renderables;
|
return m_renderables;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline WorldInstance& GraphicsComponent::GetWorldInstance()
|
inline const WorldInstancePtr& GraphicsComponent::GetWorldInstance() const
|
||||||
{
|
{
|
||||||
return *m_worldInstance;
|
return m_worldInstance;
|
||||||
}
|
|
||||||
|
|
||||||
inline const WorldInstance& GraphicsComponent::GetWorldInstance() const
|
|
||||||
{
|
|
||||||
return *m_worldInstance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,12 @@ namespace Nz
|
||||||
void InvalidateViewer(AbstractViewer* viewerInstance) override;
|
void InvalidateViewer(AbstractViewer* viewerInstance) override;
|
||||||
void InvalidateWorldInstance(WorldInstance* worldInstance) override;
|
void InvalidateWorldInstance(WorldInstance* worldInstance) override;
|
||||||
|
|
||||||
void RegisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable) override;
|
void RegisterInstancedDrawable(WorldInstancePtr worldInstance, const InstancedRenderable* instancedRenderable) override;
|
||||||
void RegisterViewer(AbstractViewer* viewerInstance) override;
|
void RegisterViewer(AbstractViewer* viewerInstance) override;
|
||||||
|
|
||||||
void Render(RenderFrame& renderFrame) override;
|
void Render(RenderFrame& renderFrame) override;
|
||||||
|
|
||||||
void UnregisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable) override;
|
void UnregisterInstancedDrawable(const WorldInstancePtr& worldInstance, const InstancedRenderable* instancedRenderable) override;
|
||||||
void UnregisterViewer(AbstractViewer* viewerInstance) override;
|
void UnregisterViewer(AbstractViewer* viewerInstance) override;
|
||||||
|
|
||||||
ForwardFramePipeline& operator=(const ForwardFramePipeline&) = delete;
|
ForwardFramePipeline& operator=(const ForwardFramePipeline&) = delete;
|
||||||
|
|
@ -75,10 +75,11 @@ namespace Nz
|
||||||
|
|
||||||
std::unordered_map<AbstractViewer*, ViewerData> m_viewers;
|
std::unordered_map<AbstractViewer*, ViewerData> m_viewers;
|
||||||
std::unordered_map<MaterialPass*, MaterialData> m_materials;
|
std::unordered_map<MaterialPass*, MaterialData> m_materials;
|
||||||
std::unordered_map<WorldInstance*, std::unordered_map<const InstancedRenderable*, RenderableData>> m_renderables;
|
std::unordered_map<WorldInstancePtr, std::unordered_map<const InstancedRenderable*, RenderableData>> m_renderables;
|
||||||
std::unordered_set<AbstractViewer*> m_invalidatedViewerInstances;
|
std::unordered_set<AbstractViewer*> m_invalidatedViewerInstances;
|
||||||
std::unordered_set<MaterialPass*> m_invalidatedMaterials;
|
std::unordered_set<MaterialPass*> m_invalidatedMaterials;
|
||||||
std::unordered_set<WorldInstance*> m_invalidatedWorldInstances;
|
std::unordered_set<WorldInstance*> m_invalidatedWorldInstances;
|
||||||
|
std::unordered_set<WorldInstancePtr> m_removedWorldInstances;
|
||||||
std::vector<std::unique_ptr<RenderElement>> m_depthPrepassRenderElements;
|
std::vector<std::unique_ptr<RenderElement>> m_depthPrepassRenderElements;
|
||||||
std::vector<std::unique_ptr<RenderElement>> m_forwardRenderElements;
|
std::vector<std::unique_ptr<RenderElement>> m_forwardRenderElements;
|
||||||
std::vector<std::unique_ptr<ElementRenderer>> m_elementRenderers;
|
std::vector<std::unique_ptr<ElementRenderer>> m_elementRenderers;
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Graphics/Config.hpp>
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
|
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class AbstractViewer;
|
class AbstractViewer;
|
||||||
class InstancedRenderable;
|
class InstancedRenderable;
|
||||||
class RenderFrame;
|
class RenderFrame;
|
||||||
class WorldInstance;
|
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API FramePipeline
|
class NAZARA_GRAPHICS_API FramePipeline
|
||||||
{
|
{
|
||||||
|
|
@ -28,12 +28,12 @@ namespace Nz
|
||||||
virtual void InvalidateViewer(AbstractViewer* viewerInstance) = 0;
|
virtual void InvalidateViewer(AbstractViewer* viewerInstance) = 0;
|
||||||
virtual void InvalidateWorldInstance(WorldInstance* worldInstance) = 0;
|
virtual void InvalidateWorldInstance(WorldInstance* worldInstance) = 0;
|
||||||
|
|
||||||
virtual void RegisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable) = 0;
|
virtual void RegisterInstancedDrawable(WorldInstancePtr worldInstance, const InstancedRenderable* instancedRenderable) = 0;
|
||||||
virtual void RegisterViewer(AbstractViewer* viewerInstance) = 0;
|
virtual void RegisterViewer(AbstractViewer* viewerInstance) = 0;
|
||||||
|
|
||||||
virtual void Render(RenderFrame& renderFrame) = 0;
|
virtual void Render(RenderFrame& renderFrame) = 0;
|
||||||
|
|
||||||
virtual void UnregisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable) = 0;
|
virtual void UnregisterInstancedDrawable(const WorldInstancePtr& worldInstance, const InstancedRenderable* instancedRenderable) = 0;
|
||||||
virtual void UnregisterViewer(AbstractViewer* viewerInstance) = 0;
|
virtual void UnregisterViewer(AbstractViewer* viewerInstance) = 0;
|
||||||
|
|
||||||
FramePipeline& operator=(const FramePipeline&) = delete;
|
FramePipeline& operator=(const FramePipeline&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ namespace Nz
|
||||||
class CommandBufferBuilder;
|
class CommandBufferBuilder;
|
||||||
class MaterialSettings;
|
class MaterialSettings;
|
||||||
class UploadPool;
|
class UploadPool;
|
||||||
|
class WorldInstance;
|
||||||
|
|
||||||
|
using WorldInstancePtr = std::shared_ptr<WorldInstance>;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API WorldInstance
|
class NAZARA_GRAPHICS_API WorldInstance
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,10 @@ namespace Nz
|
||||||
m_invalidatedWorldInstances.insert(worldInstance);
|
m_invalidatedWorldInstances.insert(worldInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardFramePipeline::RegisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable)
|
void ForwardFramePipeline::RegisterInstancedDrawable(WorldInstancePtr worldInstance, const InstancedRenderable* instancedRenderable)
|
||||||
{
|
{
|
||||||
|
m_removedWorldInstances.erase(worldInstance);
|
||||||
|
|
||||||
auto& renderableMap = m_renderables[worldInstance];
|
auto& renderableMap = m_renderables[worldInstance];
|
||||||
if (auto it = renderableMap.find(instancedRenderable); it == renderableMap.end())
|
if (auto it = renderableMap.find(instancedRenderable); it == renderableMap.end())
|
||||||
{
|
{
|
||||||
|
|
@ -99,6 +101,9 @@ namespace Nz
|
||||||
{
|
{
|
||||||
Graphics* graphics = Graphics::Instance();
|
Graphics* graphics = Graphics::Instance();
|
||||||
|
|
||||||
|
renderFrame.PushForRelease(std::move(m_removedWorldInstances));
|
||||||
|
m_removedWorldInstances.clear();
|
||||||
|
|
||||||
if (m_rebuildFrameGraph)
|
if (m_rebuildFrameGraph)
|
||||||
{
|
{
|
||||||
renderFrame.PushForRelease(std::move(m_bakedFrameGraph));
|
renderFrame.PushForRelease(std::move(m_bakedFrameGraph));
|
||||||
|
|
@ -252,7 +257,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardFramePipeline::UnregisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable)
|
void ForwardFramePipeline::UnregisterInstancedDrawable(const WorldInstancePtr& worldInstance, const InstancedRenderable* instancedRenderable)
|
||||||
{
|
{
|
||||||
auto instanceIt = m_renderables.find(worldInstance);
|
auto instanceIt = m_renderables.find(worldInstance);
|
||||||
if (instanceIt == m_renderables.end())
|
if (instanceIt == m_renderables.end())
|
||||||
|
|
@ -267,7 +272,10 @@ namespace Nz
|
||||||
if (instancedRenderables.size() > 1)
|
if (instancedRenderables.size() > 1)
|
||||||
instancedRenderables.erase(renderableIt);
|
instancedRenderables.erase(renderableIt);
|
||||||
else
|
else
|
||||||
m_renderables.erase(worldInstance);
|
{
|
||||||
|
m_removedWorldInstances.insert(worldInstance);
|
||||||
|
m_renderables.erase(instanceIt);;
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
||||||
for (std::size_t i = 0; i < matCount; ++i)
|
for (std::size_t i = 0; i < matCount; ++i)
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,9 @@ namespace Nz
|
||||||
GraphicsComponent& entityGfx = registry.get<GraphicsComponent>(entity);
|
GraphicsComponent& entityGfx = registry.get<GraphicsComponent>(entity);
|
||||||
NodeComponent& entityNode = registry.get<NodeComponent>(entity);
|
NodeComponent& entityNode = registry.get<NodeComponent>(entity);
|
||||||
|
|
||||||
WorldInstance& worldInstance = entityGfx.GetWorldInstance();
|
const WorldInstancePtr& worldInstance = entityGfx.GetWorldInstance();
|
||||||
for (const auto& renderable : entityGfx.GetRenderables())
|
for (const auto& renderable : entityGfx.GetRenderables())
|
||||||
m_pipeline->RegisterInstancedDrawable(&worldInstance, renderable.get());
|
m_pipeline->RegisterInstancedDrawable(worldInstance, renderable.get());
|
||||||
|
|
||||||
m_invalidatedWorldNode.insert(entity);
|
m_invalidatedWorldNode.insert(entity);
|
||||||
|
|
||||||
|
|
@ -75,14 +75,14 @@ namespace Nz
|
||||||
|
|
||||||
graphicsEntity.onRenderableAttached.Connect(entityGfx.OnRenderableAttached, [this](GraphicsComponent* gfx, const std::shared_ptr<InstancedRenderable>& renderable)
|
graphicsEntity.onRenderableAttached.Connect(entityGfx.OnRenderableAttached, [this](GraphicsComponent* gfx, const std::shared_ptr<InstancedRenderable>& renderable)
|
||||||
{
|
{
|
||||||
WorldInstance& worldInstance = gfx->GetWorldInstance();
|
const WorldInstancePtr& worldInstance = gfx->GetWorldInstance();
|
||||||
m_pipeline->RegisterInstancedDrawable(&worldInstance, renderable.get());
|
m_pipeline->RegisterInstancedDrawable(worldInstance, renderable.get());
|
||||||
});
|
});
|
||||||
|
|
||||||
graphicsEntity.onRenderableDetach.Connect(entityGfx.OnRenderableDetach, [this](GraphicsComponent* gfx, const std::shared_ptr<InstancedRenderable>& renderable)
|
graphicsEntity.onRenderableDetach.Connect(entityGfx.OnRenderableDetach, [this](GraphicsComponent* gfx, const std::shared_ptr<InstancedRenderable>& renderable)
|
||||||
{
|
{
|
||||||
WorldInstance& worldInstance = gfx->GetWorldInstance();
|
const WorldInstancePtr& worldInstance = gfx->GetWorldInstance();
|
||||||
m_pipeline->UnregisterInstancedDrawable(&worldInstance, renderable.get());
|
m_pipeline->UnregisterInstancedDrawable(worldInstance, renderable.get());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -106,9 +106,9 @@ namespace Nz
|
||||||
m_invalidatedWorldNode.erase(entity);
|
m_invalidatedWorldNode.erase(entity);
|
||||||
|
|
||||||
GraphicsComponent& entityGfx = registry.get<GraphicsComponent>(entity);
|
GraphicsComponent& entityGfx = registry.get<GraphicsComponent>(entity);
|
||||||
WorldInstance& worldInstance = entityGfx.GetWorldInstance();
|
const WorldInstancePtr& worldInstance = entityGfx.GetWorldInstance();
|
||||||
for (const auto& renderable : entityGfx.GetRenderables())
|
for (const auto& renderable : entityGfx.GetRenderables())
|
||||||
m_pipeline->UnregisterInstancedDrawable(&worldInstance, renderable.get());
|
m_pipeline->UnregisterInstancedDrawable(worldInstance, renderable.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderSystem::OnNodeDestroy(entt::registry& registry, entt::entity entity)
|
void RenderSystem::OnNodeDestroy(entt::registry& registry, entt::entity entity)
|
||||||
|
|
@ -139,10 +139,10 @@ namespace Nz
|
||||||
const NodeComponent& entityNode = registry.get<const NodeComponent>(entity);
|
const NodeComponent& entityNode = registry.get<const NodeComponent>(entity);
|
||||||
GraphicsComponent& entityGraphics = registry.get<GraphicsComponent>(entity);
|
GraphicsComponent& entityGraphics = registry.get<GraphicsComponent>(entity);
|
||||||
|
|
||||||
WorldInstance& worldInstance = entityGraphics.GetWorldInstance();
|
const WorldInstancePtr& worldInstance = entityGraphics.GetWorldInstance();
|
||||||
worldInstance.UpdateWorldMatrix(entityNode.GetTransformMatrix());
|
worldInstance->UpdateWorldMatrix(entityNode.GetTransformMatrix());
|
||||||
|
|
||||||
m_pipeline->InvalidateWorldInstance(&worldInstance);
|
m_pipeline->InvalidateWorldInstance(worldInstance.get());
|
||||||
}
|
}
|
||||||
m_invalidatedWorldNode.clear();
|
m_invalidatedWorldNode.clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace Nz
|
||||||
m_worldMatrix(Nz::Matrix4f::Identity()),
|
m_worldMatrix(Nz::Matrix4f::Identity()),
|
||||||
m_dataInvalided(true)
|
m_dataInvalided(true)
|
||||||
{
|
{
|
||||||
Nz::PredefinedInstanceData instanceUboOffsets = Nz::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, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic))
|
||||||
|
|
@ -39,11 +39,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
if (m_dataInvalided)
|
if (m_dataInvalided)
|
||||||
{
|
{
|
||||||
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
|
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
||||||
|
|
||||||
auto& allocation = uploadPool.Allocate(m_instanceDataBuffer->GetSize());
|
auto& allocation = uploadPool.Allocate(m_instanceDataBuffer->GetSize());
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.worldMatrixOffset) = m_worldMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.worldMatrixOffset) = m_worldMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.invWorldMatrixOffset) = m_invWorldMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.invWorldMatrixOffset) = m_invWorldMatrix;
|
||||||
|
|
||||||
builder.CopyBuffer(allocation, m_instanceDataBuffer.get());
|
builder.CopyBuffer(allocation, m_instanceDataBuffer.get());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue