Merge pull request #2584 from aws-lumberyard-dev/Atom/antonmic/SrgDebugImprovements
Shader resource group debug improvements
This commit is contained in:
@@ -82,6 +82,10 @@ namespace AZ
|
||||
//! If validation is disabled, true is always returned.
|
||||
bool ValidateAccess(ShaderInputConstantIndex inputIndex) const;
|
||||
|
||||
//! Prints to the console the shader input names specified by input list of indices
|
||||
//! Will ignore any indices outside of the inputs array bounds
|
||||
void DebugPrintNames(AZStd::array_view<ShaderInputConstantIndex> constantList) const;
|
||||
|
||||
protected:
|
||||
ConstantsLayout() = default;
|
||||
|
||||
@@ -95,7 +99,6 @@ namespace AZ
|
||||
|
||||
AZStd::vector<ShaderInputConstantDescriptor> m_inputs;
|
||||
IdReflectionMapForConstants m_idReflection;
|
||||
AZStd::vector<Interval> m_intervals;
|
||||
uint32_t m_sizeInBytes = 0;
|
||||
HashValue64 m_hash = InvalidHash;
|
||||
};
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace AZ
|
||||
/// Return the number of entries
|
||||
size_t Size() const;
|
||||
|
||||
// Returns true if size is zero
|
||||
bool IsEmpty() const;
|
||||
|
||||
class NameIdReflectionMapSerializationEvents
|
||||
: public SerializeContext::IEventHandler
|
||||
{
|
||||
@@ -169,6 +172,12 @@ namespace AZ
|
||||
return m_reflectionMap.size();
|
||||
}
|
||||
|
||||
template <typename IndexType>
|
||||
bool NameIdReflectionMap<IndexType>::IsEmpty() const
|
||||
{
|
||||
return Size() == 0;
|
||||
}
|
||||
|
||||
template <typename IndexType>
|
||||
void NameIdReflectionMap<IndexType>::Sort()
|
||||
{
|
||||
|
||||
@@ -85,6 +85,14 @@ namespace AZ
|
||||
//! Returns the constants layout.
|
||||
const ConstantsLayout* GetLayout() const;
|
||||
|
||||
//! Returns whether other constant data and this have the same value at the specified shader input index
|
||||
bool ConstantIsEqual(const ConstantsData& other, ShaderInputConstantIndex inputIndex) const;
|
||||
|
||||
//! Performs a diff between this and input constant data and returns a list of all the shader input indices
|
||||
//! for which the constants are not the same between the two. If one of the two has more constants than the
|
||||
//! other, these additional constants will be added to the end of the returned list.
|
||||
AZStd::vector<ShaderInputConstantIndex> GetIndicesOfDifferingConstants(const ConstantsData& other) const;
|
||||
|
||||
private:
|
||||
enum class ValidateConstantAccessExpect : uint32_t
|
||||
{
|
||||
|
||||
@@ -173,6 +173,9 @@ namespace AZ
|
||||
//! Different platforms might follow different packing rules for the internally-managed SRG constant buffer.
|
||||
AZStd::array_view<uint8_t> GetConstantData() const;
|
||||
|
||||
//! Returns the underlying ConstantsData struct
|
||||
const ConstantsData& GetConstantsData() const;
|
||||
|
||||
//! Returns the shader resource layout for this group.
|
||||
const ShaderResourceGroupLayout* GetLayout() const;
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RHI
|
||||
{
|
||||
class ConstantsData;
|
||||
struct DrawItem;
|
||||
class ShaderResourceGroup;
|
||||
|
||||
/// Given a ShaderResourceGroup and a reference ConstantsData input, this function will fetch the ConstantsData on the SRG and compare it
|
||||
/// to the reference ConstantsData. It will print the names of any constants that are different between the two.
|
||||
/// The parameter updateReferenceData can be used to set the reference data to the SRG's constant data after the comparison. This is
|
||||
/// useful for keeping track of differences in between calls to the function, such as between frames.
|
||||
void PrintConstantDataDiff(const ShaderResourceGroup& shaderResourceGroup, ConstantsData& referenceData, bool updateReferenceData = false);
|
||||
|
||||
/// Given a DrawItem, an SRG binding slot on that draw item and a reference ConstantsData input, this function will fetch the ConstantsData
|
||||
/// from the draw item's SRG at the binding slot and compare it to the reference ConstantsData. It will print the names of any constants
|
||||
/// that are different between the two.
|
||||
/// The parameter updateReferenceData can be used to set the reference data to the draw item's constant data after the comparison. This is
|
||||
/// useful for keeping track of differences in between calls to the function, such as between frames.
|
||||
void PrintConstantDataDiff(const DrawItem& drawItem, ConstantsData& referenceData, uint32_t srgBindingSlot, bool updateReferenceData = false);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,9 @@ namespace AZ
|
||||
if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<ConstantsLayout>()
|
||||
->Version(0)
|
||||
->Version(1) // Version 1: Adding debug helper functions to Shader Resource Groups
|
||||
->Field("m_inputs", &ConstantsLayout::m_inputs)
|
||||
->Field("m_idReflection", &ConstantsLayout::m_idReflection)
|
||||
->Field("m_intervals", &ConstantsLayout::m_intervals)
|
||||
->Field("m_sizeInBytes", &ConstantsLayout::m_sizeInBytes)
|
||||
->Field("m_hash", &ConstantsLayout::m_hash);
|
||||
}
|
||||
@@ -43,7 +42,6 @@ namespace AZ
|
||||
{
|
||||
m_inputs.clear();
|
||||
m_idReflection.Clear();
|
||||
m_intervals.clear();
|
||||
m_sizeInBytes = 0;
|
||||
m_hash = InvalidHash;
|
||||
}
|
||||
@@ -67,11 +65,8 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
// The constant data size is the maximum offset + size from the start of the struct.
|
||||
constantDataSize = AZStd::max(constantDataSize, constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount);
|
||||
|
||||
// Add the [min, max) interval for the inline constant.
|
||||
m_intervals.emplace_back(constantDescriptor.m_constantByteOffset, constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount);
|
||||
uint32_t end = constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount;
|
||||
constantDataSize = AZStd::max(constantDataSize, end);
|
||||
|
||||
++constantInputIndex;
|
||||
m_hash = TypeHash64(constantDescriptor.GetHash(), m_hash);
|
||||
@@ -100,7 +95,10 @@ namespace AZ
|
||||
|
||||
Interval ConstantsLayout::GetInterval(ShaderInputConstantIndex inputIndex) const
|
||||
{
|
||||
return m_intervals[inputIndex.GetIndex()];
|
||||
const ShaderInputConstantDescriptor& desc = GetShaderInput(inputIndex);
|
||||
uint32_t start = desc.m_constantByteOffset;
|
||||
uint32_t end = start + desc.m_constantByteCount;
|
||||
return Interval(start, end);
|
||||
}
|
||||
|
||||
const ShaderInputConstantDescriptor& ConstantsLayout::GetShaderInput(ShaderInputConstantIndex inputIndex) const
|
||||
@@ -139,8 +137,8 @@ namespace AZ
|
||||
{
|
||||
if (!m_sizeInBytes)
|
||||
{
|
||||
AZ_Assert(m_intervals.empty(), "Constants size is not valid.");
|
||||
return m_intervals.empty();
|
||||
AZ_Assert(m_idReflection.IsEmpty(), "Constants size is not valid.");
|
||||
return m_idReflection.IsEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,5 +147,20 @@ namespace AZ
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConstantsLayout::DebugPrintNames(AZStd::array_view<ShaderInputConstantIndex> constantList) const
|
||||
{
|
||||
AZStd::string output;
|
||||
for (const ShaderInputConstantIndex& constantIdx : constantList)
|
||||
{
|
||||
if (constantIdx.GetIndex() < m_inputs.size())
|
||||
{
|
||||
output += m_inputs[constantIdx.GetIndex()].m_name.GetCStr();
|
||||
output += " - ";
|
||||
}
|
||||
}
|
||||
AZ_Printf("RHI", output.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,5 +405,71 @@ namespace AZ
|
||||
AZ_Assert(m_layout, "Constants layout is null");
|
||||
return m_layout.get();
|
||||
}
|
||||
|
||||
bool ConstantsData::ConstantIsEqual(const ConstantsData& other, ShaderInputConstantIndex inputIndex) const
|
||||
{
|
||||
AZStd::array_view<uint8_t> myConstant = GetConstantRaw(inputIndex);
|
||||
AZStd::array_view<uint8_t> otherConstant = other.GetConstantRaw(inputIndex);
|
||||
|
||||
// If they point to the same data, they are equal
|
||||
if (myConstant == otherConstant)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If they point to data of different size, they are not equal
|
||||
if (myConstant.size() != otherConstant.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If they point to differing data of same size, compare the data
|
||||
// Note: due to small size of data this loop will be faster than a mem compare
|
||||
for(uint32_t i = 0; i < myConstant.size(); ++i)
|
||||
{
|
||||
if (myConstant[i] != otherConstant[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Arrays point to different locations in memory but all bytes match, return true
|
||||
return true;
|
||||
}
|
||||
|
||||
AZStd::vector<ShaderInputConstantIndex> ConstantsData::GetIndicesOfDifferingConstants(const ConstantsData& other) const
|
||||
{
|
||||
AZStd::vector<ShaderInputConstantIndex> differingIndices;
|
||||
|
||||
if (m_layout == nullptr || other.m_layout == nullptr)
|
||||
{
|
||||
return differingIndices;
|
||||
}
|
||||
|
||||
AZStd::array_view<ShaderInputConstantDescriptor> myShaderInputs = m_layout->GetShaderInputList();
|
||||
AZStd::array_view<ShaderInputConstantDescriptor> otherShaderInputs = other.m_layout->GetShaderInputList();
|
||||
|
||||
size_t minSize = AZStd::min(myShaderInputs.size(), otherShaderInputs.size());
|
||||
size_t maxSize = AZStd::max(myShaderInputs.size(), otherShaderInputs.size());
|
||||
|
||||
for (size_t idx = 0; idx < minSize; ++idx)
|
||||
{
|
||||
const ShaderInputConstantIndex inputIndex(idx);
|
||||
if (!ConstantIsEqual(other, inputIndex))
|
||||
{
|
||||
differingIndices.push_back(inputIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// If sizes are different, add difference at the end
|
||||
for (size_t idx = minSize; idx < maxSize; ++idx)
|
||||
{
|
||||
const ShaderInputConstantIndex inputIndex(idx);
|
||||
differingIndices.push_back(inputIndex);
|
||||
}
|
||||
|
||||
return differingIndices;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,5 +335,10 @@ namespace AZ
|
||||
return m_constantsData.GetConstantData();
|
||||
}
|
||||
|
||||
const ConstantsData& ShaderResourceGroupData::GetConstantsData() const
|
||||
{
|
||||
return m_constantsData;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/ConstantsData.h>
|
||||
#include <Atom/RHI/DrawItem.h>
|
||||
#include <Atom/RHI/ShaderResourceGroup.h>
|
||||
#include <Atom/RHI/ShaderResourceGroupDebug.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RHI
|
||||
{
|
||||
|
||||
void PrintConstantDataDiff(const ShaderResourceGroup& shaderResourceGroup, ConstantsData& referenceData, bool updateReferenceData)
|
||||
{
|
||||
const RHI::ConstantsData& currentData = shaderResourceGroup.GetData().GetConstantsData();
|
||||
|
||||
AZStd::vector<RHI::ShaderInputConstantIndex> differingIndices = currentData.GetIndicesOfDifferingConstants(referenceData);
|
||||
|
||||
if (differingIndices.size() > 0)
|
||||
{
|
||||
AZ_Printf("RHI", "Detected different SRG values for the following fields:\n");
|
||||
if (currentData.GetLayout())
|
||||
{
|
||||
currentData.GetLayout()->DebugPrintNames(differingIndices);
|
||||
}
|
||||
}
|
||||
|
||||
if (updateReferenceData)
|
||||
{
|
||||
referenceData = currentData;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintConstantDataDiff(const DrawItem& drawItem, ConstantsData& referenceData, uint32_t srgBindingSlot, bool updateReferenceData)
|
||||
{
|
||||
int srgIndex = -1;
|
||||
for (uint32_t i = 0; i < drawItem.m_shaderResourceGroupCount; ++i)
|
||||
{
|
||||
if (drawItem.m_shaderResourceGroups[i]->GetBindingSlot() == srgBindingSlot)
|
||||
{
|
||||
srgIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (srgIndex != -1)
|
||||
{
|
||||
const ShaderResourceGroup& srg = *drawItem.m_shaderResourceGroups[srgIndex];
|
||||
PrintConstantDataDiff(srg, referenceData, updateReferenceData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -157,10 +157,12 @@ set(FILES
|
||||
Source/RHI/ScopeAttachment.cpp
|
||||
Include/Atom/RHI/ShaderResourceGroup.h
|
||||
Include/Atom/RHI/ShaderResourceGroupData.h
|
||||
Include/Atom/RHI/ShaderResourceGroupDebug.h
|
||||
Include/Atom/RHI/ShaderResourceGroupInvalidateRegistry.h
|
||||
Include/Atom/RHI/ShaderResourceGroupPool.h
|
||||
Source/RHI/ShaderResourceGroup.cpp
|
||||
Source/RHI/ShaderResourceGroupData.cpp
|
||||
Source/RHI/ShaderResourceGroupDebug.cpp
|
||||
Source/RHI/ShaderResourceGroupInvalidateRegistry.cpp
|
||||
Source/RHI/ShaderResourceGroupPool.cpp
|
||||
Include/Atom/RHI/MemoryStatisticsBuilder.h
|
||||
|
||||
@@ -75,6 +75,12 @@ namespace AZ
|
||||
const AZ::Name& GetTargetedPassDebuggingName() const override;
|
||||
void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) override;
|
||||
PassSystemState GetState() const override;
|
||||
SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const override;
|
||||
|
||||
// PassSystemInterface statistics related functions
|
||||
void IncrementFrameDrawItemCount(u32 numDrawItems) override;
|
||||
void IncrementFrameRenderPassCount() override;
|
||||
PassSystemFrameStatistics GetFrameStatistics() override;
|
||||
|
||||
// PassSystemInterface factory related functions...
|
||||
void AddPassCreator(Name className, PassCreator createFunction) override;
|
||||
@@ -93,7 +99,6 @@ namespace AZ
|
||||
void RegisterPass(Pass* pass) override;
|
||||
void UnregisterPass(Pass* pass) override;
|
||||
AZStd::vector<Pass*> FindPasses(const PassFilter& passFilter) const override;
|
||||
SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const override;
|
||||
|
||||
private:
|
||||
// Returns the root of the pass tree hierarchy
|
||||
@@ -116,6 +121,9 @@ namespace AZ
|
||||
void QueueForRemoval(Pass* pass) override;
|
||||
void QueueForInitialization(Pass* pass) override;
|
||||
|
||||
// Resets the frame statistic counters
|
||||
void ResetFrameStatistics();
|
||||
|
||||
// Lists for queuing passes for various function calls
|
||||
// Name of the list reflects the pass function it will call
|
||||
AZStd::vector< Ptr<Pass> > m_buildPassList;
|
||||
@@ -141,13 +149,16 @@ namespace AZ
|
||||
AZ::Name m_targetedPassDebugName;
|
||||
|
||||
// Counts the number of passes
|
||||
int32_t m_passCounter = 0;
|
||||
u32 m_passCounter = 0;
|
||||
|
||||
// Events
|
||||
OnReadyLoadTemplatesEvent m_loadTemplatesEvent;
|
||||
|
||||
// Used to track what phase of execution the pass system is in
|
||||
PassSystemState m_state = PassSystemState::Unitialized;
|
||||
|
||||
// Counters used to gather statistics about the frame
|
||||
PassSystemFrameStatistics m_frameStatistics;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -67,6 +67,14 @@ namespace AZ
|
||||
FrameEnd,
|
||||
};
|
||||
|
||||
//! Frame counters used for collecting statistics
|
||||
struct PassSystemFrameStatistics
|
||||
{
|
||||
u32 m_numRenderPassesExecuted = 0;
|
||||
u32 m_totalDrawItemsRendered = 0;
|
||||
u32 m_maxDrawItemsRenderedInAPass = 0;
|
||||
};
|
||||
|
||||
class PassSystemInterface
|
||||
{
|
||||
friend class Pass;
|
||||
@@ -116,6 +124,27 @@ namespace AZ
|
||||
virtual void SetTargetedPassDebuggingName(const AZ::Name& targetPassName) = 0;
|
||||
virtual const AZ::Name& GetTargetedPassDebuggingName() const = 0;
|
||||
|
||||
//! Find the SwapChainPass associated with window Handle
|
||||
virtual SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const = 0;
|
||||
|
||||
using OnReadyLoadTemplatesEvent = AZ::Event<>;
|
||||
//! Connect a handler to listen to the event that the pass system is ready to load pass templates
|
||||
//! The event is triggered when pass system is initialized and asset system is ready.
|
||||
//! The handler can add new pass templates or load pass template mappings from assets
|
||||
virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0;
|
||||
|
||||
virtual PassSystemState GetState() const = 0;
|
||||
|
||||
// Passes call this function to notify the pass system that they are drawing X draw items this frame
|
||||
// Used for Pass System statistics
|
||||
virtual void IncrementFrameDrawItemCount(u32 numDrawItems) = 0;
|
||||
|
||||
// Increments the counter for the number of render passes executed this frame (does not include passes that are disabled)
|
||||
virtual void IncrementFrameRenderPassCount() = 0;
|
||||
|
||||
// Get frame statistics from the Pass System
|
||||
virtual PassSystemFrameStatistics GetFrameStatistics() = 0;
|
||||
|
||||
// --- Pass Factory related functionality ---
|
||||
|
||||
//! Directly creates a pass given a PassDescriptor
|
||||
@@ -172,17 +201,6 @@ namespace AZ
|
||||
//! Find matching passes from registered passes with specified filter
|
||||
virtual AZStd::vector<Pass*> FindPasses(const PassFilter& passFilter) const = 0;
|
||||
|
||||
//! Find the SwapChainPass associated with window Handle
|
||||
virtual SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const = 0;
|
||||
|
||||
using OnReadyLoadTemplatesEvent = AZ::Event<>;
|
||||
//! Connect a handler to listen to the event that the pass system is ready to load pass templates
|
||||
//! The event is triggered when pass system is initialized and asset system is ready.
|
||||
//! The handler can add new pass templates or load pass template mappings from assets
|
||||
virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0;
|
||||
|
||||
virtual PassSystemState GetState() const = 0;
|
||||
|
||||
private:
|
||||
// These functions are only meant to be used by the Pass class
|
||||
|
||||
@@ -200,7 +218,6 @@ namespace AZ
|
||||
|
||||
//! Unregisters the pass with the pass library. Called in the Pass destructor.
|
||||
virtual void UnregisterPass(Pass* pass) = 0;
|
||||
|
||||
};
|
||||
|
||||
namespace PassSystemEvents
|
||||
|
||||
@@ -38,11 +38,13 @@ namespace AZ
|
||||
|
||||
void SetDrawListTag(Name drawListName);
|
||||
|
||||
void SetPipelineStateDataIndex(u32 index);
|
||||
void SetPipelineStateDataIndex(uint32_t index);
|
||||
|
||||
//! Expose shader resource group.
|
||||
ShaderResourceGroup* GetShaderResourceGroup();
|
||||
|
||||
uint32_t GetDrawItemCount();
|
||||
|
||||
protected:
|
||||
explicit RasterPass(const PassDescriptor& descriptor);
|
||||
|
||||
@@ -76,6 +78,7 @@ namespace AZ
|
||||
RHI::Viewport m_viewportState;
|
||||
bool m_overrideScissorSate = false;
|
||||
bool m_overrideViewportState = false;
|
||||
uint32_t m_drawItemCount = 0;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -310,6 +310,7 @@ namespace AZ
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
|
||||
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: FrameUpdate");
|
||||
|
||||
ResetFrameStatistics();
|
||||
ProcessQueuedChanges();
|
||||
|
||||
m_state = PassSystemState::Rendering;
|
||||
@@ -398,6 +399,29 @@ namespace AZ
|
||||
handler.Connect(m_loadTemplatesEvent);
|
||||
}
|
||||
|
||||
void PassSystem::ResetFrameStatistics()
|
||||
{
|
||||
m_frameStatistics.m_numRenderPassesExecuted = 0;
|
||||
m_frameStatistics.m_totalDrawItemsRendered = 0;
|
||||
m_frameStatistics.m_maxDrawItemsRenderedInAPass = 0;
|
||||
}
|
||||
|
||||
PassSystemFrameStatistics PassSystem::GetFrameStatistics()
|
||||
{
|
||||
return m_frameStatistics;
|
||||
}
|
||||
|
||||
void PassSystem::IncrementFrameDrawItemCount(u32 numDrawItems)
|
||||
{
|
||||
m_frameStatistics.m_totalDrawItemsRendered += numDrawItems;
|
||||
m_frameStatistics.m_maxDrawItemsRenderedInAPass = AZStd::max(m_frameStatistics.m_maxDrawItemsRenderedInAPass, numDrawItems);
|
||||
}
|
||||
|
||||
void PassSystem::IncrementFrameRenderPassCount()
|
||||
{
|
||||
++m_frameStatistics.m_numRenderPassesExecuted;
|
||||
}
|
||||
|
||||
// --- Pass Factory Functions ---
|
||||
|
||||
void PassSystem::AddPassCreator(Name className, PassCreator createFunction)
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace AZ
|
||||
m_flags.m_hasDrawListTag = true;
|
||||
}
|
||||
|
||||
void RasterPass::SetPipelineStateDataIndex(u32 index)
|
||||
void RasterPass::SetPipelineStateDataIndex(uint32_t index)
|
||||
{
|
||||
m_pipelineStateDataIndex.m_index = index;
|
||||
}
|
||||
@@ -114,6 +114,11 @@ namespace AZ
|
||||
return m_shaderResourceGroup.get();
|
||||
}
|
||||
|
||||
uint32_t RasterPass::GetDrawItemCount()
|
||||
{
|
||||
return m_drawItemCount;
|
||||
}
|
||||
|
||||
// --- Pass behaviour overrides ---
|
||||
|
||||
void RasterPass::Validate(PassValidationResults& validationResults)
|
||||
@@ -154,17 +159,21 @@ namespace AZ
|
||||
// Assert the view has our draw list (the view's DrawlistTags are collected from passes using its viewTag)
|
||||
AZ_Assert(view->HasDrawListTag(m_drawListTag), "View's DrawListTags out of sync with pass'. ");
|
||||
|
||||
// Draw List
|
||||
viewDrawList = view->GetDrawList(m_drawListTag);
|
||||
}
|
||||
|
||||
// clean up data
|
||||
m_drawListView = {};
|
||||
m_combinedDrawList.clear();
|
||||
m_drawItemCount = 0;
|
||||
|
||||
// draw list from view was sorted and if it's the only draw list then we can use it directly
|
||||
if (viewDrawList.size() > 0 && drawLists.size() == 0)
|
||||
{
|
||||
m_drawListView = viewDrawList;
|
||||
m_drawItemCount += static_cast<uint32_t>(viewDrawList.size());
|
||||
PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -172,12 +181,12 @@ namespace AZ
|
||||
drawLists.push_back(viewDrawList);
|
||||
|
||||
// combine draw items from mutiple draw lists to one draw list and sort it.
|
||||
size_t itemCount = 0;
|
||||
for (auto drawList : drawLists)
|
||||
{
|
||||
itemCount += drawList.size();
|
||||
m_drawItemCount += static_cast<uint32_t>(drawList.size());
|
||||
}
|
||||
m_combinedDrawList.resize(itemCount);
|
||||
PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
|
||||
m_combinedDrawList.resize(m_drawItemCount);
|
||||
RHI::DrawItemProperties* currentBuffer = m_combinedDrawList.data();
|
||||
for (auto drawList : drawLists)
|
||||
{
|
||||
@@ -202,7 +211,7 @@ namespace AZ
|
||||
void RasterPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
|
||||
{
|
||||
RenderPass::SetupFrameGraphDependencies(frameGraph);
|
||||
frameGraph.SetEstimatedItemCount(static_cast<u32>(m_drawListView.size()));
|
||||
frameGraph.SetEstimatedItemCount(static_cast<uint32_t>(m_drawListView.size()));
|
||||
}
|
||||
|
||||
void RasterPass::CompileResources(const RHI::FrameGraphCompileContext& context)
|
||||
|
||||
@@ -201,6 +201,8 @@ namespace AZ
|
||||
m_attachmentCopy.lock()->FrameBegin(params);
|
||||
}
|
||||
CollectSrgs();
|
||||
|
||||
PassSystemInterface::Get()->IncrementFrameRenderPassCount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-15
@@ -230,25 +230,20 @@ namespace AZ::Render
|
||||
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
||||
auto rootPass = viewportContext->GetCurrentPipeline()->GetRootPass();
|
||||
const RPI::PipelineStatisticsResult stats = rootPass->GetLatestPipelineStatisticsResult();
|
||||
AZStd::function<int(const AZ::RPI::Ptr<AZ::RPI::Pass>)> containingPassCount = [&containingPassCount](const AZ::RPI::Ptr<AZ::RPI::Pass> pass)
|
||||
{
|
||||
int count = 1;
|
||||
if (auto passAsParent = pass->AsParent())
|
||||
{
|
||||
for (const auto& child : passAsParent->GetChildren())
|
||||
{
|
||||
count += containingPassCount(child);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
const int numPasses = containingPassCount(rootPass);
|
||||
|
||||
RPI::PassSystemFrameStatistics passSystemFrameStatistics = AZ::RPI::PassSystemInterface::Get()->GetFrameStatistics();
|
||||
|
||||
DrawLine(AZStd::string::format(
|
||||
"Total Passes: %d Vertex Count: %lld Primitive Count: %lld",
|
||||
numPasses,
|
||||
"RenderPasses: %d Vertex Count: %lld Primitive Count: %lld",
|
||||
passSystemFrameStatistics.m_numRenderPassesExecuted,
|
||||
aznumeric_cast<long long>(stats.m_vertexCount),
|
||||
aznumeric_cast<long long>(stats.m_primitiveCount)
|
||||
));
|
||||
DrawLine(AZStd::string::format(
|
||||
"Total Draw Item Count: %d Max Draw Items in a Pass: %d",
|
||||
passSystemFrameStatistics.m_totalDrawItemsRendered,
|
||||
passSystemFrameStatistics.m_maxDrawItemsRenderedInAPass
|
||||
));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::UpdateFramerate()
|
||||
|
||||
Reference in New Issue
Block a user