Graphics: Fix issue when unregistering viewer then adding it again before resources are cleaned
This commit is contained in:
parent
5c7059c8fc
commit
db83413536
|
|
@ -16,6 +16,7 @@
|
||||||
#include <NazaraUtils/FixedVector.hpp>
|
#include <NazaraUtils/FixedVector.hpp>
|
||||||
#include <NazaraUtils/SparsePtr.hpp>
|
#include <NazaraUtils/SparsePtr.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
@ -79,6 +80,7 @@ namespace Nz
|
||||||
};
|
};
|
||||||
|
|
||||||
std::size_t m_cascadeCount;
|
std::size_t m_cascadeCount;
|
||||||
|
std::vector<std::unique_ptr<PerViewerData>> m_destructionQueue;
|
||||||
std::unordered_map<const AbstractViewer*, std::unique_ptr<PerViewerData>> m_viewerData;
|
std::unordered_map<const AbstractViewer*, std::unique_ptr<PerViewerData>> m_viewerData;
|
||||||
ElementRendererRegistry& m_elementRegistry;
|
ElementRendererRegistry& m_elementRegistry;
|
||||||
FramePipeline& m_pipeline;
|
FramePipeline& m_pipeline;
|
||||||
|
|
|
||||||
|
|
@ -142,12 +142,13 @@ namespace Nz
|
||||||
|
|
||||||
std::size_t finalColorAttachment;
|
std::size_t finalColorAttachment;
|
||||||
std::vector<std::unique_ptr<FramePipelinePass>> passes;
|
std::vector<std::unique_ptr<FramePipelinePass>> passes;
|
||||||
|
FrameData frame;
|
||||||
PipelineViewer* viewer;
|
PipelineViewer* viewer;
|
||||||
Int32 renderOrder = 0;
|
Int32 renderOrder = 0;
|
||||||
RenderQueueRegistry forwardRegistry;
|
RenderQueueRegistry forwardRegistry;
|
||||||
RenderQueue<RenderElement*> forwardRenderQueue;
|
RenderQueue<RenderElement*> forwardRenderQueue;
|
||||||
ShaderBindingPtr blitShaderBinding;
|
ShaderBindingPtr blitShaderBinding;
|
||||||
FrameData frame;
|
UInt32 renderMask;
|
||||||
bool pendingDestruction = false;
|
bool pendingDestruction = false;
|
||||||
|
|
||||||
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
||||||
|
|
@ -167,6 +168,7 @@ namespace Nz
|
||||||
robin_hood::unordered_set<TransferInterface*> m_transferSet;
|
robin_hood::unordered_set<TransferInterface*> m_transferSet;
|
||||||
BakedFrameGraph m_bakedFrameGraph;
|
BakedFrameGraph m_bakedFrameGraph;
|
||||||
Bitset<UInt64> m_activeLights;
|
Bitset<UInt64> m_activeLights;
|
||||||
|
Bitset<UInt64> m_removedLightInstances;
|
||||||
Bitset<UInt64> m_removedSkeletonInstances;
|
Bitset<UInt64> m_removedSkeletonInstances;
|
||||||
Bitset<UInt64> m_removedViewerInstances;
|
Bitset<UInt64> m_removedViewerInstances;
|
||||||
Bitset<UInt64> m_removedWorldInstances;
|
Bitset<UInt64> m_removedWorldInstances;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ namespace Nz
|
||||||
|
|
||||||
void DirectionalLightShadowData::PrepareRendering(RenderResources& renderResources, const AbstractViewer* viewer)
|
void DirectionalLightShadowData::PrepareRendering(RenderResources& renderResources, const AbstractViewer* viewer)
|
||||||
{
|
{
|
||||||
|
// Push unregistered viewers data for release
|
||||||
|
for (auto& perViewerData : m_destructionQueue)
|
||||||
|
renderResources.PushForRelease(std::move(perViewerData));
|
||||||
|
m_destructionQueue.clear();
|
||||||
|
|
||||||
assert(viewer);
|
assert(viewer);
|
||||||
PerViewerData& viewerData = *Retrieve(m_viewerData, viewer);
|
PerViewerData& viewerData = *Retrieve(m_viewerData, viewer);
|
||||||
|
|
||||||
|
|
@ -304,7 +309,11 @@ namespace Nz
|
||||||
|
|
||||||
void DirectionalLightShadowData::UnregisterViewer(const AbstractViewer* viewer)
|
void DirectionalLightShadowData::UnregisterViewer(const AbstractViewer* viewer)
|
||||||
{
|
{
|
||||||
m_viewerData.erase(viewer);
|
auto it = m_viewerData.find(viewer);
|
||||||
|
assert(it != m_viewerData.end());
|
||||||
|
|
||||||
|
m_destructionQueue.push_back(std::move(it->second));
|
||||||
|
m_viewerData.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ namespace Nz
|
||||||
if (viewerData.pendingDestruction)
|
if (viewerData.pendingDestruction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((viewerData.viewer->GetRenderMask() & lightData->renderMask) != 0)
|
if ((viewerData.renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->RegisterViewer(viewerData.viewer);
|
lightData->shadowData->RegisterViewer(viewerData.viewer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +140,7 @@ namespace Nz
|
||||||
if (viewerData.pendingDestruction)
|
if (viewerData.pendingDestruction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((viewerData.viewer->GetRenderMask() & lightData->renderMask) != 0)
|
if ((viewerData.renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->RegisterViewer(viewerData.viewer);
|
lightData->shadowData->RegisterViewer(viewerData.viewer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,9 +170,7 @@ namespace Nz
|
||||||
if (viewerData.pendingDestruction)
|
if (viewerData.pendingDestruction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
UInt32 viewerRenderMask = viewerData.viewer->GetRenderMask();
|
if (viewerData.renderMask & renderMask)
|
||||||
|
|
||||||
if (viewerRenderMask & renderMask)
|
|
||||||
{
|
{
|
||||||
for (auto& passPtr : viewerData.passes)
|
for (auto& passPtr : viewerData.passes)
|
||||||
{
|
{
|
||||||
|
|
@ -280,11 +278,11 @@ namespace Nz
|
||||||
|
|
||||||
m_transferSet.insert(&viewerInstance->GetViewerInstance());
|
m_transferSet.insert(&viewerInstance->GetViewerInstance());
|
||||||
|
|
||||||
UInt32 renderMask = viewerInstance->GetRenderMask();
|
viewerData.renderMask = viewerInstance->GetRenderMask();
|
||||||
for (std::size_t i : m_shadowCastingLights.IterBits())
|
for (std::size_t i : m_shadowCastingLights.IterBits())
|
||||||
{
|
{
|
||||||
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
if (lightData->shadowData->IsPerViewer() && (renderMask & lightData->renderMask) != 0)
|
if (lightData->shadowData->IsPerViewer() && (viewerData.renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->RegisterViewer(viewerInstance);
|
lightData->shadowData->RegisterViewer(viewerInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,9 +330,15 @@ namespace Nz
|
||||||
|
|
||||||
void ForwardFramePipeline::Render(RenderResources& renderResources)
|
void ForwardFramePipeline::Render(RenderResources& renderResources)
|
||||||
{
|
{
|
||||||
Graphics* graphics = Graphics::Instance();
|
|
||||||
|
|
||||||
// Destroy instances at the end of the frame
|
// Destroy instances at the end of the frame
|
||||||
|
|
||||||
|
for (std::size_t lightIndex : m_removedLightInstances.IterBits())
|
||||||
|
{
|
||||||
|
renderResources.PushForRelease(std::move(*m_lightPool.RetrieveFromIndex(lightIndex)));
|
||||||
|
m_lightPool.Free(lightIndex);
|
||||||
|
}
|
||||||
|
m_removedLightInstances.Clear();
|
||||||
|
|
||||||
for (std::size_t skeletonInstanceIndex : m_removedSkeletonInstances.IterBits())
|
for (std::size_t skeletonInstanceIndex : m_removedSkeletonInstances.IterBits())
|
||||||
{
|
{
|
||||||
renderResources.PushForRelease(std::move(*m_skeletonInstances.RetrieveFromIndex(skeletonInstanceIndex)));
|
renderResources.PushForRelease(std::move(*m_skeletonInstances.RetrieveFromIndex(skeletonInstanceIndex)));
|
||||||
|
|
@ -344,7 +348,8 @@ namespace Nz
|
||||||
|
|
||||||
for (std::size_t viewerIndex : m_removedViewerInstances.IterBits())
|
for (std::size_t viewerIndex : m_removedViewerInstances.IterBits())
|
||||||
{
|
{
|
||||||
renderResources.PushForRelease(std::move(*m_viewerPool.RetrieveFromIndex(viewerIndex)));
|
auto& viewerData = *m_viewerPool.RetrieveFromIndex(viewerIndex);
|
||||||
|
renderResources.PushForRelease(std::move(viewerData));
|
||||||
m_viewerPool.Free(viewerIndex);
|
m_viewerPool.Free(viewerIndex);
|
||||||
}
|
}
|
||||||
m_removedViewerInstances.Clear();
|
m_removedViewerInstances.Clear();
|
||||||
|
|
@ -385,8 +390,6 @@ namespace Nz
|
||||||
m_activeLights.Clear();
|
m_activeLights.Clear();
|
||||||
for (ViewerData* viewerData : m_orderedViewers)
|
for (ViewerData* viewerData : m_orderedViewers)
|
||||||
{
|
{
|
||||||
UInt32 renderMask = viewerData->viewer->GetRenderMask();
|
|
||||||
|
|
||||||
// Extract frustum from viewproj matrix
|
// Extract frustum from viewproj matrix
|
||||||
const Matrix4f& viewProjMatrix = viewerData->viewer->GetViewerInstance().GetViewProjMatrix();
|
const Matrix4f& viewProjMatrix = viewerData->viewer->GetViewerInstance().GetViewProjMatrix();
|
||||||
viewerData->frame.frustum = Frustumf::Extract(viewProjMatrix);
|
viewerData->frame.frustum = Frustumf::Extract(viewProjMatrix);
|
||||||
|
|
@ -397,7 +400,7 @@ namespace Nz
|
||||||
const LightData& lightData = *it;
|
const LightData& lightData = *it;
|
||||||
std::size_t lightIndex = it.GetIndex();
|
std::size_t lightIndex = it.GetIndex();
|
||||||
|
|
||||||
if ((lightData.renderMask & renderMask) == 0)
|
if ((lightData.renderMask & viewerData->renderMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_activeLights.UnboundedSet(lightIndex);
|
m_activeLights.UnboundedSet(lightIndex);
|
||||||
|
|
@ -418,19 +421,17 @@ namespace Nz
|
||||||
// Viewer handling (second pass)
|
// Viewer handling (second pass)
|
||||||
for (ViewerData* viewerData : m_orderedViewers)
|
for (ViewerData* viewerData : m_orderedViewers)
|
||||||
{
|
{
|
||||||
UInt32 renderMask = viewerData->viewer->GetRenderMask();
|
|
||||||
|
|
||||||
// Per-viewer shadow map handling
|
// Per-viewer shadow map handling
|
||||||
for (std::size_t lightIndex : viewerData->frame.visibleLights.IterBits())
|
for (std::size_t lightIndex : viewerData->frame.visibleLights.IterBits())
|
||||||
{
|
{
|
||||||
LightData* lightData = m_lightPool.RetrieveFromIndex(lightIndex);
|
LightData* lightData = m_lightPool.RetrieveFromIndex(lightIndex);
|
||||||
if (lightData->shadowData && lightData->shadowData->IsPerViewer() && (renderMask & lightData->renderMask) != 0)
|
if (lightData->shadowData && lightData->shadowData->IsPerViewer() && (viewerData->renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->PrepareRendering(renderResources, viewerData->viewer);
|
lightData->shadowData->PrepareRendering(renderResources, viewerData->viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frustum culling
|
// Frustum culling
|
||||||
std::size_t visibilityHash = 5;
|
std::size_t visibilityHash = 5;
|
||||||
const auto& visibleRenderables = FrustumCull(viewerData->frame.frustum, renderMask, visibilityHash);
|
const auto& visibleRenderables = FrustumCull(viewerData->frame.frustum, viewerData->renderMask, visibilityHash);
|
||||||
|
|
||||||
FramePipelinePass::FrameData passData = {
|
FramePipelinePass::FrameData passData = {
|
||||||
&viewerData->frame.visibleLights,
|
&viewerData->frame.visibleLights,
|
||||||
|
|
@ -472,7 +473,8 @@ namespace Nz
|
||||||
|
|
||||||
void ForwardFramePipeline::UnregisterLight(std::size_t lightIndex)
|
void ForwardFramePipeline::UnregisterLight(std::size_t lightIndex)
|
||||||
{
|
{
|
||||||
m_lightPool.Free(lightIndex);
|
m_removedLightInstances.UnboundedSet(lightIndex);
|
||||||
|
|
||||||
if (m_shadowCastingLights.UnboundedTest(lightIndex))
|
if (m_shadowCastingLights.UnboundedTest(lightIndex))
|
||||||
{
|
{
|
||||||
m_shadowCastingLights.Reset(lightIndex);
|
m_shadowCastingLights.Reset(lightIndex);
|
||||||
|
|
@ -517,11 +519,10 @@ namespace Nz
|
||||||
auto& viewerData = *m_viewerPool.RetrieveFromIndex(viewerIndex);
|
auto& viewerData = *m_viewerPool.RetrieveFromIndex(viewerIndex);
|
||||||
viewerData.pendingDestruction = true;
|
viewerData.pendingDestruction = true;
|
||||||
|
|
||||||
UInt32 renderMask = viewerData.viewer->GetRenderMask();
|
|
||||||
for (std::size_t i : m_shadowCastingLights.IterBits())
|
for (std::size_t i : m_shadowCastingLights.IterBits())
|
||||||
{
|
{
|
||||||
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
if (lightData->shadowData->IsPerViewer() && (renderMask & lightData->renderMask) != 0)
|
if (lightData->shadowData->IsPerViewer() && (viewerData.renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->UnregisterViewer(viewerData.viewer);
|
lightData->shadowData->UnregisterViewer(viewerData.viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,9 +560,7 @@ namespace Nz
|
||||||
if (viewerData.pendingDestruction)
|
if (viewerData.pendingDestruction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
UInt32 viewerRenderMask = viewerData.viewer->GetRenderMask();
|
if (viewerData.renderMask & renderableData->renderMask)
|
||||||
|
|
||||||
if (viewerRenderMask & renderableData->renderMask)
|
|
||||||
{
|
{
|
||||||
for (auto& passPtr : viewerData.passes)
|
for (auto& passPtr : viewerData.passes)
|
||||||
{
|
{
|
||||||
|
|
@ -583,9 +582,7 @@ namespace Nz
|
||||||
if (viewerData.pendingDestruction)
|
if (viewerData.pendingDestruction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
UInt32 viewerRenderMask = viewerData.viewer->GetRenderMask();
|
if (viewerData.renderMask & renderableData->renderMask)
|
||||||
|
|
||||||
if (viewerRenderMask & renderableData->renderMask)
|
|
||||||
{
|
{
|
||||||
for (auto& passPtr : viewerData.passes)
|
for (auto& passPtr : viewerData.passes)
|
||||||
{
|
{
|
||||||
|
|
@ -661,11 +658,10 @@ namespace Nz
|
||||||
|
|
||||||
for (ViewerData* viewerData : viewers)
|
for (ViewerData* viewerData : viewers)
|
||||||
{
|
{
|
||||||
UInt32 renderMask = viewerData->viewer->GetRenderMask();
|
|
||||||
for (std::size_t i : m_shadowCastingLights.IterBits())
|
for (std::size_t i : m_shadowCastingLights.IterBits())
|
||||||
{
|
{
|
||||||
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
if (lightData->shadowData->IsPerViewer() && (renderMask & lightData->renderMask) != 0)
|
if (lightData->shadowData->IsPerViewer() && (viewerData->renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->RegisterToFrameGraph(frameGraph, viewerData->viewer);
|
lightData->shadowData->RegisterToFrameGraph(frameGraph, viewerData->viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -681,7 +677,7 @@ namespace Nz
|
||||||
for (std::size_t i : m_shadowCastingLights.IterBits())
|
for (std::size_t i : m_shadowCastingLights.IterBits())
|
||||||
{
|
{
|
||||||
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
if ((renderMask & lightData->renderMask) != 0)
|
if ((viewerData->renderMask & lightData->renderMask) != 0)
|
||||||
lightData->shadowData->RegisterPassInputs(framePass, (lightData->shadowData->IsPerViewer()) ? viewerData->viewer : nullptr);
|
lightData->shadowData->RegisterPassInputs(framePass, (lightData->shadowData->IsPerViewer()) ? viewerData->viewer : nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue