You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RenderPipeline.h

280 lines
12 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/RHI/DrawList.h>
#include <Atom/RPI.Public/Base.h>
#include <Atom/RPI.Public/Pass/ParentPass.h>
#include <Atom/RPI.Reflect/Pass/PassAsset.h>
#include <Atom/RPI.Reflect/Pass/PassTemplate.h>
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/map.h>
#include <AzFramework/Windowing/WindowBus.h>
namespace AZ
{
namespace RHI
{
class ShaderResourceGroup;
}
namespace RPI
{
class Scene;
class ShaderResourceGroup;
class AnyAsset;
class WindowContext;
enum class PipelineViewType
{
Unknown,
Persistent, // The view assigned to a pipeline view tag is persistent
Transient // The views assigned to a pipeline view tag are transient which only valid for a frame.
};
//! PipelineViews contains information about views used by the passes in the RenderPipeline.
//! If view type is persistent, list of views is limited to just one view
struct PipelineViews
{
PipelineViewTag m_viewTag;
PipelineViewType m_type;
PassesByDrawList m_passesByDrawList;
//! Views associated with the m_viewTag.
//! There should be only one view in the array if m_type is persistent.
//! And there might be more than one views if m_type is transient.
AZStd::vector<ViewPtr> m_views;
//! Combined DrawListTags collected from passes which are associated with this pipeline view.
RHI::DrawListMask m_drawListMask;
};
//! RenderPipeline describes how to render a scene. It has all the passes and views for rendering.
//! A scene may have several pipelines. Each pipeline have its own render frequency.
//! Pipeline can be disabled and it won't be rendered if it's disabled.
class RenderPipeline
{
friend class Scene;
public:
AZ_CLASS_ALLOCATOR(RenderPipeline, AZ::SystemAllocator, 0);
static RenderPipelinePtr CreateRenderPipeline(const RenderPipelineDescriptor& desc);
static RenderPipelinePtr CreateRenderPipelineFromAsset(Data::Asset<AnyAsset> pipelineAsset);
static RenderPipelinePtr CreateRenderPipelineForWindow(const RenderPipelineDescriptor& desc, const WindowContext& windowContext);
static RenderPipelinePtr CreateRenderPipelineForWindow(Data::Asset<AnyAsset> pipelineAsset, const WindowContext& windowContext);
// Data type for render pipeline's views' information
using PipelineViewMap = AZStd::map<PipelineViewTag, PipelineViews, AZNameSortAscending>;
//! Assign a view for a PipelineViewTag used in this pipeline.
//! This reference of this view will be saved until it's replaced in another SetPersistentView call.
void SetPersistentView(const PipelineViewTag& viewId, ViewPtr view);
//! Add a view for a PipelineViewTag used in this pipeline.
//! The view's reference will be only saved for rendering one frame and it will be cleared when the next frame starts.
//! This function should be used after OnStartFrame is called.
void AddTransientView(const PipelineViewTag& viewId, ViewPtr view);
//! Set a view to the default view tag.
//! It's the same as SetPersistentView(GetMainViewTag(), view)
void SetDefaultView(ViewPtr view);
//! Get the view for the default view tag.
//! It's the same as GetViews(GetMainViewTag()) and using first element.
ViewPtr GetDefaultView();
//! Set default view from an entity which should have a ViewProvider handler.
void SetDefaultViewFromEntity(EntityId entityId);
//! Check if this pipeline has the specified PipelineViewTag.
bool HasViewTag(const PipelineViewTag& viewTag) const;
//! Get the main view tag (the tag used for the default view).
PipelineViewTag GetMainViewTag() const;
//! Get views that are associated with specified view tag.
const AZStd::vector<ViewPtr>& GetViews(const PipelineViewTag& viewTag) const;
//! Get the draw list mask that are associated with specified view tag.
const RHI::DrawListMask& GetDrawListMask(const PipelineViewTag& viewTag) const;
//! Get this render pipeline's view information
const PipelineViewMap& GetPipelineViews() const;
//! Check whether this pipeline needs to be rendered in next tick
bool NeedsRender() const;
RenderPipelineId GetId() const;
const Ptr<ParentPass>& GetRootPass() const;
//! This function need to be called by Pass class when any passes are added/removed in this pipeline's pass tree.
void SetPassModified();
//! Notifies the pipeline it needs to recreate passes. Typical use case is for pass asset hot reloading.
void SetPassNeedsRecreate();
//! Update passes and views when any pass was modified which may affect pipeline views.
//! This function is automatically called when frame starts. User may call it manually when they expect to get up to date view information
//! after any pass changes.
void OnPassModified();
//! Check if this pipeline should be removed after a single execution.
bool IsExecuteOnce();
void RemoveFromScene();
Scene* GetScene() const;
//! return the window handle associated with this render pipeline if it's created for window
AzFramework::NativeWindowHandle GetWindowHandle() const;
//! Return the render settings that can be queried by passes to setup things like render target resolution
PipelineRenderSettings& GetRenderSettings();
const PipelineRenderSettings& GetRenderSettings() const;
//! Undoes runtime changes made to active render settings by reverting to original settings from the descriptor
void RevertRenderSettings();
//! Add this RenderPipeline to the next RPI system's RenderTick and it will be rendered once.
//! This function can be used for render a renderpipeline with desired frequence as its associated window/view
//! is expecting.
//! Note: the RenderPipeline will be only renderred once if this function is called multiple
//! time between two system ticks.
void AddToRenderTickOnce();
//! Add this RenderPipeline to RPI system's RenderTick and it will be rendered whenever
//! the RPI system's RenderTick is called.
//! The RenderPipeline is rendered per RenderTick by default unless AddToRenderTickOnce() was called.
void AddToRenderTick();
//! Disable render for this RenderPipeline
void RemoveFromRenderTick();
~RenderPipeline();
enum class RenderMode : uint8_t
{
RenderEveryTick, // Render at each RPI system render tick
RenderOnce, // Render once in next RPI system render tick
NoRender // Render disabled.
};
//! Get current render mode
RenderMode GetRenderMode() const;
//! Get draw filter tag
RHI::DrawFilterTag GetDrawFilterTag() const;
//! Get draw filter mask
RHI::DrawFilterMask GetDrawFilterMask() const;
//! Get the RenderPipelineDescriptor which was used to create this RenderPipeline
const RenderPipelineDescriptor& GetDescriptor() const;
// Helper functions to modify the passes of this render pipeline
//! Find a reference pass's location and add the new pass before the reference pass
//! After the new pass was inserted, the new pass and the reference pass are siblings
bool AddPassBefore(Ptr<Pass> newPass, const AZ::Name& referencePassName);
//! Find a reference pass's location and add the new pass after the reference pass
//! After the new pass was inserted, the new pass and the reference pass are siblings
bool AddPassAfter(Ptr<Pass> newPass, const AZ::Name& referencePassName);
//! Find the first pass with matching name in the render pipeline
//! Note: to find all the passes with matching name in this render pipeline,
//! use RPI::PassSystemInterface::Get()->ForEachPass() function instead.
Ptr<Pass> FindFirstPass(const AZ::Name& passName);
private:
RenderPipeline() = default;
static void InitializeRenderPipeline(RenderPipeline* pipeline, const RenderPipelineDescriptor& desc);
// Collect DrawListTags from passes that are using specified pipeline view
void CollectDrawListMaskForViews(PipelineViews& views);
// Build pipeline views from the pipeline pass tree. It's usually called when pass tree changed.
void BuildPipelineViews();
//////////////////////////////////////////////////
// Functions accessed by Scene class
void OnAddedToScene(Scene* scene);
void OnRemovedFromScene(Scene* scene);
// Called when this pipeline is about to be rendered
void OnStartFrame(float time);
// Called when the rendering of current frame is finished.
void OnFrameEnd();
// Find all the persistent views in this pipeline and add them and their DrawListMasks to the output map.
// if the view already exists in map, its DrawListMask will be combined to the existing one's
void CollectPersistentViews(AZStd::map<ViewPtr, RHI::DrawListMask>& outViewMasks) const;
void SetDrawFilterTag(RHI::DrawFilterTag);
// End of functions accessed by Scene class
//////////////////////////////////////////////////
RenderMode m_renderMode = RenderMode::RenderEveryTick;
// The Scene this pipeline was added to.
Scene* m_scene = nullptr;
// Pass tree which contains all the passes in this render pipeline.
Ptr<ParentPass> m_rootPass;
PipelineViewMap m_pipelineViewsByTag;
// RenderPipeline's name id, it will be used to identify the render pipeline when it's added to a Scene
RenderPipelineId m_nameId;
// Whether the pass tree was modified. It's used to trigger rebuild pipeline views when frame starts
bool m_wasPassModified = false;
// Whether the pipeline should recreate it's pass tree, for example in the case of pass asset hot reloading.
bool m_needsPassRecreate = false;
PipelineViewTag m_mainViewTag;
// Was the pipeline modified by Scene's feature processor
bool m_wasModifiedByScene = false;
// The window handle associated with this render pipeline if it's created for a window
AzFramework::NativeWindowHandle m_windowHandle = nullptr;
// Render settings that can be queried by passes to setup things like render target resolution
PipelineRenderSettings m_activeRenderSettings;
// A tag to filter draw items submitted by passes of this render pipeline.
// This tag is allocated when it's added to a scene. It's set to invalid when it's removed to the scene.
RHI::DrawFilterTag m_drawFilterTag;
// A mask to filter draw items submitted by passes of this render pipeline.
// This mask is created from the value of m_drawFilterTag.
RHI::DrawFilterMask m_drawFilterMask = 0;
// The descriptor used to created this render pipeline
RenderPipelineDescriptor m_descriptor;
};
} // namespace RPI
} // namespace AZ