Graphics: Replace RenderFrame by RenderResources
This changes makes the whole rendering independent from the RenderFrame acquired from the Swapchain. This may allow to do offscreen rendering (= without swapchain), or multi-window rendering in the future
This commit is contained in:
@@ -20,7 +20,7 @@ namespace Nz
|
||||
m_commandPool = renderDevice->InstantiateCommandPool(QueueType::Graphics);
|
||||
}
|
||||
|
||||
void BakedFrameGraph::Execute(RenderFrame& renderFrame)
|
||||
void BakedFrameGraph::Execute(RenderResources& renderResources)
|
||||
{
|
||||
for (auto& passData : m_passes)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace Nz
|
||||
case FramePassExecution::Skip:
|
||||
if (passData.commandBuffer)
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(passData.commandBuffer));
|
||||
renderResources.PushForRelease(std::move(passData.commandBuffer));
|
||||
passData.commandBuffer.reset();
|
||||
}
|
||||
continue; //< Skip the pass
|
||||
@@ -50,7 +50,7 @@ namespace Nz
|
||||
continue;
|
||||
|
||||
if (passData.commandBuffer)
|
||||
renderFrame.PushForRelease(std::move(passData.commandBuffer));
|
||||
renderResources.PushForRelease(std::move(passData.commandBuffer));
|
||||
|
||||
passData.commandBuffer = m_commandPool->BuildCommandBuffer([&](CommandBufferBuilder& builder)
|
||||
{
|
||||
@@ -66,9 +66,9 @@ namespace Nz
|
||||
builder.BeginDebugRegion(passData.name, Color::Green());
|
||||
|
||||
FramePassEnvironment env{
|
||||
*this,
|
||||
passData.renderRect,
|
||||
renderFrame
|
||||
.frameGraph = *this,
|
||||
.renderResources = renderResources,
|
||||
.renderRect = passData.renderRect
|
||||
};
|
||||
|
||||
bool first = true;
|
||||
@@ -95,7 +95,7 @@ namespace Nz
|
||||
for (auto& passData : m_passes)
|
||||
{
|
||||
if (passData.commandBuffer)
|
||||
renderFrame.SubmitCommandBuffer(passData.commandBuffer.get(), QueueType::Graphics);
|
||||
renderResources.SubmitCommandBuffer(passData.commandBuffer.get(), QueueType::Graphics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace Nz
|
||||
return m_passes[physicalPassIndex].renderPass;
|
||||
}
|
||||
|
||||
bool BakedFrameGraph::Resize(RenderFrame& renderFrame, std::span<Vector2ui> viewerTargetSizes)
|
||||
bool BakedFrameGraph::Resize(RenderResources& renderResources, std::span<Vector2ui> viewerTargetSizes)
|
||||
{
|
||||
if (std::equal(m_viewerSizes.begin(), m_viewerSizes.end(), viewerTargetSizes.begin(), viewerTargetSizes.end()))
|
||||
return false;
|
||||
@@ -159,10 +159,10 @@ namespace Nz
|
||||
for (auto& passData : m_passes)
|
||||
{
|
||||
if (passData.commandBuffer)
|
||||
renderFrame.PushForRelease(std::move(passData.commandBuffer));
|
||||
renderResources.PushForRelease(std::move(passData.commandBuffer));
|
||||
|
||||
if (passData.framebuffer)
|
||||
renderFrame.PushForRelease(std::move(passData.framebuffer));
|
||||
renderResources.PushForRelease(std::move(passData.framebuffer));
|
||||
}
|
||||
|
||||
for (auto& textureData : m_textures)
|
||||
@@ -177,7 +177,7 @@ namespace Nz
|
||||
continue;
|
||||
|
||||
// Dimensions changed, recreated texture
|
||||
renderFrame.PushForRelease(std::move(textureData.texture));
|
||||
renderResources.PushForRelease(std::move(textureData.texture));
|
||||
}
|
||||
|
||||
for (auto& textureData : m_textures)
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Nz
|
||||
{
|
||||
DebugDrawer& debugDrawer = m_pipeline.GetDebugDrawer();
|
||||
debugDrawer.SetViewerData(m_viewer->GetViewerInstance().GetViewProjMatrix());
|
||||
debugDrawer.Prepare(frameData.renderFrame);
|
||||
debugDrawer.Prepare(frameData.renderResources);
|
||||
}
|
||||
|
||||
FramePass& DebugDrawPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nz
|
||||
{
|
||||
if (m_lastVisibilityHash != frameData.visibilityHash || m_rebuildElements) //< FIXME
|
||||
{
|
||||
frameData.renderFrame.PushForRelease(std::move(m_renderElements));
|
||||
frameData.renderResources.PushForRelease(std::move(m_renderElements));
|
||||
m_renderElements.clear();
|
||||
|
||||
for (const auto& renderableData : frameData.visibleRenderables)
|
||||
@@ -67,7 +67,7 @@ namespace Nz
|
||||
m_elementRendererData[elementType] = elementRenderer.InstanciateData();
|
||||
}
|
||||
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], frameData.renderFrame);
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], frameData.renderResources);
|
||||
});
|
||||
|
||||
const auto& viewerInstance = m_viewer->GetViewerInstance();
|
||||
@@ -78,12 +78,12 @@ namespace Nz
|
||||
{
|
||||
ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
|
||||
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], frameData.renderFrame, elementCount, elements, SparsePtr(&defaultRenderStates, 0));
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], frameData.renderResources, elementCount, elements, SparsePtr(&defaultRenderStates, 0));
|
||||
});
|
||||
|
||||
m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
|
||||
{
|
||||
elementRenderer.PrepareEnd(frameData.renderFrame, *m_elementRendererData[elementType]);
|
||||
elementRenderer.PrepareEnd(frameData.renderResources, *m_elementRendererData[elementType]);
|
||||
});
|
||||
|
||||
m_rebuildCommandBuffer = true;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Nz
|
||||
UpdatePerViewerStatus(true);
|
||||
}
|
||||
|
||||
void DirectionalLightShadowData::PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer)
|
||||
void DirectionalLightShadowData::PrepareRendering(RenderResources& renderResources, const AbstractViewer* viewer)
|
||||
{
|
||||
assert(viewer);
|
||||
PerViewerData& viewerData = *Retrieve(m_viewerData, viewer);
|
||||
@@ -121,7 +121,7 @@ namespace Nz
|
||||
FramePipelinePass::FrameData passData = {
|
||||
nullptr,
|
||||
frustum,
|
||||
renderFrame,
|
||||
renderResources,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
@@ -9,15 +9,15 @@ namespace Nz
|
||||
{
|
||||
ElementRenderer::~ElementRenderer() = default;
|
||||
|
||||
void ElementRenderer::Prepare(const ViewerInstance& /*viewerInstance*/, ElementRendererData& /*rendererData*/, RenderFrame& /*currentFrame*/, std::size_t /*elementCount*/, const Pointer<const RenderElement>* /*elements*/, SparsePtr<const RenderStates> /*renderStates*/)
|
||||
void ElementRenderer::Prepare(const ViewerInstance& /*viewerInstance*/, ElementRendererData& /*rendererData*/, RenderResources& /*renderResources*/, std::size_t /*elementCount*/, const Pointer<const RenderElement>* /*elements*/, SparsePtr<const RenderStates> /*renderStates*/)
|
||||
{
|
||||
}
|
||||
|
||||
void ElementRenderer::PrepareEnd(RenderFrame& /*currentFrame*/, ElementRendererData& /*rendererData*/)
|
||||
void ElementRenderer::PrepareEnd(RenderResources& /*renderResources*/, ElementRendererData& /*rendererData*/)
|
||||
{
|
||||
}
|
||||
|
||||
void ElementRenderer::Reset(ElementRendererData& /*rendererData*/, RenderFrame& /*currentFrame*/)
|
||||
void ElementRenderer::Reset(ElementRendererData& /*rendererData*/, RenderResources& /*renderResources*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -341,30 +341,28 @@ namespace Nz
|
||||
return lightShadowData->RetrieveLightShadowmap(m_bakedFrameGraph, viewer);
|
||||
}
|
||||
|
||||
void ForwardFramePipeline::Render(RenderFrame& renderFrame)
|
||||
void ForwardFramePipeline::Render(RenderResources& renderResources)
|
||||
{
|
||||
m_currentRenderFrame = &renderFrame;
|
||||
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
// Destroy instances at the end of the frame
|
||||
for (std::size_t skeletonInstanceIndex : m_removedSkeletonInstances.IterBits())
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(*m_skeletonInstances.RetrieveFromIndex(skeletonInstanceIndex)));
|
||||
renderResources.PushForRelease(std::move(*m_skeletonInstances.RetrieveFromIndex(skeletonInstanceIndex)));
|
||||
m_skeletonInstances.Free(skeletonInstanceIndex);
|
||||
}
|
||||
m_removedSkeletonInstances.Clear();
|
||||
|
||||
for (std::size_t viewerIndex : m_removedViewerInstances.IterBits())
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(*m_viewerPool.RetrieveFromIndex(viewerIndex)));
|
||||
renderResources.PushForRelease(std::move(*m_viewerPool.RetrieveFromIndex(viewerIndex)));
|
||||
m_viewerPool.Free(viewerIndex);
|
||||
}
|
||||
m_removedViewerInstances.Clear();
|
||||
|
||||
for (std::size_t worldInstanceIndex : m_removedWorldInstances.IterBits())
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(*m_worldInstances.RetrieveFromIndex(worldInstanceIndex)));
|
||||
renderResources.PushForRelease(std::move(*m_worldInstances.RetrieveFromIndex(worldInstanceIndex)));
|
||||
m_worldInstances.Free(worldInstanceIndex);
|
||||
}
|
||||
m_removedWorldInstances.Clear();
|
||||
@@ -372,7 +370,7 @@ namespace Nz
|
||||
bool frameGraphInvalidated = false;
|
||||
if (m_rebuildFrameGraph)
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(m_bakedFrameGraph));
|
||||
renderResources.PushForRelease(std::move(m_bakedFrameGraph));
|
||||
m_bakedFrameGraph = BuildFrameGraph();
|
||||
frameGraphInvalidated = true;
|
||||
}
|
||||
@@ -384,7 +382,7 @@ namespace Nz
|
||||
viewerSizes.emplace_back(Vector2i(viewport.width, viewport.height));
|
||||
}
|
||||
|
||||
frameGraphInvalidated |= m_bakedFrameGraph.Resize(renderFrame, viewerSizes);
|
||||
frameGraphInvalidated |= m_bakedFrameGraph.Resize(renderResources, viewerSizes);
|
||||
|
||||
// Find active lights (i.e. visible in any frustum)
|
||||
m_activeLights.Clear();
|
||||
@@ -420,7 +418,7 @@ namespace Nz
|
||||
{
|
||||
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||
if (!lightData->shadowData->IsPerViewer())
|
||||
lightData->shadowData->PrepareRendering(renderFrame, nullptr);
|
||||
lightData->shadowData->PrepareRendering(renderResources, nullptr);
|
||||
}
|
||||
|
||||
// Viewer handling (second pass)
|
||||
@@ -436,7 +434,7 @@ namespace Nz
|
||||
{
|
||||
LightData* lightData = m_lightPool.RetrieveFromIndex(lightIndex);
|
||||
if (lightData->shadowData && lightData->shadowData->IsPerViewer() && (renderMask & lightData->renderMask) != 0)
|
||||
lightData->shadowData->PrepareRendering(renderFrame, viewerData.viewer);
|
||||
lightData->shadowData->PrepareRendering(renderResources, viewerData.viewer);
|
||||
}
|
||||
|
||||
// Frustum culling
|
||||
@@ -446,7 +444,7 @@ namespace Nz
|
||||
FramePipelinePass::FrameData passData = {
|
||||
&viewerData.frame.visibleLights,
|
||||
viewerData.frame.frustum,
|
||||
renderFrame,
|
||||
renderResources,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
@@ -464,7 +462,7 @@ namespace Nz
|
||||
continue;
|
||||
|
||||
if (viewerData.blitShaderBinding)
|
||||
renderFrame.PushForRelease(std::move(viewerData.blitShaderBinding));
|
||||
renderResources.PushForRelease(std::move(viewerData.blitShaderBinding));
|
||||
|
||||
viewerData.blitShaderBinding = graphics->GetBlitPipelineLayout()->AllocateShaderBinding(0);
|
||||
viewerData.blitShaderBinding->Update({
|
||||
@@ -480,33 +478,33 @@ namespace Nz
|
||||
}
|
||||
|
||||
// Update UBOs and materials
|
||||
renderFrame.Execute([&](CommandBufferBuilder& builder)
|
||||
renderResources.Execute([&](CommandBufferBuilder& builder)
|
||||
{
|
||||
builder.BeginDebugRegion("CPU to GPU transfers", Color::Yellow());
|
||||
{
|
||||
builder.PreTransferBarrier();
|
||||
|
||||
for (TransferInterface* transferInterface : m_transferSet)
|
||||
transferInterface->OnTransfer(renderFrame, builder);
|
||||
transferInterface->OnTransfer(renderResources, builder);
|
||||
m_transferSet.clear();
|
||||
|
||||
OnTransfer(this, renderFrame, builder);
|
||||
OnTransfer(this, renderResources, builder);
|
||||
|
||||
builder.PostTransferBarrier();
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
}, QueueType::Transfer);
|
||||
|
||||
m_bakedFrameGraph.Execute(renderFrame);
|
||||
m_bakedFrameGraph.Execute(renderResources);
|
||||
m_rebuildFrameGraph = false;
|
||||
|
||||
// Final blit (TODO: Make part of frame graph?)
|
||||
for (auto&& [renderTargetPtr, renderTargetData] : m_renderTargets)
|
||||
renderTargetPtr->OnRenderEnd(renderFrame, m_bakedFrameGraph, renderTargetData.finalAttachment);
|
||||
renderTargetPtr->OnRenderEnd(renderResources, m_bakedFrameGraph, renderTargetData.finalAttachment);
|
||||
|
||||
// reset at the end instead of the beginning so debug draw can be used before calling this method
|
||||
DebugDrawer& debugDrawer = GetDebugDrawer();
|
||||
debugDrawer.Reset(renderFrame);
|
||||
debugDrawer.Reset(renderResources);
|
||||
}
|
||||
|
||||
void ForwardFramePipeline::UnregisterLight(std::size_t lightIndex)
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Nz
|
||||
|
||||
if (m_lastVisibilityHash != frameData.visibilityHash || m_rebuildElements) //< FIXME
|
||||
{
|
||||
frameData.renderFrame.PushForRelease(std::move(m_renderElements));
|
||||
frameData.renderResources.PushForRelease(std::move(m_renderElements));
|
||||
m_renderElements.clear();
|
||||
|
||||
for (const auto& renderableData : frameData.visibleRenderables)
|
||||
@@ -85,7 +85,7 @@ namespace Nz
|
||||
return element->ComputeSortingScore(frameData.frustum, m_renderQueueRegistry);
|
||||
});
|
||||
|
||||
PrepareLights(frameData.renderFrame, frameData.frustum, *frameData.visibleLights);
|
||||
PrepareLights(frameData.renderResources, frameData.frustum, *frameData.visibleLights);
|
||||
|
||||
if (m_rebuildElements)
|
||||
{
|
||||
@@ -97,7 +97,7 @@ namespace Nz
|
||||
if (!m_elementRendererData[elementType])
|
||||
m_elementRendererData[elementType] = elementRenderer.InstanciateData();
|
||||
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], frameData.renderFrame);
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], frameData.renderResources);
|
||||
});
|
||||
|
||||
const auto& viewerInstance = m_viewer->GetViewerInstance();
|
||||
@@ -105,12 +105,12 @@ namespace Nz
|
||||
m_elementRegistry.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], frameData.renderFrame, elementCount, elements, SparsePtr(&m_renderState, 0));
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], frameData.renderResources, elementCount, elements, SparsePtr(&m_renderState, 0));
|
||||
});
|
||||
|
||||
m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
|
||||
{
|
||||
elementRenderer.PrepareEnd(frameData.renderFrame, *m_elementRendererData[elementType]);
|
||||
elementRenderer.PrepareEnd(frameData.renderResources, *m_elementRendererData[elementType]);
|
||||
});
|
||||
|
||||
m_rebuildCommandBuffer = true;
|
||||
@@ -202,7 +202,7 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void ForwardPipelinePass::OnTransfer(RenderFrame& /*renderFrame*/, CommandBufferBuilder& builder)
|
||||
void ForwardPipelinePass::OnTransfer(RenderResources& /*renderFrame*/, CommandBufferBuilder& builder)
|
||||
{
|
||||
assert(m_pendingLightUploadAllocation);
|
||||
builder.CopyBuffer(*m_pendingLightUploadAllocation, RenderBufferView(m_lightDataBuffer.get()));
|
||||
@@ -315,7 +315,7 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void ForwardPipelinePass::PrepareLights(RenderFrame& renderFrame, const Frustumf& frustum, const Bitset<UInt64>& visibleLights)
|
||||
void ForwardPipelinePass::PrepareLights(RenderResources& renderResources, const Frustumf& frustum, const Bitset<UInt64>& visibleLights)
|
||||
{
|
||||
// Select lights
|
||||
m_directionalLights.clear();
|
||||
@@ -352,7 +352,7 @@ namespace Nz
|
||||
return lhs.contributionScore < rhs.contributionScore;
|
||||
});
|
||||
|
||||
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
||||
UploadPool& uploadPool = renderResources.GetUploadPool();
|
||||
|
||||
auto& lightAllocation = uploadPool.Allocate(m_lightDataBuffer->GetSize());
|
||||
PrepareDirectionalLights(lightAllocation.mappedPtr);
|
||||
|
||||
@@ -224,9 +224,9 @@ namespace Nz
|
||||
return HasPass(passIndex);
|
||||
}
|
||||
|
||||
void MaterialInstance::OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||
void MaterialInstance::OnTransfer(RenderResources& renderResources, CommandBufferBuilder& builder)
|
||||
{
|
||||
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
||||
UploadPool& uploadPool = renderResources.GetUploadPool();
|
||||
for (UniformBuffer& uniformBuffer : m_uniformBuffers)
|
||||
{
|
||||
if (!uniformBuffer.dataInvalidated)
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Nz
|
||||
});
|
||||
}
|
||||
|
||||
void PointLightShadowData::PrepareRendering(RenderFrame& renderFrame, [[maybe_unused]] const AbstractViewer* viewer)
|
||||
void PointLightShadowData::PrepareRendering(RenderResources& renderResources, [[maybe_unused]] const AbstractViewer* viewer)
|
||||
{
|
||||
assert(viewer == nullptr);
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Nz
|
||||
FramePipelinePass::FrameData passData = {
|
||||
nullptr,
|
||||
frustum,
|
||||
renderFrame,
|
||||
renderResources,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Nz
|
||||
if (m_nextRenderPipeline)
|
||||
{
|
||||
if (m_renderPipeline)
|
||||
frameData.renderFrame.PushForRelease(std::move(m_renderPipeline));
|
||||
frameData.renderResources.PushForRelease(std::move(m_renderPipeline));
|
||||
|
||||
m_renderPipeline = std::move(m_nextRenderPipeline);
|
||||
m_rebuildFramePass = true;
|
||||
@@ -78,7 +78,7 @@ namespace Nz
|
||||
postProcess.SetCommandCallback([this, inputColorBufferIndex](CommandBufferBuilder& builder, const FramePassEnvironment& env)
|
||||
{
|
||||
if (m_shaderBinding)
|
||||
env.renderFrame.PushForRelease(std::move(m_shaderBinding));
|
||||
env.renderResources.PushForRelease(std::move(m_shaderBinding));
|
||||
|
||||
auto& samplerCache = Graphics::Instance()->GetSamplerCache();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nz
|
||||
graph.BindExternalTexture(attachmentIndex, m_targetTexture);
|
||||
}
|
||||
|
||||
void RenderTexture::OnRenderEnd(RenderFrame& /*renderFrame*/, const BakedFrameGraph& /*frameGraph*/, std::size_t /*finalAttachment*/) const
|
||||
void RenderTexture::OnRenderEnd(RenderResources& /*renderFrame*/, const BakedFrameGraph& /*frameGraph*/, std::size_t /*finalAttachment*/) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@ namespace Nz
|
||||
graph.AddOutput(attachmentIndex);
|
||||
}
|
||||
|
||||
void RenderTextureBlit::OnRenderEnd(RenderFrame& renderFrame, const BakedFrameGraph& frameGraph, std::size_t finalAttachment) const
|
||||
void RenderTextureBlit::OnRenderEnd(RenderResources& resources, const BakedFrameGraph& frameGraph, std::size_t finalAttachment) const
|
||||
{
|
||||
const std::shared_ptr<Texture>& sourceTexture = frameGraph.GetAttachmentTexture(finalAttachment);
|
||||
|
||||
Vector2ui sourceTextureSize = Vector2ui(sourceTexture->GetSize());
|
||||
Vector2ui targetTextureSize = Vector2ui(m_targetTexture->GetSize());
|
||||
|
||||
renderFrame.Execute([&](CommandBufferBuilder& builder)
|
||||
resources.Execute([&](CommandBufferBuilder& builder)
|
||||
{
|
||||
builder.BeginDebugRegion("Blit to texture", Color::Blue());
|
||||
{
|
||||
|
||||
@@ -36,19 +36,19 @@ namespace Nz
|
||||
graph.AddOutput(attachmentIndex);
|
||||
}
|
||||
|
||||
void RenderWindow::OnRenderEnd(RenderFrame& renderFrame, const BakedFrameGraph& frameGraph, std::size_t finalAttachment) const
|
||||
void RenderWindow::OnRenderEnd(RenderResources& renderResources, const BakedFrameGraph& frameGraph, std::size_t finalAttachment) const
|
||||
{
|
||||
const std::shared_ptr<Texture>& texture = frameGraph.GetAttachmentTexture(finalAttachment);
|
||||
|
||||
Vector2ui textureSize = Vector2ui(texture->GetSize());
|
||||
Boxui blitRegion(0, 0, 0, textureSize.x, textureSize.y, 1);
|
||||
|
||||
renderFrame.Execute([&](CommandBufferBuilder& builder)
|
||||
renderResources.Execute([&](CommandBufferBuilder& builder)
|
||||
{
|
||||
builder.BeginDebugRegion("Blit to swapchain", Color::Blue());
|
||||
{
|
||||
builder.TextureBarrier(PipelineStage::ColorOutput, PipelineStage::Transfer, MemoryAccess::ColorWrite, MemoryAccess::TransferRead, TextureLayout::ColorOutput, TextureLayout::TransferSource, *texture);
|
||||
builder.BlitTextureToSwapchain(*texture, blitRegion, TextureLayout::TransferSource, *m_swapchain, renderFrame.GetFramebufferIndex());
|
||||
builder.BlitTextureToSwapchain(*texture, blitRegion, TextureLayout::TransferSource, *m_swapchain, renderResources.GetImageIndex());
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
}, QueueType::Graphics);
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace Nz
|
||||
});
|
||||
}
|
||||
|
||||
void SkeletonInstance::OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||
void SkeletonInstance::OnTransfer(RenderResources& renderResources, CommandBufferBuilder& builder)
|
||||
{
|
||||
if (!m_dataInvalided)
|
||||
return;
|
||||
|
||||
auto& allocation = renderFrame.GetUploadPool().Allocate(m_skeletalDataBuffer->GetSize());
|
||||
auto& allocation = renderResources.GetUploadPool().Allocate(m_skeletalDataBuffer->GetSize());
|
||||
Matrix4f* matrices = AccessByOffset<Matrix4f*>(allocation.mappedPtr, PredefinedSkeletalOffsets.jointMatricesOffset);
|
||||
|
||||
for (std::size_t i = 0; i < m_skeleton->GetJointCount(); ++i)
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Nz
|
||||
});
|
||||
}
|
||||
|
||||
void SpotLightShadowData::PrepareRendering(RenderFrame& renderFrame, [[maybe_unused]] const AbstractViewer* viewer)
|
||||
void SpotLightShadowData::PrepareRendering(RenderResources& renderResources, [[maybe_unused]] const AbstractViewer* viewer)
|
||||
{
|
||||
assert(viewer == nullptr);
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Nz
|
||||
FramePipelinePass::FrameData passData = {
|
||||
nullptr,
|
||||
frustum,
|
||||
renderFrame,
|
||||
renderResources,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Nz
|
||||
return std::make_unique<SpriteChainRendererData>();
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates)
|
||||
void SpriteChainRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderResources& renderResources, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates)
|
||||
{
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Nz
|
||||
{
|
||||
if (!m_pendingData.currentAllocation)
|
||||
{
|
||||
m_pendingData.currentAllocation = ¤tFrame.GetUploadPool().Allocate(m_maxVertexBufferSize);
|
||||
m_pendingData.currentAllocation = &renderResources.GetUploadPool().Allocate(m_maxVertexBufferSize);
|
||||
m_pendingData.currentAllocationMemPtr = static_cast<UInt8*>(m_pendingData.currentAllocation->mappedPtr);
|
||||
|
||||
std::shared_ptr<RenderBuffer> vertexBuffer;
|
||||
@@ -258,13 +258,13 @@ namespace Nz
|
||||
data.drawCallPerElement[firstSpriteChain] = SpriteChainRendererData::DrawCallIndices{ oldDrawCallCount, drawCallCount };
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::PrepareEnd(RenderFrame& currentFrame, ElementRendererData& /*rendererData*/)
|
||||
void SpriteChainRenderer::PrepareEnd(RenderResources& renderResources, ElementRendererData& /*rendererData*/)
|
||||
{
|
||||
Flush();
|
||||
|
||||
if (!m_pendingCopies.empty())
|
||||
{
|
||||
currentFrame.Execute([&](CommandBufferBuilder& builder)
|
||||
renderResources.Execute([&](CommandBufferBuilder& builder)
|
||||
{
|
||||
for (auto& copy : m_pendingCopies)
|
||||
builder.CopyBuffer(*copy.allocation, copy.targetBuffer, copy.size);
|
||||
@@ -331,13 +331,13 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::Reset(ElementRendererData& rendererData, RenderFrame& currentFrame)
|
||||
void SpriteChainRenderer::Reset(ElementRendererData& rendererData, RenderResources& renderResources)
|
||||
{
|
||||
auto& data = static_cast<SpriteChainRendererData&>(rendererData);
|
||||
|
||||
for (auto& vertexBufferPtr : data.vertexBuffers)
|
||||
{
|
||||
currentFrame.PushReleaseCallback([pool = m_vertexBufferPool, vertexBuffer = std::move(vertexBufferPtr)]() mutable
|
||||
renderResources.PushReleaseCallback([pool = m_vertexBufferPool, vertexBuffer = std::move(vertexBufferPtr)]() mutable
|
||||
{
|
||||
pool->vertexBuffers.push_back(std::move(vertexBuffer));
|
||||
});
|
||||
@@ -345,7 +345,7 @@ namespace Nz
|
||||
data.vertexBuffers.clear();
|
||||
|
||||
for (auto& shaderBinding : data.shaderBindings)
|
||||
currentFrame.PushForRelease(std::move(shaderBinding));
|
||||
renderResources.PushForRelease(std::move(shaderBinding));
|
||||
data.shaderBindings.clear();
|
||||
|
||||
data.drawCalls.clear();
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Nz
|
||||
return std::make_unique<SubmeshRendererData>();
|
||||
}
|
||||
|
||||
void SubmeshRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& /*currentFrame*/, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates)
|
||||
void SubmeshRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderResources& /*renderResources*/, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates)
|
||||
{
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
@@ -346,12 +346,12 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void SubmeshRenderer::Reset(ElementRendererData& rendererData, RenderFrame& currentFrame)
|
||||
void SubmeshRenderer::Reset(ElementRendererData& rendererData, RenderResources& renderResources)
|
||||
{
|
||||
auto& data = static_cast<SubmeshRendererData&>(rendererData);
|
||||
|
||||
for (auto& shaderBinding : data.shaderBindings)
|
||||
currentFrame.PushForRelease(std::move(shaderBinding));
|
||||
renderResources.PushForRelease(std::move(shaderBinding));
|
||||
data.shaderBindings.clear();
|
||||
|
||||
data.drawCalls.clear();
|
||||
|
||||
@@ -31,14 +31,14 @@ namespace Nz
|
||||
m_viewerDataBuffer->UpdateDebugName("Viewer data");
|
||||
}
|
||||
|
||||
void ViewerInstance::OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||
void ViewerInstance::OnTransfer(RenderResources& renderResources, CommandBufferBuilder& builder)
|
||||
{
|
||||
if (!m_dataInvalidated)
|
||||
return;
|
||||
|
||||
constexpr auto& viewerDataOffsets = PredefinedViewerOffsets;
|
||||
|
||||
auto& allocation = renderFrame.GetUploadPool().Allocate(viewerDataOffsets.totalSize);
|
||||
auto& allocation = renderResources.GetUploadPool().Allocate(viewerDataOffsets.totalSize);
|
||||
AccessByOffset<Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_eyePosition;
|
||||
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
|
||||
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
|
||||
|
||||
@@ -25,14 +25,14 @@ namespace Nz
|
||||
m_instanceDataBuffer->UpdateDebugName("Instance data");
|
||||
}
|
||||
|
||||
void WorldInstance::OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||
void WorldInstance::OnTransfer(RenderResources& renderResources, CommandBufferBuilder& builder)
|
||||
{
|
||||
if (!m_dataInvalided)
|
||||
return;
|
||||
|
||||
constexpr auto& instanceUboOffsets = PredefinedInstanceOffsets;
|
||||
|
||||
auto& allocation = renderFrame.GetUploadPool().Allocate(m_instanceDataBuffer->GetSize());
|
||||
auto& allocation = renderResources.GetUploadPool().Allocate(m_instanceDataBuffer->GetSize());
|
||||
AccessByOffset<Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.worldMatrixOffset) = m_worldMatrix;
|
||||
AccessByOffset<Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.invWorldMatrixOffset) = m_invWorldMatrix;
|
||||
|
||||
|
||||
@@ -27,6 +27,11 @@ namespace Nz
|
||||
commandBuffer.Execute();
|
||||
}
|
||||
|
||||
UInt32 OpenGLRenderImage::GetImageIndex() const
|
||||
{
|
||||
return m_imageIndex;
|
||||
}
|
||||
|
||||
OpenGLUploadPool& OpenGLRenderImage::GetUploadPool()
|
||||
{
|
||||
return m_uploadPool;
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
namespace Nz
|
||||
{
|
||||
OpenGLSwapchain::OpenGLSwapchain(OpenGLDevice& device, WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) :
|
||||
m_currentFrame(0),
|
||||
m_device(device),
|
||||
m_framebuffer(*this),
|
||||
m_currentImageIndex(0),
|
||||
m_size(windowSize),
|
||||
m_sizeInvalidated(false)
|
||||
{
|
||||
@@ -90,7 +90,10 @@ namespace Nz
|
||||
bool sizeInvalidated = m_sizeInvalidated;
|
||||
m_sizeInvalidated = false;
|
||||
|
||||
return RenderFrame(m_renderImage[m_currentFrame].get(), sizeInvalidated, m_size, 0);
|
||||
OpenGLRenderImage& renderImage = *m_renderImage[m_currentImageIndex];
|
||||
renderImage.Reset(m_currentImageIndex);
|
||||
|
||||
return RenderFrame(&renderImage, sizeInvalidated, m_size);
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandPool> OpenGLSwapchain::CreateCommandPool(QueueType /*queueType*/)
|
||||
@@ -98,10 +101,8 @@ namespace Nz
|
||||
return std::make_shared<OpenGLCommandPool>();
|
||||
}
|
||||
|
||||
const OpenGLFramebuffer& OpenGLSwapchain::GetFramebuffer(std::size_t i) const
|
||||
const OpenGLFramebuffer& OpenGLSwapchain::GetFramebuffer(std::size_t /*imageIndex*/) const
|
||||
{
|
||||
assert(i == 0);
|
||||
NazaraUnused(i);
|
||||
return m_framebuffer;
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ namespace Nz
|
||||
void OpenGLSwapchain::Present()
|
||||
{
|
||||
m_context->SwapBuffers();
|
||||
m_currentFrame = (m_currentFrame + 1) % m_renderImage.size();
|
||||
m_currentImageIndex = (m_currentImageIndex + 1) % m_renderImage.size();
|
||||
}
|
||||
|
||||
void OpenGLSwapchain::SetPresentMode(PresentMode presentMode)
|
||||
@@ -155,8 +156,8 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
TransientResources& OpenGLSwapchain::Transient()
|
||||
RenderResources& OpenGLSwapchain::GetTransientResources()
|
||||
{
|
||||
return *m_renderImage[m_currentFrame];
|
||||
return *m_renderImage[m_currentImageIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDrawer::Prepare(RenderFrame& renderFrame)
|
||||
void DebugDrawer::Prepare(RenderResources& renderResources)
|
||||
{
|
||||
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
||||
UploadPool& uploadPool = renderResources.GetUploadPool();
|
||||
|
||||
if (!m_lineVertices.empty())
|
||||
{
|
||||
@@ -171,7 +171,7 @@ namespace Nz
|
||||
|
||||
if (m_viewerDataUpdated || !m_pendingUploads.empty())
|
||||
{
|
||||
renderFrame.Execute([&](CommandBufferBuilder& builder)
|
||||
renderResources.Execute([&](CommandBufferBuilder& builder)
|
||||
{
|
||||
builder.BeginDebugRegion("Debug drawer upload", Color::Yellow());
|
||||
{
|
||||
@@ -196,12 +196,12 @@ namespace Nz
|
||||
m_viewerDataUpdated = false;
|
||||
}
|
||||
|
||||
void DebugDrawer::Reset(RenderFrame& renderFrame)
|
||||
void DebugDrawer::Reset(RenderResources& renderResources)
|
||||
{
|
||||
if (m_currentViewerData.binding)
|
||||
{
|
||||
// keep pipeline layout alive as needs to stay alive until all shader bindings have been freed
|
||||
renderFrame.PushReleaseCallback([pool = m_dataPool, data = std::move(m_currentViewerData), pipelineLayout = m_renderPipelineLayout]() mutable
|
||||
renderResources.PushReleaseCallback([pool = m_dataPool, data = std::move(m_currentViewerData), pipelineLayout = m_renderPipelineLayout]() mutable
|
||||
{
|
||||
pool->viewerData.push_back(std::move(data));
|
||||
});
|
||||
@@ -210,7 +210,7 @@ namespace Nz
|
||||
|
||||
for (auto& drawCall : m_drawCalls)
|
||||
{
|
||||
renderFrame.PushReleaseCallback([pool = m_dataPool, buffer = std::move(drawCall.vertexBuffer)]() mutable
|
||||
renderResources.PushReleaseCallback([pool = m_dataPool, buffer = std::move(drawCall.vertexBuffer)]() mutable
|
||||
{
|
||||
pool->vertexBuffers.push_back(std::move(buffer));
|
||||
});
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/TransientResources.hpp>
|
||||
#include <Nazara/Renderer/RenderResources.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
TransientResources::~TransientResources()
|
||||
RenderResources::~RenderResources()
|
||||
{
|
||||
FlushReleaseQueue();
|
||||
}
|
||||
|
||||
TransientResources::Releasable::~Releasable() = default;
|
||||
RenderResources::Releasable::~Releasable() = default;
|
||||
}
|
||||
@@ -53,6 +53,11 @@ namespace Nz
|
||||
SubmitCommandBuffer(commandBuffer, queueTypeFlags);
|
||||
}
|
||||
|
||||
UInt32 VulkanRenderImage::GetImageIndex() const
|
||||
{
|
||||
return m_imageIndex;
|
||||
}
|
||||
|
||||
VulkanUploadPool& VulkanRenderImage::GetUploadPool()
|
||||
{
|
||||
return m_uploadPool;
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace Nz
|
||||
|
||||
currentFrame.Reset(imageIndex);
|
||||
|
||||
return RenderFrame(¤tFrame, invalidateFramebuffer, m_swapchainSize, imageIndex);
|
||||
return RenderFrame(¤tFrame, invalidateFramebuffer, m_swapchainSize);
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandPool> VulkanSwapchain::CreateCommandPool(QueueType queueType)
|
||||
@@ -324,6 +324,11 @@ namespace Nz
|
||||
return m_supportedPresentModes;
|
||||
}
|
||||
|
||||
RenderResources& VulkanSwapchain::GetTransientResources()
|
||||
{
|
||||
return *m_concurrentImageData[m_currentFrame];
|
||||
}
|
||||
|
||||
void VulkanSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||
{
|
||||
OnSwapchainResize(this, newSize);
|
||||
@@ -375,11 +380,6 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
TransientResources& VulkanSwapchain::Transient()
|
||||
{
|
||||
return *m_concurrentImageData[m_currentFrame];
|
||||
}
|
||||
|
||||
bool VulkanSwapchain::SetupDepthBuffer()
|
||||
{
|
||||
VkImageCreateInfo imageCreateInfo = {
|
||||
|
||||
Reference in New Issue
Block a user