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.
659 lines
31 KiB
C++
659 lines
31 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/RPI.Public/Base.h>
|
|
#include <Atom/RPI.Public/Buffer/Buffer.h>
|
|
#include <Atom/RPI.Public/GpuQuery/GpuQuerySystemInterface.h>
|
|
#include <Atom/RPI.Reflect/Image/Image.h>
|
|
#include <Atom/RPI.Public/Image/AttachmentImage.h>
|
|
#include <Atom/RPI.Public/Image/AttachmentImage.h>
|
|
#include <Atom/RPI.Public/Pass/PassAttachment.h>
|
|
#include <Atom/RPI.Public/Pass/PassDefines.h>
|
|
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
|
|
|
|
#include <Atom/RPI.Reflect/Pass/PassAsset.h>
|
|
#include <Atom/RPI.Reflect/Pass/PassDescriptor.h>
|
|
|
|
#include <Atom/RHI/DrawList.h>
|
|
#include <Atom/RHI.Reflect/Limits.h>
|
|
#include <Atom/RHI.Reflect/Scissor.h>
|
|
#include <Atom/RHI.Reflect/Viewport.h>
|
|
|
|
#include <AzCore/std/containers/span.h>
|
|
|
|
#include <AzCore/Memory/SystemAllocator.h>
|
|
#include <AzCore/std/containers/map.h>
|
|
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
|
|
|
#define AZ_RPI_PASS(PASS_NAME) \
|
|
friend class PassFactory; \
|
|
friend class PassLibrary; \
|
|
friend class PassSystem; \
|
|
friend class PassFactory; \
|
|
friend class ParentPass; \
|
|
friend class RenderPipeline; \
|
|
friend class UnitTest::PassTests; \
|
|
|
|
namespace UnitTest
|
|
{
|
|
class PassTests;
|
|
}
|
|
|
|
namespace AZ
|
|
{
|
|
namespace RHI
|
|
{
|
|
class FrameGraphBuilder;
|
|
class FrameGraphAttachmentInterface;
|
|
}
|
|
|
|
namespace RPI
|
|
{
|
|
class Pass;
|
|
class PassTemplate;
|
|
struct PassRequest;
|
|
struct PassValidationResults;
|
|
class AttachmentReadback;
|
|
class ImageAttachmentCopy;
|
|
|
|
using SortedPipelineViewTags = AZStd::set<PipelineViewTag, AZNameSortAscending>;
|
|
using PassesByDrawList = AZStd::map<RHI::DrawListTag, const Pass*>;
|
|
|
|
const uint32_t PassAttachmentBindingCountMax = 32;
|
|
const uint32_t PassInputBindingCountMax = 16;
|
|
const uint32_t PassInputOutputBindingCountMax = PassInputBindingCountMax;
|
|
const uint32_t PassOutputBindingCountMax = PassInputBindingCountMax;
|
|
|
|
enum class PassAttachmentReadbackOption : uint8_t
|
|
{
|
|
Input = 0,
|
|
Output
|
|
};
|
|
|
|
//! Atom's base pass class (every pass class in Atom must derive from this class).
|
|
//!
|
|
//! Passes are organized into a tree hierarchy with the derived ParentPass class.
|
|
//! The root of the entire hierarchy is owned by the PassSystem.
|
|
//!
|
|
//! When authoring a new pass class, inherit from Pass and override any of the virtual functions
|
|
//! ending with 'Internal' to define the behavior of your passes. These virtual are recursively
|
|
//! called in preorder traversal throughout the pass tree. Only FrameBegin and FrameEnd are
|
|
//! guaranteed to be called per frame. The other override-able functions are called as needed
|
|
//! when scheduled with the PassSystem. See QueueForBuildAndInitialization, QueueForRemoval and QueueForInitialization.
|
|
//!
|
|
//! Passes are created by the PassFactory. They can be created using either Pass Name,
|
|
//! a PassTemplate, or a PassRequest. To register your pass class with the PassFactory,
|
|
//! you'll need to write a static create method (see ParentPass and RenderPass for examples)
|
|
//! and register this create method with the PassFactory.
|
|
class Pass
|
|
: public AZStd::intrusive_base
|
|
{
|
|
AZ_RPI_PASS(Pass);
|
|
|
|
friend class ImageAttachmentPreviewPass;
|
|
|
|
public:
|
|
using ChildPassIndex = RHI::Handle<uint32_t, class ChildPass>;
|
|
|
|
// Input parameters for Prepare
|
|
struct FramePrepareParams
|
|
{
|
|
FramePrepareParams(RHI::FrameGraphBuilder* frameGraphBuilder = nullptr)
|
|
: m_frameGraphBuilder(frameGraphBuilder)
|
|
{}
|
|
|
|
RHI::FrameGraphBuilder* m_frameGraphBuilder = nullptr;
|
|
|
|
// This should include SRGs that are higher level than
|
|
// the Pass, like per-frame and per-scene SRGs.
|
|
const ShaderResourceGroupList* m_shaderResourceGroupsToBind = nullptr;
|
|
|
|
RHI::Scissor m_scissorState;
|
|
RHI::Viewport m_viewportState;
|
|
};
|
|
|
|
AZ_RTTI(Pass, "{EA34FF66-631D-433B-B449-71F5647E7BB5}", AZStd::intrusive_base);
|
|
AZ_CLASS_ALLOCATOR(Pass, SystemAllocator, 0);
|
|
|
|
virtual ~Pass();
|
|
|
|
// --- Simple getters/setters ---
|
|
|
|
//! Returns the name of the pass (example: Bloom)
|
|
const Name& GetName() const;
|
|
|
|
//! Return the path name of the pass (example: Root.SwapChain.Bloom)
|
|
const Name& GetPathName() const;
|
|
|
|
//! Returns the depth of this pass in the tree hierarchy (Root depth is 0)
|
|
uint32_t GetTreeDepth() const;
|
|
|
|
//! Returns the number of input attachment bindings
|
|
uint32_t GetInputCount() const;
|
|
|
|
//! Returns the number of input/output attachment bindings
|
|
uint32_t GetInputOutputCount() const;
|
|
|
|
//! Returns the number of output attachment bindings
|
|
uint32_t GetOutputCount() const;
|
|
|
|
//! Returns the pass template which was used for create this pass.
|
|
//! It may return nullptr if the pass wasn't create from a template
|
|
const PassTemplate* GetPassTemplate() const;
|
|
|
|
//! Enable/disable this pass
|
|
//! If the pass is disabled, it (and any children if it's a ParentPass) won't be rendered.
|
|
void SetEnabled(bool enabled);
|
|
virtual bool IsEnabled() const;
|
|
|
|
bool HasDrawListTag() const;
|
|
bool HasPipelineViewTag() const;
|
|
|
|
//! Return the set of attachment bindings
|
|
PassAttachmentBindingListView GetAttachmentBindings() const;
|
|
|
|
//! Casts the pass to a parent pass if valid, else returns nullptr
|
|
ParentPass* AsParent();
|
|
const ParentPass* AsParent() const;
|
|
|
|
// --- Utility functions ---
|
|
|
|
//! Queues the pass to have Build() and Initialize() called by the PassSystem on frame update
|
|
void QueueForBuildAndInitialization();
|
|
|
|
//! Queues the pass to have RemoveFromParent() called by the PassSystem on frame update
|
|
void QueueForRemoval();
|
|
|
|
//! Queues the pass to have Initialize() called by the PassSystem on frame update
|
|
void QueueForInitialization();
|
|
|
|
//! Adds an attachment binding to the list of this Pass' attachment bindings
|
|
void AddAttachmentBinding(PassAttachmentBinding attachmentBinding);
|
|
|
|
// Returns a reference to the N-th input binding, where N is the index passed to the function
|
|
PassAttachmentBinding& GetInputBinding(uint32_t index);
|
|
|
|
// Returns a reference to the N-th input/output binding, where N is the index passed to the function
|
|
PassAttachmentBinding& GetInputOutputBinding(uint32_t index);
|
|
|
|
// Returns a reference to the N-th output binding, where N is the index passed to the function
|
|
PassAttachmentBinding& GetOutputBinding(uint32_t index);
|
|
|
|
//! Attach an external buffer resource as attachment to specified slot
|
|
//! The buffer will be added as a pass attachment then attach to the pass slot
|
|
//! Note: the pass attachment and binding will be removed after the general Build call.
|
|
//! you can add this call in pass' BuildInternal so it will be added whenever attachments get rebuilt
|
|
void AttachBufferToSlot(AZStd::string_view slot, Data::Instance<Buffer> buffer);
|
|
void AttachBufferToSlot(const Name& slot, Data::Instance<Buffer> buffer);
|
|
void AttachImageToSlot(const Name& slot, Data::Instance<AttachmentImage> image);
|
|
|
|
// --- Virtual functions which may need to be override by derived classes ---
|
|
|
|
//! Collect all different view tags from this pass
|
|
virtual void GetPipelineViewTags(SortedPipelineViewTags& outTags) const;
|
|
|
|
//! Adds this pass' DrawListTags to the outDrawListMask.
|
|
virtual void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, PassesByDrawList& outPassesByDrawList, const PipelineViewTag& viewTag) const;
|
|
|
|
//! Check if the pass has a DrawListTag. Pass' DrawListTag can be used to filter draw items.
|
|
virtual RHI::DrawListTag GetDrawListTag() const;
|
|
|
|
//! Function used by views to sort draw lists. Can be overridden so passes can provide custom sort functionality.
|
|
virtual void SortDrawList(RHI::DrawList& drawList) const;
|
|
|
|
//! Check if the pass is associated to a view. If pass has a pipeline view tag, the rpi view assigned to this view tag will have pass's draw list tag.
|
|
virtual const PipelineViewTag& GetPipelineViewTag() const;
|
|
|
|
//! Set render pipeline this pass belongs to
|
|
virtual void SetRenderPipeline(RenderPipeline* pipeline);
|
|
RenderPipeline* GetRenderPipeline() const;
|
|
|
|
Scene* GetScene() const;
|
|
|
|
//! Validates entire tree hierarchy (ensures passes have valid state and attachments).
|
|
//! Functionality compiled out if AZ_RPI_ENABLE_PASS_VALIDATION is not defined.
|
|
virtual void Validate(PassValidationResults& validationResults);
|
|
|
|
// --- Debug and validation print functions ---
|
|
|
|
//! Prints the pass
|
|
virtual void DebugPrint() const;
|
|
|
|
//! Return the latest Timestamp result of this pass
|
|
TimestampResult GetLatestTimestampResult() const;
|
|
|
|
//! Return the latest PipelineStatistic result of this pass
|
|
PipelineStatisticsResult GetLatestPipelineStatisticsResult() const;
|
|
|
|
//! Enables/Disables Timestamp queries for this pass
|
|
virtual void SetTimestampQueryEnabled(bool enable);
|
|
|
|
//! Enables/Disables PipelineStatistics queries for this pass
|
|
virtual void SetPipelineStatisticsQueryEnabled(bool enable);
|
|
|
|
//! Readback an attachment attached to the specified slot name
|
|
//! @param readback The AttachmentReadback object which is used for readback. Its callback function will be called when readback is finished.
|
|
//! @param slotName The attachment bind to the slot with this slotName is to be readback
|
|
//! @param option The option is used for choosing input or output state when readback an InputOutput attachment.
|
|
//! It's ignored if the attachment isn't an InputOutput attachment.
|
|
//! Return true if the readback request was successful. User may expect the AttachmentReadback's callback function would be called.
|
|
bool ReadbackAttachment(AZStd::shared_ptr<AttachmentReadback> readback, const Name& slotName, PassAttachmentReadbackOption option = PassAttachmentReadbackOption::Output);
|
|
|
|
//! Returns whether the Timestamp queries is enabled/disabled for this pass
|
|
bool IsTimestampQueryEnabled() const;
|
|
|
|
//! Returns whether the PipelineStatistics queries is enabled/disabled for this pass
|
|
bool IsPipelineStatisticsQueryEnabled() const;
|
|
|
|
//! Helper function to print spaces to indent the pass
|
|
void PrintIndent(AZStd::string& stringOutput, uint32_t indent) const;
|
|
|
|
//! Prints the name of the pass
|
|
void PrintPassName(AZStd::string& stringOutput, uint32_t indent = 0) const;
|
|
|
|
//! Prints the attachment binding at the given index
|
|
void DebugPrintBinding(AZStd::string& stringOutput, const PassAttachmentBinding& binding) const;
|
|
|
|
//! Prints the attachment binding at the given index and its connection
|
|
void DebugPrintBindingAndConnection(AZStd::string& stringOutput, uint8_t bindingIndex) const;
|
|
|
|
//! Prints the pass name and all the errors accumulated during build and setup
|
|
void PrintErrors() const;
|
|
|
|
//! Prints the pass name and all the warnings accumulated during build and setup
|
|
void PrintWarnings() const;
|
|
|
|
//! Helper function to print an array of messages (like errors or warnings) for a pass
|
|
void PrintMessages(const AZStd::vector<AZStd::string>& messages) const;
|
|
|
|
//! Prints the pass and all the list of inputs and input/outputs that are missing an attachment
|
|
void PrintBindingsWithoutAttachments(uint32_t slotTypeMask) const;
|
|
|
|
//! Returns pointer to the parent pass
|
|
ParentPass* GetParent() const;
|
|
|
|
PassState GetPassState() const;
|
|
|
|
// Update all bindings on this pass that are connected to bindings on other passes
|
|
void UpdateConnectedBindings();
|
|
|
|
// Update input and input/output bindings on this pass that are connected to bindings on other passes
|
|
void UpdateConnectedInputBindings();
|
|
|
|
// Update output bindings on this pass that are connected to bindings on other passes
|
|
void UpdateConnectedOutputBindings();
|
|
|
|
protected:
|
|
explicit Pass(const PassDescriptor& descriptor);
|
|
|
|
// Creates a pass descriptor for creating a duplicate pass. Used for hot reloading.
|
|
PassDescriptor GetPassDescriptor() const;
|
|
|
|
// Imports owned imported attachments into the FrameGraph
|
|
// Called in pass's frame prepare function
|
|
void ImportAttachments(RHI::FrameGraphAttachmentInterface attachmentDatabase);
|
|
|
|
// --- Find functions ---
|
|
|
|
// Searches for an adjacent pass with the given Name. An adjacent pass is either:
|
|
// a parent pass, a child pass, a sibling pass or the pass itself (this).
|
|
// Special names: "This" will return this, and "Parent" will return the parent pass.
|
|
// Search order: 1.This -> 2.Parent -> 3.Siblings -> 4.Children
|
|
Ptr<Pass> FindAdjacentPass(const Name& passName);
|
|
|
|
// Searches this pass's attachment bindings for one with the provided Name (nullptr if none found)
|
|
PassAttachmentBinding* FindAttachmentBinding(const Name& slotName);
|
|
|
|
// Searches this pass's attachment bindings for one with the provided Name (nullptr if none found)
|
|
const PassAttachmentBinding* FindAttachmentBinding(const Name& slotName) const;
|
|
|
|
// Searches the attachments owned by this pass using the provided Name (nullptr if none found)
|
|
Ptr<PassAttachment> FindOwnedAttachment(const Name& attachmentName) const;
|
|
|
|
// Find an attachment with a matching name from either inputs, outputs or inputOutputs and returns it.
|
|
// Returns nullptr if no attachment found.
|
|
Ptr<PassAttachment> FindAttachment(const Name& slotName) const;
|
|
|
|
// Searches adjacent passes for an attachment binding matching the PassAttachmentRef. An adjacent pass is either:
|
|
// a parent pass, a child pass, a sibling pass or the pass itself (this).
|
|
const PassAttachmentBinding* FindAdjacentBinding(const PassAttachmentRef& attachmentRef);
|
|
|
|
// --- Template related setup ---
|
|
|
|
// Process a PassConnection to connect two PassAttachmentBindings
|
|
void ProcessConnection(const PassConnection& connection, uint32_t slotTypeMask = 0xFFFFFFFF);
|
|
|
|
// --- Validation and Error Functions ---
|
|
|
|
void LogError(AZStd::string&& message);
|
|
void LogWarning(AZStd::string&& message);
|
|
|
|
// --- Pass Behavior Functions ---
|
|
|
|
// These functions come in pairs, one virtual function (name ending in -Internal) and one
|
|
// non-virtual. Each non-virtual function will call it's virtual counterpart. Classes
|
|
// inheriting from Pass can override any or all of the virtual -Internal functions to
|
|
// customize it's behavior, hence why these functions are called the pass behavior functions.
|
|
|
|
// Resets everything in the pass (like Attachments).
|
|
// Called from PassSystem when pass is QueueForBuildAndInitialization.
|
|
void Reset();
|
|
virtual void ResetInternal() { }
|
|
|
|
// Builds and sets up any attachments and input/output connections the pass needs.
|
|
// Called from PassSystem when pass is QueueForBuildAndInitialization.
|
|
void Build(bool calledFromPassSystem = false);
|
|
virtual void BuildInternal() { }
|
|
|
|
// Allows for additional pass initialization between building and rendering
|
|
// Can be queued independently of Build so as to only invoke Initialize() without Build()
|
|
void Initialize();
|
|
virtual void InitializeInternal() { };
|
|
|
|
// Called after the pass initialization phase has finished. Allows passes to reset various states and flags.
|
|
void OnInitializationFinished();
|
|
virtual void OnInitializationFinishedInternal() { };
|
|
|
|
// The Pass's 'Render' function. Called every frame, here the pass sets up it's rendering logic with
|
|
// the FrameGraphBuilder. This is where your derived pass needs to call ImportScopeProducer on
|
|
// the FrameGraphBuilder if it's a ScopeProducer (see ForwardPass::FrameBeginInternal for example).
|
|
void FrameBegin(FramePrepareParams params);
|
|
virtual void FrameBeginInternal([[maybe_unused]] FramePrepareParams params) { }
|
|
|
|
// Called every frame after the frame has been rendered. Allows the pass
|
|
// to perform any post-frame cleanup, such as resetting per-frame state.
|
|
void FrameEnd();
|
|
virtual void FrameEndInternal() { }
|
|
|
|
void UpdateReadbackAttachment(FramePrepareParams params, bool beforeAddScopes);
|
|
|
|
// Setup ImageAttachmentCopy
|
|
void UpdateAttachmentCopy(FramePrepareParams params);
|
|
|
|
// --- Protected Members ---
|
|
|
|
const Name PassNameThis{"This"};
|
|
const Name PassNameParent{"Parent"};
|
|
const Name PipelineKeyword{"Pipeline"};
|
|
|
|
// List of input, output and input/output attachment bindings
|
|
// Fixed size for performance and so we can hold pointers to the bindings for connections
|
|
AZStd::fixed_vector<PassAttachmentBinding, PassAttachmentBindingCountMax> m_attachmentBindings;
|
|
|
|
// List of attachments owned by this pass.
|
|
// It includes both transient attachments and imported attachments
|
|
AZStd::vector<Ptr<PassAttachment>> m_ownedAttachments;
|
|
|
|
// List of passes before which this pass needs to execute (specified by the PassRequest)
|
|
// Note most pass ordering is determined by attachments. This is only to be used for
|
|
// dependencies between passes that don't have any attachments/connections in common.
|
|
AZStd::vector<Pass*> m_executeBeforePasses;
|
|
|
|
// List of passes that this pass needs to execute after (specified by the PassRequest)
|
|
// Note most pass ordering is determined by attachments. This is only to be used for
|
|
// dependencies between passes that don't have any attachments/connections in common.
|
|
AZStd::vector<Pass*> m_executeAfterPasses;
|
|
|
|
// The render pipeline this pass belongs to.
|
|
RenderPipeline* m_pipeline = nullptr;
|
|
|
|
// The PassTemplate used to create this pass
|
|
// Null if this pass was not created by a PassTemplate
|
|
AZStd::shared_ptr<PassTemplate> m_template = nullptr;
|
|
|
|
// The PassRequest used to create this pass
|
|
// Only valid if m_createdByPassRequest flag is set
|
|
PassRequest m_request;
|
|
|
|
// Pointer to the parent pass if this pass is a child pass
|
|
ParentPass* m_parent = nullptr;
|
|
|
|
struct
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
// Whether this pass was created with a PassRequest (in which case m_request holds valid data)
|
|
uint64_t m_createdByPassRequest : 1;
|
|
|
|
// Whether the pass is enabled (behavior can be customized by overriding IsEnabled() )
|
|
uint64_t m_enabled : 1;
|
|
|
|
// False if parent or one of it's ancestors is disabled
|
|
uint64_t m_parentEnabled : 1;
|
|
|
|
// If this is a parent pass, indicates if the pass has already created children this frame
|
|
// Prevents ParentPass::CreateChildPasses from executing multiple times in the same pass
|
|
uint64_t m_alreadyCreatedChildren : 1;
|
|
|
|
// If this is a parent pass, indicates whether the pass needs to create child passes
|
|
uint64_t m_createChildren : 1;
|
|
|
|
// Whether this pass belongs to the pass hierarchy, i.e. if you can trace it's parents up to the Root pass
|
|
uint64_t m_partOfHierarchy : 1;
|
|
|
|
// Whether this pass has a DrawListTag
|
|
uint64_t m_hasDrawListTag : 1;
|
|
|
|
// Whether this pass has a PipelineViewTag
|
|
uint64_t m_hasPipelineViewTag : 1;
|
|
|
|
// Whether the pass should gather timestamp query metrics
|
|
uint64_t m_timestampQueryEnabled : 1;
|
|
|
|
// Whether the pass should gather pipeline statics
|
|
uint64_t m_pipelineStatisticsQueryEnabled : 1;
|
|
|
|
// Whether the pass is the root pass for a pipeline. Used to control pipeline render tick rate
|
|
uint64_t m_isPipelineRoot : 1;
|
|
};
|
|
uint64_t m_allFlags = 0;
|
|
};
|
|
} m_flags;
|
|
|
|
// Arbitrary message log limit so we don't get an
|
|
// ever increasing array when an error starts spamming
|
|
static const size_t MessageLogLimit = 256;
|
|
|
|
AZStd::vector<AZStd::string> m_errorMessages;
|
|
AZStd::vector<AZStd::string> m_warningMessages;
|
|
|
|
uint32_t m_errors = 0;
|
|
uint32_t m_warnings = 0;
|
|
|
|
// Sort type to be used by the default sort implementation. Passes can also provide
|
|
// fully custom sort implementations by overriding the SortDrawList() function.
|
|
RHI::DrawListSortType m_drawListSortType = RHI::DrawListSortType::KeyThenDepth;
|
|
|
|
// For read back attachment
|
|
AZStd::shared_ptr<AttachmentReadback> m_attachmentReadback;
|
|
PassAttachmentReadbackOption m_readbackOption;
|
|
|
|
// For image attachment preview
|
|
AZStd::weak_ptr<ImageAttachmentCopy> m_attachmentCopy;
|
|
|
|
private:
|
|
// Return the Timestamp result of this pass
|
|
virtual TimestampResult GetTimestampResultInternal() const;
|
|
|
|
// Return the PipelineStatistics result of this pass
|
|
virtual PipelineStatisticsResult GetPipelineStatisticsResultInternal() const;
|
|
|
|
// Used to maintain references to imported attachments so they're underlying
|
|
// buffers and images don't get deleted during attachment build phase
|
|
void StoreImportedAttachmentReferences();
|
|
|
|
// Used by the RenderPipeline to create it's passes immediately instead of waiting on
|
|
// the next Pass System update. The function internally build and initializes the pass.
|
|
void ManualPipelineBuildAndInitialize();
|
|
|
|
// --- Hierarchy related functions ---
|
|
|
|
// Called when the pass gets a new spot in the pass hierarchy
|
|
virtual void OnHierarchyChange();
|
|
|
|
// Called when the pass is removed from it's parent list of children
|
|
virtual void OnOrphan();
|
|
|
|
// The pass removes itself from its parent.
|
|
void RemoveFromParent();
|
|
|
|
// --- Template related setup ---
|
|
|
|
// Generates bindings from source PassTemplate
|
|
void CreateBindingsFromTemplate();
|
|
|
|
// Generates attachments from source PassTemplate
|
|
void CreateAttachmentsFromTemplate();
|
|
|
|
// Generates attachments from source PassRequest
|
|
void CreateAttachmentsFromRequest();
|
|
|
|
// Uses FrameGraphAttachmentInterface to create transient attachments for the pass
|
|
void CreateTransientAttachments(RHI::FrameGraphAttachmentInterface attachmentDatabase);
|
|
|
|
// Creates an attachment from a given description and returns a pointer to it
|
|
template<typename AttachmentDescType>
|
|
Ptr<PassAttachment> CreateAttachmentFromDesc(const AttachmentDescType& desc);
|
|
|
|
// Overrides an existing attachment if matching name is found, otherwise creates and adds new attachment
|
|
template<typename AttachmentDescType>
|
|
void OverrideOrAddAttachment(const AttachmentDescType& desc);
|
|
|
|
// Updates a binding on this pass using the binding it is connected to.
|
|
// This sets the binding's attachment pointer to the connected binding's attachment
|
|
void UpdateConnectedBinding(PassAttachmentBinding& binding);
|
|
|
|
// Process a PassFallbackConnection to connect an output to an input to act as a short-circuit for when Pass is disabled
|
|
void ProcessFallbackConnection(const PassFallbackConnection& connection);
|
|
|
|
// Sets up inputs from the list of PassConnections in PassRequest
|
|
void SetupInputsFromRequest();
|
|
|
|
// Sets up outputs from the list of PassConnections in PassRequest
|
|
void SetupOutputsFromRequest();
|
|
|
|
// Sets up explicitly declared dependencies on other passes declared in the PassRequest
|
|
void SetupPassDependencies();
|
|
|
|
// Sets up inputs from the list of PassConnections in PassTemplate
|
|
void SetupInputsFromTemplate();
|
|
|
|
// Sets up outputs from the list of PassConnections in PassTemplate
|
|
void SetupOutputsFromTemplate();
|
|
|
|
// Updates attachment sizes and formats from their specified source attachments
|
|
void UpdateOwnedAttachments();
|
|
|
|
// Updates m_attachmentUsageIndex on the bindings to handle multiple bindings using the same attachment
|
|
void UpdateAttachmentUsageIndices();
|
|
|
|
// --- Private Members ---
|
|
|
|
// List of attachment binding indices for all the input bindings
|
|
AZStd::fixed_vector<uint8_t, PassInputBindingCountMax> m_inputBindingIndices;
|
|
|
|
// List of attachment binding indices for all the input/output bindings
|
|
AZStd::fixed_vector<uint8_t, PassInputOutputBindingCountMax> m_inputOutputBindingIndices;
|
|
|
|
// List of attachment binding indices for all the output bindings
|
|
AZStd::fixed_vector<uint8_t, PassOutputBindingCountMax> m_outputBindingIndices;
|
|
|
|
// Used to maintain references to imported attachments so they're underlying
|
|
// buffers and images don't get deleted during attachment build phase
|
|
AZStd::vector<Ptr<PassAttachment>> m_importedAttachmentStore;
|
|
|
|
// Name of the pass. Will be concatenated with parent names to form a unique path
|
|
Name m_name;
|
|
|
|
// Path of the pass in the hierarchy. Example: Root.Ssao.Downsample
|
|
Name m_path;
|
|
|
|
// Depth of the tree hierarchy this pass is at.
|
|
// Example: Root would be depth 0, Root.Ssao.Downsample depth 2
|
|
uint32_t m_treeDepth = 0;
|
|
|
|
// Used to track what phase of build/execution the pass is in
|
|
PassState m_state = PassState::Uninitialized;
|
|
|
|
// Used to track what phases of build/initialization the pass is queued for
|
|
PassQueueState m_queueState = PassQueueState::NoQueue;
|
|
};
|
|
|
|
//! Struct used to return results from Pass hierarchy validation
|
|
struct PassValidationResults
|
|
{
|
|
bool IsValid();
|
|
void PrintValidationIfError();
|
|
|
|
AZStd::vector<Pass*> m_passesWithErrors;
|
|
AZStd::vector<Pass*> m_passesWithWarnings;
|
|
AZStd::vector<Pass*> m_passesWithMissingInputs;
|
|
AZStd::vector<Pass*> m_passesWithMissingOutputs;
|
|
AZStd::vector<Pass*> m_passesWithMissingInputOutputs;
|
|
};
|
|
|
|
} // namespace RPI
|
|
} // namespace AZ
|
|
|
|
|
|
#ifdef AZ_ENABLE_TRACING
|
|
|
|
#define AZ_RPI_PASS_ASSERT(expression, ...) \
|
|
if (!(expression)) \
|
|
{ \
|
|
AZ_Assert(false, __VA_ARGS__); \
|
|
AZStd::string message = AZStd::string::format(__VA_ARGS__); \
|
|
LogError( AZStd::string::format(__VA_ARGS__) ); \
|
|
} \
|
|
|
|
#define AZ_RPI_PASS_ERROR(expression, ...) \
|
|
if (!(expression)) \
|
|
{ \
|
|
AZ_Error("Pass System", false, __VA_ARGS__); \
|
|
AZStd::string message = AZStd::string::format(__VA_ARGS__); \
|
|
LogError( AZStd::string::format(__VA_ARGS__) ); \
|
|
} \
|
|
|
|
#define AZ_RPI_PASS_WARNING(expression, ...) \
|
|
if (!(expression)) \
|
|
{ \
|
|
AZ_Warning("Pass System", false, __VA_ARGS__); \
|
|
AZStd::string message = AZStd::string::format(__VA_ARGS__); \
|
|
LogWarning( AZStd::string::format(__VA_ARGS__) ); \
|
|
} \
|
|
|
|
#else
|
|
|
|
#define AZ_RPI_PASS_ASSERT(expression, ...) AZ_Assert(false, __VA_ARGS__);
|
|
#define AZ_RPI_PASS_ERROR(expression, ...) AZ_Error("Pass System", false, __VA_ARGS__);
|
|
#define AZ_RPI_PASS_WARNING(expression, ...) AZ_Warning("Pass System", false, __VA_ARGS__);
|
|
|
|
#endif
|
|
|
|
|
|
#if AZ_RPI_ENABLE_PASS_DEBUGGING
|
|
|
|
// This macro will break in pass code (functions that belong to Pass or it's child classes)
|
|
// if the name of the pass being executed is the same as the one specified for targeted debugging
|
|
// in the pass system (see functions with "TargetedPassDebugging" above)
|
|
#define AZ_RPI_BREAK_ON_TARGET_PASS \
|
|
if(!GetName().IsEmpty() && \
|
|
GetName() == AZ::RPI::PassSystemInterface::Get()->GetTargetedPassDebuggingName()) \
|
|
{ \
|
|
AZ::Debug::Trace::Break(); \
|
|
}
|
|
|
|
#else
|
|
|
|
#define AZ_RPI_BREAK_ON_TARGET_PASS
|
|
|
|
#endif
|