Graphics: Rework RenderTargets

- RenderTarget have been moved to the Graphics module and are now lightweight objects between the target of rendering (swapchain or texture)
- RenderTexture no longer require a blit between the framegraph texture and the target texture (the target texture is now directly rendered onto using a new feature of the framegraph)
- ForwardFramePipeline viewers are now properly ordered by render order
This commit is contained in:
SirLynix
2023-11-20 23:00:06 +01:00
parent d06f9bda89
commit 938ba09d45
41 changed files with 445 additions and 254 deletions

View File

@@ -10,10 +10,10 @@
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/PipelineViewer.hpp>
#include <Nazara/Graphics/RenderTarget.hpp>
#include <Nazara/Graphics/ViewerInstance.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
namespace Nz
{
@@ -22,8 +22,8 @@ namespace Nz
class NAZARA_GRAPHICS_API Camera : public PipelineViewer
{
public:
inline Camera(const RenderTarget* renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType = ProjectionType::Perspective);
Camera(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
inline Camera(std::shared_ptr<const RenderTarget> renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType = ProjectionType::Perspective);
Camera(std::shared_ptr<const RenderTarget> renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
inline Camera(const Camera& camera);
inline Camera(Camera&& camera) noexcept;
~Camera() = default;
@@ -53,7 +53,7 @@ namespace Nz
inline void UpdateRenderMask(UInt32 renderMask);
inline void UpdateRenderOrder(Int32 renderOrder);
inline void UpdateSize(const Vector2f& size);
void UpdateTarget(const RenderTarget* framebuffer);
void UpdateTarget(std::shared_ptr<const RenderTarget> renderTarget);
inline void UpdateTargetRegion(const Rectf& targetRegion);
inline void UpdateViewport(const Recti& viewport);
inline void UpdateZFar(float zFar);
@@ -71,7 +71,7 @@ namespace Nz
NazaraSlot(RenderTarget, OnRenderTargetSizeChange, m_onRenderTargetSizeChange);
std::shared_ptr<PipelinePassList> m_framePipelinePasses;
const RenderTarget* m_renderTarget;
std::shared_ptr<const RenderTarget> m_renderTarget;
Color m_clearColor;
DegreeAnglef m_fov;
Int32 m_renderOrder;

View File

@@ -7,9 +7,8 @@
namespace Nz
{
inline Camera::Camera(const RenderTarget* renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType) :
inline Camera::Camera(std::shared_ptr<const RenderTarget> renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType) :
m_framePipelinePasses(std::move(pipelinePasses)),
m_renderTarget(nullptr),
m_clearColor(Color::Black()),
m_fov(90.f),
m_renderOrder(0),
@@ -21,12 +20,11 @@ namespace Nz
m_zFar((projectionType == ProjectionType::Perspective) ? 1000.f : 1.f),
m_zNear((projectionType == ProjectionType::Perspective) ? 1.f : -1.f)
{
UpdateTarget(renderTarget);
UpdateTarget(std::move(renderTarget));
}
inline Camera::Camera(const Camera& camera) :
m_framePipelinePasses(camera.m_framePipelinePasses),
m_renderTarget(nullptr),
m_clearColor(camera.m_clearColor),
m_fov(camera.m_fov),
m_renderOrder(camera.m_renderOrder),
@@ -44,7 +42,6 @@ namespace Nz
inline Camera::Camera(Camera&& camera) noexcept :
m_framePipelinePasses(std::move(camera.m_framePipelinePasses)),
m_renderTarget(nullptr),
m_clearColor(camera.m_clearColor),
m_fov(camera.m_fov),
m_renderOrder(camera.m_renderOrder),
@@ -57,7 +54,7 @@ namespace Nz
m_zFar(camera.m_zFar),
m_zNear(camera.m_zNear)
{
UpdateTarget(camera.m_renderTarget);
UpdateTarget(std::move(camera.m_renderTarget));
}
inline float Camera::GetAspectRatio() const

View File

@@ -80,7 +80,7 @@ namespace Nz
ForwardFramePipeline& operator=(ForwardFramePipeline&&) = delete;
private:
BakedFrameGraph BuildFrameGraph(RenderFrame& renderFrame);
BakedFrameGraph BuildFrameGraph();
void RegisterMaterialInstance(MaterialInstance* materialPass);
void UnregisterMaterialInstance(MaterialInstance* material);

View File

@@ -39,10 +39,11 @@ namespace Nz
inline std::size_t AddAttachmentCubeFace(std::size_t attachmentId, CubemapFace face);
inline std::size_t AddAttachmentProxy(std::string name, std::size_t attachmentId);
inline FramePass& AddPass(std::string name);
inline void AddBackbufferOutput(std::size_t attachmentIndex);
BakedFrameGraph Bake();
inline void MarkAsFinalOutput(std::size_t attachmentIndex);
inline void BindAttachmentToExternalTexture(std::size_t attachmentIndex, std::shared_ptr<Texture> texture);
FrameGraph& operator=(const FrameGraph&) = delete;
FrameGraph& operator=(FrameGraph&&) noexcept = default;
@@ -139,9 +140,10 @@ namespace Nz
using AttachmentType = std::variant<FramePassAttachment, AttachmentProxy, AttachmentArray, AttachmentCube, AttachmentLayer>;
std::vector<std::size_t> m_finalOutputs;
std::vector<std::size_t> m_backbufferOutputs;
std::vector<FramePass> m_framePasses;
std::vector<AttachmentType> m_attachments;
std::unordered_map<std::size_t, std::shared_ptr<Texture>> m_externalTextures;
WorkData m_pending;
};
}

View File

@@ -84,9 +84,14 @@ namespace Nz
return m_framePasses.emplace_back(*this, id, std::move(name));
}
inline void FrameGraph::MarkAsFinalOutput(std::size_t attachmentIndex)
inline void FrameGraph::AddBackbufferOutput(std::size_t attachmentIndex)
{
m_finalOutputs.push_back(attachmentIndex);
m_backbufferOutputs.push_back(attachmentIndex);
}
inline void FrameGraph::BindAttachmentToExternalTexture(std::size_t attachmentIndex, std::shared_ptr<Texture> texture)
{
m_externalTextures[attachmentIndex] = std::move(texture);
}
}

View File

@@ -16,6 +16,8 @@
namespace Nz
{
class Texture;
struct FrameGraphTextureData
{
struct ViewData
@@ -25,6 +27,7 @@ namespace Nz
};
std::optional<ViewData> viewData;
std::shared_ptr<Texture> externalTexture;
std::string name;
ImageType type;
PixelFormat format;

View File

@@ -97,8 +97,8 @@ namespace Nz
struct Output
{
std::size_t attachmentId;
std::optional<Color> clearColor;
std::size_t attachmentId;
};
private:

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_RENDERTARGET_HPP
#define NAZARA_GRAPHICS_RENDERTARGET_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <NazaraUtils/Signal.hpp>
namespace Nz
{
class BakedFrameGraph;
class CommandBufferBuilder;
class Framebuffer;
class FrameGraph;
class RenderFrame;
class RenderPass;
class Texture;
class NAZARA_GRAPHICS_API RenderTarget
{
public:
RenderTarget() = default;
virtual ~RenderTarget();
virtual void OnBuildGraph(FrameGraph& frameGraph, std::size_t attachmentIndex) const = 0;
virtual void OnRenderEnd(RenderFrame& renderFrame, const BakedFrameGraph& frameGraph, std::size_t finalAttachment) const = 0;
virtual const Vector2ui& GetSize() const = 0;
NazaraSignal(OnRenderTargetRelease, const RenderTarget* /*renderTarget*/);
NazaraSignal(OnRenderTargetSizeChange, const RenderTarget* /*renderTarget*/, const Vector2ui& /*newSize*/);
};
}
#include <Nazara/Graphics/RenderTarget.inl>
#endif // NAZARA_GRAPHICS_RENDERTARGET_HPP

View File

@@ -0,0 +1,11 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -0,0 +1,47 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_RENDERTEXTURE_HPP
#define NAZARA_GRAPHICS_RENDERTEXTURE_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/RenderTarget.hpp>
#include <Nazara/Renderer/Enums.hpp>
namespace Nz
{
class Texture;
class NAZARA_GRAPHICS_API RenderTexture : public RenderTarget
{
public:
inline RenderTexture(std::shared_ptr<Texture> targetTexture);
RenderTexture(std::shared_ptr<Texture> targetTexture, PipelineStage targetPipelineStage, MemoryAccessFlags targetMemoryFlags, TextureLayout targetLayout);
RenderTexture(const RenderTexture&) = delete;
RenderTexture(RenderTexture&&) = delete;
~RenderTexture() = default;
void OnBuildGraph(FrameGraph& graph, std::size_t attachmentIndex) const override;
void OnRenderEnd(RenderFrame& renderFrame, const BakedFrameGraph& frameGraph, std::size_t finalAttachment) const override;
const Vector2ui& GetSize() const override;
RenderTexture& operator=(const RenderTexture&) = delete;
RenderTexture& operator=(RenderTexture&&) = delete;
private:
std::shared_ptr<Texture> m_targetTexture;
MemoryAccessFlags m_targetMemoryFlags;
PipelineStage m_targetPipelineStage;
TextureLayout m_targetLayout;
Vector2ui m_textureSize;
};
}
#include <Nazara/Graphics/RenderTexture.inl>
#endif // NAZARA_GRAPHICS_RENDERTEXTURE_HPP

View File

@@ -0,0 +1,15 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline RenderTexture::RenderTexture(std::shared_ptr<Texture> targetTexture) :
RenderTexture(std::move(targetTexture), PipelineStage::FragmentShader, MemoryAccess::ColorRead, TextureLayout::ColorInput)
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_RENDERWINDOW_HPP
#define NAZARA_GRAPHICS_RENDERWINDOW_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/RenderTarget.hpp>
#include <Nazara/Renderer/WindowSwapchain.hpp>
namespace Nz
{
class FrameGraph;
class NAZARA_GRAPHICS_API RenderWindow : public RenderTarget
{
public:
inline RenderWindow(Swapchain& swapchain);
RenderWindow(WindowSwapchain& windowSwapchain);
RenderWindow(const RenderWindow&) = delete;
RenderWindow(RenderWindow&&) = delete;
~RenderWindow() = default;
void OnBuildGraph(FrameGraph& graph, std::size_t attachmentIndex) const override;
void OnRenderEnd(RenderFrame& renderFrame, const BakedFrameGraph& frameGraph, std::size_t attachmentId) const override;
const Vector2ui& GetSize() const override;
RenderWindow& operator=(const RenderWindow&) = delete;
RenderWindow& operator=(RenderWindow&&) = delete;
private:
void SetSwapchain(Swapchain* swapchain);
NazaraSlot(Swapchain, OnSwapchainResize, m_onSwapchainResize);
NazaraSlot(WindowSwapchain, OnSwapchainCreated, m_onSwapchainCreated);
NazaraSlot(WindowSwapchain, OnSwapchainDestroy, m_onSwapchainDestroy);
Swapchain* m_swapchain;
WindowSwapchain* m_windowSwapchain;
};
}
#include <Nazara/Graphics/RenderWindow.inl>
#endif // NAZARA_GRAPHICS_RENDERWINDOW_HPP

View File

@@ -0,0 +1,16 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline RenderWindow::RenderWindow(Swapchain& swapchain) :
m_swapchain(&swapchain),
m_windowSwapchain(nullptr)
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>